일반 유닛
class Unit:
def __init__(self, name, hp):
self.name = name
self.hp = hp
# 공격 유닛
class AttackUnit(Unit):
def __init__(self, name, hp, damage):
Unit.__init__(self, name, 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))
customer = "토르"
person = "Unknown"
while person != customer:
print("{0}, 커피가 준비 되었습니다.".format(customer))
person = input("이름이 어떻게 되세요? ")
- floor or math.floor : 내림
- ceil or math.ceil : 올림
- sqrt or math.sqrt : 제곱근
- randrange
- randrange(1, 46) : 1이상 46 미만 숫자
- randint
- randint(1,45) : 1이상 45이하 숫자
- 슬라이싱
변수명[:인덱스] → 처음부터 인덱스 직전까지 슬라이싱
변수명[인덱스:] → 인덱스부터 끝까지 슬라이싱
변수명[:] → 처음부터 끝까지 슬라이싱
- 문자열처리함
함수이름 | 의미 |
lower | 소문자로 변환 |
upper | 대문자로 변환 |
isupper | 대문자인지 확인 |
islower | 소문자인지 확인 |
replace | 문자열 바꾸기 |
index | 찾으려는 문자열의 인덱스 (없으면 에러) |
find | 찾으려는 문자열의 인덱스 (없으면 -1) |
count | 문자열이 나온 횟수 |
- 문자열 포맷
방법 1)
print("나는 %d 살 입니다" %20);
print("나는 %s을 좋아합니다" %'파이썬')
print("Apple은 %c로 시작해요" %"A")
print("나는 %s색과 %s색을 좋아해요" %("초록", "주황"))
방법 2)
print("나는 {} 살 입니다." .format(20))
print("나는 {}색과 {}색을 좋아해요." .format("파랑", "노랑"))
print("나는 {0}색과 {1}색을 좋아해요" .format("파랑", "노랑"))
print("나는 {1}색과 {0}색을 좋아해요" .format("파랑", "노랑"))
방법3)
print("나는 {age}살이며, {color}색을 좋아해요.".format(age=20, color="빨간"))
# 나는 20살이며, 빨간색을 좋아해요
print("나는 {age}살이며, {color}색을 좋아해요.".format(color="빨간", age=20))
# 나는 20살이며, 빨간색을 좋아해요 (.format 뒤에 순서를 변경해도 괜찮아요)
방법4)
age = 20
color = "빨간"
print(f"나는 {age}살이며, {color}색을 좋아해요.") # 나는 20살이며, 빨간색을 좋아해요.
- 탈출문자
print("오늘 점심은 무엇일까?\n 뭘 먹든 기분이 좋을거 같다") # \n : 줄바꿈
print("나는 \"김두한\"") # 따옴표 앞에 역슬래쉬
print("C:\\Users\\Nadocoding\\Desktop\\PythonWorkspace>") #역슬래쉬 2개
print(r"C:\Users\Nadocoding\Desktop\PythonWorkspace>") #맨 앞에 r을 넣기
print("C:\rUsers\rNadocoding\rDesktop\rPythonWorkspace>") # \r 은 커서를 맨 앞으로 이동
print("abcde\bf") # \b 은 백스페이스 역할, 왜인지는 모르겠는데 마지막에 \b을 넣으면 먹히지 않음(????)
print("Red\tHat") # \t 탭이랑 같은 역할
퀴즈 4-6 퀴즈 풀어봄
"""
Quiz) 사이트 별로 비밀번호를 만들어주는 프로그램을 작성하시오.
예) http://naver.com
규칙1 : http:// 부분은 제외 → naver.com
규칙2 : 처음 만나는 점(.) 이후 부분은 제외 → naver
규칙3 : 남은 글자 중 처음 세 자리 + 글자 갯수 + 글자 내 'e'의 갯수 + '!'로 구성
(nav) (5) (1) (!)
예) 생성된 비밀번호 : nav51!
"""
url = "http://naver.com"
#url = "http://daum.net"
#url = "http://google.com"
#url = "http://youtube.com"
url = url.replace("http://", "") #규칙1 replace 사용
url = url[:url.index(".")] #규칙2 index 사용
printUrl = url[:3] + str(len(url)) + str(url.count("e"))+"!" # 부분호출 + 길이 + 갯수카운팅 + !
print("printUrl : " + printUrl)
재미있더라 ㅎㅎㅎ
- 리스트 : 대괄호
subway = [10, 20, 30 ]
print(subway)
subway = ["유재석", "정준하", "하하"]
print(subway)
#정준하 몇번째? - index
print(subway.index("정준하"))
#마지막에 정형돈 추가 - append
subway.append("정형돈")
print(subway)
#노홍철을 유재석과 정준하 사이에 추가 - insert
subway.insert(1, "노홍철")
print(subway)
#한명씩 뒤에서 나감 - pop
subway.pop()
print(subway)
subway.pop()
print(subway)
subway.pop()
print(subway)
subway.pop()
print(subway)
subway.append("하하")
subway.append("유재석")
print(subway)
#유재석 몇명인지 체크 - count("찾고자하는")
print(subway.count("유재석"))
num_list = [1, 5, 2, 4, 3]
print(num_list)
#정렬(오름차순) - sort
num_list.sort()
print(num_list)
#역순 정렬(정렬하고 역순으로 해야함) - reverse
num_list.reverse()
print(num_list)
#지우기 - clear
num_list.clear()
print(num_list)
#같은 타입아니어도 들어감
mix_list =["축구", 5, True]
print(mix_list)
#리스트 확장
num_list = [1, 5, 2, 4, 3]
num_list.extend(mix_list)
print(num_list)
- 사전(Dictionary) - key와 value 쌍으로 이뤄짐
: 사전은 중괄호로 둘러싸서 정의할 수 있으며, key 와 value 는 콜론(:) 으로 구분짓습니다. 2개 이상의 데이터는 리스트와 마찬가지로 콤마(,)로 구분
# {} 중괄호 사용해서 사전형태의 cabinet에 key:value 입력
cabinet = {777:"노홍철", 100:"빠니보틀"}
# 1) value 값 구하기
#key 777의 value는???
print(cabinet[777])
#key 100의 value는???
print(cabinet[100])
# 2) value 값 구하기
print(cabinet.get(777)) # key 777에 해당하는 value
#대괄호 vs get
#대괄호 : 정의되지 않은 key를 전달하면 에러 발생 O => 프로그램 종료
#print(cabinet[300]) # KeyError: 300
#get : 정의되지 않은 key를 전달하면 에러 발생 X => None 을 return
print(cabinet.get(300)) # None
#get 이용해서 없는 key에 값을 설정 가능
print(cabinet.get(300, "사용불가"))
#사용여부 확인
print(300 in cabinet)
print(777 in cabinet)
# 정수형이 아닌 문자열도 가능
cabinet = {"A":"김두한", "z":"구마적" }
print(cabinet["A"])
print(cabinet.get("z"))
#업데이트 또는 추가
print(cabinet)
cabinet["A"] = "신마적" # 있는 key이므로 수정
cabinet["c"] = "개코" # 없는 key이므로 추가
print("추가 후")
print(cabinet)
# 삭제 - del
del cabinet["A"]
print("삭제 후")
print(cabinet)
#현재 사전의 key값들 모두 보기 - keys
print(cabinet.keys())
#현재 사전의 value값들 모두 보기 - values
print(cabinet.values())
#현재 사전의 key와 value 같이 보기 - items
print(cabinet.items())
#전체 삭제
cabinet.clear()
print(cabinet)
- 튜플 : 소괄호
#튜플 : 소괄호 사용, 변경, 추가, 삭제 안된다
menu = ("햄버거", "치킨")
print(menu[0])
print(menu[1])
name = "빠니보틀"
age = 38
hobby = "여행"
print(name, age, hobby)
#=============================
(name, age, job) = ("안재모", 22, "연기")
print(name, age, hobby)
# 함수를 공부할 때도 튜플 형태가 활용된다고 한다
- 세트 : 중괄호
#세트 : 중복제거,중괄호
my_set = {1, 2, 3, 3, 3}
print(my_set)
java = {"유재석", "정준하", "박명수"}
python =set(["유재석", "박명수"])
#교집합
print(java & python) #줄바뀜
print("--------------------------------------------------------------------------------------")
print(java.intersection(python))
#합집합
print(java | python)
print("--------------------------------------------------------------------------------------")
print(java.union(python))
#차집합
#print(java - python)
print("--------------------------------------------------------------------------------------")
print(java.difference(python))
print("--------------------------------------------------------------------------------------")
print("--------------------------------------------------------------------------------------")
print(python)
#set에 추가
python.add("하하") # 앞에 추가 된다
print(python)
python.remove("유재석") #
print(python)
헤깔리니까
리세튜 로 외우면 될듯 (대 중 소)
- 자료 구조 변경
#자료구조의 변경
#세트
menu = {"스시", "피자", "샤부샤부"}
print(menu, type(menu))
#리스트로 변경
menu = list(menu)
print(menu, type(menu))
#튜플로 변경
menu = tuple(menu)
print(menu, type(menu))
#다시 세트로
menu = set(menu)
print(menu, type(menu))
- 퀴즈 5-6
from random import *
"""
Quiz) 당신의 학교에서는 파이썬 코딩 대회를 주최합니다.
참석률을 높이기 위해 댓글 이벤트를 진행하기로 하였습니다.
댓글 작성자들 중에 추첨을 통해 1명은 치킨, 3명은 커피 쿠폰을 받게 됩니다.
추첨 프로그램을 작성하시오.
조건1 : 편의상 댓글은 20명이 작성하였고 아이디는 1~20이라고 가정
조건2 : 댓글 내용과 상관 없이 무작위로 추첨하되 중복은 불가
조건3 : random 모듈의 shuffle 과 sample 을 활용
(출력 예제)
-- 당첨자 발표 --
치킨 당첨자 : 1
커피 당첨자 : [2, 3, 4]
-- 축하합니다 --
"""
#list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
#========================== 방법 1 ==================================
users = range(1, 21) # 1부터 21까지의 연속된 숫자 모음
users = list(users)
shuffle(users)
winners = sample(users, 4) # 4명 무작위로 추출
print(" -- 당첨자 발표 --")
print("치킨 당첨자 : " + str(winners[0]))
print("커피 당첨자 : " + str(winners[1:]))
print("-- 축하합니다 --")
#========================== 방법 2 ==================================
member = list(range(1, 21))
chicken_member = sample(member, 1)
print("치킨 당첨자 1명 : " + str(chicken_member))
remain_member = set(member) - set(chicken_member)
#print(remain_member)
coffee_member = sample(list(remain_member), 3)
print("커피 당첨자 3 명 : " + str(coffee_member))
- if문
"""
#if문
weather = ""
if weather == "황사":
print("마스크를 꼭 쓰세여~")
#실행해야 하는 문장들은 if 위치를 기준으로 공백(스페이스) 4칸씩 들여쓰기를 해야함
if weather == "비":
print("우산챙겨")
elif weather == "황사":
print("마스크를 챙기십쇼")
else:
print("그냥 나가!!!")
"""
# input을 이용해보기
# input : input() 은 프로그램 실행 시점에 사용자로부터 어떤 값을 입력받는 용도로 사용
weather = input("오늘 날씨가 어떤가요???")
"""
if weather == "비":
print("우산챙겨")
elif weather == "황사":
print("마스크를 챙기십쇼")
else:
print("그냥 나가!!!")
"""
"""
if weather == "비" or weather == "눈":
print("우산챙겨")
elif weather == "황사":
print("마스크를 챙기십쇼")
else:
print("그냥 나가!!!")
"""
temp = int(input("기온은 어때요? "))
if 30 <= temp:
print("에어컨 틀어라!!!")
elif 10 <= temp and temp < 30:
print("축구하기 좋은 날씨!!!")
- for문
for waiting_no in [0,1,2,3,4,]:
print("대기번호 : {0}" .format(waiting_no))
for waiting_no in range(5): #0부터 5직전까지( 0 ~ 4 )
print("대기번호 : {0}" .format(waiting_no))
starbucks = ["아아", "카라멜마끼아또", "아이스 자몽 허니"]
for customer in starbucks:
print("손님 주문 음료 : " + customer +"가 나왔습니다")
- while문
customer = "아이언맨"
index = 5
while index >= 1 :
print("{0}. 커피가 준비되었습니다. {1}번 남았어요" .format(customer, index))
index -= 1
if index == 0:
print("폐기처분되었음!!!")
- 아래 코드는 내가 나도코딩님의 코드를 조금 수정해서 만들었음!!!
customer = "손흥민"
goal = 1
while True:
print("{0}선수 {1}번째 골을 득접하였습니다." .format(customer, goal))
goal+=1
if(goal == 30):
print("득정왕!!!")
break
- 이거는 나도코딩님 코드
customer = "토르"
person = "Unknown"
while person != customer:
print("{0}, 커피가 준비 되었습니다.".format(customer))
person = input("이름이 어떻게 되세요? ")
- continue && break
=>>>> continue 는 더 이상 아래 명령들을 실행하지 않고 다음 반복대상으로 넘어갈 때 사용
=>>>> break 는 즉시 반복문을 탈출하는 데 사용
absent = [2, 5] #결석한 자슼들
for student in range(1, 11):
if student in absent: # 결석자 말고 그 다음 번호로 넘어가기
continue
print("${0} 책 읽어봐" .format(student))
absent = [2, 5] #결석한 자슼들
no_book = [7]
for student in range(1, 11):
if student in absent: # 결석자 말고 그 다음 번호로 넘어가기
continue
elif student in no_book:
print("오늘 수업 접는다")
break
print("${0} 책 읽어봐" .format(student))
- 한 줄 for문
[변수로 어떤 동작 for 변수 in 반복대상] |
students = [1, 2, 3, 4, 5]
print(students)
sutdents = [i+100 for i in students]
print(students)
students = ["아이언맨", "토르", "그루트"]
students = [len(i) for i in students]
print(students)
students = ["Iron man", "Thor", "I am groot"]
print(students) # ["Iron man", "Thor", "I am groot"]
# 한 줄 for 를 이용하여 각 이름을 대문자로 변경
students = [i.upper() for i in students]
print(students) # ['IRON MAN', 'THOR', 'I AM GROOT']
6.5 퀴즈
Quiz) 당신은 Cocoa 서비스를 이용하는 택시 기사님입니다.
50명의 승객과 매칭 기회가 있을 때, 총 탑승 승객 수를 구하는 프로그램을 작성하시오.
조건1 : 승객별 운행 소요 시간은 5분 ~ 50분 사이의 난수로 정해집니다.
조건2 : 당신은 소요 시간 5분 ~ 15분 사이의 승객만 매칭해야 합니다.
(출력문 예제)
[O] 1번째 손님 (소요시간 : 15분)
[ ] 2번째 손님 (소요시간 : 50분)
[O] 3번째 손님 (소요시간 : 5분)
...
[ ] 50번째 손님 (소요시간 : 16분)
총 탑승 승객 : 2 분
내 풀이법과 나도 코딩님의 풀이법을 같이 적어봤으 ㅎ
from random import * #이걸 까먹음
#내가 푼 방식
member = range(1, 50)
count = 0
for i in member:
#print(str(i)+"번")
time = randint(5, 50) # 난수 생성
#print("시간 " + str(time))
if time >= 5 and time <= 15:
count+=1
print("총 탑승 승객 "+ str(count) + "분")
#나도코딩 정답 비슷하게 따라하기
for i in range(1,51):
time = randrange(5, 51)
if 5 <= time<=15:
count+=1
print("{0}번째 손님 소요시간 {1}분" .format(count, time))
-함수
나도코딩님께서도 말하셨지만 자바를 배운 사람으로 아래의 글에 대한 내용에 너무 동의하기에
잠깐!
함수의 이름은 그 함수의 동작을 대표하는 것으로 짓는 게 좋습니다. 이름만 보고도 어떤 동작을 하는지 유추할 수 있도록 말이죠. 예제에서는 계좌를 생성하는 동작이기 때문에 open account 라고 적었습니다. 그리고 함수의 이름은 정해진 규칙에 따라 만들어야 하는데, 문자로 시작하며 각 단어들(open, account) 을 밑줄(_) 로 구분하는 형태라면 대부분 사용 가능합니다. 보통 변수는 명사, 함수는 동사를 이용합니다.
def open_account():
print("새로운 계좌가 생성되었습니다.")
open_account()
- 전달값과 반환값
def 함수이름(전달값1, 전달값2, ...): 실행 명령문1 실행 명령문2 .... return 반환값1, 반환값2, ... |
def deposit(balance, money):
print("입금이 완료되었습니다. 잔액은 {0}원입니다" .format(balance+money))
return balance+money
balance = 0
balance = deposit(balance, 1000)
print (balance)
자바스크립트와 같음 ㅎㅎ
잠깐!!!
함수를 정의할 때 전달값을 받기 위해 사용되는 balance, money 와 같은 변수를 매개변수(parameter) 라고 부르기도 합니다.
if 조건을 통해서
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 = deposit(balance, 1000) # 1000원 입금
# 출금 시도
balance = withdraw(balance, 2000) # 2000원 출금 시도 시 잔액이 부족하므로 실패
balance = withdraw(balance, 500) # 500원 출금 시도 시 성공
print(balance) # 현재 잔액
둘을 함께 반환해주는 것으로 코드를 작성
def deposit(balance, money):
print("입금이 완료되었습니다. 잔액은 {0}원입니다" .format(balance+money))
return balance+money
def withdraw_night(balance, money):
commission = 100 #출금 수수료 100원
return commission, balance -money-commission #튜플형식으로 변환
balance = 0 #최초 잔액
balance = deposit(balance, 1000) #1000원 입금
#저녁에 출금 시도
commission, balance = withdraw_night(balance, 500)
print("수수료는 {0}이며, 잔액은 {1} 원입니다." .format(commission, balance))
- 기본값
def profile(name, age=17, main_lang="영어"):
print("이름 : {0}\t 나이 : {1} \t 사용언어 : {2}" .format(name, age, main_lang))
profile("유재석")
profile("김태호")
기본값을 사용하거나 사용하지 않음
def profile(name, age=17, main_lang="영어"):
print("이름 : {0}\t 나이 : {1} \t 사용언어 : {2}" .format(name, age, main_lang))
profile("유재석") #age, main_lang 기본값으로 사용
profile("김태호") #age, main_lang 기본값으로 사용
profile("빠니보틀", 19) # main_lang 기본값으로 사용
profile("곽튜브" , 20, "러시아어") # 기본값 사용안함
- 키워드 인자
def profile(name, age, main_lang): # 키워드 인자 : name, age, main_lang
print(name, age, main_lang)
# profile("유재석", 20, "파이썬")
# profile("김태호", 25, "자바")
profile(name="유재석", main_lang="파이썬", age=20)
profile(main_lang="자바", age=25, name="김태호")
- 가변인자
def 함수이름(전달값1, 전달값2, ..., *가변인자): 실행 명령문1 실행 명령문2 .... return 반환값 |
def profile(name, age, *language):
print("이름 : {0} \t 나이 : {1} \t " .format(name, age), end=" ")
for lang in language:
print(lang, end=" ")
print() #줄바꿈
profile("유재석", 20, "Python", "java", "C", "C++" )
- 지역변수와 전역변수
gun = 10 #총10자루
def checkpoint(soldiers):
gun = gun - soldiers
print("남은 총 : {0}" .format(gun))
print("전체 총 : {0} " .format(gun))
checkpoint(2) #2명이 경꼐근무 출발
print("남은 총 : {0}" .format(gun))
이렇게 작성하면 에러가 발생한다...
UnboundLocalError: local variable 'gun' referenced before assignment
지역 변수란???
함수 내에서만 쓸 수 있는 변수이며, 전역 변수는 모든 곳에서 쓸 수 있는 변수입니다.
그리고 checkpoint() 함수 내에서 사용하려는 gun 은 함수 외부에 선언된 gun 과는 아무 상관 없는, checkpoint() 함수 내에서 새로 만들어진 지역변수이다. 아직 아무 값도 들어가지 않고 gun 이 선언되지도 않았는데 gun - soldiers 라는 연산을 하려다보니 에러가 발생한 것이다.
gun = 10 #총10자루
def checkpoint(soldiers):
gun = 20
gun = gun - soldiers
print("남은 총 : {0}" .format(gun))
print("전체 총 : {0} " .format(gun))
checkpoint(2) #2명이 경꼐근무 출발
print("남은 총 : {0}" .format(gun))
전체 총과 남은 총은 10 으로 변함이 없고 checkpoint() 함수 내에서 새롭게 선언된 gun 에는 20 이라는 값이 저장되었다가 군인 수만큼 2를 빼니 18 로 줄어들었네요. 하지만 실제로 총기함에는 2자루의 총이 줄어든 8자루라고 나와야 정상아님?
해결책은 바로 global 이라는 키워드입니다. 함수 내에서 전역변수를 사용하겠다는 의미인데요. global gun 이라고만 하면 전역 공간에 선언된 변수를 그대로 사용하며 그 값을 직접 변경할 수도 있습니다.
gun = 10
def checkpoint(soldiers):
global gun
gun = gun - soldiers
print("남은 총 : {0}" .format(gun))
print("전체 총 : {0}" .format(gun))
checkpoint(2)
print("남은 총 : {0}" .format(gun))
전역변수가 없는 버전으로 만들어 봄. 전달값과 반환값을 적절히 활용하는 방법이며, 반환(return) 을 의미하는 내용을 담아 checkpoint_ret() 라는 새로운 함수로 정의함.
gun = 10
def checkpoint_ret(gun, soldiers):
gun = gun - soldiers
print("남은 총 : {0}" .format(gun))
return gun
print("전체 총 : {0}" .format(gun))
gun = checkpoint_ret(gun, 2)
print("남은 총 : {0}" .format(gun))
7-7 퀴즈
문제)
Quiz) 표준 체중을 구하는 프로그램을 작성하시오
* 표준 체중 : 각 개인의 키에 적당한 체중
(성별에 따른 공식)
남자 : 키(m) * 키(m) * 22
여자 : 키(m) * 키(m) * 21
조건1 : 표준 체중은 별도의 함수 내에서 계산
* 함수명 : std_weight
* 전달값 : 키(height), 성별(gender)
조건2 : 표준 체중은 소수점 둘째자리까지 표시
(출력 예제)
키 175cm 남자의 표준 체중은 67.38kg 입니다.
내가 구한 답)
def std_weight (height, gender):
if(gender == "여자"):
result = (height/100) * (height/100) * 21
return print("키 {0}cm {2}의 표준 체중은 {1}kg 입니다." .format(height, result, gender))
elif(gender == "남자"):
result = (height/100) * (height/100) * 22
return print("키 {0}cm {2}의 표준 체중은 {1}kg 입니다." .format(height, result, gender))
std_weight(155, "여자")
반올림하는거 안했네 ㅎㅎㅎ 그냥 넘어간다 ㅎㅎ 요즘 내가 제정신이 아니다
나도코딩님 답)
def std_weight(height, gender): # 키 m 단위 (실수), 성별 "남자" / "여자"
if gender == "남자":
return height * height * 22
else:
return height * height * 21
height = 175 # cm 단위
gender = "남자"
weight = round(std_weight(height / 100, gender), 2) # 소수점 둘째자리까지 반올림
print("키 {0}cm {1}의 표준 체중은 {2}kg 입니다.".format(height, gender, weight))
- 표준 입출력
print() 문에는 비밀이 하나 숨겨져있는데, 바로 문자열들을 구분하는 방법을 사용자가 직접 정의할 수 있다는 것이다. 그 비밀은 바로 sep 이다. 분리 기호를 의미하는 separator 의 줄임말이라고 한다.
print() 는 기본적으로 문장이 끝날때마다 줄바꿈을 하는걸 이미 알고 있다.
print() 는 기본적으로 문장이 끝날때마다 줄바꿈을 하기 때문에 연속적으로 2개 이상의 print() 를 이용하면 각각의 줄에 내용이 출력됩니다. 하지만 이를 한 줄에 모두 엮어서 출력하려면 end=" " 와 같이 하면 되지요.
end 적지 않으면
file= 에 sys.stdout (Standard Output, 표준 출력) 와 sys.stderr (Standard Error, 표준 에러) 를 각각 넣었는데, 출력결과는 크게 달라보이지 않다. 머지 않은 미래에 보다 큰 규모의 파이썬 프로젝트를 진행하게 되면 필요해질텐데, stdout 과 stderr 은 사용하는 용도가 조금 다르다.
보통 프로그램 수행 과정에서 몇 시에 어떤 작업을 어떤 식으로 수행하고 있으며 그 결과는 어떠한지 등의 정보를 가지는 로그를 남길 때 stdout 은 일반적인 내용을, stderr 는 에러 발생 시 관련 내용을 출력하기 위해 사용할 수 있다. 이렇게 구분지어주면 프로그램이 의도치 않은 동작을 하는 경우에 에러 로그만 확인하면 보다 빠르게 상황 파악 및 조치가 가능해진다.
파이썬 기본편을 공부하는 시점에서는 이런 게 있구나 정도로만 이해하고 넘어가도 된다고 하신다.
ljust() && rjust()
: l 과 r 은 각각 왼쪽(left) 과 오른쪽(right) 을 의미하며, 함께 전달하는 숫자값 만큼 미리 공간을 확보하고 나서 그 공간에 왼쪽 정렬 또는 오른쪽 정렬을 해주는 동작
위에 코드를 조금 바꿔보면
zfill()
: zfill() 은 함께 전달해주는 숫자만큼의 공간을 확보하고 그 공간을 zero 로, 즉 0 으로 채워주는(fill) 동작을 한다.
- 다양한 출력포맷
1) 기본
print("{0}".format(500)) # {0} 위치에 500 값 출력
2)
print("{0: >10}".format(500)) # 빈 자리는 비워두기, 우측 정렬, 10 칸의 공간 확보
3)
print("{0: >+10}".format(500)) # 빈 자리는 비워두기, 우측 정렬, + 기호, 10 칸의 공간 확보
print("{0: >+10}".format(-500))
4)
print("{0:_<10}".format(500)) # 빈 자리는 _ 로, 좌측 정렬, 10 칸의 공간 확보
큰 수를 표시할 때 꼭 필요한 콤마(,)를 넣기
print("{0:,}".format(100000000000)) # 3자리 마다 콤마 찍어주기
print("{0:+,}".format(100000000000)) # + 기호, 3자리 마다 콤마 찍어주기
print("{0:+,}".format(-100000000000))
빈 자리는 ^ 로, 좌측 정렬, + 기호, 30 칸의 공간 확보, 3자리 마다 콤마 찍어주기
print("{0:^<+30,}".format(100000000000))
실수 값 출력
print("{0:f}".format(5/3)) # 실수 값 출력
셋째자리에서 반올림하여 둘째자리까지 출력
print("{0:.2f}".format(5/3)) # 소수점 둘째자리까지 출력
- 파일입출력
open("파일명", "열기 모드", encoding="인코딩") |
이 중에서 2번째로 전달하는 "열기 모드" 에는 읽기(read, "r"), 쓰기(write, "w"), 이어쓰기(append, "a") 가 있다. 읽기(r)는 말 그대로 이미 어떤 내용을 담고 있는 파일을 읽어오기 위한 모드이며, 파일에 어떤 내용을 쓰기 위해서는 쓰기나 이어쓰기 모드를 사용한다. 이 때 동일한 이름의 파일이 있는 경우 쓰기 모드는 그 파일을 덮어쓰게 되므로 기존 내용은 다 삭제가 되며, 이어쓰기 모드는 그 파일의 내용 맨 밑에 이어서 쓴다는 차이점이 있다. encoding 은 파일 내용으로 쓰는 언어와 관련된 것인데 일반적으로 "utf8" 로 설정을 해주면 한글을 포함한 내용을 다룰 때에도 문제가 없습니다.
w 모드
score_file = open("score.txt", "w", encoding="utf8") # score.txt 파일을 쓰기("w") 모드로 열기
print("수학 : 0", file=score_file) #score.txt 파일에 내용 쓰기
print("영어 : 50", file=score_file) #score.txt 파일에 내용 쓰기
score_file.close() #score.txt 파일 닫기
a 모드
score_file = open("score.txt", "a", encoding="utf8") # score.txt 파일을 쓰기("a") 모드로 열기
score_file.write("과학 : 80")
score_file.write("\n코딩 : 100") # write 는 줄바꿈 안해주기 때문에 탈출문자(\n)로 줄바꿈 추가
score_file.close()
r 모드
score_file = open("score.txt", "r", encoding="utf8") # score.txt 파일을 읽기("r") 모드로 열기
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="") # 줄바꿈 중복을 방지하기 위해 end="" 처리
print(score_file.readline(), end="")
print(score_file.readline(), 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="") # 읽어온 줄 출력. 줄바꿈 중복을 방지하기 위해 end="" 처리
score_file.close()
score_file = open("score.txt", "r", encoding="utf8")
lines = score_file.readlines() # 모든 줄을 읽어와서 list 형태로 저장
for line in lines:
print(line, end="") # 읽어온 줄 출력. 줄바꿈 중복을 방지하기 위해 end="" 처리
score_file.close()
- pickle
pickle 은 프로그램에서 사용하고 있는 데이터를 파일 형태로 저장하거나 불러올 수 있게 해주는 모듈임
먼저 pickle 을 이용하여 데이터를 파일로 저장을 할 때는 dump() 라는 함수를 사용하는디, 첫 번째 전달값으로는 저장할 데이터를, 두 번째 전달값으로는 데이터를 저장할 파일을 적어준다네.
dump(data, dest_file) |
import pickle
profile_file = open("profile.pcicker", "wb")
profile = {"이름":"박명수","나이":30, "취미":{"축구","골프","웨딩"}}
print(profile)
pickle.dump(profile, profile_file)
profile_file.close()
profile_file = open("profile.pickle", "rb") # 읽을 때에도 바이너리(binary) 명시
profile = pickle.load(profile_file) # file 에 있는 정보를 불러와서 profile 에 저장
print(profile)
profile_file.close()
{'이름': '박명수', '나이': 30, '취미': ['축구', '골프', '코딩']}
- with
with 란 것이 있는데, 이를 이용하면 파일을 열고 나서 close() 를 호출하지 않아도 자동으로 닫아주는 역할을 해줍니다
with 작업 as 변수명: 실행 명령문1 실행 명령문2 ... |
8-6 문제 필요하지 않다는 판단에 일단 skip!!!
- 클래스
name = "마린"
hp = 40
damage = 5
print("{} 유닛이 생성되었습니다".format(name))
print("체력 {0}, 공격력 {1}\n" .format(hp, damage))
tank_name = "탱크"
tank_hp = 150
tank_damage = 35
print("{} 유닛이 생성되었습니다" .format(tank_name))
print("체력 {0}, 공경력 {1} \n" .format(tank_hp, tank_damage))
# 마린 : 공격 유닛, 군인. 총을 쏠 수 있음
name = "마린"
hp = 40
damage = 5
# 탱크 : 공격 유닛, 탱크. 포를 쏠 수 있는데, 일반 모드 / 시즈 모드
print("{} 유닛이 생성되었습니다".format(name))
print("체력 {0}, 공격력 {1}\n" .format(hp, damage))
tank_name = "탱크"
tank_hp = 150
tank_damage = 35
print("{} 유닛이 생성되었습니다" .format(tank_name))
print("체력 {0}, 공경력 {1} \n" .format(tank_hp, tank_damage))
#탱그 2 새로 추가
tank2_name = "탱크"
tank2_hp = 150
tank2_damage = 35
print("{} 유닛이 생성되었습니다." .format(tank2_name))
print("체력 {0}, 공경력 {1}\n" .format(tank2_hp, tank2_damage))
#공격 함수
def attack(name, location, damage):
print("{0} : {1} 방향으로 적군을 공격 합니다. [공격력 {2}]" .format(name, location, damage))
attack(name, "1시", damage)
attack(tank_name, "1시", tank_damage)
attack(tank2_name, "1시", tank2_damage)
클래스는 보통 붕어빵 기계의 틀에 비유를 한다고 한다. 붕어빵을 만들 때 틀에다가 재료를 넣고 불에 구우면 똑같은 모양의 붕어빵을 만들 수 있다. 틀은 하나인데 붕어빵은 계속해서 만들 수 있는 것이다. 클래스도 이러한 하나의 틀이라고 생각하시면 되는데 보통 서로 연관이 있는 변수와 함수의 집합으로 이루어짐.
class 클래스명: def 메소드1(self, 전달값1, 전달값2, ...): 실행명령문1 실행명령문2 ... def 메소드2(self, 전달값1, 전달값2, ...): 실행명령문1 실행명령문2 ... |
멤버변수 : 클래스 내에서 사용할 수 있는 변수
정리하자면...
클래스는 서로 관련이 있는 변수 (멤버변수) 와 함수 (메소드) 들의 집합이다.
- init
클래스에는 __init__() 메소드가 있습니다. 이를 생성자(Constructor) 라고 부르는데요, 사용자가 따로 호출하지 않아도 클래스 객체를 생성할 때 자동으로 호출이 되는 부분 이다. 객체를 생성할 때는 이 생성자의 전달값에 해당하는 갯수만큼 값을 던져줘야 합니다. 단, self 부분은 제외하고...
앞서 배운 코드를 또 한번더 가져옴...
class Unit:
def __init__(self, name, hp, damage):
self.name = name # 멤버변수 nameㅇ에 전달값 name 저장
self.hp = hp
self.damage = damage
print("{0} 유닛이 생성되었습니다." .format(self.name))
print("체력 {0}, 공격력 {1}" .format(self.hp, self.damage))
marine1 = Unit("마린", 40, 5) # 마린1 생성, 전달값으로 name,hp, damage를 전달
marine2 = Unit("마린", 40, 5) # 마린2 생성
tank = Unit("탱크", 150, 35) # 탱크 생성
위에 코드가 있는데 여기다가
marine3 = Unit("마린")
를 추가하면
TypeError: Unit.__init__() missing 2 required positional arguments: 'hp' and 'damage'
이렇게 에러가 뜬다...
전달값을 1개 더 추가해도
marine3 = Unit("마린", 40)
TypeError: Unit.__init__() missing 1 required positional argument: 'damage'
이렇게 에러가 뜬다
이와 같이 클래스 객체를 생성할 때는 __init__() 생성자에 정의된 self 를 제외한 갯수만큼 전달값을 넘겨주어야 합니다.
- 멤버변수
멤버변수 : 클래스 내에서 정의된 변수
class Unit:
def __init__(self, name, hp, damage):
self.name = name # 멤버변수 nameㅇ에 전달값 name 저장
self.hp = hp
self.damage = damage
print("{0} 유닛이 생성되었습니다." .format(self.name))
print("체력 {0}, 공격력 {1}" .format(self.hp, self.damage))
3번째 사용하는 Unit 클래스를 보자. Unit 클래스의 경우 name, hp, damage 가 멤버변수가 되며 클래스 내에서는 self.name 과 같은 방식으로 값을 설정하고 사용한다.
# 레이스 : 공중 유닛, 비행기. 클로킹 (상대방에게 보이지 않음)
wraith1 = Unit("레이스", 80, 5) #체력 80, 공격력 5
print("유닛 이름 : {0}, 공격력 : {1}" .format(wraith1.name, wraith1,damage))
class Unit:
def __init__(self, name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
print("{0} 유닛이 생성되었습니다.".format(self.name))
print("체력 {0}, 공격력 {1}".format(self.hp, self.damage))
# 레이스 : 공중 유닛, 비행기. 클로킹 (상대방에게 보이지 않음)
wraith1 = Unit("레이스", 80, 5) # 체력 80, 공격력 5
print("유닛 이름 : {0}, 공격력 : {1}".format(wraith1.name, wraith1.damage)) # 멤버변수 접근
# 마인드 컨트롤 : 상대방 유닛을 내 것으로 만드는 것 (빼앗음)
wraith2 = Unit("빼앗은 레이스", 80, 5)
wraith2.cloaking = True # 빼앗은 레이스만을 위한 특별한 멤버변수 정의
if wraith2.cloaking == True: # 클로킹 상태라면?
print("{0}는 현재 클로킹 상태입니다.".format(wraith2.name))
# 에러 발생
# if wraith1.cloaking == True: # 우리가 만든 레이스 클로킹 여부
# print("{0}는 현재 클로킹 상태입니다.".format(wraith1.name))
- 메서드
클래스 내에서 정의되는 함수인 메소드(method)에 대해 알아보겠다. 클래스에는 여러 개의 메소드를 정의할 수 있는데 일반 함수와 다른 점이라면 메소드는 전달값을 정의하는 부분 처음에 self 를 적어준다는 점, 그리고 메소드 내에서 self. 을 통해 클래스 멤버변수에 접근 가능하다는 점입니다.
이번에는 공격을 할 수 있는 유닛만을 위한 새로운 클래스를 정의하고 이름은 AttackUnit 이라고 하겠다. AttackUnit 은 Unit 클래스와 동일하게 __init__() 생성자에서 name, hp, damage 멤버 변수를 정의하는데 print() 를 통한 출력문은 따로 적지 않겠다. 이 때 유닛 이름과 공격력은 이미 클래스 객체의 멤버 변수로 정의되어 있기 때문에 자기 자신을 의미하는 self. 을 쓰고, 공격 방향은 명령을 받을 때마다 달라질 수 있으므로 멤버 변수가 아닌 전달값을 사용하기 위해 self. 없이 쓴다는 점 주의해라.
class AttackUnit: #공격 유닛
def __init__(self, name, hp, damage):
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): #damage 만큼 유닛 피해
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage)) #데미지 정보 출력
self.hp -= damage #유닛의 체력에서 전달받은 damamge 만큼 감소
print("{0} : 현재 체력은 {1} 입니다" .format(self.name, self.hp)) # 남은 체력 출력
if self.hp <= 0: #남은 체력이 0 이하이면?
print("{0} : 파괴되었습니다." .format(self.name)) #유닛 파괴 처리
# 파이어뱃 : 공격 유닛, 화염방사기.
firebat1 = AttackUnit("파이어뱃", 50, 16) #체력 50, 공격력 16
firebat1.attack("5시")
firebat1.damaged(25)
firebat1.damaged(25)
- 상속
클래스에는 상속이라는 개념이 있어서 공통되는 부분은 코드를 중복으로 적지 않고도 재사용을 할 수 있다.
클래스를 상속받을 때는 클래스 이름 뒤에 괄호를 적고 상속 받을 클래스 이름을 명시해주면 된다. 그리고 이 때 두 클래스는 자식클래스와 부모클래스라고 표현한다. 마치 실생활에서 자식이 부모로부터 상속받는 것과 같이 말이다.
class 자식클래스(상속받을 부모클래스): |
그리고 코드를 재사용하기 위해 AttackUnit 클래스의 __init__() 생성자에서 name, hp 멤버변수를 정의하는 부분은 다음과 같이 부모 클래스의 __init__() 생성자를 호출하는 방식으로 코드를 간소화할 수가 있습니다. 이 때도 self 를 넘겨주는 것은 잊지 말아야 하지요.
상속을 이용하여 작성한 코드
# 일반 유닛
class Unit:
def __init__(self, name, hp):
self.name = name
self.hp = hp
# 공격 유닛
class AttackUnit(Unit):
def __init__(self, name, hp, damage):
Unit.__init__(self, name, 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))
- 다중상속
# 일반 유닛
class Unit:
def __init__(self, name, hp):
self.name = name
self.hp = hp
# 공격 유닛
class AttackUnit(Unit):
def __init__(self, name, hp, damage):
Unit.__init__(self, name, 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))
# 날 수 있는 기능을 가진 클래스
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, damage) # 이름, 체력, 공격력
Flyable.__init__(self, flying_speed) # 공중 이동 속도
# 발키리 : 공중 공격 유닛, 한번에 14발 미사일 발사.
valkyrie = FlyableAttackUnit("발키리", 200, 6, 5) # 이름, 체력, 공격력, 공중 이동 속도
valkyrie.fly(valkyrie.name, "3시") # 3시 방향으로 발키리를 이동
- 메서드 오버라이딩 (vs 오버로딩 : 동일한 이름의 함수를 매개변수 타입, 개수에 따라 다른 기능으로 동작 가능)
<== 다시 여러번 보기!!!==>
오버라이딩
: 상속 관계에 있는 클래스들 사이에서 부모 클래스에 정의된 메소드를 그대로 사용하지 않고 자식 클래스에서 같은 이름으로 메소드를 새롭게 정의하여 사용하도록 할 수 있는데 이를 메소드 오버라이딩(method overriding) 이라고 함.
# 일반 유닛
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(Unit):
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)
Flyable.__init__(self, flying_speed)
def move(self, location):
print("[공중 유닛 이동]")
self.fly(self.name, location)
# 벌쳐 : 지상 유닛, 기동성이 좋음
vulture = AttackUnit("벌쳐", 80, 10, 20) # 지상 speed 10
# 배틀크루저 : 공중 유닛, 체력도 굉장히 좋음, 공격력도 좋음
battlecruiser = FlyableAttackUnit("배틀크루저", 500, 25, 3)
vulture.move("11시")
# battlecruiser.fly(battlecruiser.name, "9시")
battlecruiser.move("9시") # 오버라이딩된 move() 호출
- pass
다른 작업을 먼저 하고 나서 나중에 코드를 완성한다고 가정할 때,. 이럴 때 파이썬에서는 pass 를 쓸 수 있다.
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
pass
# 서플라이 디폿 : 건물 1 개 건물 = 8유닛
supply_depot = BuilingUnit("서플라이 디폿", 500, "7시") #체력 500, 생성 위치 7시
pass 는 아무것도 하지 않고 일단은 그냥 넘어간다는 의미로 사용됩니다. 즉, __init__() 생성자는 실제로는 완성되지 않았지만 마치 완성된 것처럼 보여질 수 있는 것이죠.
- super
<== 다시 여러번 보기!!!==>
기존 코드는 아래와 같다.
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
Unit.__init__(self, name, hp, 0) # speed 0 : 건물은 지상 이동 불가
self.location = location
클래스에서도 이와 같이 부모 클래스의 이름을 직접 적지 않고도 부모 클래스에 접근하는 방법이 있다. 바로 super() 라는 것인데, 앞의 코드는 다음과 같이 함으로써 동일한 동작을 수행하게 된다. 단, super() 를 사용할 때는 self 를 제외한다는 점을 주의해야한다.
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
super().__init__(name, hp, 0) # 부모 클래스 접근. self 없이 사용
self.location = location
class Unit:
def __init__(self):
print("Unit 생성자")
class Flyable:
def __init__(self):
print("Flyable 생성자")
# class FlyableUnit(Unit, Flyable):
class FlyableUnit(Flyable, Unit): # 순서 변경
def __init__(self):
# super().__init__()
Unit.__init__(self) # Unit 클래스 생성자 호출
Flyable.__init__(self) # Flyable 클래스 생성자 호출
# 드랍쉽
dropship = FlyableUnit()
9-10. 스타크래프트 전반전
9-11. 스타크래프트 후반전
9-12. 퀴즈
class House:
# 매물 초기화 : 위치, 건물 종류, 매물 종류, 가격, 준공년도
def __init__(self, location, house_type, deal_type, price, completion_year):
self.location = location
self.house_type = house_type
self.deal_type = deal_type
self.price = price
self.completion_year = completion_year
# 매물 정보 표시
def show_detail(self):
print(self.location, self.house_type, self.deal_type, self.price, self.completion_year)
houses = []
house1 = House("강남", "아파트", "매매", "10억", "2010년")
house2 = House("마포", "오피스텔", "전세", "5억", "2007년")
house3 = House("송파", "빌라", "월세", "500/50", "2000년")
houses.append(house1)
houses.append(house2)
houses.append(house3)
print("총 {0}대의 매물이 있습니다.".format(len(houses)))
for house in houses:
house.show_detail()
- 예외처리
try ~ exception
- 에러 발생시키기
실제로 에러 상황이 발생한 것이 아니라도 프로그램이 허용하지 않는 동작을 하려고 할 때 의도적으로 에러를 발생시킬 수 있으며 문법은 다음과 같습니다.
raise 에러종류 |
ex)
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요: "))
num2 = int(input("두 번째 숫자를 입력하세요: "))
if num1 >= 10 or num2 >= 10: # 입력받은 수가 한 자리인지 확인
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
- 10.3 사용장정의 예외처리
-10-4.finally
-10-5.퀴즈 #9
-11-1.모듈
-11-2.패키지
-11-3._all_
-11-4.모듈 직접 실행
-11-5.패키지, 모듈 위치
- 11-6.pip install
- 11-7.내장함수
- 11-8.외장함수
- 11-9.퀴즈 #10
'Python' 카테고리의 다른 글
vscode open in broser default 변경 (0) | 2024.06.04 |
---|---|
파이썬 게임만들기 따라하기!!! (0) | 2024.05.29 |
파이썬 설치된 패키지 목록 보기 (0) | 2024.05.24 |