쓰임의 차이
def cal(a,b) << 함수 cal의 매개변수인 a,b
def cal(*args): # << 변수(인자)를 무제한으로 넣을 수 있음. args는 argument의 줄임말임. for name in args: print(f'{name}아, 밥 먹어라.') cal('민수','경수','진수','남형') ☝️ cal()함수가 호출 될 때 들어가는 인자들은 '민수','경수','진수','남형' 이 된다.
사전적 정의
1. 어떤 문제의 해결을 위하여, 입력된 자료를 토대로 하여 원하는 출력을 유도하는 규칙의 집합.
2. 여러 단계의 유한 집합으로 구성되는데, 각 단계는 하나 또는 그 이상의 연산을 필요로 한다.
오늘 새롭게 알게된 함수
# 알고리즘 1주 - 알고리즘과 친해지기 문제
# 함수 정리
# ㄴ .isalpha() << 문자열의 구성이 알파벳 or 한글인지 확인할 수 있음. 공백이나 숫자가 들어가면 False 반환
# 아스키코드를 이용한 문자를 인덱스로 만드는 방법, 인덱스를 문자로 만드는 방법
# a => 0
# a => ord(a) - ord('a') ==> 97로 변환 - 97로 변환 = 0
#
# 0 => a
# 0 => 1. 0 + ord(a) 2. 97로 변환 3.chr(97) = a
#--------------------------------------------------------------------------------------
# 연습문제 1. - 최대값 찾기
# Q. 다음과 같이 숫자로 이루어진 배열이 있을 때, 이 배열 내에서 가장 큰 수를 반환하시오.
# 내가 푼 문제
input = [3, 5, 6, 1, 2, 4]
def find_max_num(array):
maxNum = 0 # 함수 밖에 있을 때는 에러가 났는데, 왜 안에 들어오니까 안나는가? >> UnboundLocalError: local variable 'maxNum' referenced before assignment
for num in input:
if maxNum < num:
maxNum = num
return maxNum
result = find_max_num(input)
print(f"{result} 내가 풀었을 때 값")
# 정답 (1번 해결 방안), 이중 for문 학습 꼭 하기.
input = [3, 5, 6, 1, 2, 4]
def find_max_num(array):
for num in array: # array에 있는 각각의 변수를 num이란 변수에 담아 주는 것.
for compare_num in array: # 비교할 변수들을 뽑기위해 반복문 한 번 더 작성.
if num < compare_num: # num이 compare_num보다 작다면 실패.
break
else: # for else문 : for문이 다 끝날 때 까지 break가 실행되지 않았다면 else문 실행.
return num
result = find_max_num(input)
print(f"문제 1번_방법 1. 정답 값{result}")
# 정답 (2번 해결 방안)
input = [3, 5, 6, 1, 2, 4]
def find_max_num(array):
max_num = array[0]
for num in array:
if num > max_num:
max_num = num
return max_num
result = find_max_num(input)
print(f"문제 1번_방법 2. 정답 값{result}") # << 이중 for문보다 시간복잡도 부분에서 더욱 효율적인 코드라 할 수 있다.
#--------------------------------------------------------------------------------------
# 연습문제 2. 최빈값 찾기
# 방법 1.
input = "hello my name is Hwui"
def find_max_occurred_alphabet(string):
alphabet_array = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
max_occurrence = 0
max_alphabet = alphabet_array[0]
for alphabet in alphabet_array:
occurrence = 0
for char in string:
if char == alphabet:
occurrence += 1
if occurrence > max_occurrence:
max_occurrence = occurrence
max_alphabet = alphabet
return max_alphabet
result = find_max_occurred_alphabet(input)
print(result)
# 방법 2.
input = "hello my name is Hwuiwwwwwww"
def find_max_occurred_alphabet(string):
alphabet_occurrence_array = [0] * 26 # 알파벳 별 빈도수를 저장하기 위한 길이가 26인 것을 0으로 초기화된 배열 생성 (알파벳의 숫자가 26이기 때문에)
for char in string:
if not char.isalpha():
continue # break와 달리 반복문의 다음 인덱스로 넘어가게 하는 방법
# else:
arr_index = ord(char) - ord("a") # 각 char에 대한 array index를 구함
# ㄴ ord(char) - ord("a") => hello my name is sparta를 하나씩 도는 매개변수 char의 ord에서 ord("a")를 아스키코드로 int 반환하면 == 97 즉, 계속 돌고 도는 char 매개변수의 아스키코드 int 변환값에 소문자 "a"의 아스키코드인 97을 빼줌으로써 알파벳 숫자 인덱스를 0부터 25까지(총 26개) 구성할 수 있게 된다.
# print(arr_index) a b c d e f g h ... 가 0 1 2 3 4 5 6 7의 값으로 나옴
alphabet_occurrence_array[arr_index] += 1
max_occurrence = 0
max_alphabet_index = 0
for index in range(len(alphabet_occurrence_array)): #index in range
# index 0 -> alphabet_occurrence 3 (a가 3번 나왔으니까 3)
alphabet_occurrence = alphabet_occurrence_array[index]
if alphabet_occurrence > max_occurrence:
max_alphabet_index = index
max_occurrence = alphabet_occurrence
return chr(max_alphabet_index + ord('a'))
result = find_max_occurred_alphabet(input)
print(result)
#--------------------------------------------------------------------------------------
# 연습문제 3. 알파벳 빈도수 세기
# 필요한 기능 : 문자인지 아닌지 .isalpha()를 사용하여 확인, 컴퓨터가 인식할 수 있게 문자를 아스키코드로 변환,
# ord(c) => 문자를 아스키코드로 반환
# chr(i) => 숫자를 아스키코드에 대응하여 문자로 반환
def find_alphabet_occurrence_array(string):
alphabet_occurrence_array = [0] * 26 # 알파벳 별 빈도수를 저장하기 위한 길이가 26인 것을 0으로 초기화된 배열 생성 (알파벳의 숫자가 26이기 때문에)
for char in string:
if not char.isalpha():
continue # break와 달리 반복문의 다음 인덱스로 넘어가게 하는 방법
# else:
arr_index = ord(char) - ord("a") # 각 char에 대한 array index를 구함
# ㄴ ord(char) - ord("a") => hello my name is sparta를 하나씩 도는 매개변수 char의 ord에서 ord("a")를 아스키코드로 int 반환하면 == 97 즉, 계속 돌고 도는 char 매개변수의 아스키코드 int 변환값에 소문자 "a"의 아스키코드인 97을 빼줌으로써 알파벳 숫자 인덱스를 0부터 25까지(총 26개) 구성할 수 있게 된다.
# print(arr_index) a b c d e f g h ... 가 0 1 2 3 4 5 6 7의 값으로 나옴
alphabet_occurrence_array[arr_index] += 1 # 기존에 [0] * 26으로 초기화해주었던 alphabet_occurrence_array 배열에 [arr_index]에 해당하는 자리, 즉 [0부터 25]가 들어가면, 해당 배열 자리에 +1씩 카운트가 올라간다.
# ㄴ Q. 왜 +=1 을 해주는지 여쭤보기 A. [arr_index]에 arr_index = ord(char) - ord("a")해서 나온 값이 3이라면 3번째 배열에 +1을 해줄 것이다. 이런 식으로 해당 배열에 하나씩 카운트를 올려주는 구동되는 코드.
# print('a'.isalpha()) True
# print('2'.isalpha()) False
# print(''.isalpha()) False
return alphabet_occurrence_array
print((find_alphabet_occurrence_array("hello my name is Hwui")))
핵심
map : 리스트의 모든 원소를 조작하기
- 함수 사용법 => map(function, iterable)
첫 번째 매개변수로는 "함수"가 들어오고, 두 번째 매개변수로는 "반복 가능한 자료형 -리스트, 튜플 등 -"이 온다.
- map()
함수의 반환 값은 map 객체이기 때문에 해당 자료형을 꼭 list나 tuple로 형변환 시켜줘야 한다.
lamda
- 함수 사용법 => lambda 매개변수 : 표현식
- *lambda식을 쓸 때는 관형적으로 lambda x : x
<< 이렇게 작성해주는 것이 통상적이다.
filter - 리스트의 모든 원소 중, 특별한 것만 뽑기
*map과 아주 유사하지만, True인 것들만 뽑아서 출력해줌.
people = [
{'name': 'bob', 'age': 20},
{'name': 'carry', 'age': 38},
{'name': 'john', 'age': 7},
{'name': 'smith', 'age': 17},
{'name': 'ben', 'age': 27},
{'name': 'bobby', 'age': 57},
{'name': 'red', 'age': 32},
{'name': 'queen', 'age': 25}
]
# 1. map()을 이용해서 people 리스트를 돌아볼 것임.
# 내가 만든 코드
# def check_adult(age):
# for person in people:
# age = person['age']
# if age > 20:
# return '성인입니다.'
# elif 13 < age < 20:
# return '청소년입니다.'
# else:
# return '유아입니다.'
# 정답
def check_adult(person):
if person['age'] > 20:
return '성인'
else:
return '청소년'
result = map(check_adult, people) # people을 하나하나 돌면서, check_adult 함수에 넣어라. << 인자가 즉 people을 하나씩 도는 map이 되는 것임.
print(list(result)) # map객체를 리스트로 형변환하여 출력
# print(result) # <map object at 0x7fd1180d9b80> << map object라고 뜸.
# 위와 동일한 코드로 축약하자면 return ('성인' if person['age'] > 20 else '청소년')
# 2. lambda() 사용 (map()과 응용)
result = map(lambda person : ('성인' if person['age'] > 20 else '청소년'), people) # lamda가 map의 매개변수로 들어온 상황임..lambda person : ('성인' if person['age'] > 20 else '청소년') >> (1번 매개변수), people(2번 매개변수)
# people을 돌면서 person에다가 넣고, 그 person을 표현식처럼 return해라. << map과 lambda를 같이 썼을 때의 코드 해석
print(list(result)) # map객체를 리스트로 형변환하여 출력
# 3. fliter() 사용 - 조건에 맞는 값만 출력. (== True만 반환)
result = filter(lambda x : x['age'] > 20 , people) # << filter의 매개변수로 lambda x : x (1번), people(2)번인 상태.
print(list(result)) # filter object로 나오는 것을 리스트로 형변환하여 출력 <filter object at 0x7fc2e80692e0>
핵심
주요 내용
def cal(a,b):
# def cal(a, b=2): << 초기 매개변수 기본값을 고정해줄 수 있음 b에 다른 값이 들어오면, 그 값으로 계산도 가능. 장점 - result = cal(1)을 넣었을 때, 자동으로 def cal(1,2)로 코드를 읽고 결과값을 출력해줌
return a+2*b
result = cal(1,2)
# result = cal(a=1,b=2) << 이처럼 매개변수를 직접 지정해줄 수 있음 장점 - 매개변수 자리에 순서를 안 맞춰도 된다.
# result = cal(a=2, b=1) << 이렇게 지정해주면 4라는 결과가 출력된다.
print(result)
def cal(*args): # << 변수(인자)를 무제한으로 넣을 수 있음. args는 argument의 줄임말임.
for name in args:
print(f'{name}아, 밥 먹어라.')
cal('대형','민현','권후','배익')
# 키워드 인수를 여러 개 받는 방법 **kwargs << keyword argument의 줄임말.
def cal(**kwargs):
print(kwargs) # 딕셔너리로 반환
cal(name='민수', age=15, height=170) # def cal)_**kwargs에 들어가서, 딕셔너리로 반환된다.
핵심
class Monster():
hp = 100
alive = True
def damage(self, attack):
self.hp = self.hp - attack # << '나의 hp가' == self.hp (함수 안에서 스스로를 지칭하려면 self.를 사용. 자바스크립트의 this와 유사함) 여기서는 class Monster의 hp를 가르킨다.
if self.hp <= 0:
self.alive = False
def status_check(self):
# if self.alive == True: 아래 코드와 동일함. class Monster의 기본 속성값으로 True가 들어가있기 때문.
if self.alive:
print('아직 살아있다.')
else:
print('사망했습니다.')
m1 = Monster() # << 인스턴스.
m1.damage(150)
m1.status_check()
m2 = Monster()
m2.damage(90)
m2.status_check()
- 혼자만의 정리
- class Monster()는 붕어빵 틀이고,
m1 = Monster()는 class Monster() 붕어빵 틀에 넣어서 구워져 나온 붕어빵(m1)이다.
오늘의 감정
파이썬 알고리즘 문제를 처음 접해봤다.
코드가 익숙하지 않을 뿐더러, 알고있는 코드도 별로 없다.
구글링을해서 필요한 기능을 하는 코드를 알아내도, 어떤 로직으로 코드를 연결되게 짜야하는지에 대한 이해도가 너무나 떨어진다.
19분 짜리 알고리즘 영상을 거진 3시간을 붙잡았다. 그래도 이해가 다 되지 않았다. 스스로 화가 많이 났다.
그래서 인프런에서 33,000을 주고 강의를 결제했다.
하지만 역시나 이해가 되지 않는 것은 똑같았고, 스스로에게 화가 많이 났다.
처음 보고 이해를 바로 할 수 있다면 좋겠지만, 나는 그렇게 머리가 좋지 않은 사람이라는 걸 스스로 알고있다. 그래서 곧 바로 안될 것 이란걸 알지만서도 제대로 이해하지 못함에 화가 많이 난다.
일주일 뒤면 팀프로젝트를 다시 시작하는데, 다른 분들에 비해 내가 지식적으로 뒤쳐져있는 것 같은 느낌이 든다. 그래서 조금 불안하다.
오늘 느낀점 되새기기
- 화가 난 상태로 코드를 백 번 보는 것 보다, 진정하고 다시 코드를 보는 게 이해하는 데 있어서 도움될 수 있다.
- 오늘 이해가 되지않아 스스로에게 너무 화가 많이 났다. 그래서 그런지 더욱 코드가 이해되지 않았다. 사실 지금도 오늘 공부했던 알고리즘 코드 이해도는 30% 정도 되는 것 같다.
-End-
비슷한상태로 공부했고, 지금도 답답한경우를 많이 만나고있지만
저보다 훨씬 더 잘해내고 계신것 같아요!!
개발자는 집념이 가장 중요한것 같습니다
다만 광적인 집착은 좋지않으니 너무 코드가 풀리지 않을땐 잠시 바깥공기도 쐬시고 하면 좋을것같아요 ㅎㅎ
갑자기 이해되는 경우가 많거든요...!