본문 바로가기
SeSAC/파이썬 프로그래밍

[SeSAC 성동캠퍼스 1기] 파이썬 프로그래밍 3일차

by zivvon 2023. 11. 1.
목차 접기

파이썬 프로그래밍 3일차 포스트에 들어가기 앞서!

 

파이썬 프로그래밍 2일차 Mission이었던 '리스트' 없이 몇 번만에 로또 1등 당첨 되는지에 대한 프로그래밍 을 완수하지 못 해서 리스트를 써서 구현해보았다 이마저도 Runtime이 2분이 넘어가는데도 1등은 죽어도 당첨이 안 되는 .. 😱

로또 당첨이 이렇게 힘든겁니다..  그래도 2등은 되더라 4860번만에

 

소스코드!

import random

try_num = 0

user_num = []
num = input("로또 번호를 쓰세요 : ").split()

for i in num:
    user_num.append(int(i))

print(user_num)

while True:
    cnt = 0
  
    # 로또 시도 횟수
    try_num += 1
  
    lotto_num = list(range(1, 46))
    # 중복 없이 로또 번호 뽑기
    lotto_num = random.sample(lotto_num, 6)

    print(lotto_num)

    # 내 번호가 로또 번호 리스트 안에 있으면 cnt 값 증가
    ## 만약! cnt == 6, 즉 전부 맞았으면 1등 당첨
    for n in user_num:
        if n in lotto_num:
            cnt += 1

    if cnt == 6:
        print(try_num, "번만에 로또 1등에 당첨되셨습니다!!! 축하해요!", sep="")
        break
    elif cnt == 5:
        print(try_num, "번만에 로또 2등에 당첨되셨습니다!", sep="")
        break
    else:
        print(cnt, "개만 맞았네요 낙첨입니다. 다시 도전해보세요", sep="")
      

print("로또를 종료합니다.")

Ch7. 리스트, 튜플, 딕셔너리

[ 리스트(List) ]

: 하나씩 사용하던 변수를 붙여서 한 줄로 붙여놓은 개념

- 리스트는 종이상자를 한 줄로 붙인 후에 박스 전체의 이름(numList)을 지정하여 사용

- 각각의 데이터에는 번호(첨자)를 붙여 접근

리스트 이름 = [값, 값2, 값3, ...]
각 변수를 사용하는 경우 리스트 사용
num1, num2, num3 = 0, 0, 0
num1 사용
num2 사용
num3 사용
numList = [10, 20, 30]
numList[0] 사용
numList[1] 사용
numList[2] 사용

 

ex) 리스트 생성해서 합계 구해보기

hap = 0

numList = [0, 0, 0, 0]

numList[0] = int(input("숫자 : "))
numList[1] = int(input("숫자 : "))
numList[2] = int(input("숫자 : "))
numList[3] = int(input("숫자 : "))

for i in range(4):
    hap += numList[i]

print("합계 :", hap)

 

- 리스트의 다양한 형태

1. 비어있는 리스트 생성 ex) numList = []
2. 정수로만 구성된 리스트 ex) intList = [1, 2, 3]
3. 문자열로만 구성된 리스트 ex) strList = ['새싹성동', '1기', 'Good']
4. 다양한 데이터 형식을 섞은 리스트 ex) mixList = [10, 20, 'SK쉴더스']
⚠️ 4번과 같은 형태는 자주 사용하지 않으므로 참고만 할 것

 

- 리스트를 하나씩 추가하기

리스트이름.append(값) ex) numList = []일 때, numList.append(10)

 

- 반복문 활용하여 리스트에 값 추가하기

# 반복문 활용한 리스트 값 추가하기
## 예제
numList = []
for i in range(0, 4):
	numList.append(i)

 

- 리스트에 값 대입

: 리스트의 첨자가 순서대로 변할 수 있도록 반복문과 함께 활용

 

- 리스트 값에 접근하기 ⭐

'첨자를 활용한 리스트 접근 방법'
1. 첨자가 음수 값인 경우 : 맨 뒤가 -1로 시작하여 그 바로 앞이 -2가 됨
2. 콜론(:)을 사용하여 범위를 지정하는 경우
: 리스트이름[시작첨자 : 끝첨자 + 1] (리스트의 시작부터 끝까지 모두 지정)
⚠️ 콜론의 앞이나 뒤의 숫자를 생략 가능

 

- 리스트의 덧셈 : 요소들이 합쳐져 하나의 리스트가 됨

- 리스트의 곱셈 : 곱한 횟수만큼 리스트가 반복됨

# 리스트의 덧셈과 곱셈 예제
numList = [10, 20, 30]
myList = [1, 2, 3]

print(numList + myList)
#[10, 20, 30, 1, 2, 3]

print(numList * 3)
#[10, 20, 30, 10, 20, 30, 10, 20, 30]

 

ex) 오늘의 명언 랜덤하게 출력하기

# 오늘의 명언 출력하기
import random

wise = ["언제나 현재에 집중할 수 있다면 행복할 것이다",
        "큰 목표를 이루고 싶으면 허락을 구하지 마라.",
        "창조적인 삶을 살려면 내가 틀릴지도 모른다는 공포를 버려야 한다.",
        "늘 하던 대로 하면 늘 얻던 것을 얻는다.",
        "성공한 사람이 되려고 노력하기보다 가치있는 사람이 되려고 노력하라.",
        "지옥을 겪고 있다면 계속 겪어 나가라."
       ]

print(random.choice(wise))

~> 나는 choice() 메소드를 사용해서 구현했는데 len() 함수랑 randint() 메소드 사용해서도 구현 가능하다!

 

- 리스트 값 변경하기

1. 첨자를 사용하여 값 변경하기
2. 연속된 범위의 값 변경하기
3. 리스트 안에 리스트 추가하기
⚠️ 자주 사용하는 방식은 아니므로 주의 필

 

- 리스트에 값 삽입하기 ⭐

~> append(값) : 맨 뒤에 값 추가하기

~> insert(위치, 값) : 정해진 위치에 값 삽입하기

# insert() 메소드 예제
numList = [10, 20, 30]
numList.insert(1, 123)
print(numList)
## [10, 123, 20, 30]

⚠️ insert() 메소드는 위치에 걸맞는 요소의 값을 원하는 값으로 대체하는 게 아니라 끼어넣는 거!

 

- 리스트 값 삭제하기 ⭐

~> del() : 리스트의 항목 삭제, 이 때 del() 함수에 리스트 이름을 넣으면 리스트가 통째로 삭제됨

~> remove(지울 값) : 리스트에서 특정 값 삭제

⚠️ 중복된 값을 지울 때 모든 값을 지우지 않고, 처음 만나는 한 개의 값만 삭제함!

 

❓del() 함수와 remove() 함수의 차이?

     del()           remove()     
del list[항목위치] list.remove('항목명')
항목 위치(인덱스나 슬라이스)로 데이터 삭제 리스트 안에 있는 데이터의 이름을 알고 있고,
그 데이터를 삭제할 때 사용함
⚠️ 리스트의 메소드가 아님! ⚠️ 리스트 안에 중복되는 항목이 있을 때,
첫 번째에 해당되는 항목만 삭제함

 

- 리스트의 값 추출하기

~> pop() : 제일 뒤의 값을 뽑아내서 값을 알려준 뒤 삭제

 

- 리스트에서 개수 세기

~> count(찾을 값) : 찾을 값이 몇 개인지 개수를 세서 알려줌

 

- 리스트 정렬하기

~> sort() : 리스트의 값을 정렬함

~> sort(reverse=True) : 내림차순으로 정렬함

⚠️ sort()의 default값은 reverse=False, 즉 오름차순이 디폴트 값

 

- 리스트의 차례를 반전하기

~> reverse() : 리스트의 마지막 인덱스부터 위치가 반대로 됨

 

- 리스트 복사하기

~> copy() : 리스트를 새로운 리스트로 복사함

 

[ 2차원 리스트 ] ⭐

: 1차원 리스트를 여러 개 연결한 리스트

- 2개의 첨자를 사용함 : 리스트이름[행][열]

 

ex) for문을 활용한 2차원 리스트 출력

# for문을 활용한 2차원 리스트 출력
## 중첩 for문 사용!

numList2 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

for i in range(3):
    for j in range(4):
        print(" ", numList2[i][j], end='')
    print("")

 

ex) 심사위원 점수 결과 구하기

# 심사위원 점수 결과 구하기
name = input("선수 이름을 입력해주세요 : ")
print(name, "선수 경기 끝났습니다~~ 짝짝짝")

score = []

for i in range(5):
    score.append(int(input("평가 점수 ==> ")))

avg = sum(score) / len(score)

print("심사위원 평균 점수 : ", avg)

 

ex) 컴퓨터끼리 가위바위보 대결하기

# 컴퓨터끼리 가위바위보 대결하기
import random

cnt = 10000

while cnt > 0:
    cnt -= 1
  
    com1 = random.randint(1, 3)
    com2 = random.randint(1, 3)

    if com1 == com2:

 

[ 튜플 ]

: 읽기 전용의 리스트

ㄴ 튜플을 왜 쓰는 걸까?

A) 튜플은 리스트와 비교하면 비교적 메모리용량을 아끼고 퍼포먼스를 향상시키는데 도움이 되기 때문!

 

- 소괄호로 생성함

- 리스트와 상당히 비슷하지만 값을 읽을 수만 있고 수정할 수는 없음!

 

- 튜플 생성하기

~> 튜플은 소괄호로 생성하지만, 괄호가 없어도 무방함 ex) numTup1 = (10, 20,30), numTup2 = 10, 20, 30
~> 튜플의 항목이 한 개일 때, 튜플 뒤에 콤마(,)를 붙여야 함 ex) numTup3 = (10, )
      Why?
      A) 값 한 개를 괄호로 묶으면 튜플이 아니라 그냥 값이 되기 때문, 더하여 튜플 형태 유지하기 위한 때문

 

- 튜플은 '읽기 전용'이기 때문에 append() 함수나, 값의 변경 등을 수행하면 오류가 발생한다!

- 튜플 자체를 통째로 삭제하려면 del(튜플이름) 함수 사용

 

- 튜플에 접근하기

1. 튜플이름[인덱스] : 특정 항목에 접근하기
2. 콜론(시작인덱스 : 끝인덱스 + 1) : 튜플의 범위에 접근하기

 

- 튜플의 더하기 및 곱하기 연산

numTup1 = (10, 20, 30, 40)
numTup2 = ('A', 'B')

# 덧셈
print(numTup1 + numTup2)
## output (10, 20, 30, 40, 'A', 'B')

# 곱셈
print(numTup2 * 3)
## output ('A', 'B', 'A', 'B', 'A', 'B')

 

✏️ 하나 더 알기!

[ 튜플과 리스트의 상호 변환 ]

: 튜플과 리스트는 서로 변환 가능! 예를 들어 튜플의 항목을 변경하려면 튜플을 리스트로 변경해서 항목 변경 후, 다시 리스트를 튜플로 변환하는 방법 사용 가능.

- 'list(튜플)' 함수는 튜플을 리스트로 변환해 주며, 'tuple(리스트)' 함수는 리스트를 튜플로 변환해 줌

 

[ 딕셔너리 ]

: 단어 의미 그대로 '영어사전'과 같은 구조를 가짐, 즉 딕셔너리는 2개의 쌍이 하나로 묶이는 자료구조 의미

- 딕셔너리는 중괄호{}로 묶여 있음

- 키(Key)와 값(Value)의 쌍으로 이루어짐 => 키(Key) : 단어, 값(Value) : 뜻

딕셔너리 변수 = { 키1 : 값1, 키2 : 값2, 키3 : 값3, ... }

 

- 딕셔너리 생성하기

ex) 키(Key)가 1, 2, 3이 값(Value)이 'a', 'b', 'c'인 딕셔너리

myDict = {1 : 'a', 2 : 'b', 3 : 'c'}
print(myDict)

⚠️ 키와 값을 반대로 생성해도 무방함!

=> 즉, 키와 값을 사용자가 지정하는 것이지 어떤 값을 반드시 사용해야 하는 규정은 없으며, 딕셔너리는 순서가 없음

 

- 딕셔너리 생성 예제

~> 딕셔너리는 여러 개의 정보를 하나의 변수로 표현할 때 유용하게 사용됨

 

ex) 회사원 홍길동의 정보를 딕셔너리로 생성하기

dict = {'사번' : 1000, '이름' : '홍길동', '부서' : '케이팝'}
print(dict)

+ 딕셔너리에 정보를 더 추가하기

dict = {'사번' : 1000, '이름' : '홍길동', '부서' : '케이팝'}
dict['연락처'] = '010-0000-0000'

print(dict)

+ 정보를 추가할 때, 이미 키가 딕셔너리에 존재하는 경우 => '기존의 키에 대한 값이 변경됨!'

dict = {'사번' : 1000, '이름' : '홍길동', '부서' : '케이팝'}
dict['연락처'] = '010-0000-0000'

print(dict)

dict['부서'] = '한빛아카데미'
print(dict)

+ 딕셔너리의 키는 중복되지 않고 유일함

=> 만약 동일한 키를 갖는 딕셔너리를 생성한다면 오류가 발생하지는 않고, 마지막에 있는 키의 값이 적용되어 생성됨

 

+ 딕셔너리의 쌍을 삭제하기

del(딕셔너리이름[키]) 함수를 사용
del(dict['부서'])

 

✏️ 하나 더 알기!

[ 딕셔너리의 개수 파악하기 ]

딕셔너리의 개수는 len(딕셔너리이름) 함수로 확인할 수 있으며 한 쌍을 한 개로 계산

 

- 딕셔너리와 관련된 유용한 함수

~> 딕셔너리이름.keys() : 딕셔너리의 모든 키만 뽑아서 반환

~> list(딕셔너리이름.keys()) : 출력 결과에 dict_keys가 붙지 않음

~> 딕셔너리이름.values() : 딕셔너리의 모든 값을 리스트로 만들어서 반환, 이때 dict_values보기 싫으면 list(딕셔너리이름.values()) 사용하기!

~> 딕셔너리이름.items() : 튜플 형태로 구하기

dict = {'사번' : 1000, '이름' : '홍길동', '부서' : '케이팝'}
dict['연락처'] = '010-0000-0000'
dict['부서'] = '한빛아카데미'

print(dict.keys())
# output
## dict_keys(['사번', '이름', '부서', '연락처'])

print(list(dict.keys()))
# output
## ['사번', '이름', '부서', '연락처']

print(dict.values())
# output
## dict_values([1000, '홍길동', '한빛아카데미', '010-0000-0000'])

print(dict.items())
# output
## dict_items([('사번', 1000), ('이름', '홍길동'), ('부서', '한빛아카데미'), ('연락처', '010-0000-0000')])

~> in : 딕셔너리 안에 키가 있는지 확인 가능 ⭐

     => 딕셔너리에 키가 있으면 True, 없으면 False를 반환

     => in은 if문과 함께 사용되는 경우가 많음

 

~> 딕셔너리에 저장된 것을 한 건씩 출력하려면 for문 사용

for key in dict.keys():
    print(key, dict[key])

 

~> 'for key in 리스트 구문' : 리스트에 있는 것을 하나씩 추출해서 key에 넣고 반복문 실행하므로 위와 같은 결과 도출

for key in ['사번', '이름', '부서']:
    print(key, dict[key])

 

ex) 가수 정보를 딕셔너리에 저장하고 출력하기

grp = {'이름' : '트와이스', '구성원수' : 9, '데뷔' : '서바이벌 식스틴', '대표곡' : 'CRY FOR ME'}

keyName = []
valueName = []

for i in range(len(grp)):
    keyName = list(grp.keys())
    valueName = list(grp.values())
    
for i in range(len(grp)):
    print(keyName[i], "==>", valueName[i])

 

ex) 편의점 재고 관리하기

# 편의점 재고 관리하기
stocks_box = {}

for i in range(3):
    things = input("입력 물품 ==> ")
    stocks = input("재고량 ==> ")
    stocks_box[things] = stocks

print("*** 물품의 재고량 확인 ***")

for i in range(2):
    search = input("찾을 물품 ==> ")
    print(stocks_box[search] + "개 남았어요")

음! 문제에 조건이 없다고 생각해서 책에 나와있는 output대로 구현하다 보니 멋대로 3번, 2번 반복하는 반복문을 끼워넣어 구현했다 but.. 물품 입력하는 작업 무한 반복할 수 있게 while문으로 구현하면 되는구나 하하...

 

print("*** 편의점 재고 관리하기 ***")
print("재고량을 그만 입력하고 싶으면 'q'를 눌러주세요!")
stocks_box = {}

while True:
    things = input("입력 물품 ==> ")
    if things == 'q':
        break
      
    stocks = input("재고량 ==> ")
    stocks_box[things] = stocks

print("*** 물품의 재고량 확인 ***")
print("재고량을 그만 검색하고 싶으면 'z'를 눌러주세요!")

while True:
    search = input("찾을 물품 ==> ")

    if search in stocks_box:
        print(stocks_box[search] + "개 남았어요")
    else:
        if search == 'z':
            break
        else:
            print("그 물품은 없어요.")

print("저희 서비스를 이용해주셔서 감사합니다.")

이렇게! 응용할 수 있다 다만 여기서 break문을 쓰는 구문의 순서에 유의해서 작성해야 제대로 된 재고 관리 프로그램이 작동된다 :)


Ch8. 함수를 이용한 고급 프로그래밍

[ 함수 ]

: 무엇을 넣으면 그것이 처리되어 다시 어떤 것을 돌려주는 기능을 함

 

ex) 음료수 자판기

- 자판기에 동전을 넣고 콜라 버튼을 누르면, 그 안에서 어떤 처리가 되어 콜라가 나옴
- 동전의 금액이 콜라를 뽑을 수 있는 액수인지, 만약 콜라를 뽑을 수 있는 금액이라면 내부에서 기계가 어떤 방식으로 작동하는지 등은 알 수 없음 
- 따라서 함수를 블랙박스라고 표현

 

- 파이썬에서 제공하는 함수의 사용법

별도의 반환값이 없는 함수의 경우 => 함수이름()
함수에 별도의 반환값이 있다면 변수에 반환값을 받아야 함 => 변수 이름 = 함수이름()
1. 반환값이 없는 함수
- print() 함수는 괄호 안에 들어있는 내용을 화면에 출력함 ex) print("새싹성동1기 최고!")

2. 반환값이 있는 함수
- int() 함수는 입력받은 문자열을 변환해서 정수로 반환함 ex) num = int("1234")

 

- 사용자 정의 함수가 필요한 이유

: 공통된 기능 뽑아내고, 그것을 호출해서 사용하자!

 

- 함수의 기본 형태

: 함수는 매개변수(Parameter)를 입력받은 후 그 매개변수를 가공 및 처리한 후에 반환값 돌려줌

 

ex) 두 정수를 입력받아 두 정수의 합계를 반환하는 plus() 함수

## 함수 정의
def plus(v1, v2):
    result = 0
    result = v1 + v2
    return result

## 전역변수 선언
sum = 0

## 메인 코드 부분
sum = plus(100, 200)
print("100과 200의 plus() 함수 결과는", sum)
위 코드에서 함수를 정의하고 호출하는 동작 순서는!
㉮ plus(100, 200)에서 함수 호출
㉯ def plus(v1, v2) 구문의 함수 실행
㉰ return result 결과 반환
㉱ sum에 반환값 대입

 

ex) 함수를 사용한 계산기 구현

## 사용자 입력
mark = input("계산 입력 ( +, -, *, / ) : ")

num1 = input("첫 번째 숫자 입력 : ")
num2 = input("두 번째 숫자 입력 : ")

## 함수 정의
def cal(v1, v2):
    result = 0
    if mark == '+':
        result = v1 + v2
        return result
    elif mark == '-':
        result = v1 - v2
        return result
    elif mark == '*':
        result = v1 * v2
        return result
    elif mark == '/':
        result = v1 / v2
        return result

## 전역변수 선언
res = 0

## 메인 코드 부분
res = cal(int(num1), int(num2))
print("## 계산기 :", num1, mark, num2, "=", res)

다음에는 사칙연산 기호까지 매개변수로 하는, 즉 총 3개의 매개변수를 가지는 계산 함수로 짜보자!

더해서, 나눗셈을 할 때의 조건 또한 달아보는 응용도 해보자!

 

[ 함수의 매개변수 전달 ]

- 함수에 매개변수의 개수를 정해놓으면 함수를 호출할 때, 매개변수의 개수를 정확히 맞춰서 호출해야 함

 

ex) 숫자 두 개의 합과 세 개의 합을 구하는 함수

## 함수 정의 부분
def para2_func(v1, v2):
    result = 0
    result = v1 + v2
    return result

def para3_func(v1, v2, v3):
    result = 0
    result = v1 + v2 + v3
    return result

## 전역변수 선언
sum = 0

## 메인코드
sum = para2_func(10, 20)
print("매개변수 두 개 함수 호출 결과 ==>", sum)
sum = para3_func(10, 20, 30)
print("매개변수 세 개 함수 호출 결과 ==>", sum)

 

- 매개변수의 개수를 정해놓는 방법

~> 함수에 매개변수의 개수를 정해놓으면 함수를 호출할 때 정확히 매개변수의 개수에 맞춰서 호출!

 

- 매개변수에 기본값을 설정해놓는 방법

~> 가장 많이 전달될 매개변수 개수를 준비해놓고 각 매개변수에 기본값 설정하기

## 함수 정의 부분

# 매개변수 3개 사용하는 함수 기준으로 파라미터 기본값 0으로 설정!
def para_func(v1, v2, v3 = 0):
    result = 0
    result = v1 + v2 + v3
    return result

## 전역변수 선언
sum = 0

## 메인코드
sum = para_func(10, 20)
print("매개변수 두 개 함수 호출 결과 ==>", sum)
sum = para_func(10, 20, 30)
print("매개변수 세 개 함수 호출 결과 ==>", sum)

 

[ 값 반환하기 ]

1. 반환값이 없는 함수 : 함수 실행 결과, 돌려줄 것이 없는 경우에는 return문 생략 또는 반환값 없이 return만 써도 됨
- 대체로 return 없이 함수를 끝내는 경향
- 반환값 없이 함수를 마치면 아무것도 반환하지 않고 함수가 종료됨

2. 반환값이 1개 있는 함수 : 함수에서 어떤 계산이나 작동한 후 반환할 값이 있으면 'return 반환값' 형식으로 표현

3. 반환값이 2개 있는 함수 : 반환할 값이 2개라면 'return 반환값1, 반환값2' 형식으로 표현

 

- pass 키워드

: 함수의 이름과 형태만 만들어 놓고, 내부는 나중에 코딩하고 싶은 경우에 사용하는 키워드

def func():
	pass

~> 함수뿐 아니라, if문이나 반복문에서도 아무것도 안 하는 코드로 채울 때에도 사용함

 

ex) 로또 추첨하기

로또 복권은 1~45 숫자 중에서 6개를 추첨하는 게임. 로또를 추첨하는 함수 작성해서 함수 호출할 때마다, 숫자를 하나씩 뽑아서 반환하도록 코드를 작성해보자! 단, 새로 뽑은 숫자가 기존에 뽑은 적이 있는지 확인해야 하고 기존에 뽑은 적이 있는 숫자라면 무시하고 새로 뽑아야 한다.
## 로또 추첨하기
import random

lotto_num = []

def lotto_func():
    num = random.randint(1, 45)

    if num in lotto_num:
        lotto_func()
    else:
        lotto_num.append(num)

    return lotto_num
  
print("** 로또 추첨을 시작합니다. **")

for i in range(6):
    lotto_func()
  
print("")
print("오늘의 로또 번호 ==>", *lotto_num)
# 만약! 로또 번호를 오름차순으로 정렬하고 싶다면
def lotto_func():
    num = random.randint(1, 45)

    if num in lotto_num:
        lotto_func()
    else:
        lotto_num.append(num)

    return lotto_num.sort() # 반환값에 sort() 함수 적용

 

[ 유효 범위 ]

: 자신이 활동할 수 있는 범위

 

[ 지역변수 ]

: 말 그대로 한정된 지역(local)에서만 사용되는 변수

 

[ 전역변수 ]

: 프로그램 전체(global)에서 사용되는 변수

 

⚠️ 지역변수와 전역변수의 이름이 같은 경우

- 지역변수가 우선!

ex) 1반 교실과 복도에 홍길동이라는 같은 이름을 가진 학생이 있을 경우

- 1반에서 홍길동 학생을 부르면 복도의 홍길동이 아닌 1반의 홍길동이 대답
- 하지만 2반에서 선생님이 홍길동을 부르면 복도에 있는 홍길동이 대답

- 함수 내에 변수가 정의되어 있는가를 확인하면 간단히 구분 가능

함수1 함수2
a = 10
print(a)
print(a) // 이때의 a는 전역변수 a

~> 같은 a라고 해도 함수1의 a는 함수 내에서 따로 정의했으므로 지역변수

~> 함수2의 a는 함수 안에 정의된 것이 없으므로 전역변수

 

[ global 예약어 ]

: 함수 안에서 사용되는 변수로 지역변수 대신에 무조건 전역변수로 사용하고 싶은 경우에 사용하는 예약어

- global 예약어와 함께 나오는 변수명은 무조건 전역변수

 

ex) 100일 기념일 날짜 구하기

현재 시간을 구하고, 현재 시간부터 일정 날짜가 지난 후의 날짜를 구하는 코드를 작성해봅시다. 예를 들어 연인과 오늘부터 1일일 경우에 100일 기념일이 언제인지 체크하는 코드를 작성합니다.
## 100일 기념일 날짜 구하기
# datetime 모듈 사용
from datetime import datetime, timedelta

def getCurrent():
    curDate = datetime.now()
    return curDate

def getAfterDate(now, day):
    afterDate = now + timedelta(days=day)
    return afterDate

nowDate, afterDate = None, None

nowDate = getCurrent()
print("현재 날짜와 시간 ==>", nowDate)

afterDate = getAfterDate(nowDate, 100)
print("100일 후 날짜와 시간 ==>", afterDate)

https://docs.python.org/3.6/library/datetime.html

 

8.1. datetime — Basic date and time types — Python 3.6.15 documentation

8.1. datetime — Basic date and time types Source code: Lib/datetime.py The datetime module supplies classes for manipulating dates and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is

docs.python.org

 

ex) 비밀번호 생성하기

입력한 비밀번호가 비밀번호 규칙에 맞으면 생성되고, 규칙에 맞지 않으면 다시 생성하도록 메시지를 출력하는 프로그램을 작성해 봅시다.

[ 비밀번호 규칙 ]
(1) 8글자 이상
(2) 영문자 및 숫자로만 생성해야 하며 기호는 불가능
## 비밀번호 생성하기
def getPwd():
    password = input("새로운 비밀번호를 입력하세요 : ")
    return password

def checkPwd(password):
    if (len(password) < 8) or (password.isalnum() == False):
        print("오류! 비밀번호가 규칙에 맞지 않습니다")
        getPwd()
    else:
        print("Good~ 비밀번호가 올바르게 생성되었어요")
        return False

while True:
    password = getPwd()

    if checkPwd(password) == False :
        break

ㅎㅎ.. 틀린 소스코드입니다!

무엇이 틀렸냐!

(1) 한글이 걸러지지 않음
(2) 처음 오류 발생했을 때, 두 번째 실행에서 while문 안에 if문이 안 걸려서 제대로 된 output이 안 나옴

 

동기분들 도움을 듬뿍 받아서 1차 완성한 코드 (이것도 틀린 코드)

## 비밀번호 생성하기
import re


def getPwd():
  password = input("새로운 비밀번호를 입력하세요 : ")
  return password


def checkPwd(password):
  if (len(password) < 8) or re.match(r'[_]|\W', password) or re.match(
      r'[ㄱ-힣]', password):
    print("오류! 비밀번호가 규칙에 맞지 않습니다")
    return True
  else:
    print("Good~ 비밀번호가 올바르게 생성되었어요")
    return False


password = getPwd()

while True:
  if checkPwd(password):
    password = getPwd()
  else:
    break

정규표현식을 처음 접해본 데 의의를 두고 틀린코드라도 첨부해봤다

프론트엔드만 해왔던 우물 안 개구리임을 뼈저리게 느꼈던 구간.. 개발 분야는 정말 넓고 더 열심히 해야겠다 :(

 

드디어 정답코드!

## 비밀번호 생성하기
def getPwd():
    password = input("새로운 비밀번호를 입력하세요 : ")
    return password

def checkPwd(password):
    if (len(password) < 8):
        print("오류! 비밀번호가 규칙에 맞지 않습니다")
        return True
    for i in password:
        if (str(i).isalnum() == False) or (str(i).isascii() == False):
            print("오류! 비밀번호가 규칙에 맞지 않습니다")
            return True
    return False

password = getPwd()

while True:
    if checkPwd(password):
        password = getPwd()
    else:
        print("Good~ 비밀번호가 올바르게 생성되었어요")
        break

 

✏️ 더 알아보기

[ 문자열 주요 메소드 정리 ] ⭐

- str.capitalize() : 문자열의 첫 글자만 대문자로 만들고 나머지는 소문자로 된 문자열 반환, 이 때 첫 문자가 영문 알파벳이 아닌 경우는 변환되지 않은 원래 문자 그대로이며 나머지 문자들만 소문자로 바뀜

- str.lower() : 문자열에서 영문 알파벳 문자를 모두 소문자로 바꾼 문자열 반환, 영문 알파벳이 아닌 문자는 무시

- str.upper() : 문자열에서 영문 알파벳 문자를 모두 대문자로 바꾼 문자열 반환, 영문 알파벳이 아닌 문자는 무시

- str.ljust(w, [, fillchar]) : 문자열 왼쪽 정렬하고 w만큼 공백 문자로 채운 문자열 반환, fillchar을 따로 지정해주면 공백 대신 그 문자로 공간을 채움. w가 원래 문자열의 길이보다 작은 숫자이면 원래 문자열 반환

- str.rjust(w, [, fillchar]) : 문자열 오른쪽 정렬하고 w만큼 공백 문자로 채운 문자열 반환, fillchar을 따로 지정해주면 공백 대신 그 문자로 공간을 채움. w가 원래 문자열의 길이보다 작은 숫자이면 원래 문자열 반환

- str.count(sub[, start[, end]]) : 특정 문자열이 몇 번 등장하는지 알려줌. start와 end를 지정할 수 있는데 일반적인 문자열 슬라이스 할 때와 같이 인덱스 지정해주면 됨. start와 end 지정해주면 그 범위 안에서만 검색

- str.find(sub[, start[, end]]) : 문자열에서 sub으로 주어진 문자열 찾음. sub 문자열이 있는 경우 그 문자열이 시작되는 지점의 index 반환. sub 문자열을 찾지 못한 경우 -1이 반환

- str.isalnum() : 문자열이 알파벳과 숫자로만 이루어져 있으면 True, 아니면 False를 반환. 문자열의 각 글자가 isalpha(), isdecimal(), isdigit(), isnumeric() 중 하나에 해당하면 해당 글자는 isalnum()에 대해 True. 

⚠️ 한글도 True 반환!

- str.isalpha() : 문자열이 알파벳으로만 이루어져 있으면 True, 한 글자라도 다른 글자가 들어있으면 False

- str.isascii() : 문자열의 모든 문자가 ASCII 문자이면 True, 아니면 False 반환. 공백 문자도 True 반환.

- str.isdigit() : 문자열의 모든 문자가 숫자로만 이루어져 있으면 True, 아니면 False

- str.isnumeric() : 문자열의 모든 문자가 numeric 문자이면 True, 아니면 False

⚠️ isdigit() 에 포함된 문자 이외에도 Unicode 값을 가진 문자들이 모두 포함됨

 


 

마치며

오늘의 후기 : 도움주신 분들에게 모든 영광을 돌리며! 확실히 하드웨어적으로도 관심이 많은 분들이 많구나 하하.. 전공으로 하고 있지만 아무것도 모르는 내가 약간 부끄러워지는 날이었다 😱 앞으로 더더 열심히 공부하겠다고 다짐한 하루입니다 파이팅 ^^.......