Python

tabi·2022년 10월 1일
0

Python

목록 보기
2/2

https://www.youtube.com/watch?v=kWiCuklohdY&list=PLMsa_0kAjjrd8hYYCwbAuDsXZmHpqHvlV&index=2&t=5226s&ab_channel=%EB%82%98%EB%8F%84%EC%BD%94%EB%94%A9 나도코딩님 강의를 바탕으로 공부한 내용입니다.

1. 출력

print("Python")

-문자열: ("또는 '를 문자열 앞 뒤에 붙여준다.)
-숫자열: (붙이지 않아도 됨)

print(10)

-Boolean(참/거짓)

print(5>3) #True

2. 변수

Animal = "강아지"
Name = "Tabi"
Age = 3
Is_adult = Age >= 2     

이후 Print 문에서 출력 시

print(" 우리집 " + Animal + "의 이름은 " + Name + "예요")
print(Name + "는 " + str(age) + "살이에요.)
print(Name + "는 어른일까요? " + str(is_adult))

정수형과 Boolean은 str( )로 감싸준다.

3. 주석

-주석 처리 시 # 적고 기록
-여러문장을 주석 처리 시

문장을
주석처리
가능

앞 뒤를 작은 따옴표로 감싸줌
-Ctrl+/ 눌러 주석처리도 가능

4. 연산자

1) 사칙연산

print(1+1) #2
print(4-2) #2
print(2*4) #8
print(8/2) #4

2) 제곱, 나머지, 몫

print(2**3) #2^3 = 8
print(5%3) #나머지 구하기 = 2
print(5//3) #몫 구하기 = 1

3) 비교

print(9 > 2) #True
print(7 >= 8) #False
print(5 <= 5) #True

4) 같은 값 표현

print(4 == 4) #True
print(3 == 2) #False
print(2 + 3 == 5) #True

5) 같지 않은 값 표현

print(1 != 3) #True
print(not(1 != 3) #False, Not은 뒤에 있는 값의 반대를 의미함

6) 다중조건

print((3 > 0) and (3 < 5)) #True
print((5 > 1) or (3 > 5)) #True

And = 모두 만족, and는 &로도 표현가능
Or = 둘 중 하나만 만족, or는 |로도 표현가능

5. 수식과 변수

print((1 + 3) * 2) #8
number = 1 + 3 * 2 #7
print(number)
number = number + 3 #10
print(number) #10

number = number + 3 #10
위 문장을 줄여 쓰고 싶다면

number += 3
print(number) #10

number *= 2
print(number) #20

number /= 2
print(number) #10

number -= 2
print(number) #8

number %= 3
print(number) #2

6. 숫자처리함수

1) 절대값(abs)

print(abs(-5)) #5

2) 제곱(pow)

print(pow(4, 2)) #4^2 = 4*4 =16

3) 최대값&최소값(max, min)

print(max(5, 10)) #10
print(min(2, 7)) #2

4) 반올림(round)

print(round(3.14)) #3
print(round(3.99)) #4

5) 파이썬 Math library 이용하기

from math import *
print(floor(4.88)) #내림, 4
print(ceil(4.11)) #올림, 5
print(sqrt(16)) #제곱근, 4

7. 랜덤함수

from random import *
print(random()) #0.0 포함 ~ 1.0 미만의 임의의 값 생성
print(random() * 10) #0.0 포함 ~ 10.0 미만의 임의의 값 생성

소숫점을 빼고 싶다면(int)

print(int(random() * 10)) #0 포함 ~ 10 미만의 임의의 값 생성

결과값에서 0을 빼고, 10을 포함시키고 싶다면(+1)

print(int(random() * 10) + 1) #1 포함 ~ 10 이하의 임의의 값 생성

위 문장들을 조금 더 쉽게 표현하고 싶다면(randrange, 앞만 포함)

print(randrange(1, 11)) #1 포함 11 미만의 임의의 값 생성

위 문장들을 조금 더 쉽게 표현하고 싶다면(randint, 양 끝 모두 포함)

print(randint(1, 10)) #1 포함 10 이하의 임의의 값 생성

8. 문자열

1) 문자열

sentence = '나는 소년입니다.'
print(sentence) #나는 소년입니다.
sentence2 = "오늘은 날씨가 좋아요."
print(sentence2) #오늘은 날씨가 좋아요.
sentence = """
나는 소년이고,
오늘은 날씨가 좋아요.
"""
print(sentence3) #(줄바꿈) 나는 소년이고, 오늘은 날씨가 좋아요. (줄바꿈)

큰 따옴표 세 개를 앞 뒤로 붙이면 줄바꿈이 된다.

2) 슬라이싱(원하는 정보만 잘라서 가져오는 것)

jumin = "990120-1234567"
print("성별 : " + jumin[7]) #성별정보는 7번째에 위치해있으므로 7 입력
print("연 : " + jumin[0:2]) #0:2는 0번째 자리부터 2번째 직전까지의 수를 가져옴(0,1)
print("월 : " + jumin[2:4]) #2, 3번째 값을 가져옴
print("일 : " + jumin[4:6]) #4, 5번째 값을 가져옴

print("생년월일 : " + jumin[:6]) #앞에 0을 적지 않아도 됨(0:6), 처음부터 6번째 직전까지의 수를 가져옴
print("뒤 7자리 : " + jumin[7:]) #뒤에 14를 적지 않아도 됨(7:14), 7번째부터 끝까지의 수를 가져옴

print("뒤 7자리(뒷자리부터) : " + jumin[-7:]) #뒷자리부터 가져오려면 맨 뒤는 -1번째, -7번째까지 가져옴

가져오고 싶은 정보의 위치를 jumin[] 대괄호 사이에 넣어준다.
앞자리는 0부터 conunt

3) 문자열 처리 함수

  • 소문자(lower)/대문자(upper)로 표현하기
python = "Python is Amazing"
print(python.lower()) #python is amazing
print(python.upper()) #PYTHON IS AMAZING

#첫번째 값이 대문자(isupper)인지 확인하려면?
print(python[0].isupper()) #python 변수의 첫번째 위치가 대문자인지, True

#문자열의 길이(length)를 알고싶다면?
print(len(python)) #17

#문자열의 단어를 바꾸고(replace) 싶다면?
print(python, replace("Python", "Java")) #Java is amazing

#어떤 문자가 어느 위치(index)에 있는지 확인하고 싶다면?
index = python.index("n")
print(index) #python이라는 문장에서 n이 몇번째에 있는지 확인가능, 5
index = python.index("n", index + 1) #앞에서 n을 찾고, 그 이후 위치를 다시 검색
print(index) #15

print(python.index("Java")) #index 사용 시 없는 문자를 찾으면 오류가 발생하게 되고, 이후에 다른 명령어를 입력해도 작동하지 않음.

#원하는 문자가 포함(find)되어 있는지 알고싶다면?
print(python.find("Java")) #-1, 포함되어 있지 않은 경우 -1로값이 나옴

#원하는 문자가 몇 번 나오는지 횟수(count)를 알고 싶다면?
print(python.count("n"))

4) 문자열 포맷, 문자열 표현방식

print("a" + "b") #ab
print("a", "b") #a b
'''

# 4-1) 방법1
'''python
	#1. 원하는 위치에 원하는 정수값(d) 입력하기
print("나는 %d살 입니다." % 20)
	#2 원하는 위치에 원하는 문자열(s) 입력하기
print("나는 %s을 좋아해요." % "파이썬")
print("나는 %s색과 %s색을 좋아해요." % ("파란", "빨간"))
	#3 원하는 위치에 원하는 단일문자(c) 입력하기
print("Apple 은 %c 로 시작해요." % "A")
	# *참고* %s를 사용하면 정수, 문자열, 문자에 상관없이 출력가능하다.
	#4 원하는 위치에 원하는 문자열(s) 두 개 이상 입력하기
# 4-2) 방법2
print("나는 {}살입니다.".format(20)) #나는 20살입니다.
print("나는 {}색과 {}색을 좋아해요.".format("파란", "빨간")) #나는 파란색과 빨간색을 좋아해요.(연속적으로 입력한 값이 출력)
print("나는 {0}색과 {1}색을 좋아해요.".format("파란", "빨간")) #나는 파란색과 빨간색을 좋아해요.
# 4-3) 방법3
print("나는 {age}살이며, {color}색을 좋아해요.".format(age = 20, color = "빨간)) #나는 20살이며, 빨간색을 좋아해요.
# 4-4) 방법4(Python ver. 3.6 이상에서 사용가능)
age = 20
color = "빨간"
print(f"나는 {age}살이며, {color}색을 좋아해요.")

9. 리스트

= 순서를 가지는 객체의 집합

# 리스트 []
#지하철 칸별로 10명, 20명, 30명이 타고 있는 경우를 묶는다면?
subway1 = 10
subway2 = 20
subway3 = 30
subway = [10, 20, 30]
print(subway) # [10, 20, 30]

#문자로도 표현가능하다
subway = ["a", "b", "c"]
print(subway) # ['a', 'b', 'c']

#a가 몇 번째 칸에 타고 있는지?
print(subway.index("a")) #0, 1, 2순으로 보면 1번째에 탑승하고 있다.

#다음 정류장에서 d가 탑승함
subway.append("d")
print(subway) #['a', 'b', 'c', 'd']

#다음 정류장에서 e가 a와 b 사이에 탑승함
subway.insert(1, "e")
print(subway) #['a', 'e', 'b', 'c', 'd']

#지하철에 있는 사람을 한 명씩 뒤에서 꺼냄
print(subway.pop()) #d
print(subway) #['a', 'e', 'b', 'c']

#같은 이름의 사람이 몇 명 있는지 확인
subway.append("a")
print(subway) #['a', 'e', 'b', 'a']
print(subway.count("a") #2

#정렬하기
list = [5,2,3,1,4]
list.sort()
print(list) #[1, 2, 3, 4, 5]

#뒤집어 정렬하기
list.reverse()
print(list) #[5, 4, 3, 2, 1]

#모두 지우기
list.clear()
print(list) #[]

#자료형을 섞어 사용 가능
mix_list = ["a", 20, true]
print(mix_list)

#리스트 확장
list = [5,2,3,1,4]
mix_list = ["a", 20, true]
list.extend(mix_list)
print(list)

10. 사전(Dictionary)

{} 중괄호 사용
1) 기본

cabinet = {5:"a", 10:"b"} #5번 열쇠를 a가, 10번 열쇠를 b가 가지고 있음
cabinet = {"가": "a", "나":"b"} #문자형으로도 가능

2) 사전 자료형에서 값 가져오기

# List와 달리 index는 지원하지 않음

print(cabinet[5]) #a
print(cabinet.get(5)) #a

print(cabinet[7]) #오류발생함, 이후 명령문은 출력되지 않음
print(cabinet.get(8)) #None, 이후 명령문 출력 가능
print(cabinet. get(8, "사용가능")) #사용 가능

3) 사전 자료형에 값이 있는지 확인하기

print(5 in cabinet) #True
print(3 in cabinet) #False

4) 새로운 사람이 오면?

print(cabinet)
cabinet["A-9"] = "철수" #캐비넷에 A-9번을 만들고 그 키에 철수가 들어가는 것, 이전에 사용중인 숫자인 경우 값이 업데이트 됨

5) 손님이 간 경우

del cabinet["A-9"]

6) 현재 사용 중인 Key만 출력하려는 경우

print(cabinet.keys())

7) Value들만 출력

print(cabinet.values())

8) 모두 출력

print(cabinet.items())

9) 캐비넷 영업 종료?

cabinet.clear()
print(cabinet) #{}

10) Dictionary 합치기

# List는 +기호, Set는 .union() 혹은 |를 이용해 합칠 수 있으나 Dic에서는 다른 방법을 사용해야 함.
# 다만 Key의 값은 중복되지 않으므로 중복되는 Key가 존재할 경우 뒤에 입력한 Key의 값이 앞의 것으로 변경됨.

#첫번째: update 함수 이용하기
A = {"과자": 100, "아이스크림": 50}
B = {"사탕": 20, "껌": 5}
A.update(B)
print(A) #{'과자': 100, '아이스크림': 50, '사탕': 20, '껌': 5}

#두번째: dict 함수 이용하기
A = {"과자": 100, "아이스크림": 50}
B = dict(사탕=20,=5)
C = dict(A, **B)
print(C) #{'과자': 100, '아이스크림': 50, '사탕': 20, '껌': 5}

11) Tuple을 Dictionary로 변환하기

#첫번째: dict() 함수 이용하기
A = (("과자", 100), ("아이스크림", 50), ("사탕", 20)) #튜플이 다음과 같은 형식으로 주어졌을 때,
Result = dict((x, y) for x, y in A)
print(Result) #{'과자': 100, '아이스크림': 50, '사탕': 20}

#두번째: Using Dictionary Comprehension(???????) & enumerate() 함수 이용하기

#세번째: zip(), dict() 함수 이용하기
A = ("과자", "아이스크림", "사탕")
B = (100, 50, 20) #튜플이 다음과 같은 형식으로 2개 주어졌을 때 key와 value의 개수가 일치하는 만큼만 출력됨
Result = dict(zip(A, B)) #zip함수가 A 튜플을 Key로, B 튜플을 value로 가져옴
print(Result) #{'과자': 100, '아이스크림': 50, '사탕': 20}

12) List를 Dictionary로 변환하기

A = ["과자", "아이스크림", "사탕"]
B = [100, 50, 20]
#위와 같은 List가 2개 있다고 할 때

#첫번째: for, remove 이용하기
Result = {} #빈 Dictionary 만들어주기
for key in A:
  for value in B:
    Result[key] = value
    B.remove(value)
    break
print(Result) #{'과자': 100, '아이스크림': 50, '사탕': 20}

#두번째: for, range 이용하기
Result = {A[i]: B[i] for i in range(len(A))}
print(Result) #{'과자': 100, '아이스크림': 50, '사탕': 20}

#세번째: zip(), dict() 함수 이용하기
Result = dict(zip(A, B))
print(Result) #{'과자': 100, '아이스크림': 50, '사탕': 20}

11. 튜플()

리스트와 다르게 내용변경 및 추가가 불가능함.
리스트보다 속도가 빨라 내용변경이 없는 경우에 사용
원칙적으로 튜플은 괄호와 함께 데이터를 정의해야 하지만, 사용자 편의를 위해 괄호 없이도 동작함

menu = ("돈까스", "치즈돈까스")
print(menu[0]) #돈까스
print(menu[1]) #치즈돈까스

#서로 다른 변수에 서로 다른 값들을 넣어줄 때도 사용가능하다.
name, age, hobby = ("a", 21, "파이썬")
print(name, age, hobby)

12. 집합(Set)

중복이 안 되고 순서가 없는 경우에 사용

set = {1,2,2,3,3}
print(set) #{1, 2, 3}

#교집합 구하기
java = {"a", "b", "c"}
python = {"a", "d"}
print(java & python) #{'a'}
print(java.intersection(python)) #{'a'}

#합집합
print(java | python) #{'a', 'b', 'c', 'd'}
print(java.union(python)) #{'a', 'b', 'c', 'd'}

#차집합
print(java - python) #{'b', 'c'}
print(java.difference(python)) #{'b', 'c'}

#추가하는 경우
python.add("e")
print(python) #{'a', 'd', 'e'}

#제거하는 경우
java.remove("c")
print(java) #{'a', 'b'}

13. 자료구조의 변경

#카페
menu = {"커피", "주스", "녹차"}
menu = set(menu)
print(menu, type(menu)) #{"커피", "주스", "녹차"} <class 'set'>, set는 중괄호

menu = list(menu)
print(menu, type(menu)) #["커피", "주스", "녹차"] <class 'list'>, list는 대괄호

menu = tuple(menu)
print(menu, type(menu)) #("커피", "주스", "녹차") <class 'tuple'>, tuple은 일반괄호

14. If(분기)

상황에 따라 맞는 코드를 쓰는 것
Ex) 비가 오는 날에는 우산을, 미세먼지가 심한 날에는 마스크를 챙겨야 함

weather = "비" #이 곳에 "맑음", "미세먼지", "구름" 등이 들어감
if weather == "비" or weather == "눈":
	print("우산을 챙기세요")
elif weather == "미세먼지":
	print("마스크를 챙기세요")
else:
	print("준비물은 필요 없어요.")
    
weather = input("오늘 날씨는 어때요? ") #오늘 날씨는 어때요? 뒤에 커서가 사용자의 입력을 기다리게 됨, 이 때 날씨를 입력해 주면 이에 따른 출력문이 나온다.
if weather == "비" or weather == "눈":
	print("우산을 챙기세요.")
elif weather == "미세먼지":
	print("마스크를 챙기세요.")
else:
	print("준비물은 필요 없어요.")
    
temp = int(input("기온은 어때요? ")) #기온은 숫자이므로 int로 감싸줌
if 30 <= temp:
	print("너무 더워요. 나가지 마세요.")
elif 10 <= temp and temp < 30: #앞 조건과 뒤 모두 성립할 때
	print("괜찮은 날씨에요.")
elif 0 <= temp <10: #0 이상 10도 미만
	print("외투를 챙기세요.")
else:
	print("너무 추워요. 나가지 마세요.")

15. 반복문

1) for

print("대기번호 : 1")
print("대기번호 : 2")
print("대기번호 : 3")
print("대기번호 : 4")
#대기번호를 매번 코드로 입력하려면 너무 오래 걸리므로 반복문 for을 이용한다.

for wait_num in [0, 1, 2, 3, 4]:
	print("대기번호: {0}".format(wait_num))
#위 문장은
for wait_num in range(5): #0,1,2,3,4와 동일/순차적으로 커지는 경우에 사용
	print("대기번호: {0}".format(wait_num))
for wait_num in range(1, 6): #1,2,3,4,5와 동일
	print("대기번호: {0}".format(wait_num))

starbucks = ["철수", "영희", "민수"]
for customer in starbucks:
	print("{0}님, 커피가 준비되었습니다.".format(customer))

2) while
어떤 '조건'이 만족할 때까지 반복하라는 의미의 함수
ex) 카페에 방문한 고객을 n번 이상 불렀으나 음료를 찾아가지 않으면 음료를 버린다는 정책이 있는 경우

customer = "철수"
index = 5 #5번 부를 때까지
while index >= 1: #index가 1보다 크거나 같을 때까지 시행
	print("{0}, 커피가 준비 되었습니다. {1}번 남았습니다.".format(customer, index))
    index -= 1 #부르는 횟수를 한 번씩 줄여나감
    if index == 0: #5번 다 호출됨
    	print("{0}님, 음료는 폐기 되었습니다.".format(customer))
        
#손님이 올 때까지 호출하는 카페의 경우, 무한루프(계속해서 호출하므로 ctrl+c를 눌러 강제종료 가능)
customer = "민수"
index = 1
while True:
	print("{0}, 커피가 준비되었습니다. 호출{1}회".format(customer, index))
    index += 1
    
#커피가 준비된 손님이 오면 호출을 종료(반복문 탈출), 다른 사람이 오면 계속해서 호출
customer = "영희"
person = "Unknown"
while person != customer :
	print("{0}, 커피가 준비 되었습니다. {1}번 남았어요.".format(customer))
    person = input("이름이 어떻게 되세요? ")

3) Continue, Break
ex) 학생들에게 책을 읽도록 시키는 경우에 결석한 번호는 넘어가고 다른 사람들에게 책을 읽도록 하는 것이 continue

absent = [2, 5] #결석
no_book = [7] #책을 안 가지고 옴
for student in range(1, 11): #1~10번까지
	if student in absent:
    	continue #컨티뉴를 만난 경우 이후 명령문을 시행하지 않고 다음 '반복'으로 넘어감
    elif student in no_book:
    	print("오늘 수업은 여기까지. {0}는 교무실로 따라와.".format(student))
        break #반복값의 존재여부와 상관없이 바로 반복문 탈출(종료)
    print("{0}, 책을 읽어봐.".format(student))

4) 한 줄 for

#Ex) 출석번호 1, 2, 3, 4, 5 앞 자리에 100을 붙이기로 한 경우 -> 101, 102, 103, 104, 105
students = [1,2,3,4,5]
print(students) #[1, 2, 3, 4, 5]
students = [i+100 for i in students] #students 리스트에 들어있는 i값을 하나씩 불러오면서 이 i값에 100을 더해주는 것
print(students) #[101, 102, 103, 104, 105]

#Ex) 학생 이름을 길이로 변환
students = ["Chul su", "Minsu", "Young Hee"]
students = [len(i) for i in students] #students에서 i값을 하나씩 조회하며 그 길이를 리스트에 넣어줌]
print(students) #[7, 5, 9]

#Ex) 학생 이름을 대문자로 변환
students = ["Chul su", "Minsu", "Young Hee"]
students = [i.upper() for i in students]
print(students)

Ex) 택시 매칭 서비스를 이용하는 경우
50명의 승객과 매칭, 총 탑승 승객 수를 구하시오.
조건1: 승객별 운행소요 시간은 5~50분 사이의 난수
조건2: 소요시간 5~15분 사이의 승객만 매칭하기
조건3: 출력문은 "[O] 1번째 손님 (소요시간: 15분)"~50번째, "총 탑승 승객: N 분"

from random import *
customer = 0
for i in range(1, 51):
  time = randrange(5, 51)
  if 5 <= time <= 15:
    print("[O] {0}번째 손님 (소요시간: {1}분)".format(i, time))
    customer += 1
  else:
    print("[ ] {0}번째 손님 (소요시간: {1}분)".format(i, time))

print("총 탑승 승객: {0}분".format(customer))

16. 함수

def open_account(): #코드에서의 함수의 정의는 def로 시작, 함수의 이름을 적고 (): 로 닫는다.
	print("새로운 계좌가 생성되었습니다.") #함수는 정의만 되는 것, 호출하지 않는 이상 값을 불러오지는 않음
open_account() #함수 호출 -> 실행 -> 새로운 계좌가 생성되었습니다.

17. 전달값과 반환값

#만약 Parameter 값을 입력하지 않았을 때 error 값이 아닌 특정 값을 내보내고 싶다면, (user_name="anonymous") 라고 입력해주면 됨, default value값을 주는 것
def deposit(balance, money): #전달하려는 값을 () 안에 입력, 입금하는 경우
	print("입금이 완료되었습니다. 잔액은 {0} 원입니다.".format(balance + money))
    return balance + money #반환은 return
    
balance = 0 #잔액
balance = deposit(balance, 1000) #입금이 
print(balance)
    
def withdraw(balance, money): #출금
	if balance >= money: # 잔액이 출금보다 많으면
    	print("출금이 완료되었습니다. 잔액은 {0}원입니다."format(balance - money))
        return balance - money
    else:
    	print("출금이 완료되지 않았습니다. 잔액은 {0}원입니다."format(balance))
        return balance   
balance = 0 #잔액
balance = withdraw(balance, 2000)
print(balance)

def withdraw_night(balance, money): #저녁에 출금하는 경우 수수료 발생
  commission = 100 #수수료 100원
  return commission, balance - money - commission #수수료는 100원이고, 잔고에서 출금하고자 하는 금액과 수수료를 뺀다. 2개의 값을 ,로 구분해서 반환(여러개의 값을 한 번에 반환할 수도 있다는 것)

balance = 1000 #잔고는 1000원
commission, balance = withdraw_night(balance, 500)
print("수수료는 {0}원이며, 잔액은 {1} 원입니다.".format(commission, balance)) #수수료는 100원이며, 잔액은 400 원입니다.

이 부분을 공부하던 중에 길드원이 비싼 템을 먹어 배운 걸 활용해서 코드를 만들어 보았다^_^... 경매장 수수료가 5% 일 때 순수익은?

템가격 = input("템가격 ")
템가격 = int(템가격)

def calculate(템가격):
  print("수익은 {0}원 입니다.".format(템가격 * 0.95))
  return 템가격 * 0.95

수익 = calculate(템가격)
print(수익)

out put

100을 입력하면

템이 170억 짜리라

161억이나 버셨군요... 부럽다.

18. 기본값

함수에서 기본값 설정하기

def profile(name, age, main_lang):
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}".format(name, age, main_lang))
profile("철수", 20, "파이썬")
profile("민수", 21, "자바")
#Output 이름: 철수	나이: 20	주 사용 언어: 파이썬
#Output 이름: 민수	나이: 21	주 사용 언어: 자바

#만약 같은 학교, 같은 학년, 같은 반, 같은 수업 소속이라면? 이럴 때 사용하는 것이 '기본값'
def profile(name, age=18, main_lang=파이썬):
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}".format(name, age, main_lang)) #이렇게 입력하면 프로필 함수가 호출될 때, 나이, 언어에는 기본으로 18, 파이썬을 입력하겠다는 의미)
profile("철수")
profile("민수")
#Output 이름: 철수	나이: 18	주 사용 언어: 파이썬
#Output 이름: 민수	나이: 18	주 사용 언어: 파이썬

참고

#코드가 긴 경우 \ + enter를 치면 같은 문장으로 인식됨
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}".format(name, age, main_lang))

#위 코드는 아래의 코드와 같다
print("이름: {0}\t나이: {1}\t주 사용 언어: {2}"\
        .format(name, age, main_lang))

19. 키워드값

키워드값을 이용한 함수 호출
함수에서 전달받는 매개 변수의 값을 키워드를 이용해 호출하면, 순서가 뒤섞여 있어도 키워드에 맞는 값을 불러온다.

def profile(name, age, main_lang):
  print(name, age, main_lang)

profile(name= "철수", age=20, main_lang= "파이썬")
profile(main_lang= "자바", name= "민수", age= 21)

#Output 철수 20 파이썬
#Output 민수 21 자바

20. 가변인자(매개변수)

가변인자를 이용한 함수 호출

def profile(name, age, lang1, lang2, lang3, lang4, lang5):
  print("이름: {0}\t나이: {1}\t".format(name, age), end=" ") #end를 빈칸으로 넣어두면 줄바꿈 없이 문장을 계속해서 출력해준다.
  print(lang1, lang2, lang3, lang4, lang5)

profile("철수", 20, "Python", "Java", "C", "C++", "C#")
profile("민수", 21, "Kotlin", "Swift", "", "", "")

#위와 같이 코드를 작성하면 lang1~lang5에 해당하는 인자를 다 적어줘야 함.
#추가되는 인자가 있을 수도 있고 매번 빈칸을 적어주는 것이 번거로우므로, 서로 다른 개수의 값을 넣어줄 때 사용하는 것이 '가변인자'

def profile(name, age, *language): #*을 이용
  print("이름: {0}\t나이: {1}\t".format(name, age), end=" ") #end를 빈칸으로 넣어두면 줄바꿈 없이 문장을 계속해서 출력해준다.
  for lang in language:
    print(lang, end= " ")
  print()

profile("철수", 20, "Python", "Java", "C", "C++", "C#", "Javascript")
profile("민수", 21, "Kotlin", "Swift")

21. 지역변수와 전역변수

  • 지역변수: 함수 내에서만 쓸 수 있음, 함수가 호출될 때 만들어졌다가 함수 호출이 끝나면 사라짐
  • 전역변수: 프로그램 내 어디서든지 부를 수 있는 변수
gun = 10
def checkpoint(soldiers): #경계근무 나가는 군인의 수
  gun = gun - soldiers
  print("[함수 내] 남은 총: {0}".format(gun))

print("전체 총: {0}".format(gun))
checkpoint(2) #2명이 경계근무 나감
print("남은 총: {0}".format(gun))

#위와 같이 코드를 짜는 경우 checkpoint라는 코드블럭 내에서 만들어진 변수이므로 블럭 내에서 지정되지 않아 오류가 나게 됨. 이것이 '지역변수'(UnboundLocalError: local variable 'gun' referenced before assignment)

gun = 15 #전역변수
def checkpoint(soldiers): #경계근무 나가는 군인의 수
  global gun #'global'이라는 함수로 전역 공간에 있는 gun(변수)을 가져와서 사용
  gun = gun - soldiers
  print("[함수 내] 남은 총: {0}".format(gun))

print("전체 총: {0}".format(gun))
checkpoint(2) #2명이 경계근무 나감
print("남은 총: {0}".format(gun))

#이렇게 코드를 짜야 정상적으로 코드가 작동함. 전역변수(코드블럭 외부에서 선언된 변수)

#그러나 전역변수를 많이 사용하면 할 수록 코드가 복잡해지므로 지양하는 것이 좋음!

gun = 10
def checkpoint_ret(gun, soldiers): #gun은 함수 내 지역변수임
  gun = gun - soldiers
  print("[함수 내] 남은 총: {0}".format(gun))
  return gun #return을 해줌으로써 바뀐 gun이라는 변수의 값을 외부로 던짐

print("전체 총: {0}".format(gun))
gun = checkpoint_ret(gun, 2) #외부에서 gun 변수의 값을 다시 받고 계산해서 저장
print("남은 총: {0}".format(gun))

#이렇게 짜 주는 것이 좋다.

#Ex) 표준체중 구하기
#std_weight = int(std_weight)

def std_weight(height, gender):
  if gender == "남자":
    return height * height * 22
  else:
    return height * height * 21

height = 175
gender = "남자"
weight = round(std_weight(height/100, gender), 2)

print("키 {0}cm {1}의 표준체중은 {2}kg 입니다.".format(height, gender, weight)) #키 175cm 남자의 표준체중은 67.38kg 입니다.

22. 표준입출력

1) 표준 출력

print("Python", "Java", "Javascript", sep=" vs ") #'sep'을 이용해 어떻게 출력될지 바꿀 수 있음. Python vs Java vs Javascript

print("Python", "Java", "Javascript", sep=",", end="?")
print("무엇이 더 재밌을까요?")
#end를 이용해 문장의 끝부분을 ?로 바꾸고, 줄바꿈 없이 한 문장으로 출력할 수 있다.

import sys
print("Python", "Java", file=sys.stdout) #표준출력, 사용자가 확인해야 하는 출력은 out으로 처리
print("Python", "Java", file=sys.stderr) #확인해서 프로그램 코드를 수정해줘야 하는 부분에 err 처리를 해 줌

scores = {"수학":0, "영어":50, "코딩":100}
for subject, score in scores.items():
	print(subject.ljust(8), str(score).rjust(4), sep=":") #ljust는 8개의 공간 확보하고 왼쪽 정렬, rjust는 4개의 공간 확보하고 오른쪽 정렬
    
#은행 대기순번표 001, 002, 003...
for num in range(1,21):
	print("대기번호 : " + str(num).zfill(3)) #.zfill(3)을 이용해 출력가능, 3칸의 공간을 확보하고 출력하는데 값이 없는 빈 공간은 0으로 채워달라는 의미

2) 표준 입력

answer = input("아무 값이나 입력하세요 : ")
print("입력하신 값은 " + answer + "입니다.")
#이 때 값은 str으로 나온다. 사용자 입력을 통해 값을 받게 되면 항상 문자열 형태로 저장됨!

23. 다양한 출력포맷

# 빈 자리는 빈공간으로 두고, 오른쪽 정렬을 하되 총 10자리 공간을 확보하려면?
print("{0: >10}".format(500)) #       500

# 양수일 때는 +로 표시, 음수일 땐 -로 표시, 부등호 앞에 있는 +가 없으면 양수일 때는 그냥 500으로 출력됨
print("{0: >+10}".format(500)) #       +500
print("{0: >+10}".format(-500)) #       -500

# 왼쪽 정렬하고, 빈칸을 _로 채움
print("{0:_<10}".format(500)) #500_______

# 세자리마다 콤마 찍어주기
print("{0:,}".format(10000000000)) #10,000,000,000

# 세자리마다 콤마 찍고 +- 부호 붙이기
print("{0:+,}".format(10000000000))
print("{0:+,}".format(-10000000000))

# 세자리마다 콤마 찍고 +- 부호 붙이고, 자릿수 확보하기
print("{0:^<+30,}".format(10000000000))

# 소수점 출력
print("{0:f}".format(5/3)) #1.666667

# 소수점 특정 자리수까지만 표시하고 싶을 때(셋째자리에서 반올림)
print("{0:.2f}".format(5/3)) #1.67

24. 파일 입출력

파이썬을 통해 파일을 열어 내용을 불러오거나 쓸 수 있다.

mode 정리
1) ' r ' : 기본값, 파일 읽어오기
2) ' w ' : 파일 쓰기 모드
파일이 존재하지 않는다면 새롭게 파일 생성
파일이 이미 존재하면 커서(fp)를 맨 앞으로 돌려 작성되기에 덮어쓰기 됨(이전 내용 사라질 수 있음)
3) ' a ' : 쓰기모드
파일이 이미 존재하는 경우 파일 끝에 커서가 존재해 이어쓰기 가능
4) ' x ' : 파일이 존재하지 않는다면 새롭게 파일 생성하고 쓰기모드로 열림
파일이 이미 존재하면 에러 발생
5) ' b ' : 바이너리 모드(16진수로 표현)
6) ' t ' : 텍스트 모드(기본값)

  • 두번째 인자로 'r', 'w', 'a', 'x' 와 같이 't'나 'b'를 따로 쓰지 않으면 기본적으로 텍스트 모드인 't'로 열림
    ex) 'r' = 'rt'와 동일한 의미
    읽기+바이너리 모드는 'rb' 로 입력

CSV 파일

  • csv 파일에서 encoding 오류 발생 시 encoding="utf-8-sig"로 지정
  • csv 파일 이용 시 열은 쉼표로, 새 행은 새 줄로 구분

1) 파일을 만들고 내용 입력하기

score_file = open("score.txt", "w", encoding="utf8") #첫번째에는 파일 이름, w는 write로 기존의 파일에 덮어쓰기 처리 됨, 이렇게 쓰기 위한 목적의 파일임을 입력하고, 마지막에 encoding="utf8"을 적어 준다. 인코딩 정보를 정의해주지 않으면 한글문자가 제대로 출력되지 않는 경우가 있어 써 주는 것이 좋다.
print("수학: 0", file=score_file)
print("영어: 50", file=score_file)
score_file.close() #파일을 열어 쓰고 닫아주어야 한다.
#print 시에는 자동으로 줄 바꿈이 된다.

score_file = open("score.txt", "a", encoding="utf8") #a는 append로 이전에 존재하는 파일에 이어서 쓰고 싶을 때 입력함.
score_file.write("과학: 80")
score_file.write("\n코딩: 100") #.write를 쓸 때는 줄 바꿈이 안 돼서 \n으로 줄바꿈 처리를 해준다.
score_file.close()

2) 파일 내용 읽어오기

  • 전체 내용 불러오기
score_file = open("score.txt", "r", encoding="utf8") #r는 read로 파일의 내용을 읽어오는 용도로 입력
print(score_file.read()) #파일에 있는 모든 내용을 불러와 읽는다.
score_file.close()
  • 일부 내용 불러오기
# 몇 줄짜리인지 아는 경우
score_file = open("score.txt", "r", encoding="utf8")
print(score_file.readline(), end="")
print(score_file.readline(), end="")
print(score_file.readline(), end="")
#줄별로 읽기 동작을 수행하는데, 한 줄만 읽어오고 커서는 다음 줄로 이동함. 줄바꿈 없이 나타내고 싶으면 end="" 이용하기.
score_file. close()

# 몇 줄짜리인지 모르는 경우
score_file = open("score.txt", "r", encoding="utf8")
While True:
	line = score.file.readline()
    if not line:
    	break
    print(line, end="") #줄바꿈 없이 출력
score_file.close()

# 리스트에 값 넣어 출력하기
score_file = open("score.txt", "r", encoding="utf8")
lines = score_file.readlines() #모든 line을 가지고 와서 list 형태로 저장
for line in lines:
	print(line, end="")
#이 방식은 score_file에 있는 모든 내용을 가지고 와서 list 형태로 집어넣고 list에서 한 줄 씩 불러와서 출력해주는 것
score_file.close()

#파일을 읽은 후 종목코드를 리스트에 저장
매수종목1 = open("매수종목1.txt", mode="r", encoding="utf8")
lines = 매수종목1.readlines()

codes = []
for line in lines:
    code = line.strip()
    codes.append(code)
    
print(codes)
매수종목1.close()

#파일을 읽은 후 종목코드와 종목명을 딕셔너리로 저장
#종목명을 key로 종목명을 value로 저장
매수종목2 = open("매수종목2.txt", mode="r", encoding="utf8")
lines = 매수종목2.readlines()

data = {}
for line in lines:
    line = line.strip() #"\n" 제거
    k, v = line.split()
    data[k] = v #dictionary에 집어넣는 방법은 인덱싱 기호로 key를 주고 value 값 입력하는 것
    
print(data)
매수종목2.close()

25. Pickle

프로그램 상에서 사용하고 있는 데이터를 파일형태로 저장해 다른 사람과 주고 받을 수 있게 하는 것

import pickle
profile_file = open("profile.pickle", "wb") #wb는 write binary 타입임을 의미함, pickle을 쓰기 위해서는 항상 binary 타입이라고 정의해 줘야 한다. 인코딩은 따로 설정해주지 않아도 됨.
profile = {"이름":"철수", "나이":20, "취미": ["축구", "골프", "코딩"]}
print(profile)
pickle.dump(profile, profile_file) #pickle을 이용해 위 데이터를 파일에 쓰기 위해 pickle.dump(파일에 저장할 내용, 어떤 파일을 쓸 것인지)를 입력해준다. profile에 있는 정보를 file에 저장
profile_file.close()

#위의 파일에서 데이터 가져오기
profile_file = open("profile.pickle", "rb") #r은 read
profile = pickle.load(profile_file) #load를 통해 파일에 있는 정보를 profile에 불러옴
print(profile)
profile_file.close()

26. With

with를 사용하면 close문을 사용할 필요없이 with문을 탈출하며 자동으로 종료되어 파일을 열고 닫는 작업을 편리하게 수행할 수 있음

import pickle

with open("profile.pickle", "rb") as profile_file: #파일을 열고 profile_file이라는 변수에 저장
	print(pickle.load(profile_file))

#Ex) 일반적인 파일을 생성하고 불러오기
with open("study.txt", "w", encoding="utf8") as study_file:
	study_file.write("파이썬을 열심히 공부하고 있어요.")

with open("study.txt", "r", encoding="utf8") as study_file:
	print(study_file.read())

예제) 1주차 ~ 50주차까지의 주간보고 파일 생성하기

for i in range(1, 51):
  with open(str(i) + "주차.txt", "w", encoding="utf8") as report_file:
    report_file.write("- {0} 주차 주간보고 -".format(i))
    report_file.write("\n부서 :")
    report_file.write("\n이름 :")
    report_file.write("\n업무 요약 :")

27. 클래스

서로 연관이 있는 변수와 함수의 집합

아래와 같이 게임 속 진영을 코딩한다고 하면 캐릭터가 추가될 때마다 매번 변수 설정을 해주어야 하는 번거로움이 있어
클래스(틀)를 가지고 찍어낼 수 있도록 하는 것

name = "전사"
HP = 100
damage = 10

print("{0} 가 생성되었습니다.".format(name))
print("체력 {0}, 공격력 {1}\n".format(HP, damage))

name_m = "마법사"
HP_m = 70
damage_m = 8

print("{0} 가 생성되었습니다.".format(name_m))
print("체력 {0}, 공격력 {1}\n".format(HP_m, damage_m))

def attack(name, location, damage):
	print("{0} : {1} 방향으로 적군을 공격 합니다. [공격력 {2}]".format(name, location, damage))
    
attack(name, "1시", damage)
attack(name_m, "1시", damage_m)

클래스를 활용한 코딩

class Unit:
	def __init__(self, name, hp, damage):
	#기본적으로 __init__ 함수가 만들어져야 한다.
    	self.name = name
        self.hp = hp
        self.damage = damage
        print("{0} 가 생성되었습니다.".format(self.name))
        print("체력 {0}, 공격력 {1}".format(self.hp, self.damage))
        
전사1 = Unit("전사", 100, 10) #Class명인 Unit을 가져오고, self를 제외한 name, hp, damage를 입력)
전사2 = Unit("전사", 100, 10)
마법사 = Unit("마법사", 70, 8)

1) 생성자

def __init__(self, name, hp, damage):

위의 예시에서 전사, 마법사와 같이 어떤 class로 부터 만들어지는 것을 객체라고 한다.
전사, 마법사는 Unit class의 인스턴스이다.

객체가 생성될 때는 기본적으로 init 함수에 정의된 개수와 동일하게 지정해주어야 한다.(self는 제외)

2) 멤버 변수
어떤 클래스 내에서 정의된 변수

class Unit:
  def __init__(self, name, hp, damage):
	#기본적으로 __init__ 함수가 만들어져야 한다.
    self.name = name
    self.hp = hp
    self.damage = damage
    print("{0} 가 생성되었습니다.".format(self.name))
    print("체력 {0}, 공격력 {1}".format(self.hp, self.damage))
    
궁수1 = Unit("궁수", 80, 9)
print("유닛 이름: {0}, 공격력: {1}".format(궁수1.name, 궁수1.damage)) #이런식으로 외부에서 멤버 변수를 사용할 수 있다.(위의 self.name, hp, damage를 가져다 쓰는 것)
#output 궁수 가 생성되었습니다./체력 80, 공격력 9/유닛 이름: 궁수, 공격력: 9

궁수2 = Unit("보우마스터", 80, 9)
궁수2.guidedarrow = True

if 궁수2.guidedarrow == True:
	print("{0}는 현재 가이디드 애로우 적용 상태입니다.".format(궁수2.name))
    
# 위에서 변수를 만들 때에는 이름, 체력, 공격력만 만들었었는데 외부에서 가이디드 애로우라는 변수를 추가로 할당하여 True값을 넣은 것
# 파이썬에서는 클래스 외부에서 추가로 객체에 변수를 만들어 쓸 수 있음. 단, 기존 객체에는 적용 안 됨.

28. 메소드

클래스 내에서 메소드 앞에는 항상 self를 써준다.

class Unit:
  def __init__(self, name, hp, damage):
	#기본적으로 __init__ 함수가 만들어져야 한다.
    self.name = name
    self.hp = hp
    self.damage = damage
    print("{0} 가 생성되었습니다.".format(self.name))
    print("체력 {0}, 공격력 {1}".format(self.hp, self.damage))
    
class AttackUnit:
  def __init__(self, name, hp, damage):
	#기본적으로 __init__ 함수가 만들어져야 한다.
    self.name = name
    self.hp = hp
    self.damage = damage
  def attack(self, location):
	print("{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]".format(self.name, location, self.damage))
  
  def damaged(self, damage):
  	print("{0} : {1} 데미지를 입었습니다.".format(self.name, damage))
    self.hp -= damage
    print("{0} : 현재 체력은 {1} 입니다.".format(self.name, self.hp))
    if self.hp <= 0:
    	print("{0}: 사망하였습니다.".format(self.name))

Archmage1 = AttackUnit("썬콜", 11, 8)
Archmage1.attack("5시")

Archmage1.damaged(5)
Archmage1.damaged(6)

29. 상속

class Unit:
  def __init__(self, name, hp):
    self.name = name
    self.hp = hp
 
# 같은 Method가 쓰일 때, Unit class의 내용을 상속 받아서 AttackUnit을 생성할 수 있음.
 
class AttackUnit:
  def __init__(self, name, hp, damage):
    self.name = name
    self.hp = hp
    self.damage = damage

아래와 같이 코드를 생성하면 된다.

class Unit:
  def __init__(self, name, hp):
    self.name = name
    self.hp = hp
 
class AttackUnit(Unit): #상속받고 싶은 Class를 괄호 안에 적어줌
  def __init__(self, name, hp, damage):
  	Unit.__init__(self, name, hp)
    self.damage = damage

30. 다중상속

여러개의 부모 클래스로부터 자식 클래스가 상속받는 경우를 다중상속이라 한다.

class Unit:
  def __init__(self, name, hp, speed):
    self.name = name
    self.hp = hp
    self.speed = speed

  def move(self, location):
    print("[지상 이동]")
    print("{0} : {1} 방향으로 이동합니다. [속도 {2}]".format(self.name, location, self.speed))
 
class AttackUnit:
  def __init__(self, name, hp, speed, damage):
    Unit.__init__(self, name, hp, speed)
    self.damage = damage

  def attack(self, location):
    print("{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]".format(self.name, location, self.damage))

  def damaged(self, damage):
    print("{0} : {1} 데미지를 입었습니다.".format(self.name, damage))
    self.hp -= damage
    print("{0} : 현재 체력은 {1} 입니다.".format(self.name, self.hp))
    if self.hp <= 0:
      print("{0}: 사망하였습니다.".format(self.name))

# 날 수 있는 기능을 가진 클래스
class Flyable:
  def __init__(self, flying_speed):
    self.flying_speed = flying_speed

  def fly(self, name, location):
    print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]".format(name, location, self.flying_speed))
    
# 공중에서 공격 가능한 클래스
class FlyableAttackUnit(AttackUnit, Flyable): #다중상속을 받을 클래스를 쉼표로 표기
  def __init__(self, name, hp, damage, flying_speed):
    AttackUnit.__init__(self, name, hp, 0, damage) #여기서 지상 스피드는 0이라는 의미
    Flyable.__init__(self, flying_speed)

31. 메소드 오버라이딩

부모 클래스에서 정의된 method가 아닌 자식 클래스에서 정의한 method를 사용하고 싶을 때 이것을 메소드 오버라이딩이라고 함.

class Unit:
  def __init__(self, name, hp, speed):
    self.name = name
    self.hp = hp
    self.speed = speed

  def move(self, location):
    print("[지상 이동]")
    print("{0} : {1} 방향으로 이동합니다. [속도 {2}]".format(self.name, location, self.speed))
 
class AttackUnit:
  def __init__(self, name, hp, speed, damage):
    Unit.__init__(self, name, hp, speed)
    self.damage = damage

  def attack(self, location):
    print("{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]".format(self.name, location, self.damage))

  def damaged(self, damage):
    print("{0} : {1} 데미지를 입었습니다.".format(self.name, damage))
    self.hp -= damage
    print("{0} : 현재 체력은 {1} 입니다.".format(self.name, self.hp))
    if self.hp <= 0:
      print("{0}: 사망하였습니다.".format(self.name))

# 날 수 있는 기능을 가진 클래스
class Flyable:
  def __init__(self, flying_speed):
    self.flying_speed = flying_speed

  def fly(self, name, location):
    print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]".format(name, location, self.flying_speed))
    
# 공중에서 공격 가능한 클래스
class FlyableAttackUnit(AttackUnit, Flyable):
  def __init__(self, name, hp, damage, flying_speed):
    AttackUnit.__init__(self, name, hp, 0, damage) #여기서 지상 스피드는 0이라는 의미
    Flyable.__init__(self, flying_speed)

# 아델: 지상에서 이동 가능, 기동성이 좋음
Adele = AttackUnit("아델", 120, 15, 20)

# 호영: 공중에서 이동가능, 기동성, 좋음
Hoyeong = FlyableAttackUnit("호영", 100, 12, 10)

Adele.move("11시")
Hoyeong.fly(Hoyeong.name, "9시")

그런데 위와 같이 코딩을 하는 경우 날 수 있는 기능을 가진 유닛과 지상 유닛을 매번 구분해서 함수를 사용해주어야 하는 불편함이 있다.

move 함수를 써 이를 통일시키려면

# 공중에서 공격 가능한 클래스
class FlyableAttackUnit(AttackUnit, Flyable): #다중상속을 받을 클래스를 쉼표로 표기
  def __init__(self, name, hp, damage, flying_speed):
    AttackUnit.__init__(self, name, hp, 0, damage) #여기서 지상 스피드는 0이라는 의미
    Flyable.__init__(self, flying_speed)
    
  def move(self, location):
  	print("[공중 유닛 이동]")
    self.fly(self.name, location)
    
# 아델: 지상에서 이동 가능, 기동성이 좋음
Adele = AttackUnit("아델", 120, 15, 20)

# 호영: 공중에서 이동가능, 기동성, 좋음
Hoyeong = FlyableAttackUnit("호영", 100, 12, 10)

Adele.move("11시")
Hoyeong.move("9시")

이렇게 수정해주면 된다.

32. Pass

아무것도 안 하고 일단 넘어간다는 의미

class BuildingUnit(Unit):
	def __init__(self, name, hp, location):
    	pass
        
# 보조 건물을 짓는다고 할 때
supply_build = BuildingUnit("보조 건물", 300, "4시")

위와 같이 코드를 작성하고 실행시키면 오류없이 일단 작동된 것처럼 나옴

def game_start():
	print("[알림] 새로운 게임을 시작합니다.")
    
def game_over():
	pass
    
game_start()
game_over

위와 같이 작성하는 경우 게임을 실행하면 문구가 나오고, 게임이 끝나면 pass를 통해 그냥 넘어감

33. Super

class BuildingUnit(Unit):
	def __init__(self, name, hp, location):
    	Unit.__init__(self, name, hp, 0)
        self.location = location
        
#위와 같이 표현할 수도 있으나 아래처럼 표현도 가능하다.

class BuildingUnit(Unit):
	def __init__(self, name, hp, location):
    	#Unit.__init__(self, name, hp, 0)
        super().__init__(name, hp, 0) #super를 통해 초기화 할 때는 괄호를 붙여주고 self 정보는 안 보내준다.
        self.location = location

그런데 Super를 이용해 두 개 이상의 부모 클래스를 다중상속 받을 때

class Unit:
	def __init__(self):
    	print("Unit 생성자")
     
class Flyable:
	def __init__(self):
    	print("Flyable 생성자")
        
class FlyableUnit(Unit, Flyable):
	def __init__(self):
    	super().__init__()
        
#드랍쉽
dropship = FlyableUnit()

위와 같이 코드를 작성하고 실행하면
순서 상 맨 처음에 상속받는 클래스에 대해서만 init 함수가 호출되는 문제가 있다.

따라서 다중상속 시, 혹은 모든 부모클래스에 대한 초기화가 필요한 경우에는 아래와 같이 코드를 작성해야 한다.

class FlyableUnit(Unit, Flyable):
	def __init__(self):
    	#super().__init__() super 사용 X
        Unit.__init__(self)
        Flyable.__init__(self)

34. 예외처리

어떤 error가 발생했을 때 그에 대해 처리해줌

try:
실행 코드
except:
예외가 발생했을 때 수행할 코드
else:
예외가 발생하지 않았을 때 수행할 코드
finally:
예외 발생 여부와 상관없이 항상 수행할 코드

Example)

per = ["10.31", "", "8.00"]
for i in per:
    try:
        print(float(i))
    except:
        print(0)
    else:
        print("clean data")
    finally:
        print("변환 완료")

출력:

print("나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요: "))
num2 = int(input("두 번째 숫자를 입력하세요: "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))

# 이런 경우의 예시에서는 숫자가 아닌 문자를 입력하면 error가 뜬다. 이 때 오류처리를 하기 위해 아래와 같이 예외처리를 사용한다.

try:
  print("나누기 전용 계산기입니다.")
  num1 = int(input("첫 번째 숫자를 입력하세요: "))
  num2 = int(input("두 번째 숫자를 입력하세요: "))
  print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
	print("에러! 잘못된 값을 입력하였습니다.")
except ZeroDivisionError as err:
	print(err) #0을 입력 시에도 error가 발생하므로 0의 경우도 코딩해줌, output: division by zero

이렇게도 처리할 수 있다.

try:
  print("나누기 전용 계산기입니다.")
  nums = []
  nums.append(int(input("첫 번째 숫자를 입력하세요: ")))
  nums.append(int(input("두 번째 숫자를 입력하세요: ")))
  nums.append(int(nums[0] / nums[1]))
  print("{0} / {1} = {2}".format(nums[0], nums[1], nums[2]))
except ValueError:
	print("에러! 잘못된 값을 입력하였습니다.")
except ZeroDivisionError as err:
  print(err) #Error 내용을 출력

# 이 때, nums.append(int(nums[0] / nums[1]))를 입력하지 않으면 또 error가 발생한다. 이것을 처리하기 위해서는 아래와 같은 코드를 추가해주면 된다.

except: #ValueError나 ZeroDivisionError가 아닌 다른 모든 경우를 여기서 처리함
  print("알 수 없는 에러가 발생하였습니다.")
  print(err) #Error 내용을 출력

35. 에러 발생시키기

의도적으로 에러를 발생시켜야 하는 경우

try:
	print("한 자리 숫자 나누기 전용 계산기입니다.")
	num1 = int(input("첫 번째 숫자를 입력하세요 :"))
    num2 = int(input("첫 번째 숫자를 입력하세요 :"))
    if num1 >= 10 or num2 >= 10: #error 발생
    	raise ValueError
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))

except ValueError:
	print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
    
#필요 시 의도적으로 에러를 발생시켜서 except 구문으로 내려오도록 할 수 있다.

#예외 발생 시 에러 메시지를 변수로 바인딩하기
data = [1, 2, 3]

for i in range(5):
    try:
        print(data[i])
    except IndexError as e:
        print(e)

36. 사용자 정의 예외처리

직접 정의해서 예외를 만들 수도 있다.

class BigNumberError(Exception):
  def __ init__(self, msg):
    self.msg = msg

  def __str__(self):
    return self.msg

try:
	print("한 자리 숫자 나누기 전용 계산기입니다.")
	num1 = int(input("첫 번째 숫자를 입력하세요 :"))
    num2 = int(input("첫 번째 숫자를 입력하세요 :"))
    if num1 >= 10 or num2 >= 10: #error 발생
    	raise BigNumberError("입력값: {0}, {1}".format(num1, num2))
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))

except ValueError:
	print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
 
except BigNumberError as err:
  print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
  print(err)

Ex) 치킨 10마리를 판매한다고 할 때, 음수값이나 문자열은 입력하지 못하게 하고, 재고가 모두 소진되었을 때 프로그램이 종료되도록 코드를 짠다면?

class SoldoutError(Exception):
  pass

chicken = 10
waiting = 1

while(True):
  try:
    print("[남은 치킨: {0}]".format(chicken))
    order = int(input("치킨 몇 마리 주문하시겠습니까?"))
    if order > chicken:
      print("재료가 부족합니다.")
    elif order <= 0:
      raise ValueError
    else:
      print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다.".format(waiting, order))
      waiting += 1
      chicken -= order
    if chicken == 0:
      raise SoldoutError
  except ValueError:
    print("잘못된 값을 입력하였습니다.")
  except SoldoutError:
    print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
    break

37. Finally

예외처리 구문이 정상적으로 수행되거나 오류가 발생하여도 무조건 실행되는 구문

try:
	print("한 자리 숫자 나누기 전용 계산기입니다.")
	num1 = int(input("첫 번째 숫자를 입력하세요 :"))
    num2 = int(input("첫 번째 숫자를 입력하세요 :"))
    if num1 >= 10 or num2 >= 10: #error 발생
    	raise BigNumberError("입력값: {0}, {1}".format(num1, num2))
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))

except ValueError:
	print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
 
except BigNumberError as err:
  print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
  print(err)

finally:
	print("계산기를 이용해 주셔서 감사합니다.")
    
#try 구문 내 맨 마지막에 작성한다.

38. 모듈

필요한 것들끼리 부품끼리 잘 만들어진 파일
파이썬에서는 함수 정의나 클래스 등의 파이썬 문장들을 담고 있는 파일을 모듈이라고 한다.
확장자: .py

모듈 호출 방법 4가지 요약

import os #os.rename()
from os import rename #rename()
from os import * #getcwd(), rename() 등
import os as myos #myos.getcwd() 모듈 이름이 길 때 사용

예시

#일반 가격
def price(people):
  print("{0}명 가격은 {1}원입니다.".format(people, people * 10000))

#조조할인 가격
def price_morning(people):
  print("{0}명 조조할인 가격은 {1}원입니다.".format(people, people * 6000))

#군인할인 가격
def price_soldier(people):
  print("{0}명 조조할인 가격은 {1}원입니다.".format(people, people * 4000))

#이렇게 적은 코드를 파일명 theater_module.py로 저장한 후 사용한다.
#모듈은 내가 그 모듈을 쓰려는 파일과 같은 경로에 있거나 python library들이 있는 폴더에 있어야 사용가능한다.

이렇게 만들어진 모듈을 활용하는 방법은 아래와 같다.

import theater_module
theater_module.price(3) #3명이서 영화보러 갔을 때 가격 -> 3명 가격은 30000원 입니다.
theater_module.price_morning(4) #4명이서 영화보러 갔을 때 가격 -> 4명 가격은 24000원 입니다.
theater_module.price_soldier(5) #5명이서 영화보러 갔을 때 가격 -> 5명 가격은 20000원 입니다.

모듈명을 매번 작성하기 번거로우면 줄여 쓰는 것도 가능하다.
방법은 아래와 같다.

import theater_module as mv #매번 theater_module이라고 작성하기 번거로우므로 줄여서 쓸 수 있다. as 뒤에 붙이면 theater_module을 mv로 호출하는 것
mv.price(3) #3명이서 영화보러 갔을 때 가격 -> 3명 가격은 30000원 입니다.
mv.price_morning(4) #4명이서 영화보러 갔을 때 가격 -> 4명 가격은 24000원 입니다.
mv.price_soldier(5) #5명이서 영화보러 갔을 때 가격 -> 5명 가격은 20000원 입니다.

더 짧게 쓰기 위해서는

from theater_module import * #from random import * 과 같은 의미
#이 모듈에 있는 모든 것을 활용하겠다는 의미
price(3)
price_morning(4)
price_soldier(5)

원하는 함수만 갖다 쓰기 위해서는

from theater_module import price, price_morning #특정 함수만 가져다 쓰겠다고 명시적으로 표기
price(5))
price_morning(6)
#여기서 price_soldier(7)는 쓸 수가 없다.

함수 하나만 쓰는 경우에 줄여서 쓰고 싶은 경우

from theater_module import price_soldier as price
#함수 하나만 가져다 쓰는 경우에 함수명을 줄이고 싶다면 이렇게 as 뒤에 표기해서 줄여서 쓸 수도 있다.
price(4)

39. 패키지

모듈들을 모아놓은 집합
하나의 디렉토리에 여러 모듈 파일들을 갖다 놓은 것을 패키지라고 한다.

만약 여행사 프로젝트를 담당한다고 할 때, 태국과 베트남 여행상품을 제공하는 것을 파이썬 패키지로 제작해보기
패키지명은 Travel

#폴더생성(Travel) : 패키지 디렉토리
#Travel 밑에 새로운 파일 두 개 생성 -> Thailand.py, Vietnam.py, __init__.py

#Thailand.py 파일 내 코딩
class ThailandPackage:
  def detail(self):
    print("[태국 패키지 3박 5일] 방콩, 파타야 여행(야시장 투어) 50만원")

#Vietnam.py 파일 내 코딩
class VietnamPackage:
  def detail(self):
    print("[베트남 패키지 3박 5일] 다낭 효도 여행 60만원")

#__init__.py 파일은 일단 비워둔다.

패키지를 사용하는 방법은 아래와 같다.

#다만 import 뒤에는 항상 모듈이나 패키지만 기재가능(클래스나 함수는 직접 import 할 수 없다.)

import Travel.Thailand
trip_to = Travel.Thailand.ThailandPackage() #trip_to 변수 생성
trip_to.detail() #함수 호출

단, import가 아닌 from 구문에서는 모듈이나 패키지, 클래스나 함수도 직접 사용 가능하다.

Ex)

from Travel.Thailand import ThailandPackage #Travel 패키지 안에 있는 Thailand 모듈에서 ThailandPackage라는 클래스를 import한 것
trip_to = ThailandPackage()
trip_to.detail()

40. all

문법 상 공개범위를 설정해주지 않으면 오류가 발생한다.
이를 위해 all을 사용

from Travel import * # *은 Travel이라는 패키지의 모든 것을 가져다 쓴다는 것
trip_to = Vietnam.VietnamPackage()
trip_to.detail()

#위의 코드는 공개범위를 설정해주지 않았기에 오류가 발생함. 따라서
#__init__.py 파일 내에

__all__ = ["Vietnam", "Thailand"] #을 작성 후 실행해보면 위 코드에서 오류가 발생하지 않는다.

41. 모듈 직접 실행

패키지를 만들 때 코드가 제대로 작동하는지 알아보기 위해 사용

실행하고자 하는 파일의 코드 아래쪽에 다음과 같은 코드를 적는다.

if __name__ == "__main__":
	print("Thailand 모듈을 직접 실행") #Thailand.py 파일 내에서 코드를 직접 실행한다는 것
    print("이 문장은 모듈을 직접 실행할 때에만 실행됨")
    trip_to = ThailandPackage()
    trip_to.detail()
else:
	print("Thailand 외부에서 모듈 호출") #외부에서 모듈을 가져와 실행할 경우 출력

42. 패키지, 모듈 위치

패키지나 모듈의 위치를 확인하고 싶을 때에는 아래와 같은 코드를 실행한다.

import inspect
import random
print(inspect.getfile(random)) #random이라는 모듈이 어느 위치에 있는지 파일 정보를 알려줌

43. pip install

pip로 패키지 설치하기
필요한 패키지를 적재적소에 잘 가져다 쓰는 것도 중요함

구글에서 pypi 검색 [https://pypi.org/]

Ex) beautifulsoup4 4.11.1

웹 페이지에서 내가 원하는 정보를 스크랩 해올 수 있는 라이브러리로
copy 부분을 눌러 복사해서 터미널 부분에 붙여넣어 패키지 설치

설치 완료 후 웹페이지 부분에 있는 코드를 붙여넣어 실행해 본다.

#입력
from bs4 import BeautifulSoup
soup = BeautifulSoup("<p>Some<b>bad<i>HTML")
print(soup.prettify())

출력

터미널 부분에 pip list를 입력하면 현재 설치되어 있는 패키지 확인 가능

터미널 부분에 pip show beautifulsoup4(패키지명) 입력하면 패키지 정보 확인 가능

업그레이드가 필요한 경우 터미널 부분에 pip install --upgrade beautifulsoup4(패키지명) 입력해 업그레이드 가능

패키지 삭제를 원하는 경우 pip uninstall beautifulsoup4 입력

Y/N를 입력해 삭제 가능

44. 내장함수

내장함수란 이미 내장되어 있기에 import를 입력할 필요없이 사용가능한 함수
Google에서 list of python builtins를 검색해 내장함수 목록 확인가능
[https://docs.python.org/ko/3/library/functions.html]

몇가지 예시)
1) input : 사용자의 입력을 받는 함수

language = input("무슨 언어를 좋아하세요?")
print("{0}은 아주 좋은 언어입니다!".format(language))

2) dir : 어떤 객체를 넘겨줬을 때 그 객체가 어떤 변수와 함수를 가지고 있는지 알려주는 함수

#입력
print(dir())
import random #외장함수
print(dir())
import pickle
print(dir())

출력(사용가능한 함수가 추가된 것을 확인 가능)

#입력
import random
print(dir(random))

이렇게 입력하면 Random 모듈 내에서 사용 가능한 함수가 출력됨

리스트 내에서 사용 가능한 함수를 출력하고 싶다면

#입력
lst = [1, 2, 3]
print(dir(lst))

출력

문자열 내에서 사용가능한 함수를 출력하고 싶다면

#입력
name = "Jim"
print(dir(name))

출력

45. 외장함수

내장함수와 달리 직접 import 해서 사용해야 하는 함수
Google에서 list of python modules를 검색해 외장함수 목록 확인가능
[https://docs.python.org/ko/3/py-modindex.html]

몇가지 예시)
1) glob : 경로 내의 폴더/ 파일 목록 조회(윈도우의 dir과 같은 역할)

import glob
print(glob.glob("*.py")) #검색하고자 하는 파일명을 괄호 안에 넣어줌, 여기서는 확장자가 py인 모든 파일을 알려줌

2) os : 운영체제에서 제공하는 기본 기능(ex. 폴더 생성 및 삭제 등)

#예시 1
import os
print(os.getcwd()) #현재 디렉토리를 표기

#예시 2
folder = "sample_dir"
if os.path.exists(folder): #만약 sample_dir이라는 폴더가 있다면 이 구문을 타라는 것
	print("이미 존재하는 폴더입니다.")
    os.rmdir(folder) #폴더 삭제
    print(folder, "폴더를 삭제하였습니다.")
else:
	os.makedirs(folder) #폴더 생성
	print(folder, "폴더를 생성하였습니다.")
    
#예시 3
print(os.listdir()) #glob과 유사하게 사용가능

3) time, datetime, timedelta : 시간관련 함수

#입력
import time
print(time.localtime())
print(time.strftime("%Y-%M-%D %H:%M:%S"))

출력

#입력
import datetime
print("오늘 날짜는 ", datetime.date.today())

출력

#timedelta는 두 날짜 사이의 간격을 알려준다.
#입력
import datetime
today = datetime.date.today() #오늘 날짜 저장
td = datetime.timedelta(days=100) #오늘 날짜로부터 100일 뒤는??
print("우리가 만난지 100일은", today + td) #오늘부터 100일 후

출력

4) strftime : 날짜형 데이터를 원하는 형식의 문자형으로 변환가능

print(now.strftime("%y%m%d %H%M%S")) #HMS(시, 분, 초)는 대문자로 기입한다.(소문자 입력 시 error 발생)

<strftime을 이용한 서식 표현>
4-1) 연도 구별 (대소문자)

print('[대문자Y]를 입력하는 경우 :',now.strftime('%Y'))
# [대문자Y]를 입력하는 경우 : 2022
print('[소문자y]를 입력하는 경우 :',now.strftime('%y'))
# [소문자y]를 입력하는 경우 : 22

4-2) 시간 구분 (H,I)

print('[H]를 입력하는 경우 :',now.strftime('%H시'))
# 24시간 단위로 표현
# [H]를 입력하는 경우 : 21
print('[I]를 입력하는 경우 :',now.strftime('%I시'))
# 12시간 단위로 표현
# [I]를 입력하는 경우 : 09

4-3) 초 구분 (S,f)

print('[S]를 입력하는 경우 :',now.strftime('%S초'))
# 초 단위
# [S]를 입력하는 경우 : 24초
print('[f]를 입력하는 경우 :',now.strftime('%f'))
# 마이크로초 (6자리)
# [f]를 입력하는 경우 : 155185

4-4) datetime 데이터에서 월(Month)과 요일(day) 정보 불러오기

  • 날짜 정보 중 유일하게 고유명사를 가진 정보인 요일과 월
  • a-(무슨)요일, b-월
# 요일,월 정보를 영어로 불러오기 (aA,bB 사용)
print('[A,B]를 입력하는 경우 :',now.strftime('%A, %B')) # 영어 fullname이 출력된다
# [A,B]를 입력하는 경우 : Friday, October
print('[a,b]를 입력하는 경우 :',now.strftime('%a, %b')) # 영어 shortname이 출력된다
# [a,b]를 입력하는 경우 : Fri, Oct

5) strptime : 문자형으로 주어진 데이터를 날짜형으로 변환해주기 위해 사용

# datetime type str >> datetime type datetime

import datetime

today = datetime.datetime.today() # 현재날짜, 시간 호출 후 지정
strf = today.strftime('%Y-%m-%d %H:%M:%S') # 2022-10-21 06:08:29
print(type(strf)) # <class 'str'>

strp = datetime.datetime.strptime(strf, '%Y-%m-%d %H:%M:%S')
print(strp) # 2022-10-21 06:08:29

print(type(strp)) # <class 'datetime.datetime'>

46. 시간지연 함수 Sleep

sleep()을 이용해 전달된 시간(second)만큼 지연 시킬 수 있다.

만약 1초에 한 번 시간을 출력하는 코드를 만들고 싶다면

import time
import datetime

while True:
    now = datetime.datetime.now()
    print(now)
    time.sleep(1) # 1초에 한 번

위와 같이 코드를 작성하면 된다.

Sleep()은

  • float을 전달하여 ms 단위의 시간도 지연가능
  • 0.001 이상의 값만 입력가능(그 이하의 값이 전달되면 0.001초만 sleep)

47. None

  • 변수 및 list, dictionary 안에 넣을 수 있는 data type
  • False 와 다르게 무언가가 '없을 때' 사용
  • 무언가 있어야 하는데 없다고 나타내줌
  for job in jobs:
    zone = job.find("div", class_="mosaic-zone")
    if zone == None:
      print("job li")
    else:
      print("mosaic li")
profile
개발 공부중

0개의 댓글