파이썬에서는 리스트 안에 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번에 걸쳐 출력됨을 확인할 수 있습니다.


블로그 이미지

방구석 세계인

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

,

이번 포스팅에서는 turtle 모듈을 활용하여 키를 입력하면 아이콘이 움직이게 만들어 보겠습니다.


turtle 모듈 import 하기

from turtle import Turtle, Screen

먼저 위와 같이 작성해 줍니다. turtle은 turtle 이라는 모듈의 이름입니다.

우리는 아이콘을 만들고 스크린창을 띄워야 하니 Turtle(아이콘), Screen(스크린) 클래스를 import 할 것입니다.

여기서, turtle과 Turtle의 차이가 무엇인가 의문이 들 수 있습니다.

turtle은 모듈 이름이며, Turtle은 클래스 이름입니다. 어떤 것이 모듈이고, 클래스인지 구분하기 위해서 모듈은 소문자로, 클래스는 앞글자를 대문자로 명명하기로 규칙을 정하였습니다. 이것은 전 세계의 개발자들 사이에서 통용되는 규칙 입니다.


from turtle import Turtle, Screen

timmy = Turtle()
timmy.shape("turtle")
screen = Screen()

screen.exitonclick()

먼저 timmy라는 이름으로 아이콘(Turtle())을 만들었습니다. 그리고 shape 함수를 이용하여 모양을 거북이로 설정하였습니다.

여담으로 여기서 해당 모듈의 이름이 turtle인 이유를 추측할 수 있습니다. 기본 아이콘 모양이 거북이 이기 때문입니다.

다시 본론으로 돌아가서, 이제 스크린창을 만들어야 합니다. 그래서 screen이라는 이름으로 스크린(Screen())을 만들었습니다.

마지막으로 exitonclick 함수를 작성하여 스크린창이 화면에 계속 유지되도록 해줍니다.

함수를 실행하면 위와 같이 스크린창과 거북이 모양의 아이콘이 뜰 것입니다.


onkey 함수로 아이콘을 움직이게 만들기

파이썬에는 다양한 모듈이 존재하며 각 모듈들의 사용법을 설명해놓은 웹페이지가 있습니다.

turtle 모듈은 아래의 링크에서 사용법을 볼 수 있습니다.

(https://docs.python.org/3/library/turtle.html)


위의 링크에 들어가 살펴보면 listen과 onkey 함수의 기능에 대해 자세히 알아볼 수 있습니다.

onkey 함수는 onkey(key = X, fun = X)의 형태로 되어 있으며, key를 설정하면 function이 실행되는 구조입니다.

listen 함수는 onkey 함수를 실행하기 위해 따라오는 함수입니다.


만약 f 키를 눌렀을때 아이콘이 앞으로 움직이게 하고 싶다면 아래와 같이 코드를 작성하면 됩니다.

from turtle import Turtle, Screen

timmy = Turtle()
timmy.shape("turtle")
screen = Screen()

def move_fd():
timmy.forward(100)

screen.onkey(key="f", fun = move_fd)
screen.listen()
screen.exitonclick()

코드를 실행하고 f키를 누르면 위의 스크린샷처럼 아이콘이 앞으로 움직임을 확인할 수 있습니다.

이런 방식으로 뒤로가기, 시계방향으로 움직이기, reset하기 등 다양하게 응용할 수 있습니다.

블로그 이미지

방구석 세계인

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

,

함수(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/)


블로그 이미지

방구석 세계인

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

,

While 반복문

While 반복문은 특정 조건을 만족하면 반복문 안의 내용이 무한히 반복되도록 만드는 구문입니다.


#while loop

while True:
question = input("Do you like fruit? type Y or N : ")

위의 코드를 보겠습니다. True라는 조건에 맞으면, "Do you like fruit? type Y or N : "라는 질문이 계속 반복되는 구조입니다.


그럼 N을 입력했을 때 질문을 멈추게 하려면 어떻게 해야할까요?


break

#break

while True:
question = input("Do you like fruit? type Y or N : ")
if question == "N":
break

위의 코드처럼 break를 추가하면 반복문을 멈추게 할 수 있습니다. 이제 N을 입력하면 더 이상 질문이 반복되지 않고 종료될 것입니다.


continue

#continue

while True:
question = input("Do you like fruit? type Y or N : ")
if question == "N":
break
elif question == "Y" :
question2 = input("Do you like apple? type Y or N : ")

이번엔 Y를 입력했을 때 "Do you like apple? type Y or N : " 라는 질문이 이어지도록 코드를 추가하였습니다. 두번째 질문에서 N를 입력했을 때, 프로그램을 끝내지 않고 다시 첫번째 질문으로 돌아가려면 어떻게 해야할까요?


#continue

while True:
question = input("Do you like fruit? type Y or N : ")
if question == "N":
break
elif question == "Y" :
question2 = input("Do you like apple? type Y or N : ")
if question2 == "N":
continue
else :
print("I'll give you an apple.")
break

그렇다면 continue를 추가하면 됩니다. 이제 두번째 질문에서 N으로 답하면 프로그램이 끝나지 않고 다시 첫번째 질문으로 돌아가게 될 것입니다.


블로그 이미지

방구석 세계인

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

,