코드스테이츠(컴퓨터 공학 기본)(Computer Science) Session 5 / Sprint 1(다양한 상황에 대한 시뮬레이션)

나이브한코딩·2021년 7월 10일
0
post-thumbnail

컴프리헨션(comprehension)

  • 컴프리헨션은 실제 프로그래밍에서 한 줄로 파이썬 기능을 구현할 수 있는 기능이다.

  • 코드간소화를 위해서 사용되고 직관적이며 속도도 빠르다.

  • 조건이 복잡해지는 경우에는 직관성이 떨어지고, 메모리 사용량이 증가하여 사용하기가 어렵다.

numbers = [1, 2, 3, 4]
squares = []

for n in numbers:
  squares.append(n**2)

print(squares) # [1, 4, 9, 16]
numbers = [1, 2, 3, 4]
squares = [n**2 for n in numbers]

print(squares) # [1, 4, 9, 16]
list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]

common_num = []

for a in list_a:
  for b in list_b:
    if a == b:
      common_num.append(a)
      
print(common_num) # [2, 3, 4]
list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]

common_num = [a for a in list_a for b in list_b if a == b]

print(common_num) # [2, 3, 4]
# 딕셔너리 컴프리헨션

test = {'A': 5, 'B': 7, 'C': 9, 'D': 6, 'E': 10} 

test = {na:test for na,test in test.items() if na != 'E'}
print(test) # {'A': 5, 'B': 7, 'C': 9, 'D': 6}
# 아래와 같이 조건을 반복문 대신 조건을 먼저 쓸 수 있다.
# 조건을 위해 if를 사용하는 경우 else를 작성해줘야된다.

pas = {name: 'PASS' if numbers > 8 else 'NO PASS' for name, numbers in numbers.items()}
print(pas) # AttributeError: 'list' object has no attribute 'items'
# 아래처럼 반복문을 연속으로 작성가능하다.
# set은 특성상 중복값을 제외한다.

print('list for loop : ',[n for n in range(1, 5+1) for n in range(1, 5+1)]) # list for loop :  [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

print('set for loop : ',{n for n in range(1, 5+1) for n in range(1, 5+1)}) # list for loop :  [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
# 두개의 리스트를 하나의 딕셔너리로 합침. 
# 하나는 key, 또 다른 하나는 value로 사용한다
subjects = ['math', 'history', 'english', 'computer engineering']
scores = [90, 80, 95, 100]
score_dict = {key: value for key, value in zip(subjects, scores)}
print(score_dict) # {'math': 90, 'history': 80, 'english': 95, 'computer engineering': 100}

# 튜플 리스트를 딕셔너리 형태로 변환
score_tuples = [('math', 90), ('history', 80), ('english', 95), ('computer engineering', 100)]
score_dict = {t[0]: t[1] for t in score_tuples}
print(score_dict) # {'math': 90, 'history': 80, 'english': 95, 'computer engineering': 100}

지역변수와 전역변수

  • 코드가 복잡해지거나 기능이 많아지는 경우, 변수사용에 따라 함수 및 클래스의 접근이 달라진다.

  • 변수이름설정, 변수활용도에 따른 변수설계가 중요하다.

  • 지역변수 : 해당 변수가 포함된 함수 안에서만 수정하고, 읽을 수 있다.

  • 일반 전역변수 : 하나의 파이썬 파일전체에서 값을 읽을 수 있다. 되도록이면 함수 안에서 사이드이펙트 및 가독성을 위해 값을 수정하지 않도록 한다.

  • global 전역변수 : 일반 전역변수와 다른 점은 변수가 생성되는 시점만 다르다.

  • 지역변수는 이름이 같더라도, 소속된 함수가 다르면 다른 변수로 취급된다.

  • 전역변수는 하나의 파이썬파일에 있는 모든 함수에 쓰일 수 있다.

# 아래 소스코드를 한 줄씩 실행하면서 지역변수와 전역변수에 대해 파악한다.

g_var = 'g_var'   # 전역변수

  
# 값 수정후(수정값)
def variables():
  
  global glo_var  # global 전역변수
  glo_var = 'glo_var' # global 전역변수에 새로운 값 할당
  lo_var = 'lo_var'   # 지역변수

  print()
  print('(값 수정후)함수 안에서 g_var(전역변수) : ', g_var)  # 수정되지 않고 초기값을 출력함
  print('(값 수정후)함수 안에서 glo_var(global 전역변수) : ', glo_var)  # 함수에서 수정된 후 값을 출력함
  print('함수 안에서 lo_var(지역변수) : ', lo_var)    # 특정 함수에서만 출력되는 지역변수

# 전역변수를 파라미터로 담은 함수
def second_variables(glo_var,g_var):
  glo_var = 'glo_var in second_variables()'
  g_var = 'g_var in second_variables()'
  lo_var = 'second lo_var'
  print('서로 다른 함수에서 지역변수이름이 같은 경우 :',lo_var)
  
  return glo_var,g_var
  
# 값 수정전(초기값)
g_var = 'g_var_new_value'
glo_var = 'glo_var_new_value'
print('(값 수정전)함수 밖에서 g_var(전역변수) : ', g_var)  
print('(값 수정전)함수 밖에서 glo_var(global 전역변수) : ', glo_var) # 새로 할당된 값으로 수정됨
# print('함수 밖에서 lo_var(지역변수) : ', lo_var) # 특정 함수 안에서만 사용하는 지역변수이므로 출력안됨

# 전역변수의 값 수정
#print('함수의 파라미터가 전역변수인 경우 :', second_variables(glo_var, g_var))

# 지역변수를 갖고 오는 경우
#print('함수의 파라미터가 지역변수인 경우 :', second_variables(glo_var, lo_var))

# 함수에서 수정된 전역변수 재호출
print('전역변수값 :',glo_var, g_var)

variables()

# (값 수정전)함수 밖에서 g_var(전역변수) :  g_var_new_value
# (값 수정전)함수 밖에서 glo_var(global 전역변수) :  glo_var_new_value
# 전역변수값 : glo_var_new_value g_var_new_value

# (값 수정후)함수 안에서 g_var(전역변수) :  g_var_new_value
# (값 수정후)함수 안에서 glo_var(global 전역변수) :  glo_var
# 함수 안에서 lo_var(지역변수) :  lo_var

구문 및 예외적인 상황에 대해 처리해본다.

  • 생각하는 시간 : 예외처리는 어떻게 사용될까?

  • 실제 대규모 서비스에서 공동작업을 진행하는 경우, 예외처리를 하는 것이 중요하다.

  • 파이썬에서는 루프가 반복 수행하는 내부 구문 바로 다음에 if 없이도 else 구문을 추가할 수 있다.

  • for~else 구문에서는 break에 따라 수행여부가 달라진다.

  • if/else 구문에서 else는 '앞의 구문이 수행되지 않으면 else구문을 수행하시오' 라는 뜻이다.

  • try/except 구문 또한 이 구문 앞의 try 구문을 수행하다가 예외발생 시, except 구문을 수행하시오' 라는 뜻이다.

for i in range(3):
  print('loop : ', i) # 1) 루프반복수행
else : 
  print('Else statement') # 2) else 구문 추가수행
  
# loop :  0
# loop :  1
# loop :  2
# Else statement
# 그렇다면 break문이 있다면?
for i in range(3):
  print('loop : ', i) # 1) 루프반복수행
  if i == 1:
    break     # break는 어떤 영향을 줄 것인가?
else : 
  print('Else statement') # 2) else 구문 추가수행
  
# loop :  0
# loop :  1
# 반복문에 빈 리스트를 넣으면 어떻게 될까?
for i in []:
  print('loop : ', i) # 1) 루프반복수행
else : 
  print('Else statement') # 2) else 구문 추가수행
  
# Else statement
# 반복문이 while 형태로 False인 경우에는 어떨까?
while False:
  print('loop : ', i) # 1) 루프반복수행
else : 
  print('Else statement') # 2) else 구문 추가수행

# Else statement
# 서로소 판별문제
p_a = 5
p_b = 3

for i in range(2, min(p_a, p_b) +1):    
  print('testing ....', i)

  if p_a % i == 0 and p_b % i == 0:
    print('서로소가 아닙니다.')
    break

else:
  print('서로소입니다.')

# testing .... 2
# testing .... 3
# 서로소입니다.
# for~else 예시

for i in []:
  print('실행안됨')

else:
  print('실행되면 안됨')

# 실행되면 안됨
# while~else 예시

while False:
    print('실행안됨')
  
else:
    print('실행되면 안됨')

# 실행되면 안됨
# 첫번째방법. 조건에 맞는 경우, 함수에서 부울값을 반환해주는 방법
def bool_return(v1, v2):
  for i in range(2, min(v1, v2) +1):
    if v1 % i == 0 and v2 % i == 0:
      return False
  return True

# 조건점검
#assert bool_return(4,9), '서로소입니다.'
#assert bool_return(3,6), '코드 점검 메시지입니다.'
assert not bool_return(3,6), '서로소 아닙니다.'

print('bool_return:',bool_return(4,9))    # 디폴트값 반환

# bool_return: True
# 두번째방법. 조건에 맞는 경우, 함수에서 결과값 변수를 반환해주고 break로 빠져나온다.
def variable_return(p_a, p_b):
  is_variable = True
  for i in range(2, min(p_a, p_b) +1):
    if p_a % i == 0 and p_b % i == 0:
      is_variable = False
      break
  return is_variable

# 조건점검
assert variable_return(4,9), '서로소입니다.'
#assert variable_return(3,6), '코드 점검 메시지입니다2.'
assert not variable_return(3,6), '서로소 아닙니다.'

print('variable_return:',variable_return(4,9))    # 변수값 반환

# variable_return: True
def try_finally_ex(filename):
  print('function start')       # right case / error case, 1
  handle = open(filename, encoding='utf-8')

  try:
    print('try test')    # right case , 2

    raise NotImplementedError
    print('raise test')
    return handle.read()

  except FileNotFoundError:
    print('file except')  # right case

  else:
    print('file else')

  finally:
    print('finally call') # right case, 3
    handle.close

filename = 'a.txt' # right case
#filename = 'b.txt'  # error case
try_finally_ex(filename)  # error case, 4
# try / except
try:
  print(3/0)
except:
  print('except case')

# except case
# try / except
try:
  print(5/0)
except ZeroDivisionError:
  print('except case ZeroDivisionError')

# except case ZeroDivisionError
# try / except
try:
  print(7/0)
except ZeroDivisionError as e:
  print(e)

# division by zero
# try / except / else
try:
  print(3/1)
except:
  print('except case')
else:
  print('else case')
  
# 3.0
# else case
# try / except / finally
try:
  print(5/0)
except:
  print('except case')
finally:
  print('finally case')
  
# except case
# finally case
# try / except / finally
try:
  print(5/0)
  print(try test)
except NameError as n:
  print(n)
except ZeroDivisionError as z:
  print(z)
  pass
  
# SyntaxError: invalid syntax
# try / raise / except
try:
  print('try test')
  test = int(input())
  if test < 0:
    raise NotImplementedError   # 예외사항에 대해 처리하는 raise!
  print('test2 : ',test) 

except NotImplementedError:
  print('NotImplemented Error')
# None을 return 하는 경우

def none_test(num1, num2):
    try:
        return num1 / num2
    except ZeroDivisionError:
        return None       # None 반환

# 문제없음, 단순히 None이 있는지 없는지 판단함
# result = none_test(0,2)
# print(result)
if result is None:
    print('result is None')

# 문제발생
result = none_test(0, 2)
print(result)
# 조건식에서 not을 활용하는 경우, 파이썬에서는 None, 빈문자열, 빈리스트, 0을 모두 False로 판단한다
# 단순히 결과값이 0인데도 not result 조건으로 인해 False 처리된다.
# if not result:              
#     print('not result')

# 0.0
# None을 return 하지 않는다.

def not_none_return(num1, num2):
  try:
    return num1 / num2
  except ZeroDivisionError as z:
    raise ValueError('숫자 입력값이 잘못된 경우') from z  
  else:
    print(result)

try:
    #result = not_none_return(2, 0) # case 1 - 정상적으로 except 처리
    #result = not_none_return(0, 2) # case 2 - 값 반환
except ValueError:
    print('숫자 입력값이 잘못된 경우')  # None을 반환하는 대신 예외를 발생시킨다.
else:
    print(result)
profile
안녕하세요, 코딩 공부하는 비전공자 취준생입니다.

0개의 댓글

관련 채용 정보