[내일배움캠프] 데이터 트랙/본 캠프

[내일배움캠프] 23일 차 - 파이썬 개인 과제 리뷰

554083460 2025. 6. 13. 21:25

 

 

 

 파이썬 개인 과제

 

 

문제 1

숫자 리스트의 평균 계산하기

 

 

최종 답안

numbers = [10, 20, 30, 40, 50]
def calculate_stock(numbers):
    avg = sum(numbers) / len(numbers)
    return avg

 

 


 

 

문제 2

계산기 만들기

  • 함수명: simple_calculator
  • num1 , num2 : 숫자 입력 값
  • operator : 문자열 형태의 사칙 연산자 (+, -, * , /)
  • 나누려는 숫자 num2 가 0인 경우 다음 문자를 반환 “Cannot divide by zero

 

 

최종 답안

def simple_calculator(num1, num2, operator):
    if operator == "+":
        return num1 + num2
    elif operator == "-":
        return num1 - num2
    elif operator == "*":
        return num1 * num2
    elif operator == "/":
        if num2 == 0:
            return "Cannot divide by zero"
        else:
            return num1 / num2
    else:
        return "Operator not supported"

 

 


 

 

문제 3

가장 큰 값 구하기

 

 

최종 답안

sales_data = {"apple": 50, "orange": 2, "banana" : 30}
def find_top_seller(sales_data):
    max_sales = max(sales_data.values())
    for keys in sales_data:
        if sales_data[keys] == max_sales:
            top_product = keys
    return top_product, max_sales

 

참고 답안

sales_data = {"apple": 50, "orange": 2, "banana" : 30}
def find_top_seller(sales_data):
    max_sales = -1  # 초기화하기 위해 존재할 수 없는 값 설정
    top_product = ''
    for key, value in sales_data.items():
        if value > max_sales:
            max_sales = value
            top_product = key
    return top_product, max_sales

 

 

새롭게 알게 된 것

 

괄호 없이 튜플 각각의 값만 얻는 법

sales_data = {"apple": 50, "orange": 2, "banana" : 30}
for key, value in sales_data.items():
    print(key)  # apple
    print(value)  # 50
    print(key, value)  # apple 50

 

 


 

 

문제 4 

 

 

처음 답안 (틀림)

input_string = "abracadabra123321"
def remove_duplicates_and_count(input_string):
    result_with_frequency = []
    element = {}
    l = list(input_string)
    for i in l:
        element[i] = l.count(i)
        l.remove(i)
    for j in element:
        result_with_frequency += tuple(j.items())
    return result_with_frequency

 

중간 답안 (틀림)

input_string = "abracadabra123321"
def remove_duplicates_and_count(input_strings):
    result_with_frequency = []
    element = {}
    l = list(input_strings)
    for i in l:
        element[i] = l.count(i)
        l = [x for x in l if x != i]
        # 리스트 컴프리헨션: 불필요한 코드
        # l(list) 자체를 바꿔버림, 맨 처음 반복문에서의 l와 두 번째 반복문의 l은 다름
    for key, value in element.items():
        result_with_frequency.append((key, value))
    return result_with_frequency

 

최종 답안

input_string = "abracadabra123321"
def remove_duplicates_and_count(input_string):
    result_with_frequency = []
    element = {}
    l = list(input_string)
    for i in l:
        element[i] = l.count(i)
    for key, value in element.items():
        result_with_frequency.append((key, value))
    return result_with_frequency

 

참고 답안

input_string = "abracadabra123321"
def remove_duplicates_and_count(input_string):
    frequency = {}  # 자료의 빈도수를 넣을 딕셔너리 초기화
    for char in input_string:
        if char in frequency.keys():
            frequency[char] += 1
        else:
            frequency[char] = 1
    return list(frequency.items())
remove_duplicates_and_count(input_string)

 

 

틀린 이유 

 

반복문 작동 방식을 제대로 이해하지 못해서 count가 제대로 집계되지 않음

  • 아래와 같이 l의 원소 i를 차례대로 반복하도록 설계하고
    for문 안에서 l을 다시 정의해
    바뀐 l의 원소 i가 반복되는 문제
 for i in l:
    element[i] = l.count(i)
    l = [x for x in l if x != i]

 

 


 

 

문제 5

이동 거리 구하기

 

 

처음 답안 (미완, 틀림)

player_positions = {
    "John Doe": [(0, 0), (1, 1), (2, 2), (5, 5)],
    "Jane Smith": [(2, 2), (3, 8), (6, 8)],
    "Mike Brown": [(0, 0), (3, 4), (6, 8)]
}

def calculate_total_distances(player_positions):
    records = []
    jd = player_positions["John Doe"]
    d = 0
    for i in range (len(jd)-1):
        d += ((jd[i][0]-jd[i+1][0])**2 + (jd[i][1]-jd[i+1][1])**2)**1/2  # 1/2승을 어떻게 처리해야 할까?
    d = round(d, 2)
    records.append(("John Doe", d))

    return records

calculate_total_distances(player_positions)

 

중간 답안 (틀림)

player_positions = {
    "John Doe": [(0, 0), (1, 1), (2, 2), (5, 5)],
    "Jane Smith": [(2, 2), (3, 8), (6, 8)],
    "Mike Brown": [(0, 0), (3, 4), (6, 8)]
}

def calculate_total_distances(player_positions):
    records = []
    jd = player_positions["John Doe"]
    d1 = 0
    for i in range (len(jd)-1):
        d1 += ((jd[i][0]-jd[i+1][0])**2 + (jd[i][1]-jd[i+1][1])**2)**(1/2)
    records.append(("John Doe", round(d1, 2)))
    
    js = player_positions["Jane Smith"]
    d2 = 0
    for i in range (len(js)-1):
        d2 += ((js[i][0]-js[i+1][0])**2 + (js[i][1]-js[i+1][1])**2)**(1/2)
    records.append(("Jane Smith", round(d2, 2)))
    
    mb = player_positions["Mike Brown"]
    d3 = 0
    for i in range (len(mb)-1):
        d3 += ((mb[i][0]-mb[i+1][0])**2 + (mb[i][1]-jd[i+1][1])**2)**(1/2)  # 코드 복붙하다가 놓친 부분!
    records.append(("Mike Brown", round(d3, 2)))
    
    return records

calculate_total_distances(player_positions)

 

최종 답안

player_positions = {
    "John Doe": [(0, 0), (1, 1), (2, 2), (5, 5)],
    "Jane Smith": [(2, 2), (3, 8), (6, 8)],
    "Mike Brown": [(0, 0), (3, 4), (6, 8)]
}

def calculate_total_distances(player_positions):
    records = []
    for key, value in player_positions.items():
        d = 0
        for i in range (len(value)-1):
            d += ((value[i][0]-value[i+1][0])**2 + (value[i][1]-value[i+1][1])**2)**(1/2)
        records.append((key, round(d, 2)))
    return records

 

참고 답안

player_positions = {
    "John Doe": [(0, 0), (1, 1), (2, 2), (5, 5)],
    "Jane Smith": [(2, 2), (3, 8), (6, 8)],
    "Mike Brown": [(0, 0), (3, 4), (6, 8)]
}

def calculate_total_distances(player_positions):
    records = []
    for player, positions in player_positions.items():  # 사람 별 반복문
        total_distance = 0.0  # 값이 소수점이므로 소수점으로 초기화!
        for i in range(len(positions)-1):  # 한 사람의 거리 별 반복문
            x1, y1 = positions[i]  # 첫 번째 점
            x2, y2 = positions[i+1]  # 두 번째 점
            distance = ((x2-x1)**2 + (y2-y1)**2)**0.5
            total_distance += distance
        records.append((player, round(total_distance, 2)))
    return records

 

틀린 이유 

 

1. 코드 복붙하다가 바꿔야 할 변수를 바꾸지 않음

 

2. 1/2승 구하는 식에서 연산자의 우선 순위 고려하지 않아서 의도대로 작동하지 않음

  • 틀린 코드
    √x = x ** 1/2
  • 정확한 코드
    √x = x ** (1/2)

 

 

개선점

 

1. 튜플 언패킹

  •  

2. d = 0 등으로 초기화 선언할 때, 이후에 더해질 값이 소수점 값이라면 d = 0.0으로 선언해서 명확하게 한다

  •  

 


 

 

문제 6

Github에 있는 데이터 불러오기

 

 

최종 답안

import pandas as pd

def get_csv(url):
    df = pd.read_csv(url, sep = ';')
    return df

 

 

체크할 사항

 

컬럼을 불러온 후, 각 컬럼의 데이터 타입을 파악하자!

  • 특히 날짜에 주의!

 


 

 

문제 7

결측치 확인

 

 

최종 답안

import pandas as pd

def get_csv(url):
    df = pd.read_csv(url, sep = ';')
    return df

df = get_csv(url)

def get_missing(data):
    return df.isnull().sum()

 

 

새롭게 알게 된 것

 

메서드 체이닝(Method Chaining)

  • 메서드 실행 → 메서드의 결과에 대해 또 메서드 실행
  • 예시: df.isnull().sum()
    • df: 데이터프레임 (표 형태)
    • df.isnull(): df에 대해 null이면 True, not null이면 False 담아서 새로운 데이터프레임 반환
    • df.isnull().sum(): df.isnull()의 결과인 데이터프레임에 대해 1(True)인 값만 합산
      판다스에서 True는 1, False는 0

 


 

 

문제 8

조건에 맞는 데이터 출력하기

 

 

최종 답안

import pandas as pd
df = get_csv(url)
def get_price(df):
    data = df.set_index('Destination')
    result = data.groupby(level=0).agg(
          mean = ('Price', 'mean'),
          median = ('Price', 'median')
    )
    result['mean'] = result['mean'].round(1)
    result['median'] = result['median'].round(1)
    return result

 

참고 답안

import pandas as pd
df = get_csv(url)
def get_price(df):
    return df.groupby('Destination')['Price'].agg(['mean', 'median']).round(1)

 

 


 

 

문제 9

수요일에 예약된 비행기 표 값 평균 구하기

 

 

최종 답안

import pandas as pd
df = get_csv(url)
def get_wed_price(df):
    df['Date_of_Journey'] = pd.to_datetime(df['Date_of_Journey'], dayfirst=True)
    df['num_day'] = df['Date_of_Journey'].dt.dayofweek
    wed = df[df['num_day'] == 2]
    mean_wed = round(wed['Price'].mean(), 2)
    return mean_wed

 

참고 답안

def get_wed_price(df):
    df['Date_of_Journey'] = pd.to_datetime(df['Date_of_Journey'], format ='%D-%m-%Y')
    # 요일 컬럼 추가
    df['Day_of_Week'] = df['Date_of_Journey'].dt.day_name()
    # 수요일에 예약된 항공권의 평균 가격 계산
    wednesday_avg_price = df[df['Day_of_Week'] == 'Wednesday']['Price'].mean() 
    # 불리언 인덱싱
    return wednesday_avg_price.round(1)

 

 

새롭게 알게 된 것

 

컴퓨터에는 기본적으로 날짜를 넣어주면 무슨 요일인지 알려주는 시스템이 있다!

  • 이 문제의 Date_of_Journey 컬럼은 문자열이라  날짜를 넣어도 무슨 요일인지 알려주지 않음
    따라서 문자열에서 날짜형으로 바꿔야 한다!
  • 날짜형 자료 중에 요일 반환해주는 메서드 찾기!
  • 날짜형 자료 중에서도 맨 처음 오는 것이 무엇인지 알아야 한다! 일이 먼저인지, 월이 먼저인지, 연도가 먼저인지

 

참고 자료

pandas_datetime

 

 


 

 

문제 10

출발 시간 기준 비행기 수 집계하기

 

 

중간 답안

import pandas as pd

def get_csv(url):
    df = pd.read_csv(url, sep = ';')
    return df

df = get_csv(url)

def get_cat(df):
    df['Time_Of_Day'] = df['Dep_Time'].apply(lambda x: '아침' if '05:00' <= x < '12:00' else 
                                            ('오후' if '12:00' <= x < '18:00' else
                                             ('저녁' if '18:00' <= x < '24:00' else '밤')))
    grouped_count = df.groupby('Time_Of_Day')['Airline'].count()
    new_df = grouped_count.reset_index()
    new_df = new_df.sort_values(by='Airline', ascending=False)
    return new_df

 

 

최종 답안

import pandas as pd
from datetime import time
def get_cat(df):
    df['time_seg'] = pd.to_datetime(df['Dep_Time'], format='%H:%M').dt.time
    df['Time_Of_Day'] = df['time_seg'].apply(lambda x: '아침' if time(5, 0) <= x < time(12, 0) else 
                                            ('오후' if time(12, 0) <= x < time(18, 0) else
                                             ('저녁' if time(18, 0) <= x <= time(23, 59) else '밤')))
    grouped_count = df.groupby('Time_Of_Day')['Airline'].count()
    new_df = grouped_count.reset_index()
    new_df = new_df.sort_values(by='Airline', ascending=False)
    new_df = new_df.reset_index(drop=True)
    return new_df

 

참고 답안

def get_cat(df):
    df['Dep_Time'] = pd.to_datetime(df['Dep_Time'], format='%H:%M')
    # 출발 시간을 기준으로 "아침", "오후", "저녁", "밤"으로 분류하는 lambda 함수 적용
    df['Time_Of_Day'] = df['Dep_Time'].apply(
        lambda x: '아침' if 5 <= x.hour < 12 else
                '오후' if 12 <= x.hour < 18 else
                '저녁' if 18 <= x.hour < 24 else
                '밤'
    )

    # 분류 결과 확인
    return df.groupby(['Time_Of_Day'])[['Airline']].count().sort_values(by='Airline', ascending= False).reset_index()
get_cat(df)

 

 

틀린 이유 

 

판다스 메서드 쓸 때, 메서드 결과를 할당하지 않아 코드 결과가 그냥 사라짐

  • 파이썬에서 할당이 필요한 메서드와 할당 필요 없는 메서드 구분하는 것 중요하다
  • 할당 필요없음: list의 append()
  • 할당 필요함: 판다스 대부분