왼쪽 : 밖의 변수를 함수에 넣었고, 함수 안에서 다른 내용으로 바꾸었을때
함수를 호출하면 바꾼 내용으로 나옴
그러나 함수 안쓰고 변수를 부르면 밖의 원래 값으로 나옴
전역변수를 함수 안에서 수정하고
글로벌로 함수 안에서 수정된건
함수 안부르고 변수만 불러도 함수 안에서 수정된 값으로 나옴
def printArea() :
tirArea = wide * hight /2
racArea = wide * hight
print(f'삼각형 넓이 : {tirArea}')
print(f'사각형 넓이 : {racArea}')
wide=int(input('가로 길이 입력:'))
hight=int(input('세로 길이 입력:'))
printArea()
totalVisit = 0
def CounttotalVisit() :
global totalVisit
totalVisit += 1
print(f'누적 방문객{totalVisit}')
CounttotalVisit()
CounttotalVisit()
CounttotalVisit()
CounttotalVisit()
CounttotalVisit()
CounttotalVisit()
글로벌은 바꾸고자하는 변수 외치고
그다음 줄로 바꾸고 변수 바꿔야함!
함수 안에 또 다른 함수!
def calculator() :
n1=int(input(f'실수1 입력'))
n2=int(input(f'실수2 입력'))
choose = int(input('1. add, 2. min, 3. divm 4. mul'))
def addCal() :
print(f'{n1}+{n2}={n1+n2}')
def minCal() :
print(f'{n1}-{n2}={n1-n2}')
def divCal() :
print(f'{n1}/{n2}={n1/n2}')
def mulCal() :
print(f'{n1}*{n2}={n1*n2}')
if choose == 1 :
addCal()
elif choose == 2 :
minCal()
elif choose == 3 :
divCal()
else:
minCal()
calculator()
함수 선언을 보다 간단히!
사용법
lambda 변수:변수 사용내용
triArea = lambda wide, hight : wide*hight/2
racArea = lambda wide, hight : wide*hight
roundArea = lambda radius : radius ** 2 * 3.14
wide = int(input('가로길이'))
hight = int(input('세로길이'))
radius = int(input('반지름길이'))
resultTriArea=triArea(wide, hight)
resultRacArea=racArea(wide, hight)
resultRoundArea=roundArea(radius)
print(f'삼각형 넓이 :{resultTriArea}')
print(f'사각형 넓이 :{resultRacArea}')
print(f'원 넓이 :{resultRoundArea}')
함수가 선언되어 있는 파이썬 파일
랜덤한 숫자 10개 뽑기는
random.sample(range(범위, 범위),뽑는 개수여기서는 10개)
모듈은 파이썬 파일이다!
import, from, as
모듈 이름 너무 길때 앞으로 이렇게 쓰겠다 하고 as
원래 모듈명.실행명 쓰는건데
from뒤에 뭐만쓰겠다 하니까
그 뒤에 . 안쓰고 쓰겠다고한 실행명만 넣어서 바로 실행 가능
만약 다 쓸거다 하면 import뒤에 * 만쓰면되는거고
한줄한줄안띄어도 괜찮고 import 뒤에 콤마로 해서 써도 괜찮음!
전역변수 __name__을이용한 실행파일 지정
실행파일은뭐여?
파이썬 파일을 여러개 만들었을거 아녀
그걸 같이 쓰기 위해 묶었을 때
어떤 파일을 먼저쓰이는건지 파이썬 엔진이 찾고
차례로 시작할텐데
그 먼저쓰일것을 __main__을 찾으면됨
add,sub,multi,div 만들어놓고
실행파일에서 add, sub,multi,div 순서대로 print하면
add가 먼저 실행될거자너
그래서 add 파일가서
print(__name__)하면 __main__이 나올 것임.
그러나, add,sub,multi,div에 print(__name__) 넣어두고
실행파일에서 돌려보면
add는 __main__이 안나올거임.
왜냐?
실행파일이 __main__이니까.
그래서 이걸 조건으로 걸고 할수도있음
add 파일이 main일 때만
아래 내용 실행하라 하는식으로
파일명 : caculator
def CMtoMM(n):
return round( n* 10 ,3)
def CMtoInch(n):
return round( n* 0.393 ,3)
def CMtoM(n):
return round( n* 0.01 ,3)
def CMtoFt(n):
return round( n* 0.032 ,3)
if __name__ == '__main__':
print(f'10cm={CMtoMM(10)}mm')
print(f'10cm={CMtoInch(10)}inch')
print(f'10cm={CMtoM(10)}m')
print(f'10cm={CMtoFt(10)}ft')
실행파일
import calculator as uc
if __name__ == '__main__' :
inputNum=int(input('길이입력 cm'))
result = uc.CMtoMM(inputNum)
print(f'result (mm) : {result}')
result = uc.CMtoInch(inputNum)
print(f'result (inch) : {result}')
result = uc.CMtoM(inputNum)
print(f'result (m) : {result}')
result = uc.CMtoFt(inputNum)
print(f'result (ft) : {result}')
모듈을 묶어서 관리하자
한 실행 파일안에 주루루룩 쓰는게 아니라
실행 파일 만들고
그 아래 파일 만들면
import 실행 파일하면
아래에 들어갔던 파일 딸려나온다
패키지 경로 알려줌
내가 만든 모듈 venv로 경로 옮기면 일반 파이썬 모듈처럼 쓸 수 있음!
#수학관련 함수
#합
listVar=[2,5,3.14,58,10,2]
print(f'sum(listVar) = {sum(listVar)}')
#최대값
print(f'max(listVar) = {max(listVar)}')
#최솟값
print(f'min(listVar) = {min(listVar)}')
#거듭제곱 pow(지수, 제곱)
print(f'pow(2,3)={pow(2,3)}')
#반올림 round(타겟 숫자, 반올림원하는 소숫점 자리수 )
print(f'round(3.141592, 2)={round(3.141592, 2)}')
import math
#절댓값
print(f'math.fabs(-546)={math.fabs(-546)}')
#올림
print(f'math.ceil(5.654) = {math.ceil(5.654)}')
#내림
print(f'math.floor(5.654) = {math.floor(5.654)}')
#버림
print(f'math.trunc(5.564) = {math.trunc(5.564)}')
#최대 공약수(숫자1, 숫자2)
print(f'math.gcd(14, 21)={math.gcd(14,21)}')
#팩토리얼
print(f'math.factorial(10)={math.factorial(10)}')
#제곱근
print(f'math.sqrt(12)={math.sqrt(12)}')
import time
#시간 요소
localtime=time.localtime()
print(localtime)
#tm_year=2023
#tm_mon=6
# tm_mday=11
# tm_hour=19
# tm_min=24
# tm_sec=32
# tm_wday=6
# tm_yday=162
# tm_isdst=0(Time Zone 이 DaylightSaving 사용하는지 여부)
객체를 이용한 프로그램으로, 객체는 속성과 기능으로 구성된다.
클래스는 하나 만들어도
객체는 무한대로 만들수 있음
현존하는 모든 프로그ㅜ램은 객체 지향적임
속성 = 변수
def __init__(self포함 변수들):
self=클래스
기능 = 함수
def 기능(self)
클래스는 첫글자 대문자해야함
객체 생성할 때 self 는 안채워도됨.
생성된 객체는 레퍼런스객체라고 함
2개만했다
class Airplane :
def __init__(self, company, goto):
self.company = company
self.goto = goto
def airplaneInfo(self):
print(f'company : {self.company}')
print(f'goto : {self.goto}')
plane1 = Airplane('asia', 'korea')
plane2 = Airplane('tway', 'busan')
plane1.airplaneInfo()
plane2.airplaneInfo()
일단
변수 = 클래스(속성1,속성2, ...)
하고 속성 바꾸고싶다
변수.속성명='바꾸는 내용'
class Cal :
def __init__(self, num1, num2) :
self.num1 = num1
self.num2 = num2
def add(self):
result = self.num1 + self.num2
return result
a = Cal(1, 2)
print(a.add())
변수안에 뭔가를 저장한게 아니라
메모리에 저장해두고
변수는 그 메모리 주소를 가져온거임
그래서 변수1=메모리저장내용
변수1=변수2
변수1 메모리 저장 내용 바꿔도변수2 바뀜
당연한거 아녀..?
score = [int(input('국어 점수 입력')),
int(input('영어 점수 입력')),
int(input('수학 점수 입력')),
]
print(score)
copySocre = score.copy()
print(copySocre)
for i, Newscore in enumerate(copySocre) :
result = Newscore * 1.1
copySocre[i] = 100 if result >100 else result
print(copySocre)
print(f'이전 평균 : {sum(score)/len(score)}')
print(f'이후 평균 : {sum(copySocre)/len(copySocre)}')
진짜 개 불친절하다...
enumerate 알려준적이 없는데... 하라고 하니 정말 당황스럽다
enumerate 함수에 대해서는 여기로
내가 이해한 바를 풀어보자면
list = [10, 21, 20]
for a , b in enumerate(list)
이렇게 되어있으면
저 for상태에서는 list 풀어보면 이렇게 되어있을 거임
a = 0 , b = 10
a = 1 , b = 21
a = 2 , b =20
아마도..?
그래서 for 뒤로 오는
list[a] 라 하면
list[0]=10인거지
그래서 답으로 낸 함수를 보면
for i, Newscore in enumerate(copySocre) :
result = Newscore * 1.1
copySocre[i] = 100 if result >100 else result
copyscore에 들어간 것들은 enumerate하는데
순서는 i에 값은 newscore에 할당함
그래서 result는 copysocre의 모든 값에 1.1을 곱한건데
만약 copyscore의[i]번째에 있는게 1.1곱해서 100이넘어가면 100으로 바꾸고 아니면 그대로 두라는거지.
얕은 복사는 각 변수를 통해 속성 값 바꾸면
같이 바뀜
깊은복사는 아예 다른거로 복사해버린거기때문에
하나의 변수를 바꿔도 다른 변수의 값은 안바뀜
num = [1,2,3,4]
numCopy = []
#얕은 복사
num = numCopy
print(f'id(num) : {id(num)}')
print(f'id(num) : {id(numCopy)}')
#깊은복사 (for & append)
for n in num :
numCopy.append(n)
print(f'id(num) : {id(num)}')
print(f'id(num) : {id(numCopy)}')
#깊은복사 (extend)
numCopy.extend(num)
print(f'id(num) : {id(num)}')
print(f'id(num) : {id(numCopy)}')
#깊은 복사 (copy)
numCopy = num.copy()
print(f'id(num) : {id(num)}')
print(f'id(num) : {id(numCopy)}')
#깊은 복사 ([:])
numCopy = num[:]
print(f'id(num) : {id(num)}')
print(f'id(num) : {id(numCopy)}')
score = [8.7, 9.1, 8.9, 7.9, 9.5, 8.8, 8.3, 9.0]
scoreCopy = score.copy()
score.sort()
print(score)
scoreCopy.sort()
scoreCopy.pop(0)
scoreCopy.pop(6)
print(scoreCopy)
originalAver = round( sum(score)/len(score), 2)
print(f'origianlTotal = {round(sum(score), 2)}')
print(f'originalAver = {originalAver}')
copyAver = round (sum(scoreCopy)/len(scoreCopy), 2)
print(f'copyTotal = {round(sum(scoreCopy),2)}')
print(f'copyAver = {copyAver}')
print(f'oriAvg-copyAvg = {originalAver - copyAver}')
또! 졸라 불친절해
sort : 리스트 객체 자체를 정렬해줌 기본적으로 오름차순으로 정렬
https://blockdmask.tistory.com/564
pop : 리스트 값 삭제인데 뒤에 오는 인덱스에 있는 값을 삭제해줌
https://ponyozzang.tistory.com/587
다른 클래스의 기능을 내 것 처럼 사용하자!
상속하는법
class1를
class2에 상속하려면
def Class2(Class1) :
하고 작성하기
class TwoCal :
def add(self, num1, num2):
result = num1 + num2
return result
def min(self, num1, num2):
result2 = num1 - num2
return result2
class FinCal(TwoCal) :
def mul(self, num1, num2):
result3 = num1 * num2
return result3
def div(self, num1, num2):
result4 = num1 / num2
return result4
now = FinCal()
print(now.add(1,2))
print(now.min(1,2))
print(now.mul(1,2))
print(now.div(1,2))
super방법 외에 상위class의 init을 강제로 불러오는 법이 있음
근데 상위class의 init을 불러오려면 그 옆에 변수도 넣어야하니 하위 class 의 변수가 들어가서 상위클래스까지 건들 수 있게 변수를 넣어줘야함
여기서는 cNum1, 2가 그 예임
class MidExam :
def __init__(self, midKor, midEng, midMath):
print('Mid Exam init called.')
self.midKor = midKor
self.midEng = midEng
self.midMath = midMath
class FinExam(MidExam) :
def __init__(self, midKor, midEng, midMath, finKor, finEng, finMath):
print('Fin Exam init called.')
super().__init__(midKor, midEng, midMath)
self.finKor = finKor
self.finEng = finEng
self.finMath = finMath
def totalScore(self):
resulttotalScore = self.midKor + self.midEng+ self.midMath+ self.finKor\
+ self.finEng+ self.finMath
return resulttotalScore
def averScore(self):
resultaverScore = self.totalScore() / 6
return resultaverScore
def MidTotalScore(self):
resultMidTotalScore = self.midKor + self.midEng+ self.midMath
return resultMidTotalScore
def MidAverScore(self):
resultMidAverScore = self.resultMidTotalScore/3
return resultMidAverScore
def FinTotalScore(self):
resultFinTotalScore = self.finKor+ self.finEng+self. finMath
return resultFinTotalScore
def FinAverScore(self):
resultFinAverScore = self.resultFinTotalScore/3
return resultFinAverScore
exam = FinExam(1,2,3,4,5,6)
print(exam)
totalScore=exam.totalScore()
averScre=exam.averScore()
print(f'총점 :{totalScore}, 평균 :{averScre}')
2개 이상의 클래스를 상속한다.
class BasicCalculator :
def add(self, num1, num2):
result = num1 + num2
return result
class DeveloperCalculator :
def mod(self, num1, num2):
result = num1 % num2
return result
class Calculator (BasicCalculator, DeveloperCalculator) :
def __int__(self):
pass
cal = Calculator()
calTry=cal.add(1,2)
print(calTry)
다중상속 받고나서
def는 init하고
pass로 남겨둠
(특별하게 넣어줄게 없다는 가정 하)
메서드를 재정의 한다!
이름을 동일하게 하여 재정의하는 것임.
단, super는 굳이 필요한건 아닌것으로 보임. 여기서는 왜 했는지 나도 의문이다..
class TriArea :
def __init__(self, w, h):
self.w = w
self.h = h
def triInfo(self):
print(f'wide : {self.w}')
print(f'height : {self.w}')
def getArea(self):
result = self.w*self.w/2
return result
class NewArea(TriArea) :
def __init__(self, wide, Hight):
self.wide = wide
self.Hight = Hight
super().__init__(self.wide, self.wide)
def getArea(self):
return 'TriArea :'+str(super().getArea())
ta = NewArea(7,5)
triArea=ta.getArea()
print(f'{triArea}')
오버라이딩 하려면
def 그 함수 이름
return super().오버라이딩함수() 하고 하고싶은거 처리
메서드 구현을 강요한다
상위클래스가 하위클래스에게 이건 꼭 구현해라 하고 강요
하기 위해서는 모듈 불러와야함
from abc import ABCMeta
from abc import abstractmethod
상위 클래스에서 def 중 하위로 넘기는건 위에
@abstaractmethod 달아줘야함
그런데 추상 클래스 만드는 이유가 뭐여?
어떠한 특정 기능을 상속받았을때
하위 클래스마다 다르게 표현되어야할 때
하위클래스마다 다르게 작성할 수 있게 함
from abc import ABCMeta
from abc import abstractmethod
class Cal(metaclass=ABCMeta):
@abstractmethod
def add(self, num1, num2):
pass
class RealCal(Cal):
def add(num1, num2):
result = num1 + num2
return result
now = RealCal.add(1, 2)
print(now)
하위에서 추상 채워줄라고 했는데
add(self, num1, num2):
해서 하면
RealCal.add() missing 1 required positional argument: 'num2'
이런 에러가 뜨더라.
그래서 self를 지우고 하니까 됨.
self 지워도 되는ㄱ 맞어...?
예상하지 못한 문제로 프로그램 실행이 어려운 상태
zerodiviaion : 0으로 나누었을때
IOE : 파일 없음
Index : 그 위치에 값없음 (예 : 리스트형에 3개만있는데 4번째 찾을떄)
Indentation : 들여쓰기
발생된 예외를 별도 처리함으로써 프로그램 전체의 실행에 문제가 없도록 함.
에러가 있으면 except를 내고
에러가 안나면 try를 낸다
혹시모르니 다 묶어야지~ 안되고
예외가 날 거 같은 그 부분만 묶어야함
nums라는 자료형을 만들거야
개수 센다 한개부터시작
개수가 6개 미만까지만 할건데
이렇게 넣어
num=~~
이거 에러 생기면(숫자형말고 다른거오면)
이 메세지 출력해줘
개수 6개 미만 될때까지 게속해
에러 안생겼으면 nums자료형에 에러없는 num append해주고
숫자 개수 하나 늘려
다했으면
nums 출력해
예외가 발생하지 않은 경우에 실행하는 구문!
else는 try에서 예외가 발생하지 않았을떄 실행하는 구문
try/except/else 가능
try /else 불가능
except 무조건 있어야함
twoLis = []
threeLis = []
realLis = []
n = 1
while n <6 :
try:
num = float(input('input number'))
except:
print('wrong try again.')
continue
else:
if num - int(num) != 0 :
print('실수')
realLis.append(num)
else:
if num % 2 == 0 :
print('짝수')
twoLis.append(num)
else:
print('홀수')
threeLis.append(num)
n +=1
print(f'짝수:{twoLis}')
print(f'홀수:{threeLis}')
print(f'실수:{realLis}')
에외가 발생하던 안하던 무조건 실행
twoLis = []
threeLis = []
realLis = []
datalist = []
n = 1
while n <6 :
try:
num = input('input number')
floatNum = float(num)
except:
print('wrong try again.')
continue
else:
if floatNum - int(floatNum) != 0 :
print('실수')
realLis.append(floatNum)
else:
if floatNum % 2 == 0 :
print('짝수')
twoLis.append(floatNum)
else:
print('홀수')
threeLis.append(floatNum)
n +=1
finally: datalist.append(num)
print(f'짝수:{twoLis}')
print(f'홀수:{threeLis}')
print(f'실수:{realLis}')
print(f'전체리스트:{datalist}')
이렇게 리스트 형태로 만들떄 finally로 모든데이터를 받는 거라면
처음에 받을 떄 int로 받으면 안됨.
일단은 받고 아래로 빼서 숫자형으로 바꿔서 써야함
num = input('input number')
floatNum = float(num)
exception은 예외를 담당하는 클래스
에러를 글자로 나오게해주는거임.
except : Exception as e
print(f'exception : {e}')
일부러 예외를 발생하는 raise
def sendMSG(msg):
if len(msg) < 10 :
print('sms로 발송')
else:
raise Exception('길이 초과, mms로 발송', 1)
def sendMMS(msg) :
if len(msg) >10 :
print('mms로 발송')
else:
raise Exception('길이 미달, sms로 발송', 2)
msg = input('write msg :')
try: sendMMS(msg)
except Exception as e:
print(f'e:{e.args[0]}')
print(f'e:{e.args[1]}')
if e.args[1] == 1:
sendMMS(msg)
elif e.args[1]== 2:
sendMSG(msg)
print(len(msg))
메세지 길이에 따라 sms, mms인지 봐주고
sms에 넣었을때길이 초과이면 에러메세지 2개 (길이초과~~ , 1)를 나오게함
mms도 마찬가지
이제 진짜 msg를 넣고
일단 mms에 넣어
되면 보내는거고,
안되면 에러메세지 먼저 길이 미달 어쩌구~ 뽑고
숫자 2가 나온다음에
sms 함수로 가서
sms로 발송 이러는거임