Python의 명령어는 아래와 같다.
if, for, while, break, continue, return
판단이 가능한 문장을 표현식이라고 합니다.
if bool 데이터 : bool 데이터가 True인 경우 수행할 문장 elif bool 데이터 : 앞의 데이터가 False이고, 현재 데이터가 True인 경우 수행할 문장 .... else : 앞의 모든 데이터가 False인 경우 수행할 문장
elif와 else 는 if없이 사용 불가능합니다.
elif는 0번 이상, else는 생략 혹은 한번만 가능
#하나의 점수를 이볅받아서 60점 이상이면 합격 #무조건 프로그램 종료라는 문구를 출력 score=int(input("점수를 입력하세요 : ")) #실제 프로그램이라면 잘못된 입력을 할 수 있으므로 예외처리를 #해주는 것이 좋습니다. print(type(score)) #정말로 문자열이 int로 바뀐건지 확인하기 if score>=60: data=30 print("합격") else : print(data) print("프로그램 종료")
if score==False
보다는if !score:
라고 한다.
왜냐하면 == 연산은 __eq__ 이 메서드를 사용하는 것이기에 메모리 사용 단점이 존재한다.
""" 90에서 100사이이면 A 80에서 89사이이면 B 70에서 79사이이면 C 60에서 69사이이면 D 0에서 59사이면 F """ score = int(input("점수를 입력해주세요")) #int 형변환은 문자열이 int 형태의 친구라면 int로 #하지만 다른 실수나 그러면 못해줌 #물론 int형인 실수를 정수형으로는 바꿀 수 있음 if score>=90 and score<=100: print("A") elif score>=80 and score<=89: print("B") elif score>=70 and score<=79: print("C") elif score>=60 and score<=69: print("D") elif score>=0 and score<=59: print("F") else : #사용자의 입력은 랜덤하기에 제약을 주는 용도로 사용하자. print("잘못된 점수 입력입니다.")
이와 같이 else는 예외처리를 하는데 사용하는 것이 좋다.
- int 형변환은 문자열이 int 형태의 값이라면 int로
- 하지만 다른 실수나 그러면 못해줌
- 물론 int형인 실수를 정수형으로는 바꿀 수 있음
- 굳이 실수형태도 받고 싶다하면
int(float(input()))
# 0 이면 일요일, 1이면 월요일, .... 6이면 토요일 을 출력하자 dayDict={0:"일요일", 1:"월요일", 2:"화요일", 3:"수요일", 4:"목요일", 5:"금요일", 6:"토요일"} day=int(input("0에서 6까지의 숫자를 입력하세요")) if day>=0 and day<=6: # 원래 dict쓸 때 이것도 가능하다. 하지만 잘 안쓴다. #(없는 값 넣으면 에러) print(dayDict[day]) else: print("잘못된 입력입니다.") # get을 쓰자. 한 번에 끝난다. print(dayDict.get(day, "알 수 없는 요일"))
dict에서 get은 일치하는 키가 있으면 그 값을 가져오고, 없으면 두 번째 매개변수의 값을 리턴한다.
x=10 y if x>=10: y=True else: y=False
x=10 y=False if x<10 else Ture # y는 x가 10미만이면 False를 대입 아니면 True 대입
밑에가 중요해
while bool 데이터 : bool 데이터가 True인 경우 수행할 문장
while bool 데이터 : bool 데이터가 True인 경우 수행할 문장 else: while이 break를 만나지 않고 정상 종료된 경우 수행할 문장
idx=0 while idx<10: print(idx) idx+=1 #if idx>5:#이게 수행되면 else사용 x # break else: print("반복문 종료") print(idx)
else는 반복문이 모두 정상적으로 수행하고 종료된 경우에 호출된다. break나 예외 발생 시 호출이 안된다.
예외 발생 때문에 걸어두는 것이다.
while Ture: 반복할 내용
for 임시변수 in 순서열 : 순서열의 데이터를 하나씩 임시변수에 대입하고 수행할 문장
순서열은 __iter__가 구현된 인스턴스 :
순서열 : str, dict, set, tuple, list, bytes
range(숫자)
: 0부터 숫자 전까지 1씩 증가한 숫자열range(시작숫자,종료다음숫자)
range(시작숫자, 종료다음숫자, 간격)
news="http://www.donga.com/news/search?p=" newsList=[] newsCnt=67 listLength=15 pagenum=int((newsCnt/listLength)+1) for i in range(1,pagenum+1): newsList.append(news+str((i-1)*15+1)) print(newsList) for i in range(1,32,15): print("http://www.donga.com/news/search?p=",i,sep="") for i in range(3): print("http://www.donga.com/news/search?p=", (i*15)+1,sep="") for i in range(3): q="http://www.donga.com/news/search?p="+str((i*15)+1) print(q)
여러 방식이 존재한다.
#2 부터 100까지 완전수의 개수 #완전수 : 자신을 제외한 약수의 합이 자신과 같다. perfectNum=[] startNum=2 endNum=1000 for i in range(startNum,endNum+1): divisorSum=1 #1은 모든 수의 약수이기에 for j in range(2,i//2+1):#2부터 하자 #자기보다 절반보다 큰 숫자가 약수가 될 확률 #+1을 해줘야지 i//2까지 가겠지 if(i%j==0): divisorSum+=j if(i==divisorSum): perfectNum.append(i) print(perfectNum) print(len(perfectNum))
# 피보나치 수열 # 첫 번째와 두 번쨰 데이터는 1 # 세 번째 데이터부터는 앞의 2개의 합 # # list append해서 간단하게? # fibonacci=[1,1] #앞에는 고정이라 그냥 해두자 n=10 for i in range(2,n): # 굳이 반복문의 횟수를 늘리려고 하지 말자. fibonacci.append(fibonacci[i-2]+fibonacci[i-1]) print(fibonacci) # #재귀함수 쓰면 안되나? # def fibo(n): if n==1 or n==2: return 1 else : return fibo(n-2)+fibo(n-1) # #강사님이 원한 것 # def prof_fibo(n): if n==1 or n==2: return 1 else: n_1=1 #직전항 n_2=1 # 두번쨰 앞의 항 result=0 #실제 결과 for i in range(3,n+1): # 1, 2번항은 이미 한거라 뺀거야. result=n_1+n_2 n_2=n_1 n_1=result return result # # 결과물을 확인해보자. # idx=int(input("구하고자 하는 피보나치 수열의 값은?")) print("fibonacci 리스트를 확인하면 : "+str(fibonacci[idx-1])) print("fibo함수를 사용하면 : "+str(fibo(idx))) print("강사님이 생각한 함수를 사용하면 : "+str(prof_fibo(idx)))
결국 어떻게든 똑같은 코드를 묶어서 줄여 써보자
분석을 하는 사람들은 파이썬 함수의 원형을 잘 봐야한다.
dir(__builtins__))
def 함수이름(매개변수 나열): 함수 내용 return 데이터
함수 이름은 사용자 엉의 명칭을 사용
매개변수는 없을 수 도 있습니다.
return도 생략 가능합니다.
함수이름(매개변수에 대입할 데이터 나열)
#hello python을 2번 출력 #hello java를 2번 출력 print("hello python") print("hello python") print("hello java") print("hello java") #횟수 및 변수를 바꾸려면 싹 바꿔야 하는 불편함이 있다. for i in range(3): print("hello python") def whoR(name,n): for i in range(n): print("hello",str(name)) whoR("R", 5) whoR # 함수 이름은 함수를 저장한 곳의 참조 print(whoR) #이를 한다면 id를 보여줌 #<function whoR at 0x0000021604264700> python id : 16진수
return 데이터
를 이용하면 데이터를 가지고 돌아갑니다.python은 여러개의 데이터를 return 할 수 있습니까?
- 근본적으로는 잘못되었습니다.
- 1개의 데이터이지만 여러개의 데이터를 가리키는 데이터라 여러개를 가지고 return하는 것으로 보이는 것입니다.
- ✔ python은 콤마(,)를 이용해서 데이터를 나열하면 tuple로 간주
- 10,20 (10,20) : tuple(row)로 인식- 이전의 파이썬 문법에서 함수의 헤더에 리턴되는 자료형을 적지 않았지만, 최근에는 가독성의 문제 때문에 헤더 부분에 리턴되는 데이터의 타입을 기재하는 경우가 많습니다.
- return 되는 데이터가 없을 때는 None이라 기재합니다.
def fibo(n)->리턴되는 데이터타입 : //요샌 이렇게 쓴다. if n==1 or n==2: return 1 else : return fibo(n-2)+fibo(n-1)
코드를 쉽게 짜고, 가독성을 높이는 것은 매우매우 중요하다!!!
result=intAddWithInt(100,300) x=intAddWithInt(result,600) ########################################### intAddWithInt(intAddWithInt(100,300),600)
위는 스택을 하나씩 순서대로 하지만 밑에는 recursion으로 스택 2개임
def intOpWithInt(a,b): return a+b, a-b # 아래 두줄은 다 맞는 말이다. t=intOpWithInt(100,200) #튜플 전체를 받는 것 add, sub=intOpWithInt(100,200) # 튜플을 분해해서 받는 것
데이터를 불러오는 것이라면 튜플 전체를 받고,
분석을 하기 위한 것이라면 분해해서 받는 것이 좋다.
분석 데이터에서 주로 기울기/절편 이라면 분해가 좋겠지.
전처리하는 함수를 만들거면 return을 하세요.
원본데이터를 편집하는 방법은 좋지 않기 떄문입니다.
def intOpWithInt(a,b): return a+b, a-b add, sub=intOpWithInt(100,200) # 100이나 200 둘 중 하나라도 없으면 에러
def add(a : int,b : int)-> int: return a+b dataAdd=add(100,200)
이렇게 한다면 선언문 line 한줄만 보고 정수 2개를 받아 덧셈연산을 통해 결과를 정수형태로 return하는 함수라고 파악 할 수 있다.
int add(int a, int b){ c는 이렇게 쓴다. add(a: int, b: int)->int : python은 이렇게 한다.
위의 python 표기 방법은 UML(표준 표기법)이다. 뭐지?
표기법을 기억해야 한다.
def callByValue(a:int)->None: a=20 print(a) x=30 callByValue(x) print(x)
x는 scala 데이터라 x가 전달되는 것이 아닌, 30이 전달됩니다.
그래서 a는 20으로 바뀐다.
def callByReference(li:list)->None: li[0]=20 print(li) l=[100,200,300] callByValue(l) print(l)
l의 값을 넣는 것 보다는, l의 참조를 넘겨준 것이라 생각해야 한다. 즉, 참조를 할 수 있게 되어 100, 200, 300에 접근 할 수 있게 되어 l의 값 자체가 바뀌어진다.
어지간하면 프로그램에서는 callByValue로 하라고 한다. 속도나 여러 문제로 callByReference로 종종하지만 sw 개발 관련 가점은 Value이다.
결국 책 원본을 빌려주느냐 vs 책 사본을 빌려주느냐(돈이 들어)
매개변수이름=값
의 형태로 작성하면 매개변수의 값을 생략하면 기본값이 설정됩니다.print("hello")
를 하면 자동 줄바꿈되는것...
이 뒤에 붙어서!기본값이 설정된 매개변수를 호출할 때 생략할 수 있습니다.
def collect(a,b): print(a) print(b) collect(10,20) collect(*[100,200]) #list를 분할해서 a에 100, b에 200대입 collect(*{"key1":100,"key2":200}) #이러면 key값이 들어감 #즉 a="key1", b="key2" collect(**{"key1":100,"key2":200}) #이러면 value가 전달 #즉 a=100, b=200 이 전달됨
python matplotlib 쓸 때, 매개변수 많아서 스트레스 받는데
이거 쓰면 참 좋다.
#가변 매개변수 사용하기 #함수 내부에서는 튜플로 def merge(*li): for element in li: print(element) merge(10) merge([1,23,4,5]) merge([1,2],[3,4],(5,6),7)
가변 매개변수 앞에 있는 매개변수를 대입할 때, 매개변수 이름과 함께 대입하면 에러
가변 매개변수 뒤에 있는 매개변수를 대입할 떄는 반드시 매개변수 이름과 함께 대입해야 한다.
앞은 이름 x 뒤는 이름 o
def merge(name,*li,age): #생략 merge("mino",10,20,30,26) #가능 merge(name="mino", 10, 20, 30, 26) # 에러 merge("mino", 10, 20, 30, age=26) # 에러 아님
함수를 호출할 때 존재하지 않는 매개변수 이름을 이용해서 대입하면 dict로 받아들일 수 있다.
def merge(name, **param): for k in param: print(k,param[k]) merge(name="mino", job="student", gender="남자") # job, gender는 매개변수에 없으니 **param으로 dict로 쑥 들어감
가장 최악
유의할 점 : 반드시 종료지점이 존재해야 한다.
def dataSum(n:int)->int: if n==1: return 1 return n+dataSum(n-1)
else를 안썼지만, return이 else와 같은 역할을 하고 있다.
그래서 반복문에서도 break를 안쓰고 return 하는 경우도 있다.
def fibo(n:int)->int: if n==1 or n==2: return 1 return fibo(n-2)+fibo(n-1) print(fibo(10)) #55가 나오면 된다.
피보나치를 재귀함수로 만들어보자
가독성이 매우 뛰어납니다.
python default lib에 memoization으로 재귀가 그렇게 느리지 않습니다.
fibonacci=[1,1] n=10 for i in range(2,n): fibonacci.append(fibonacci[i-2]+fibonacci[i-1]) print(fibonacci)
몰랐는데 이것도 memoization 아니야? - 맞아
import functools @funtools.lru_cache() #추가한다면 기존코드에?
memoization - 함수의 호출 결과를 저장해 둔 후 그 값으로 재사용하는 것
def temp(): pass
TDD 테스트 주도 개발 : 껍데기부터 만들어 가는 것이다.
왜 이렇게 해? : 처음부터 다 구현하려면 힘들다.
현실적으로 "시기"가 매우 중요하기에 빠르게 해야 한다.
def 함수이름(매개변수이름 : 자료형)->리턴타입:
주석을 써주고 싶을 수 있잖아?
변수가 score면 일반적으로 0~100 인걸 써주고싶은데
함수 내부에 적어놨어서 들어가서 봐야하니까 외부에 써두자
def 함수이름(매개변수이름 : '문자열'자료형)->리턴타입:
문자열로 주석 작성
def pan(score:'int >=0 and <=100'=0)->None:
??
def fibo(n:int)->int: if n==1 or n==2: return 1 return fibo(n-2)+fibo(n-1) fibo.__doc__="재귀를 이용해서 피보나치 수열의 값을 리턴하는 함수"
이렇게 하면 된다.
def dragonAttack(): print("드래곤의 공격") def tankAttack(): print("탱크의 공격") dragonAttack() tankAttack()
이렇게 한다면 명령어를 2개 따로 해야 한다.
def dragonAttack(): print("드래곤의 공격") def tankAttack(): print("탱크의 공격") dragonAttack() tankAttack() delegate=tankattack delegate()
이러면 key하나로 함수 2개를 조절할 수 있게 되었어.
#함수가 함수를 내부에 만들어서 리턴하면 고위 함수라고 합니다. def outer(): def inner(): print("내부함수") return inner
이는 함수를 호출해서 그 결과를 변수에 대입하고 그 변수를 통해서 함수를 호출해야 합니다.
func=outer(), func()
이렇게 말이죠
lambda 매개변수 나열 : 리턴할 내용
2개의 숫자를 받아서 더한 결과를 리턴하는 람다는
lamda x,y:x+y
이다.
lambda는 이름이 없어, 그럼 호출할 때 만들어지고 소멸한다.