프로그래밍/python

[학교/파이썬/20.06.22] 과제2

pxatd 2020. 6. 30. 03:59
728x90

과제 2는 딕셔너리, tkinter 등 꽤 심화된 내용이 들어가서 과제를 하는데도 스토리빌드를 짜야하는(?) 마냥 생각없이 써내려갈 수 는 없었습니다. 이번 과제 역시 교수님께서 "두근두근파이썬"에서 5문제를 선정하셨습니다.

 

교수님께서 제시한 문제입니다. 

-9장 2번

-9장 8번

-10장 6번

-11장 5번

-13장 1번


9장 2번

주사위를 던져 나오는 값의 빈도를 계산하고 출력하는 프로그램입니다. 

random모듈을 활용한 가장 기본적인  문제라고 할 수 있죠 이 문제는 작년 겨울방학때 이미 C언어로 구현해본 적이 있어서 어렵지 않게 해낼 수 있었습니다. 

import random

counters=[0,0,0,0,0,0]

for i in range(1000):
    dice=random.randint(1,6)
    if dice==1:
        counters[0]=counters[0]+1
    elif dice==2:
        counters[1]=counters[1]+1
    elif dice==3:
        counters[2]=counters[2]+1
    elif dice==4:
        counters[3]=counters[3]+1
    elif dice==5:
        counters[4]=counters[4]+1
    elif dice==6:
        counters[5]=counters[5]+1
        

print("주사위가 1인 경우는",counters[0])
print("주사위가 2인 경우는",counters[1])
print("주사위가 3인 경우는",counters[2])
print("주사위가 4인 경우는",counters[3])
print("주사위가 5인 경우는",counters[4])
print("주사위가 6인 경우는",counters[5])

9장 8번

딕셔너리에 문제와 정답을 저장하고 하나씩 꺼내서 사용자에게 제시하는 프로그램입니다. 

print("다음은 어떤 단어에 대한 설명일까요?")
problems={"파이썬":"최근에 가장 떠오르는 프로그래밍 언어",
                  "변수":"데이터를 저장하는 메모리 공간",
                  "함수":"작업을 수행하는 문장들의 집합에 이름을 붙인것",
                  "리스트":"서로 관련이 없는 항목들의 모임"
        }
for word in problems.keys():
    print(problems[word])
    print("(1)파이썬 (2)함수 (3)리스트 (4)변수")
    userans=input()
        
    if userans==word:
        print("정답입니다. !")
    else:
        print("정답이 아닙니다.")
                
print("문제가 끝났습니다.")

 

제가 처음 생각했던 것은 딕셔너리에서 문제를 출력하고 사용자에게 답을 받아 둘을 비교한 뒤 맞으면 다음문제로, 틀리면 같은문제를 반복하며 맞출때까지 보여주는 프로그램을 만들고 싶었는데 문제의 조건인 "사용자는 번호로 답하지 말고 문자열로 답해야한다"를 지키다보니 마음대로 되지 않았습니다. 그 이유는 조건을 만족시키지 않으면 if-else 반복문을 통해 print(문자열로만 입력하십시오)를 출력하려고 코드를 작성했으나 그렇게되면 문자열입력 반복문 안에 또 정답입니다/아닙니다를 넣어야하고 이상하게 꼬여버리는 것이였습니다. break를 적절히 넣어 실행시켜봤지만 마음대로 작동하지 않았습니다. 이에대해 교수님께 질문했고, "문자열로만 입력하라"와 "같은 문제를 반복출력" 할 필요 없다 는 답변을 받았습니다. 따라서 지저분했던 코드를 모두 지우고 지금과같은 코드가 되었습니다.


10장 6번

tkinter를 사용하여 가위바위보 게임을 GUI버전으로 작성하는 문제입니다. 사용자의 결과는 왼쪽에, 컴퓨터의 결과는 오른쪽에 출력되고 최종 결과를 중앙에 보여주는 프로그램입니다. 

from tkinter import *
import random
import tkinter as tk
from PIL import Image, ImageTk

def push(a):
    global computer
    computer = random.randint(1, 3)
    canvas1.delete("all")

    if computer == 1: #가위
        canvas2.create_image (250, 200, image=tk_s1)
    elif computer == 2: #바위
        canvas2.create_image (250, 200, image=tk_r1)
    elif computer == 3: #보
        canvas2.create_image (250, 200, image=tk_p1)

    if a == "가위":
        canvas1.create_image (200, 200, image=tk_s1)

        if computer == 1:
            l1 = Label(window, text='======', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2= Label(window, width=10, text='무승부!',fg="darkgreen", font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 2:
            l1 = Label(window, text='<<<<<<',font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window,text='컴퓨터 승!',fg="darkgreen", font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 3:
            l1 = Label(window, text='>>>>>>',font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2= Label(window, text='사용자 승!',fg="darkgreen",font=("둥근모꼴",30,"bold"))
            l2.grid (row=1, column=1)

    elif a == "바위":
        canvas1.create_image (200, 200, image=tk_r1)

        if computer == 1:
            l1 = Label(window, text='>>>>>>', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window, text='사용자 승!',fg="darkgreen", font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 2:
            l1 = Label(window, text='======', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window, width=10,text='무승부!' ,fg="darkgreen",font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 3:
            l1 = Label(window, text='<<<<<<', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window, text='컴퓨터 승!',fg="darkgreen", font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

    elif a == "보":
        canvas1.create_image (200, 200, image=tk_p1)
        
        if computer == 1:
            l1 = Label (window, text='<<<<<<', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window, text='컴퓨터 승!', fg="darkgreen",font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 2:
            l1 = Label(window, text='>>>>>>', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window, text='사용자 승!',fg="darkgreen", font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

        elif computer == 3:
            l1 = Label(window, text='======', font = ("둥근모꼴",30, "bold"))
            l1.grid (row=0, column=1)
            l2 = Label(window,width=10, text='무승부!', fg="darkgreen",font = ("둥근모꼴",30, "bold"))
            l2.grid (row=1, column=1)

window = Tk()
window.title("두근두근 가위바위보")

canvas1 = tk.Canvas (window, width=500, height=400)
canvas1.grid(row=0, column=0)
canvas2 = tk.Canvas (window, width=500, height=400)
canvas2.grid (row=0, column=2)

s1=Image.open("scissor.png")
r1=Image.open("rock.png")
p1=Image.open("paper.png")
tk_s1=ImageTk.PhotoImage(s1)
tk_r1=ImageTk.PhotoImage(r1)
tk_p1=ImageTk.PhotoImage(p1)

num = 0
rsp = ["바위","보","가위"]
for loop in rsp:
    def clickRSP(j=loop):
        push(j)
    button=Button(window, text=loop,  font=("둥근모꼴",12,"bold"), width = 25, command=clickRSP)
    button.grid (row=2, column=num)
    num=num+1
    
window.mainloop

개인적으로 중간 대체 프로젝트만큼 시간을 오래 할애했던 문제입니다. 애초에 tkinter GUI가 익숙하지 않은 상황인데다 버튼이 눌릴 때 마다 전 동작이 화면에서 지워지고 새롭게 동작해야 하는 것을 구현하기가 어려웠습니다. 코드에서는 clickRSP 함수를 만들었지만 이것 역시 구글링의 도움을 받은 것입니다. 코드 마지막의 반복문 몇 줄을 제외하고는 크게 어려울 부분이 없지만 하나의 변수로 묶고, 화면을 구성하는 과정도 어려웠습니다. 책에는 자세히 설명되어있지 않아 블로그에 나와있는 설명을 정독하며 따라했는데, 그 결과 캔버스에 grid frame place pack 등 기본 개념은 확실하게 익힌 것 같습니다. 

이 문제에서 처음 코드를 짤 때 생각했던것은 하나의 window 안에 두개의 그림을 집어넣어 실행시키는 것이였습니다. (기존 기말 프로젝트도 window 하나로 사용했음) 그러나 하나의 window로 진행하니 그림을 따로 집어넣기가 어려웠고 자잘한 오류가 발생하였습니다. 그래서 아예 생각을 바꿔보자 하고 canvas1, canvas2로 나누어 배정하였습니다. 그렇게 했더니 각각의 객체가 올바르게 생성되어 문제에서 원하는 대로 작동 할 수 있었습니다. 

 

실행화면

 

 


11장 5번

텍스트 파일 data.txt에 실수값을 미리 저장해놓고, 이 파일을 읽어서 합계와 평균을 계산 한 후 output.txt로 저장하는 프로그램입니다. 

from tkinter import *

file=input("입력 파일 이름: ")
infile=open(file,"r")
readfile=infile.readlines()
infile.close()

total=0
avg=0
cnt=0

for line in readfile:
    total = total + float(line)
    cnt = cnt + 1
avg = total / cnt

file=input("출력 파일 이름: ")
outfile=open(file,"w")

outfile.write("합계=")
print(str(total),file=outfile)
outfile.write("평균=")
print(str(avg),file=outfile)
outfile.close()

13장 1번

원을 나타내는 클래스 Circle을 정의하고 반지름, 원의 둘레, 원의 면적을 출력하는 프로그램 입니다. 

class Circle:
    def __init__(self,radius):
        self.radius=radius

    def calcPerimeter(self): #원의 둘레 
        self.calcperimeter=3.141592*2*self.radius

    def calcArea(self): #원의 면적
        self.calcarea=3.141592*self.radius**2
    
myCircle=Circle(100)
print("반지름:  ",myCircle.radius,end="   ")
myCircle.calcArea()
print("원의 면적:  ",myCircle.calcarea,end="   ")
myCircle.calcPerimeter()
print("원의 둘레:  ",myCircle.calcperimeter,end="   ")

 

728x90