[멋쟁이사자처럼 데이터분석] 시간, 함수

블체·2025년 4월 7일

Notion에서 정리한 내용을 공유용으로 옮긴 내용입니다.
양식과 구성의 어색함이 있을 수 있습니다.

04/07(월) 학습내용을 바탕으로 업로드하였음

오늘 진짜 거의 마지막이라고 미친 듯이 어려운 거 몰아친 느낌
따라가기도 벅차서 거의 기권함
변명을 해보자면 어제 공부하다가 4시 반에 자서 6시 반에 일어났다...


시간

유닉스 타임

  • C 언어 : OS 개발을 위해 → 유닉스 → 리눅스(라이트 유닉스)

  • UTC : 1970-01-01-00:00:00:0ms

  • 당시 메모리 용량 비쌈

    • 어떻게 하면 최소의 용량으로 데이터를 관리할 수 있을까?
      • 7개의 데이터를 저장하려면 4(정수) * 7 = 28byte 필요
  • 유닉스 타임 개발 : UTC 기준 1970년 1월 1일 자정(0시 0분 0초)에서부터 현재까지 몇 초가 지났는지를 정수 형태로 표시
    - 8 byte 기준 서기 42만 년의 데이터 관리 가능
    - 현재는 ms 보다 더 작은 단위 필요 : ns 단위나 더 적은 단위 지원

  • time.time

    • 유닉스 타임
    • 1970년 1월 1일 0시 0분 0초 0ms(세계 표준시 기준, 대한민국은 9시간을 더한다)을 0으로 정하고 1ms 마다 증가시키거나 감소시킨 값
    • 컴퓨터 입장에서의 시간 값
    • a1 = time.time()
    • 서로 중복되지 않는 유일한 값이 필요 → 현재 시간 사용
  • time.localtime

    • 사람 입장에서의 시간 값
    • 현재 컴퓨터에 설정되어 있는 지역 기준
a2 = time.localtime()

print(f'타임 존 : {a2.tm_zone}')
print(f'년 : {a2.tm_year}')
print(f'월 : {a2.tm_mon}')
print(f'현재 월에서 몇 번째 일인지 : {a2.tm_mday}')
print(f'시 : {a2.tm_hour}')
print(f'분 : {a2.tm_min}')
print(f'초 : {a2.tm_sec}')
print(f'이번 주에서 몇 번째 일인지 : {a2.tm_wday}')
print(f'올해에서 몇 번째 일인지 : {a2.tm_yday}')
타임 존 : 대한민국 표준시
년 : 2025
월 : 4
현재 월에서 몇 번째 일인지 : 7
시 : 9
분 : 41
초 : 27
이번 주에서 몇 번째 일인지 : 0   # 월요일
올해에서 몇 번째 일인지 : 97

시간 진짜 오지게 빠르다

a1 = time.localtime()
a2 = time.strftime("%Y년 %m월 %d일 %H시 %M분 %S초", a1)
2025년 04월 07일 10시 13분 02초

  • 수행 시간 측정 방법
# 코드 실행 시작 시간
start_time = time.perf_counter()

for v1 in range(5) :
    time.sleep(1)

# 코드 실행 종료 시간
end_time = time.perf_counter()

print(f'시작 시간 : {start_time}')
print(f'종료 시간 : {end_time}')
print(f'총 수행 시간 : {end_time - start_time}')
시작 시간 : 5228.2431957
종료 시간 : 5233.2443848
총 수행 시간 : 5.001189100000374

함수

  • 코드를 미리 만들어 놓고 필요할 때마다 수행할 수 있도록 만든 코드 블럭
  • 재사용이 쉬움

return

  • 되돌아간다 → 파이썬은 끝까지 수행되거나 값이 없으면 ‘None’ 전달
  • 되돌아가면서 값을 전달한다

  • 함수 수행 원리
    • 함수를 쓸 거야 = ‘호출한다(Call)’
    • 끝까지 수행되면 알아서 되돌아감
    • but 유효성 검사시 문제가 있다면 return 이용해 호출
    • return 만나면 호출한 쪽으로 되돌아감
  • 개발에서 함수 사용 방법
    • 중복된 코드는 없는 게 좋음
    • 따라서 필요한 기능 미리 함수로 만들어 놓음
    • 코드 한 줄이거나 한 번만 사용하더라도 함수로 만들어 놓음
    • 그 후 함수 호출해서 사용 : 수정시 찾기 쉬움

함수

  • 코드를 관리하는 요소
  • 개발자가 만든 코드를 수행하다가 함수 내부의 코드가 필요할 경우 코드의 흐름을 함수 쪽으로 이동하여 수행하고 끝나면 다시 돌아오는 개념
  • 중복된 코드를 작성하지 않을 수 있어서 코드의 재사용이 좋아지고 생산성이 좋아지며 유지·보수가 용이해진다.
  • 함수 내부의 코드를 동작시키기 위해 "함수를 사용하겠습니다"라고 하는 것을 "함수를 호출한다"라고 부른다.


  • 함수를 호출하기 전에 반드시 함수를 작성한 부분이 실행되어야만 한다.
    test1()
    오류

  • 함수 정의
# 코드가 수행되다가 함수를 만나게 되면 함수의 존재만 파악하고
# 함수 내부의 코드는 수행되지 않는다.

def test1() :
    print('test1 함수')
    print('안녕하세요')
  • 함수 호출
    test1()
    test1 함수
    안녕하세요

  • 파이썬에서 함수의 이름 = 함수를 가지고 있는 변수
    print(test1)
    <function test1 at 0x000001BA25446DE0>

    • 함수 뒤에 괄호가 들어가면 호출 : test1( )
    • 그냥 함수만 쓰여 있으면 ‘test1’이라는 변수
  • 다른 변수에 담아 함수를 호출할 수 있다.
    test2 = test1 test2()
    test1 함수
    안녕하세요

    • 굉장히 좋은 기능
    • but 조심해서 사용해야 함
  • 주의

# 함수의 이름은 변수이므로 다른 것을 넣을 수 있다.
# 단, 다시는 그 이름으로 함수를 호출할 수 없다.
test1 = 100
test1()

TypeError: 'int' object is not callable

(그냥 ‘100’이 되어 버려서 함수가 아니게 됨)

  • 실수로 어느 함수에 새로운 값을 집어넣어 버리면 그 함수는 동작하지 않음
  • list 같은 내장 함수도 마찬가지
  • 변수 이름 조심히 정하기!!!
    - 애매하다 싶으면 숫자 붙이기

매개변수 (parameter, 파라미터)

  • 함수를 호출할 때 함수에게 값들을 전달할 수 있다.
def test3(a1, a2, a3) :
    print(a1)
    print(a2)
    print(a3)
  • 파이썬은 함수를 호출할 때 함수에 정의되어 있는 모든 매개변수에 들어갈 값을 결정해 줘야 한다 → 개수 맞춰야 함
  • 함수를 호출할 때 전달하는 값은 매개변수에 담겨져 매개변수에 저장할 값으로 결정된다.
  • 작성해 준 값은 함수의 매개변수에 1:1 대응하여 하나씩 담기게 된다.
test3(10, 20, 30)
test3(100, 200, 300)
10
20
30
100
200
300
  • 함수에 정의되어 있는 매개변수의 개수보다 부족하게 값을 전달하면 값이 결정되지 않는 매개변수가 있기 때문에 오류가 발생한다.
    test3(10, 20)
    → 오류 발생
  • 매개변수보다 더 많이 전달하면 오류가 발생한다.
    test3(10, 20, 30, 40)
    → 오류 발생

※ 오류 메시지가 발생
  • 의미 파악해서 해결하려 노력!

  • 모르면 GPT

  • 함수를 호출할 때 값만 작성하면 순서대로 1:1 매칭하여 값을 저장한다.

  • 어떠한 매개변수에 값을 담을지 정해줄 수도 있다. (순서 무관)

test3(a2 = 30, a3 = 30, a1 = 10)
  • 만약 어느 변수에 담길 것임을 지정하지 않은 값이 있다면 변수의 이름을 지정하지 않은 값은 무조건 앞쪽에 몰려 있어야 한다.
test3(10, a3=30, a2=20) # 오류 발생 X
test3(a3=30, 20, a1=10) # 오류 발생 O
  • 저장될 값은 한 변수당 하나씩만 가능하다.
# a2에 저장될 값을 두 개를 지정하였으므로 오류 발생한다.
test3(10, a2=20, a2=30, a3=30)

기본값을 가지고 있는 매개변수

  • 기본값을 가지고 있는 매개변수에 저장될 값을 결정해주지 않으면 기본값으로 결정된다.
def test4(a1, a2 = 2, a3 = 3) :
    print(a1)
    print(a2)
    print(a3)

# a1은 기본값이 설정되어 있지 않기 때문에
# 함수를 호출할 때 반드시 값을 전달해야 하고
# a2와 a3은 기본값이 설정되어 있기 때문에
# 함수를 호출할 때 값을 전달하지 않으면 기본값으로 결정된다.
  • 함수를 호출할 때 값을 전달하면 기본값이 아닌 전달한 값으로 결정되고 기본값이 있는 매개변수에 값을 전달하지 않으면 기본값으로 결정된다.
test4(10, 20, 30)
test4(10, 20)
test4(10)
test4(10, a3=30)
10
20
30

10
20
3
# 앞에서 2개는 순서대로 전달, 전달되지 않은 a3은 기본값인 3

10
2
3
# a1은 전달, 전달되지 않은 a2, a3는 기본값인 a2 =2, a3 = 3

10
2
30
# 순서대로 a1에 10 전달, a3 = 30으로 지정되었으니 a2는 기본값인 2

반환 값

  • 파이썬은 반환 값을 명시하지 않을 경우 None을 반환한다.
def test5() :
    print('test5 함수 호출')
a1 = test5()
# print('test5 함수 호출')까지 작동하고 None이 a1에 들어감
# 따라서 반환 값 따로 출력 안 됨
print(a1) # None 출력

test5 함수 호출
None

  • return 다음에 값을 적어주면 값 하나를 반환할 수 있다.
def test6(a1, a2) :
    r1 = a1 + a2
    return r1 # r1 : 반환 값
  • 함수를 호출하여 함수가 반환하는 값을 받는다.
t1 = test6(10, 20) 
print(t1)

t2 = test6(100, 200)
print(t2)

# test6 함수 위치로 올라가서 진행
# r1 = 100 + 200 = 300
# return 만나 r1 반환되어 t2 = r1 = 300
# print(t2) 하면 300 출력

30
300

  • return 키워드는 함수의 수행을 중단하고 함수를 호출하는 쪽으로 돌아간다라는 의미
  • 함수의 수행을 더 이상 하고 싶지 않을 때 많이 사용
  • 유효성 검사 : 정상적으로 동작해야 하는 조건이 있다면 그 조건에 위배될 시 중단
def test7(a1) :
    if a1 % 2 == 0 :
        # 함수 수행 중단
        return

    print(f'test7 : {a1}')
test7(3)
test7(4)

test7 : 3

(3 인 경우 if 가 거짓이기 때문에 if 아래는 출력되지 않고, 바로 print(a1) 으로 → a1 = 3 출력

4인 경우 if가 참이기 때문에 return → return 뒤 반환 값이 없으므로 a1 = none. 뒤 print 건너뛰고 함수 끝남 → 출력 X)

  • 함수는 무조건 값 하나만 반환됨
    • 여러 값이 반환되는 것이 아닌 ‘튜플 하나’를 반환하는 것
def test8(a1, a2) :
    r1 = a1 + a2
    r2 = a1 - a2
    r3 = a1 * a2
    r4 = a1 // a2
    # 아래의 반환은 동시에 여러개의 값을 반환하는 것이 아닌
    # 튜플로 생성하여 튜플 하나를 반환하는 것이다.
    return r1, r2, r3, r4

확인해 보면

t1 = test8(10, 3)
print(t1)
print(type(t1))

(13, 7, 30, 3)
<class 'tuple'>

  • 원리는 이러하고 할 때는 그냥 값 여러 개를 반환하는 것처럼 사용하면 됨
  • 주로 아래처럼 많이 사용
t1, t2, t3, t4 = test8(10, 3)
print(t1, t2, t3, t4)

13 7 30 3

가변형 매개변수

def test1 = (a1, a2) :
    t1 = a1 + a2
    print(t1)

def test2 = (a1, a2, a3) :
    t2 = a1 + a2 + a3
    print(t2)

def test3 = (a1, a2, a3, a4) :
    t2 = a1 + a2 + a3 + a4
    print(t2)

# 무한히 반복할 수 없으므로 편한 방법을 찾음
  • 가변형 매개변수
    • 매개변수 하나로 다수의 값을 받을 수 있다라는 개념

*args → tuple

  • 함수를 호출할 때 전달해주는 값들을 모아 튜플로 만들어 변수에 담아 준다.
def test9(*a1) :
    return sum(a1)
t1 = test9(10, 20, 30)
t2 = test9(10, 20, 30, 40, 50)
t3 = test9(10, 20, 30, 40, 50, 60, 70, 80)

print(t1)
print(t2)
print(t3)

60
150
360

**kargs

  • 전달되는 값들을 모아 딕셔너리로 만들어서 변수에 담아준다.
  • 이때 함수를 호출하는 쪽에서 사용한 이름이 딕셔너리의 이름이 된다.
def test10(**a1) :
    print(a1)
test10(k1=10, k2=20, k3=30)
test10(t1=100, t2=200, t3=300)

→ *{'k1': 10, 'k2': 20, 'k3': 30}

{'t1': 100, 't2': 200, 't3': 300}*

섞여 있는 경우

  • *와 일반 매개변수
# *변수와 다른 일반적인 매개변수와 섞여 있을 경우
# 앞의 두 개는 a1, a2, 뒤의 두개는 a4, a5에 담기고 나머지는 튜플로 만들어져서
# a3에 담긴다.

def test11(a1, a2, *a3, a4, a5) :
    print(a1)
    print(a2)
    print(a3)
    print(a4)
    print(a5)

예시)

# *변수 다음에 있는 매개변수로 들어갈 값은 이름을 지정해줘야 한다.
# (키워드 인자로 써야 한다.)
test11(10, 20, 30, 40, 50, 60, 70, 80, a4=90, a5=100)

# 또는 a4, a5에 기본값 정해줘도 됨
10
20
(30, 40, 50, 60, 70, 80)
90
100
  • a1 → 10 / a2 → 20에 담김
    • 뒤의 매개변수들은 이름 지정해야 함 → a4 = 90 / a5 = 100
      • 키워드 인자 : 함수를 호출할 때 인자의 이름을 직접 지정해서 전달하는 것 (a4 = 90, a5 = 100) ↔ 위치 인자 : 순서대로 값을 넣는 방식
      • 키워드 인자 뒤에는 위치 인자를 쓰면 X
  • 가운데는 전부 튜플로 a3에 전달됨
    test11(10, 20, 30, 40, 50, 60, a4 = 70, a5 = 80, 90, 100)
    # 에러

- **와 일반 매개변수
# **변수 다음에는 다른 변수를 두면 안 된다.
def test12(a1, a2, **a3, a4, a5) :
    print(a1, a2, a3)
    
# 에러

- * 와 ** 섞여 있는 경우
# (학습)
def test12(a1, a2, *args, a4, a5, **a3):  # OK!
    print(a1, a2, args, a4, a5, a3)
test12(10, 20, 30, 40, 50, a4=60, a5=70, x=100, y=200)

10 20 (30, 40, 50) 60 70 {'x': 100, 'y': 200}


함수 연습

  • 저번 자동차 딕셔너리 문제

문제1)

자동차의 정보가 다음과 같이 구성되어 있다.

자동차 하나의 정보는 다음과 같다.

모델명, 연식, 배기량, 색상, 주행거리

첫 번째 자동차 : 붕붕이, 2000, 500, 노란색, 100000

두 번째 자동차 : 방구차, 1950, 200, 빨간색, 200000

세 번째 자동차 : 아스라다, 1980, 5000000, 흰색, 300000

출력은 다음과 같다.

각 자동차의 정보를 모두 출력한다.

총 배기량과 배기량 평균을 출력한다.

총 주행거리와 총 주행거리 평균을 출력한다.

  • 설계 과정
    • 설계 (출력)
      1. 자동차의 정보를 담는다.
      
      2. 총 배기량과 배기량 평균을 구한다.
      
      3. 총 주행거리와 주행거리 평균을 구한다.
      
      4. 자동차의 정보를 출력한다.
      
      5. 총 배기량, 배기량 평균, 총 주행거리, 주행거리 평균을 출력한다.
      • 항상 출력은 한 번에 모아서
    1. 입력

      # 자동차의 정보를 담는 함수
      def setCarInfo(name, year, cc, color, length) :
          car_dict = {
              '이름' : name,
              '연식' : year,
              '배기량' : cc,
              '색상' : color,
              '주행거리' : length
          }
          return car_dict

      ※ 가급적이면 함수는 매개변수만 가지고 뭔가 처리되는 형태로 만들기

      여러 개를 수정할 일 없이 독립성 보장받도록

      # 자동차의 정보를 담는다.
      car1 = setCarInfo('붕붕이', 2000, 500, '노란색', 100000)
      car2 = setCarInfo('방구차', 1950, 200, '빨간색', 200000)
      car3 = setCarInfo('아스라다', 1980, 5000000, '흰색', 300000)
    2. # 총 배기량과 배기량 평균을 구해 반환한다.
      def get_cc_info(*cars) :
          # 배기량 총합을 담을 변수
          total_cc = 0
          # 자동의 수 만큼 반복한다.
          for car in cars :
              # 배기량을 누적한다
              total_cc = total_cc + car['배기량']
      
          # 배기량 평균을 구한다.
          avg_cc = total_cc // len(cars)
      
          return total_cc, avg_cc
      # 총 배기량과 배기량 평균을 구한다.
      total_cc, avg_cc = get_cc_info(car1, car2, car3)
      # print(total_cc, avg_cc) 중간출력 확인 후 지우거나 주석 처리
    3. # 총 주행거리와 주행거리 평균을 구하는 함수
      def get_length_info(*cars) :
          # 총 주행거리를 담을 변수
          total_length = 0
          # 자동차의 수만큼 반복하면서 주행거리를 누적한다.
          for car in cars :
              total_length = total_length + car['주행거리']
      
          # 주행거리 평균을 구한다.
          avg_length = total_length // len(cars)
      
          return total_length, avg_length
      # 총 주행거리와 주행거리 평균을 구한다.
      total_length, avg_length = get_length_info(car1, car2, car3)
      # print(total_length, avg_length) 마찬가지로 중간 확인
    4. # 자동차의 정보를 출력한다.
      def show_car_info(*cars) :
          for car in cars :
              print(f'이름 : {car["이름"]}')
              print(f'연식 : {car["연식"]}')
              print(f'배기량 : {car["배기량"]}')
              print(f'색상 : {car["색상"]}')
              print(f'주행거리 : {car["주행거리"]}')
              print()
      # 자동차의 정보를 출력한다.
      show_car_info(car1, car2, car3)
    5. # 총 배기량, 배기량 평균, 총 주행거리, 주행거리 평균을 출력한다.
      def show_cc_length_info(total_cc, avg_cc, total_length, avg_length) :
          print(f'총 배기량 : {total_cc}')
          print(f'평균 배기량 : {avg_cc}')
          print(f'총 주행거리 : {total_length}')
          print(f'평균 주행거리 : {avg_length}')
      # 총 배기량, 배기량 평균, 총 주행거리, 주행거리 평균을 출력한다.
      show_cc_length_info(total_cc, avg_cc, total_length, avg_length)
  • 답안

이름 : 붕붕이
연식 : 2000
배기량 : 500
색상 : 노란색
주행거리 : 100000

이름 : 방구차
연식 : 1950
배기량 : 200
색상 : 빨간색
주행거리 : 200000

이름 : 아스라다
연식 : 1980
배기량 : 5000000
색상 : 흰색
주행거리 : 300000

총 배기량 : 5000700
평균 배기량 : 1666900
총 주행거리 : 600000
  • print
    • sep=’ ‘
    • end=’/n’
  • 처음 보는 함수가 나온다 → shift + tab
    • 매개변수 구조 확인

※ 구글링 팁

  • python ㅇㅇㅇ not working 으로 검색
  • Stack overvflow : 개발자 커뮤니티

객체 지향 정리 안 끝난 겸 한 번 잘라버리자

진짜 함수 파트랑 클래스 파트는...어떻게 할 수가 없다.
일단 이해에 최선을 다했고, 내일 일찍 일어나서 숙제 마저 해봐야겠음
일단 오늘은 2시간 잤더니 너무 피곤해...

물론 1시에 할 소리는 아니지만

아 그리고 이유는 모르겠지만 오늘 클래스 질문 많이 했더니

GPT가 착해짐
갑자기 이모티콘을 쓰고 칭찬도 세 줄씩 하기 시작
뭐지 나 어려워서 열받은 거 들켰나?
서로 사무적이던 사이였는데 갑자기 응원하는 거 웃겼지만
오늘 큰 도움 되었으니 귀엽게 넘어가준다

profile
벨로그 적응할 수 있을까

0개의 댓글