[SK shieldus Rookies 19기] 2.1. 파이썬(2) while문, for문, 파일 입출력, 함수, 파일 읽고 쓰기

WoongchiSec·2024년 3월 4일

SK shieldus Rookies

목록 보기
3/23

  • 맨 아래에 서비스 샷 몇개 추가합니다 ㅎㅎ

1교시

지난 과제 점검

ver1

a = int(input("첫번째 수 : "))
b = int(input("두번째 수 : "))
c = int(input("세번째 수 : "))

ans = min(a, b, c)

if a % 2 != 0:
	ans = a
    
if b % 2 != 0 and b > ans:
	ans = b
    
if c % 2 != 0 and c > ans :
	ans = c
    
print(ans)
	
  • and 조건이 늘어나면 변수가 늘어났을 때 복잡해지고 가독성과 확장성이 떨어짐

ver2.

a = int(input("첫번째 수 : "))
b = int(input("두번째 수 : "))
c = int(input("세번째 수 : "))

numbers = [a, b, c]

numbers.sort()
#numbers.sort(reverse=True) : 역순 정렬

ans = 0
for no in numbers:
	if no % 2 != 0 :
    	ans = no
        break
        
if ans == 0:
	ans = min(numbers)

print(ans)

#이러면 위에 변수 늘어나도 손 안대도 댐

ver3

a = int(input("첫번째 수 : "))
b = int(input("두번째 수 : "))
c = int(input("세번째 수 : "))

numbers = [a, b, c]

odd_numbers = [ no for no in numbers if no % 2 != 0 ]
# 내꺼 챗GPT ver2 참고. 이부분 이해 필요. 
# print(odd_numbers) : 넘버스의 홀수만 뽑은 넘버

if odd_numbers:
	print(max(odd_numbers))
else:
	print(min(numbers))

ver4(조금 더 쉽게 필터 응용)

a = int(input("첫번째 수 : "))
b = int(input("두번째 수 : "))
c = int(input("세번째 수 : "))

numbers = [a, b, c]

def odd(no):
	return no % 2 != 0:
    	return no
        
odd_numbers = list((filter(odd, numbers)) 
              # 리스트같은 나열된 데이터 -> odd 함수로부터 리턴받은 것들만 가져옴. -> odd : 특정 조건만 걸러냄
				#얜 리스트 아니어도 되는데 아래 list 라 list인게 읽기 편함

if list(odd_numbers): #list 로 바꿔야함 !@ 리턴되는 데이터여서. 
	print(max(odd_numbers))
else:
	print(min(numbers))              

+ver. 리스트 내가 원하는 대로 늘릴 수 있음. q 입력전까지.

numbers = []  # while 안이 아닌 위에 따로 정의해야함. 

while True:
	a =  input("숫자를 입력하세요. 끝내려면 q를 입력하세요: ")
    if a == 'q' :
    	break

	numbers.append(int(a))
    
    
def odd(no):
	return no % 2 != 0:
    	return no
        
odd_numbers = list((filter(odd, numbers)) 
			# 여기 list 를 넣어줘야 아래 max 에서 리스트로 받음

if list(odd_numbers):  
	print(max(odd_numbers))
else:
	print(min(numbers))        
  • 스터디 서로 문제내기, 코딩 테스트, 온라인 test 문제

3-2. while문.

기본 구조

  • 반복(loop)
    • for [여기에 넣어줌. 나열 데이터가 소진될때까지] in (나열된 데이터)
    • while : 조건문이 True 면 계속 반복
  treeHit = 0
  while treeHit < 10:
  	treeHit = treeHit +1
    print("나무를 %d번 찍었습니다." % treeHit)
    if treeHit == 10 :
    	print("나무 넘어갑니다ㅏ.")

만들기

prompt

  • Add, Del, List, Quit

강제로 빠져나가기

  • break문
    • 가장 가까운 루프 종료
n = 0
m = 0
while True :
	n += 1
    print(f"#1 >>>  ({n}, {m})")
    
    while True :
    	m += 1
    	print(f"#2 >>>({n}, {m})")
		if m > 3 : break
        print(ff"#3 >>> ({n}, {m})")

	if n > 3 : break
	print(f"#4 >>> ({n}, {m})")

맨 처음으로 돌아가기

  • 상태 유지하면서 loop 시작 부분으로

  • continue

a = 0
while a < 10 :
	a += 1
    if a % 2 == 0 : continue
    # 아래 print 실행 안하고 올라감 (순서도로 이해)
    print(a)

2교시

  • 위키독스에서 '점프 투 장고'도 참고.
    • 나중에 프로젝트 할때 웹개발..?

3-3 for문

기본 구조

for 변수 in 리스트(or 튜플, )

예제

a = [(1, 2), (3, 4), (5, 6)]
for (first, last) in a :

응용

marks = [90, 24, 51, 12, 67]

number = 0 #학생번호

continue

number = 0
for mark in marks :
number += 1
...

range

시작 <= range() < 끝

for i in range(1, 10):
	print(i, end=" ")
for i in range(1, 10, 2):
	print(i, end=" ")
#1부터 10전까지 2씩 증가    

#range (len(리스트변수)) 방법

scores = [ 10, 22, 30, 44, 50, ,66]

for index in range(len(scores)): #인덱스 크기만큼의 레인지
	print(score)

print(f"{index+1}번째 학생의 점수는 {scores[index]}점입니다.")

#enumerate() 함수 이용 방법

scores = [ 10, 22, 30, 44, 50, ,66]
scoresWithIndex = list(enumerate(scores)) #덱스와 값의 튜플로 만들어줌!
for index, score in scroresWithIndex:
	print(f"{index+1}번쨰 학생의 점수는 {score}점입니다.")
  • 클린코드
    • 파이썬 코드가 있는지 확인
    • api 문서, 라이브러리 자주 보기. data structure.
for dan in range(2, 10):
	print(f"{dan}단")
	for no in range(1, 10):
    	print(f"{dan} x {no} = {dan * no}")
# print(f"{dan} x {no} = {dan * no:2}") : 끝자리 맞추기 

가로로 보이게

for dan in range(0, 10):
	for dan in range(1, 10):
    	if no == 0 : 
        	print(f"{dan}단", end=" "*10)
        else:
    		print(f"{dan} x {no} = {dan * no:2}, end="\t")
    print()

리스트 컴프리헨션

append 이용

a = [1, 2, 3, 4]
result = []
for num in a :
	result.append(num*3)
    
print(result)

컴프리헨션 표기법

a = [1, 2, 3, 4]
result = [num * 3 for num in a]
print(result)

map() 함수 이용

numbers = [1, 2, 3, 4]
def threeTimes(num):
	return num * 3
    
results3 = list(map(threeTimes, numbers))
print(results3)

map vs filter

  • map : 사상 (함수 있으면 1:1 대응) #그렇네? ㅋㅋㅋ
  • filter : 조건 맞는 몇개만 공역으로 가져감 (m:n 대응 m>=n)
  • reduce : 하나로 수렴 (m:1관계, 평균구할때? 큰 데이터 . 최종적 만들어진 결과) #상수함수?
    • map reduce 라고도 함
a = [1, 2, 3, 4]
result = []
for num in a :
	if num % 2 != 0: #홀수만 넣어서 하겠따
	result.append(num*3)
    
print(result)
a = [1, 2, 3, 4]
result = [num * 3 for num in a if num % 2 != 0]
print(result)
numbers = [1, 2, 3, 4]
def oddNumbers(num):
	return num % 2 != 0  #return : 조건 만족할 떄 넘버만 리턴한다! 걸러주는 것! 연산 결과 들어가는 게 아님

def threeTimes(num):
	return num * 3
    
results3 = list(map(threeTimes, filter(oddnumbers, number)))
print(results3)

두 수 입력 -> 최대 공약수

a= int(input("첫번째 수 : "))
b= int(input("두번째 수 : "))

if a > b : 
	a, b = b, a  #작은수, 큰수
   
  for i in range(a, 0, -1): #역순하면 처음게 가장 큰 거 
	a % i == 0 and b % i == 0: #공약수
    	print(f"{a}와 {b}의 최대 공약수 : {i})
        break
   
#for i in range(1, a+1):
#	a % i == 0 and b % i == 0: #공약수
#    	print(i)

# 근데 작은수 큰수 안해도 되지 않나? if 햇으니 다른 경우도 해야 할테고. 만약 저런다면 max, min 해도 댈것같은데.

(오후) 3교시
필터, 맵 함수 추가 설명

Quiz

  • 몸무게 리스트 -> 80 이상 비만, 아니면 정상 출력 -> results 리스트 작성
    • ex. [20, 70, 87, 99] -> ['정상', '정상', '비만', '비만']
    • 빈 리스트에 append() 함수 이용 -> 조건 따른 데이터 추가
weights = [20, 70, 87, 99, 82, 60]

results = []
for w in weights :
	if w >= 80 :
    	results.append('비만')
    else :
    	results.append('정상')
  • map 이용
weights = [20, 70, 87, 99, 82, 60]

def checkWeights(w) :
	if w >= 80 :
    	return '비만'
    else : 
    	return '정상'
        
result = list(map(checkWeights, weights))      
  • 위 코드를 "몸무게 : 정상여부" 형식으로 출력
    • range(len(리스트)) 함수 -> 인데스 가져와 출력
weights=[20,70,87,99,82,60]

results=["정상" if weight < 80 else "비만" for weight in weights]

for i in range(len(weights)):
print(f"{weights[i]} : {results[i]}")

enumerate 이용

weights=[20,70,87,99,82,60]

results=["정상" if weight < 80 else "비만" for weight in weights]

for index, weight in enumerate(weights):
    print(f"{weght} : {result[index]}")

zip() 이용

weights=[20,70,87,99,82,60]

results=["정상" if weight < 80 else "비만" for weight in weights]

print(list(zip(weights, results)))
weights=[20,70,87,99,82,60]

results=["정상" if weight < 80 else "비만" for weight in weights]

for weight, result in zip(weights, results):
	print(f"{weight} : {result})

4.파이썬 입출력

4-1 함수

함수란

  • 반복되는 동작 -> 한 뭉치 -> 코드를 줄임

구조

def 함수이름(매개변수) : #함수 헤더
수행할
문장1 #함수 본문
수행할_문장2

def add(a, b):
return a + b

매개변수와 인수

  • 매개변수 : parameter
  • 인수 : arguments

입력값과 리턴값 따른 함수 형태

입력값 O or X, 리턴값 O or X -> 총 4가지 타입

    1. 일반적 (둘다 있음)
def add(a, b)
	result = a + b
    return result

- 2. 입력값 X
def say() :
	return 'Hi'

    1. 리턴값 X
def add(a, b):
	print("%d, %d의 합은 %d입니다." %(a, b, a+b))
    #자동으로 None 이 리턴댐 (리턴값 따로 없다는 것)   

- 4. 입력값, 리턴값 둘다 X ``` def say() : print('Hi') ``` ### 매개변수 지정 호출
def sub(a,  b):
	return a-b
    
#sub(a=1, b=2) : 순서 관계없이 사용할 수 있는 장점

입력값 몇개일지 모를 때

def 함수_이름(*매개변수) :
	수행할_문장
   	...

여러 개 입력값 함수

add_many(1, 2, 3) add_many(1, 2, 3, 4, 5, 6, 7)

def add_many(*args):
	result = 0
    for i in args:
    	result += 1 
    return result     

def add_mul(choice, args): #choice : 값 1개, args : 여러개 가능, 같이 있으면 하나만 나오는 게 먼저 나와야함. 여러개가 나중에 -> 몇개 될지 모르니깐

	if choice == "add": #choice 에 add 입력
    	result = 0
        for i in args:
        	result += 1
    elif ...

키워드 매개변수, kwargs

** : 키워드 가지고 있는 args

def pirnt_kwargs(**kwargs):
	print(kwargs)
    
    
def calcurator(operator, *operand):
	if operator == "+":
    	result = 0
    	for i in operand:
        	result += 1
        return result
    
    if operator == "*":
    	result = 1
    	for i in operand:
        	result *= 1
        return result
        
print(calcurator("*", 10, 20, 30))
print(calcurator("+", 10, 20, 30))
def cacurator2(**kwargs):
	return calcurator(kwargs["operator"], *kwargs["operand"])
    

print(calcurator2(operator="*", operand=[10, 20, 30]))
print(calcurator2(operator="*", operand=[10, 20, 30]))

# key, value 형태는 ** 2개

4교시

함수의 리턴값은 항상 하나

#튜플 괄호 생략 (실제론 튜플 데이터 1개 반환)

def add_and_mul(a,b):
	return a+b, a*b   
def cal(a, b):
	return a+b, a-b, a*b, a/b
    
print(cal(20,2))
  • return : 중간 함수 종료 시킬 때 쓸 수도
def say_nick(nick):
	if nick == "바보" :
    	return
    print("나의 별명은 %s 입니다." %nick)
  • call stack
    • 함수 호출되었을 떄 반환 주소(위치) 저장
    • 왜 필요? 함수 안에서 함수 호출 경우
      • 메인 함수 위치 #100 -> 스택에 기록
      • 하위 함수 위치 #200 -> 스택 위에다가 기록 (LIFO)
      • return 만나면 스택 맨 위 #200 만나서 거기로 감
      • 또 return 만나면 #100 으로 점프 -> 실행
      • stack 이용한 주소 관리로 메인 함수 반환 주소 가능
      • 메인함수 반환 -> OS 쪽으로 반환
      • 스택 메모리에 접근 가능하면 -> 주소 바꿈 -> 공격자 심은 프로그램이 #300번지에 있을 때, #300으로 바꿔놓음 -> 공격자가 심어놓은 코드 실행 -> 버퍼 오버 플로우, 포맷 문자열 삽입 취약점 (메모리 핸들링 언어에서 발생, C, C++)

매개변수 초깃값 미리 설정

def say_myself(name, age, man=True): #3번째가 True 인데 미리 설정해서 내가 생략하더라도 아래에선 True 로 동작
  • 꼭 입력 안해도 되는 건 뒤에서 부터 정의
    - 맨 앞에 있으면 내가 man 입력 했는지 햇갈리니깐.

함수 안에서 선언한 변수 효력 범위

a = 1                
def vartest(a):  # 얘는 여기만
	a = += 1     # 얘는 여기만
    
vartest(a) #맨 첫줄 정의
print(a)   #맨 첫줄 정의

함수 안에서 함수 밖 변수 변경 방법

return 사용

global 명령

  • 전역 변수 사용

lambda 예약어

  • def 와 동일 역할
    • def 함수이름(매개변수) :
      함수본문
  • 이름 = lambda 매개변수
    • 간단한 경우 또는 def 못쓸 떄
    • 최근 많이 쓰는 추세
add = lambda a, b: a+b
result = add(3, 4)
print(result)

+ 내장함수 사용법 확인 => help(function_name)

  • cmd -> python -> ~
  • help(enumerate)
def add(a, b):          #함수 헤더 -> 함수이름(매개변수)
	return a + b		#함수 본문 -> 들여쓰기 구분
    
  • 내가 만든 함수 help 할수도 -> 함수 헤더가 출력됨

지역변수

  • 함수 호출할 때마다 생성 -> 함수 반환되면 제거
    • 매개변수도 지역변수 될 수도 있음
    • 함수 안에서 정의한 변수
def add(a, b):
	result = a + b
    return result
  • a, b : 지역변수
    • return 하면 사라짐
  • 파이썬 : 함수 호출할 때마다 지역변수 저장하는 네임페이스 생성

난수

  • random number (예측 x)
import random

for i in range(0, 10):
	print(random.random())			# 0 < random.random() < 1 실수 
    
    r = int(random.random()*100) 	# 0 < r < 100 정수
    print(r)
	
print()    
for i in range(0, 10):
	r = random.randrange(1, 7		# 1 <= r < 7
    print(r)

4교시

실습1. 숫자맞추기

  1. 0 < and < 100 임의 난수 맞추는 게임
  2. 사용자가 숫자 입력하면 메세지
    "크다", "작다", "00번만에 맞췄습니다."
  3. 사용자 숫자 입력 기회 10번 제한
    남은 기회 출력
    모든 기회 사용되면 프로그램 종료

내가 한 거 (못함)

from random import *

answer = int(random()*100)

i = int(input("숫자를 입력하세요 : "))
    #int 넣기

cnt = 0

while cnt < 11:
    if i > answer : 
        print(f"정답보다 큽니다. 남은 기회 {cnt}번")
        cnt += 1
        i = int(input("숫자를 입력하세요 : "))

    elif i < answer : 
        print("정답보다 작습니다. 남은 기회{cnt}번")
        cnt += 1
        i = int(input("숫자를 입력하세요 : "))

    else : print(f"{cnt}만에 맞췄습니다.")

print("모든 기회가 사용되었습니다.")

YSG 님

import random

target = random.randint(1, 100)
count = 0
print("숫자 맞추기 게임을 시작합니다.")
	for i in range(10) :
	num = input(f"{10-i}번의 기회가 남았습니다. 1-100 사이의 숫자를 입력하시오.")
if int(num) == target:
	print(f"정답입니다. {i+1}번 만에 맞추셨습니다.")
	break
elif int(num) > target:
	print("입력한 숫자가 정답보다 큽니다.")
else:
	print("입력한 숫자가 정답보다 작습니다.")
	count +=1
if count == 10:
	print(f"모든 기회를 소진하였습니다. 정답은 {target}입니다.")

수정본

실습2 행맨

  1. 영어 문장 입력
  2. 문장 임의 단어 하나 추출 -> 해당 단어 맞추는 게임
  3. 단어 길이만큼 "_" 출력 -> 단어 : ___
  4. 사용자 알파벳 입력 -> 해당 위치에 알파벳 출력 -> t입력 -> t
  5. 단어를 맞추는 횟수는 10번으로 제한
  6. 횟수 안에 단어 맞추면 단어와 시도 횟수 출력

필요한 부분

words = input('여러 단어로 구성된 문장을 입력하세요. : ")

# 문장부호를 제거 !"#$%&'()*+,-./:;<=>@[]^_`{|}~
words = re.sub(r'[!"#$%&'()*+,-./:;<=>@[]^_`{|}~]', '', words)
for word in words.split():
	pirnt(word) 

내가 삽질한거 (못함)

import re
from random import *

words = input('여러 단어로 구성된 문장을 입력하세요. : ')



words = re.sub(r'[^\w\s]', '', words)


answer = sample(list(words.split()), 1)

print(answer)


  • 맨 아래 elif 에 break / try_count >= 10:

교과서 수업 듣고 모의고사 푸는 느낌인데...ㅋㅋㅋ

5교시

4-3. 파일 읽고 쓰기

파일 생성하기

  • f = open("새파일.txt", 'w') #open 함수, 파일 객체 리턴, (경로, 모드-w는 쓰기, r 읽기, a추가모드(마지막에 새로운 내용 추가할 때)

  • path : 파일 존재 위치, 파일명 (경로)

    • 유닉스, 리눅스 : /
    • 윈도우 : \
    • 역 슬래시 문자 인식 -> \ -> 지저분함 -> 문자열 앞에 r 붙임 -> 이스케이프 문자 그냥 문자열로 인식

파일을 쓰기 모드로 열어 내용 쓰기

f = open(r'new_file.txt', 'w')
# 실행 -> new 파일 없어도 만들어짐 (지우고 다시)

f = open(r'new_file.txt', 'r')
# 실행 -> 읽어야 대는데 없으니까 에러남 

f = open(r'new_file.txt', 'a')
# 실행 -> 없어도 생김
f = open(r'new_file.txt', 'w', encoding='utf-8') # 한글같은 유니코드 포함되면 encoding='utf-8' 넣어야함.
						# 이 상태로 a로 하면 2번 됨 (뒤에 붙인다!)
                        # w는 다시해도 똑같음 (덮어쓰니까!)

for i in range(1, 11):
	f.write(f'{i}번째 라인'\n)
    
f.close()		#오픈했던 파일 반환
				#동시성, 공유자원, 동기화오류(교착상태에서 자료 처리 바꿔서 한 거), 교착상태(Dead rock사거리 차)
				# 한번에 한 프로그램만 가능하도록

파일 읽는 법

readline

f = open(r'new_file.txt', 'w', encoding='utf-8') 

while True:		 		#얘 안하면 1라인만 가져옴
	line = f.readline()
    if not line:		# 왜 이렇게 하는지는 내일 -> 커서와 관련 있음!
    	break
    print(line, end=' ')

f.close()

today is...

쉽지 않다.. 아니 어렵다.

비전공자가 한번에 IT에 쉽게 가는게 당연히 어렵지.

너무 부담갖지 말고,

진짜 초심처럼 막 엄청 잘해진다는 목표보다,

이 과정 완주 자체에만 목표를 두고,

그저 매일매일 조금씩 내가 할 수 있는 걸 하자.

파이팅!!

오늘 지각 안하고 오늘 하루 완주한 거 잘했다!!

하루하루 완주하다보면 과정 전체 완주하겠지!

하루하루 최선을 다하자!

파이팅!

서비스 샷

1

profile
It's log on my way to whitehack

0개의 댓글