파이썬에서는 리스트 안에 for 반복문, if 구문을 넣어 코드를 간략화할 수 있습니다. 마찬가지로 딕셔너리 안에도 for 반복문, if 구문을 넣어 코드를 간략화 할 수 있습니다.


dictionary에 for 반복문 넣기 (list가 주어진 경우)


students = ["student a", "student b", "student c", "student d", "student e"]

students라는 리스트가 주어져 있습니다. 이제 리스트 안에 있는 5명의 학생에게 50~100 사이의 점수를 랜덤하게 부여하는 딕셔너리를 만들려고 합니다.


import random
students = ["student a", "student b", "student c", "student d", "student e"]

scores = {student:random.randint(50,100) for student in students}

print(scores)


위와 같이 딕셔너리를 만들 수 있습니다.


코드의 구조를 보면 아래와 같습니다.

variable = {key : value for key in list}


dictionary에 for 반복문 넣기 (dictionary가 주어진 경우)

students = {"student a" : 90,
"student b" : 80,
"student c" : 70,
"student d" : 60,
"student e" : 50}

이번에는 딕셔너리에 있는 학생 5명의 점수를 일괄적으로 10점 올려보도록 하겠습니다.

students = {"student a" : 90,
"student b" : 80,
"student c" : 70,
"student d" : 60,
"student e" : 50}

add_scores = {student : score + 10 for (student, score) in students.items()}

print(add_scores)

위와 같이 코드를 작성하여 모든 학생의 점수를 일괄적으로 10점 올렸습니다.


코드의 구조를 보면 아래와 같습니다.

variable = {new_key : new_value for (key, value) in dictionary.items()}

*딕셔너리 이름 뒤에는 .items()를 붙여야 에러가 발생하지 않습니다.



dictionary에 if 구문 넣기


이번에는 바로 위에서 만든 딕셔너리에서 점수가 80점 이상인 학생만 골라내 새로운 딕셔너리를 만들어 보겠습니다. 

students = {"student a" : 90,
"student b" : 80,
"student c" : 70,
"student d" : 60,
"student e" : 50}

add_scores = {student : score + 10 for (student, score) in students.items()}

passed_students = {student : score for (student, score) in add_scores.items() if score >= 80}

print(passed_students)

위의 코드 처럼 딕셔너리 안에 if 구문을 넣으면 점수가 80점 이상인 학생만 골라낼 수 있습니다.


코드의 구조를 보면 아래와 같습니다.

variable = {new_key : new_value for (key, value) in dictionary.items() if statement}


블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

 list에 for 반복문 넣기

1, 2, 3, 4, 5, 6, 7, 8, 9, 10 이라는 숫자들로 리스트를 만드려면 보통 아래와 같이 코드를 작성할 것입니다.

numbers = []
for i in range(1, 10+1):
numbers.append(i)

print(numbers)



위의 방식을 이용하면 3줄의 코드를 작성하여 numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 라는 리스트를 만들 수 있습니다. 하지만 파이썬에서는 단 한줄의 코드만으로 똑같은 리스트를 작성할 수 있습니다.


numbers = [n for n in range(1, 10+1)]

print(numbers)

위의 코드처럼 리스트 안에 for 반복문을 넣으면 단 한줄의 코드만으로도 numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 라는 리스트를 만들 수 있습니다.


for 반복문이 안에 들어가는 리스트의 구조는 아래와 같습니다.

variable = [<result> for <each value in the list> in <how many times will loop>]


list에 if 구문 넣기

numbers = [1, 2, 4, 523, 9, 11, 32, 6]

이번엔 위의 리스트에서 짝수만 골라서 새로운 리스트를 선언해보려고 합니다. if 구문을 이용하면 짝수만 골라낼 수 있을 것입니다. 여기서 만약 if 구문을 리스트 안에다 넣을 수 있다면 작성할 코드의 숫자를 줄일 수 있을 것입니다.


numbers = [1, 2, 4, 523, 9, 11, 32, 6]

even_numbers = [n for n in numbers if n % 2 == 0]

print(even_numbers)


if 구문이 안에 들어가는 리스트의 구조는 아래와 같습니다.

variable = [<result> for <each value in the list> in <how many times will loop> if statement]


블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

with 구문

파이썬에서는 확장자가 .py가 아닌 다른 파일도 읽어보거나 수정할 수 있습니다. (ex. .txt, .docx 파일) 이것을 가능하게 해주는 구문이 with 구문입니다.


먼저 위와 같이 .txt 파일 하나와 .py 파일 하나를 생성했습니다.

그 후, example.txt 파일 안에 아래와 같이 글자를 적고 저장했습니다.


이제 파이썬에서 example.txt의 내용을 읽어보도록 하겠습니다.


read, readline, readlines 함수

with open("example.txt") as greeting:
a = greeting.read()
print(a)

여기서 open 함수는 example.txt 파일을 연다는 뜻이며, as 구문은 example.txt 파일의 해당 파이썬 파일에서 쓸 변수 이름을 정해주는 역할을 합니다. 여기서는 as greeting이라 했으므로, example.txt는 greeting이라는 변수 이름을 얻었습니다.

마지막으로 read 함수는 example.txt의 내용을 출력해주는 역할을 합니다.


with open("example.txt") as greeting:
a = greeting.readline()
b = greeting.readline()
c = greeting.readline()
print(a)
print(b)
print(c)

readline 함수는 example.txt의 내용을 한줄씩 출력해주는 함수 입니다.

따라서 위의 코드에서 각각 변수 a는 Hello, 변수 b는 Hi, 변수 c는 Nice to meet you를 의미하게 됩니다.


with open("example.txt") as greeting:
a = greeting.readlines()
print(a)

readlines 함수는 example.txt의 내용 한줄 한줄을 리스트 안에 넣어주는 함수입니다.



with 구문의 3가지 모드 (read, write, append)

with 구문에는 3가지 모드가 있습니다. 읽기(read), 쓰기(write), 추가하기(append) 모드가 바로 그것입니다. 3가지 모드의 특성은 아래와 같습니다.


 mode ="r"(read)

읽기만 가능 

 mode="w"

(wirte)

쓰기만 가능 (*기존 내용에 덮어쓰기만 가능)

 mode="a"

(append)

쓰기만 가능 (*기존 내용에 추가하여 작성하기만 가능)


그럼 write모드를 이용하여 example.txt의 내용을 수정해보겠습니다.

with open("example.txt", mode="w") as greeting:
a = greeting.write("xin chao")

example.txt의 기존 내용은 모두 사라지고 xin chao라는 글자로 바뀐 것을 확인할 수 있습니다.

(*xin chao는 베트남어로 안녕하세요 라는 뜻입니다.)


블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

상속(inheritance)

클래스에는 상속(inheritance)이라는 개념이 있습니다. 두개 이상의 클래스가 있을 때, 상위에 있는 클래스가 하위에 있는 클래스에게 자신의 기능을 물려주는 것을 뜻합니다.


Example

class Korea(상위 클래스)가 가지고 있는 함수

population, ethnic_composition, who_has_sovereignty


class Seoul(하위 클래스)가 가지고 있는 함수

specialty, ethnic_composition, who_has_sovereignty


-> class Korea의 ethnic_composition, who_has_sovereignty 함수는 class Seoul이 가진 동일 이름의 함수와 값이 같음(*한국과 서울의 민족 구성 및 주권 소재는 같기 때문). 따라서 class Korea의 ethnic_composition, who_has_sovereignty는 class Seoul에 물려줄 수 있음.


이 때, 상위에 있는 class Korea는 super class(부모 클래스)라 하며, 하위에 있는 class Seoul은 sub class(자식 클래스)라고 부릅니다.


super class(부모 클래스) 와 sub class(자식 클래스)

이제 실제로 코드를 작성해보겠습니다.

super class로 class Mammal을, sub class로 class Human을 만들어 보겠습니다.

class Mammal:
def __init__(self):
print("Mammals")

def legs_arms(self):
self.legs = 2
self.arms = 2
print("Mammals have 2 legs and 2 arms")

def breathe(self):
print("Mammals inhale O2, exhale CO2")

class Human(Mammal):
def __init__(self):
super().__init__()
print("Humans")

def read_write(self):
print("Humans can read and write")

mammal = Mammal()
print()
human = Human()

실행결과는 아래와 같습니다.

class Mammal을 실행하니 Mammals이라 출력되었습니다.

그런데 class Human을 실행하니 Mammals 와 Humans가 같이 출력되었습니다. __init__ 함수에 Mammals를 프린트하라는 지시가 없었는데도 말입니다.


그 이유는 class Human의 __init__ 함수에 super class인 class Mammal의 __init__ 함수를 상속해주었기 때문입니다. ( super().__init__() )

그래서 class Human을 실행하면 class Mammal로 부터 상속받은 Mammals와 class Human 자체가 가지고 있는 Humans가 같이 출력된 것입니다.


그럼 혹시 class Mammal이 가진 모든 method들을 상속 받을 수 있을까요?


class Mammal:
def __init__(self):
print("Mammals")

def legs_arms(self):
self.legs = 2
self.arms = 2
print("Mammals have 2 legs and 2 arms")

def breathe(self):
print("Mammals inhale O2, exhale CO2")

class Human(Mammal):
def __init__(self):
super().__init__()
print("Humans")

def read_write(self):
print("Humans can read and write")

mammal = Mammal()
print()
human = Human()
print()
human.legs_arms()
human.breathe()

class Mammal의 legs_arms, breathe 함수를 class Human에게 주어 실행시켜보니 잘 실행됨을 확인할 수 있습니다.


class Mammal:
def __init__(self):
print("Mammals")

def legs_arms(self):
self.legs = 2
self.arms = 2
print("Mammals have 2 legs and 2 arms")

def breathe(self):
print("Mammals inhale O2, exhale CO2")

class Human(Mammal):
def __init__(self):
super().__init__()
print("Humans")

def read_write(self):
print("Humans can read and write")

mammal = Mammal()
print()
human = Human()
print()
mammal.read_write()

반면에 class Mammal에 없는 read_write 함수를 class Mammal에게 주고 실행시켜보니 에러가 발생합니다. sub class의 함수는 super class에 적용되지 않음을 확인할 수 있습니다. 


상속은 일반적으로 부모에서 자식에게 물려주는 것이지, 자식에서 부모로 물려주는 일은 아닙니다. 이 점을 생각하면 왜 위의 실행결과가 나오는지 쉽게 이해할 수 있습니다.



블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,


turtle 모듈을 이용하여 위와 같이 원 3개를 스크린창에 띄워보려고 합니다.

from turtle import Turtle, Screen

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
snake = []
for position in POSITIONS:
snake_segment = Turtle(shape="circle")
snake_segment.color("white")
snake_segment.shapesize(1, 1, 0.1)
snake_segment.penup()
snake_segment.speed("slowest")
snake_segment.goto(position)
snake.append(snake_segment)

screen.exitonclick()


실제로 코드를 실행해보면 왼쪽처럼 실행될 것입니다. (*gif 파일이 약간 깨져서 원이 겹쳐보입니다만 실제로 실행해보면 원이 겹쳐보이지는 않습니다.)

오른쪽처럼 3개의 원이 한번에 뜨도록 할 수는 없을까요??


turtle 모듈의 tracer, update 함수

turtle 모듈의 tracer 함수는 스크린창의 출력을 조절 할 수 있는 함수입니다. (*구체적인 내용은 아래의 표를 참고)


tracer = 0 

tracer = 1

 코드 0 

코드 0

코드 1

코드 1 

코드 2

코드 2 

코드 0,1,2

한번에

출력가능

 코드 0,1,2

하나씩

출력











from turtle import Turtle, Screen

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.tracer(0)
POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
snake = []
for position in POSITIONS:
snake_segment = Turtle(shape="circle")
snake_segment.color("white")
snake_segment.shapesize(1, 1, 0.1)
snake_segment.penup()
snake_segment.speed("slowest")
snake_segment.goto(position)
snake.append(snake_segment)

screen.exitonclick()

그럼 tracer함수를 작성하고, 매개변수는 0으로 한 다음 실행해보겠습니다.


실행해보니 아무것도 뜨지 않습니다. 왜냐하면 screen.tracer(0)의 정확한 의미는 코드들이 실행되는 과정을 스크린창에 출력하지 않는 것이기 때문입니다.

이럴때 필요한 함수가 update 함수입니다. 원을 만드는 코드인 for 반복문 아래에 update함수를 넣으면, 원이 생성되는 과정은 보여주지 않으면서 3개의 원이 생성된 결과만 보여줄 수 있습니다.

from turtle import Turtle, Screen

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.tracer(0)
POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
snake = []
for position in POSITIONS:
snake_segment = Turtle(shape="circle")
snake_segment.color("white")
snake_segment.shapesize(1, 1, 0.1)
snake_segment.penup()
snake_segment.speed("slowest")
snake_segment.goto(position)
snake.append(snake_segment)
screen.update()

screen.exitonclick()


screen.tracer(0)의 영향을 받는 코드들은 정상적으로 실행되고 있으나 스크린창에는 뜨지 않습니다.

하지만 중간 중간에 update 함수를 넣으면 그동안 실행되었던 코드들이 스크린창에 업데이트 되는 효과를 볼 수 있습니다.


그럼 3개씩 총 6개의 원을 스크린에 뜨게 해보겠습니다. 원은 2번에 걸쳐서 스크린에 뜨게 될 것입니다. 

from turtle import Turtle, Screen
import time

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.tracer(0)
POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
POSITIONS2 = [(-60, 0), (-80, 0), (-100, 0)]
snake = []
time.sleep(3)
for position in POSITIONS:
snake_segment = Turtle(shape="circle")
snake_segment.color("white")
snake_segment.shapesize(1, 1, 0.1)
snake_segment.penup()
snake_segment.speed("slowest")
snake_segment.goto(position)
snake.append(snake_segment)
screen.update()
time.sleep(3)

for position in POSITIONS2:
snake_segment = Turtle(shape="circle")
snake_segment.color("white")
snake_segment.shapesize(1, 1, 0.1)
snake_segment.penup()
snake_segment.speed("slowest")
snake_segment.goto(position)
snake.append(snake_segment)
screen.update()
screen.exitonclick()

time 모듈의 sleep 함수를 이용하면 원이 출력되는 2번의 과정 사이에 3초의 텀을 줄 수 있습니다.

그래서 중간에 sleep 함수를 추가하였습니다.

실행해보면 위처럼 원이 3개씩 2번에 걸쳐 출력됨을 확인할 수 있습니다.


블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

함수(function)를 매개변수(parameter)로 사용하는 경우

def add(n1, n2):
return n1 + n2
def subtract(n1, n2):
return n1 - n2
def multiply(n1, n2):
return n1 * n2
def divide(n1, n2):
return n1 / n2

파이썬에서 기본 사칙연산 (더하기, 빼기, 곱하기, 나누기)을 수행하는 함수를 만들어 보았습니다.

총 4개의 함수가 만들어졌습니다. 

위의 함수를 이용하여 4+5를 계산해보고 싶다면 add(4, 5)를 작성하고 실행해주면 될 것입니다.


Example

5+9 = add(5, 9)

9-7 = subtract(9, 7)

8*12 = multiply(8, 12)

90/21 = divide(90, 21)


그런데 함수를 하나만 더 작성한다면 좀 더 편리하게 만들 수 있습니다.


def add(n1, n2):
return n1 + n2
def subtract(n1, n2):
return n1 - n2
def multiply(n1, n2):
return n1 * n2
def divide(n1, n2):
return n1 / n2

def calculator(n1, n2, func):
return func(n1, n2)

print(calculator(2,3,subtract))

그래서 calculator라는 함수를 하나 더 만들어 보았습니다. 그리고 calculator의 매개변수로 func을 추가했습니다. 이제 매개변수 func의 자리에 필요한 함수를 넣는다면 원하는대로 계산을 해줄 것입니다.


Example

5+9 = calculator(5, 9, add)

9-7 = calculator(9, 7, subtract)

8*12 = calculator(8, 12, multiply)

90/21 = calculator(90, 21, divide)



블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

튜플 (tuple)

튜플은 다른 프로그래밍 언어에는 없고, 파이썬에만 있는 특별한 기능 중 하나입니다.

튜플은 리스트 (list)와 같은 자료형으로, 생긴것도 리스트와 비슷하게 생겼습니다.


list_example = [1, 2, 3, 4, 5]
tuple_example = (1, 2, 3, 4, 5)

리스트, 튜플을 각각 하나씩 선언해보았습니다. 리스트는 []로 감싸지며, 튜플은 ()로 감싸진다는 차이점을 알 수 있습니다.


그럼 리스트, 튜플 사이의 기능적 차이점은 어떻게 될까요?


리스트

list_example = [1, 2, 3, 4, 5]
print(list_example)

list_example[0] = 10
print(list_example)


튜플

tuple_example = (1, 2, 3, 4, 5)
print(tuple_example)

tuple_example[0] = 10
print(tuple_example)

리스트는 이미 선언된 요소를 중간에 자유롭게 바꿀 수 있습니다.

그래서 처음에 [1, 2, 3, 4, 5]로 선언된 것을 [10, 2, 3, 4, 5]로 바꿀 수 있었습니다.

하지만 튜플은 한번 선언된 요소를 중간에 바꿀 수 없습니다.

그래서 [1, 2, 3, 4, 5]로 선언된 것을 [10, 2, 3, 4, 5]로 바꾸려하자 에러가 발생했습니다.



프로그램을 작성하다보면 리스트 내부의 요소를 변경해서는 안되는 일이 생길 수 있습니다.

그럼 해당 리스트에 주석을 달아놓던지하여 요소를 변경해서는 안된다고 표시해줄 수 있을 것입니다. 하지만 프로그램은 한 번 만들면 끝이 아니라 이후 계속 유지, 보수를 해줘야 합니다. 그러나 시간의 흐름에 따라 해당 리스트 내부의 요소를 변경해서는 안된다는 사실을 잊어버릴 수도 있습니다.

그럴때 아예 튜플로 선언해버리면 해당 문제를 사전에 예방할 수 있을 것입니다.

 


튜플 (tuple) 선언 할 때 tip

1. 튜플 내 요소를 하나만 생성하고 싶을 때

tuple_example = (1,) O
tuple_example = (1) X

요소가 하나뿐이더라도 튜플을 생성할 때에는 요소 뒤에 항상 comma(,)를 붙여야 합니다.


2. 괄호 생략

#둘 다 가능함
tuple_example = (1, 2, 3, 4, 5)

tuple_example = 1, 2, 3, 4, 5

튜플을 생성할 때, 괄호를 쓰지 않아도 아무 문제 없이 정상적으로 생성됩니다.

블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

커피 자판기 만들기 (실습)

이번에는 커피 자판기 프로그램을 만들어 보려고 합니다. (물론 실제로 커피를 만들어주는 프로그램이 아니라 가상의 커피 자판기를 만드려는 것입니다)

espresso, latte, cappuccino 이렇게 3가지의 메뉴를 뽑을 수 있고, report를 입력했을 땐 남은 재료 현황, off를 입력했을땐 자판기 작동이 멈추도록 프로그램을 짜려고 합니다.

먼저 아래의 코드를 복사, 붙여넣기 한 후 몇 번 동작시켜서 자판기의 구조를 파악해보시길 바랍니다.


# current resources status
water = 1000
milk = 600
coffee = 300
money = 0

# coins setting / quarters : 0.25, dimes : 0.10, nickles : 0.05, pennies : 0.01
quarter = 0.25
dime = 0.10
nickle = 0.05
penny = 0.01

def running() :
"""coffee machine running"""
global water, milk, coffee, money
# is resources sufficient? (if not, print current status)
switch = True
while switch:
# prompt user by asking "what would you like?? (espresso/latte/cappuccino) : "
question = input("What would you like? espresso(1.5$) / latte(2.5$) / cappuccino(3.0$) : ")

# report function (shows current resources up. hidden function for maintainers)
if question == "report":
print(f"Current stock \n water : {water}ml \n milk : {milk}ml \n coffee : {coffee}g \n money : {money}$")
continue
elif question == "off":
switch = False

# coin insert question and make progress
input_quarter = float(input("How many quarters?(0.25$) : "))
input_dime = float(input("How many dimes(0.10$) : "))
input_nickle = float(input("How many nickles(0.05$) : "))
input_penny = float(input("How many pennies(0.01$) : "))

def coin_calculation(coin, input_coin) :
"""calculate inputted coins"""
coin *= input_coin
return coin

inputted_money = float(coin_calculation(quarter, input_quarter))

+ float(coin_calculation(dime, input_dime)) + float(coin_calculation(nickle, input_nickle))

+ float(coin_calculation(penny, input_penny))

# check inserted coins are enough or not / stock check / money check
if question == "espresso" and inputted_money > 1.5:
if water >= 50 and coffee >= 18:
print(f"Here is espresso and ${round(inputted_money - 1.5, 2)} in change")
money += 1.5
water -= 50
coffee -= 18
else:
if water < 50:
print("Sorry, there is no water enough.")
if coffee < 18:
print("Sorry, there is no coffee enough.")
elif question == "latte" and inputted_money > 2.5:
if water >= 200 and milk >= 150 and coffee >= 24:
print(f"Here is latte and ${round(inputted_money - 2.5, 2)} in change")
money += 2.5
water -= 200
milk -= 150
coffee -= 24
else:
if water < 200:
print("Sorry, water is not enough.")
if milk < 150:
print("Sorry, milk is not enough.")
if coffee < 24:
print("Sorry, coffee is not enough.")
elif question == "cappuccino" and inputted_money > 3.0:
if water >= 250 and milk >= 100 and coffee >= 24:
print(f"Here is cappuccino and ${round(inputted_money - 3.0, 2)} in change")
money += 3.0
water -= 250
milk -= 100
coffee -= 24
else:
if water < 250:
print("Sorry, there is no water enough.")
if milk < 100:
print("Sorry, there is no milk enough.")
if coffee < 24:
print("Sorry, there is no coffee enough.")
else:
print("You inserted not enough money or chose wrong menu.")


running()

몇번 작동 시킨 후, 다시 작성된 코드를 봅니다. 위의 코드는 작동하는데에는 문제가 없습니다. 하지만 자판기에 메뉴를 추가한다던지, 재료 사용량을 바꾼다던지, 가격을 바꾼다던지 등등.. 프로그램을 수정할 일이 생기면 어떨까요? 위의 코드는 수정하기에 조금 불편할 것입니다.

프로그램은 한 번 완성하면 끝나는 것이 아닙니다. 버그를 찾아 수정해야하고, 버전을 업데이트해야하는 경우도 많습니다. 그렇기 때문에 코드를 읽기 쉽게, 그리고 나중에 수정하기 쉽게 작성할 필요가 있습니다. 이번 포스팅에서는 그 중, 수정하기 쉽게 작성하기에 포커스를 맞춰볼 것입니다.



dictionary를 이용해 코드 간소화

#1
MENU = {
"espresso": {
"ingredients": {
"water": 50,
"coffee": 18,
},
"cost": 1.5,
},
"latte": {
"ingredients": {
"water": 200,
"milk": 150,
"coffee": 24,
},
"cost": 2.5,
},
"cappuccino": {
"ingredients": {
"water": 250,
"milk": 100,
"coffee": 24,
},
"cost": 3.0,
}
}
resources = {
"water": 1000,
"milk": 600,
"coffee": 300,
}
profit = 0
#4
def is_ingredient_sufficient(order_ingredients):
"""return True if ingredients are enough, return False if ingredients are not enough"""
for item in order_ingredients:
if order_ingredients[item]>resources[item]:
print(f"sorry. {item} is not enough.")
return False
return True

#6
def coin_process():
"""insert coins and sum up how much is it"""
print("please insert coins")
total = float(input("How many quarters?(0.25$) : ")) * 0.25
total += float(input("How many dimes?(0.10$) : ")) * 0.10

total += float(input("How many nickles?(0.05$) : ")) * 0.05

total += float(input("How many pennies?(0.01$) : ")) * 0.01

return total

#8
def is_transaction_successful(money_inputted, beverage_cost):
"""Return True if money is enough. return False if money is not enough"""
if money_inputted >= beverage_cost:
charge = round(money_inputted - beverage_cost, 2)
print(f"${charge} in charge.")
global profit
profit += beverage_cost
return True
else :
print("Sorry. That is not enough money.")
return False

#10
def make_coffee(ordered_ingredients, beverage_name):
"""Deduct the required ingredients from the resources"""
for item in ordered_ingredients:
resources[item] -= ordered_ingredients[item]
print(f"Here is your {beverage_name}.")

#2
is_on = True
while is_on:
#3
choice = input("What would you like? espresso(1.5$) / latte(2.5$) / cappuccino(3.0$) : ")
if choice == "off":
is_on = False
elif choice == "report":
print("Current stock")
print(f"water : {resources['water']}ml")
print(f"milk : {resources['milk']}ml")
print(f"coffee : {resources['coffee']}g")
print(f"money : ${profit}")
else:
#5
drink = MENU[choice]
if is_ingredient_sufficient(drink['ingredients']):
#7
payment = coin_process()
#9
if is_transaction_successful(payment, drink['cost']):
#11
make_coffee(drink['ingredients'], choice)

이번에는 각 메뉴에 들어가는 재료, 비용을 딕셔너리로 만든 후 다시 코드를 작성하였습니다.

이제 메뉴, 재료, 가격 등을 수정하려면 딕셔너리 내부 위주로하여 쉽게 수정하실 수 있을 것입니다.


그리고 코드를 작성한 순서를 매겨보았습니다. 

while 반복문 안에 커피를 뽑는 과정을 작성하면서 필요한 함수들이 생기면 추가하는 방식으로 작성하였습니다.




*이 글은 Udemy 강좌 100 Days of Code - The Complete Python Pro Bootcamp for 2021의 Day 15 (intermediate) - Local Development Environment Setup & Coffee Machine Project 내용을 바탕으로 작성하였습니다.

(URL : https://www.udemy.com/course/100-days-of-code/)


블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,

* 저도 프로그래밍을 처음 공부 하는 것이기 때문에 틀린 설명이 있을 수도 있습니다. 그런 부분을 발견했을 때 따끔한 피드백을 주시면 감사하겠습니다!


if 조건문만 활용하여 경우의 수 만들기

1~100사이의 숫자를 랜덤으로 2개를 뽑아 변수 a, b를 만들고, a, b 중 누가 더 큰지 맞추는 간단한 프로그램을 만들어 보겠습니다.


import random

numbers = range(1,100+1)

a = random.choice(numbers)
b = random.choice(numbers)

guess = input("Which one is bigger? type a, b, or match : ")

변수 a, b를 설정하였고, 프로그램을 실행했을 때 a, b 중 하나를 선택할 수 있도록 input 함수까지 작성하였습니다.

그 다음으로, 답을 선택 했을 때 나올만한 경우의 수를 생각해보도록 하겠습니다.
아래의 표 처럼 총 9가지 경우의 수가 나올 것입니다.


 a>b and guess = "a" 

 (right)

a<b and guess = "a" 

 (wrong) 

a=b and guess = "a" 

 (wrong) 

 a>b and guess = "b" 

(wrong)

a<b and guess = "b" 

(right) 

 a=b and guess = "b" 

(wrong) 

 a>b and guess = "match" (wrong)

 a<b and guess = "match" (wrong)

 a=b and guess = "match" (right)



그럼 if 조건문을 활용하여 9가지의 경우의 수와 그에 따른 결과를 입력해보겠습니다.


#if 조건문만 활용

import random

numbers = range(1,100+1)

a = random.choice(numbers)
b = random.choice(numbers)

guess = input("Which one is bigger? type a, b, or match : ")

if a>b and guess == "a" :
    print(f"right. result : a = {a}, b = {b}")
elif a>b and guess == "b" :
    print(f"wrong. result : a = {a}, b = {b}")
elif a>b and guess == "match" :
    print(f"wrong. result : a = {a}, b = {b}")  
elif a<b and guess == "a" :
    print(f"wrong. result : a = {a}, b = {b}")
elif a<b and guess == "b" :
    print(f"right. result : a = {a}, b = {b}")
elif a<b and guess == "match" :
    print(f"wrong. result : a = {a}, b = {b}")
elif a==b and guess == "a" :
    print(f"wrong. result : a = {a}, b = {b}")
elif a==b and guess == "b" :
    print(f"wrong. result : a = {a}, b = {b}")
elif a==b and guess == "match" :
    print(f"right. result : a = {a}, b = {b}")


표의 내용을 참고하여 위와 같이 입력하면 될 것입니다.

하지만 왠지 경우의 수가 너무 많아 복잡해보입니다.. 경우의 수가 이것보다 더 많다면, 일일히 if 조건문으로 모든 경우의 수를 입력하기 힘들 것입니다. 그리고 경우의 수를 일일히 입력하다보면 실수로 코드를 잘못 입력할 가능성도 그만큼 올라갈 것입니다. 게다가 오류가 발생한다면, 어디서 오류가 났는지 찾는 것도 번거로울 것입니다.

이럴 때는 return과 boolean을 활용하여 경우의 수를 줄이는 것이 더 효과적일 것입니다.



return과 boolean을 활용한 조건문 간소화

#return과 boolean 활용

import random

numbers = range(1,100+1)

a = random.choice(numbers)
b = random.choice(numbers)

guess = input("Which one is bigger? type a or b, or match : ")
def check(guessab) :
    if a == b :
        return guess == "match" 
    elif a > b :
        return guess == "a"
    elif a < b :
        return guess == "b"

result = check(guess, a, b)

if result == True :
    print(f"right. result : a = {a}, b = {b}")
else : 
    print(f"wrong. result : a = {a}, b = {b}")


먼저 check라는 함수를 만들었습니다. 우리가 답으로 선택할 수 있는 경우의 수는 a, b, match 이렇게 3가지가 있을 것입니다. 이것을 if 조건문과 return 기능을 통해, a = b이면 guess는 match, a > b이면 guess는 a, a < b이면 guess는 b가 되도록 설정하였습니다.

그 다음으로는 result = check(guess, a, b)라고 변수를 선언하였습니다.

마지막으로 boolean을 활용하여 유저가 직접 입력한 답과 check 함수에서 만든 조건과 일치하면 정답, 일치하지 않으면 오답이라고 출력되도록 만들었습니다.






프로그램을 실행해보면 위의 스크린샷 처럼 잘 작동되고 있음을 확인할 수 있습니다.


이렇게 return과 boolean을 활용하면 경우의 수가 줄어들기 때문에 써야하는 if 구문의 숫자도 줄일 수 있다는 장점이 있습니다. 

블로그 이미지

방구석 세계인

관심분야 : 외국어 학습, 프로그래밍, 책 리뷰 등...

,