본문 바로가기

문제풀이

파이썬: 개인 과제(필수) 풀이 및 해설 정리

문제 1. 제품 재고 관리

 

- 배경:

당신은 소매점에서 근무하며 제품의 재고 관리를 담당하고 있습니다. 제품의 재고는 매주 갱신되며, 재고가 부족하거나 과잉인 제품을 식별하는 것이 중요합니다.

- 목표:
주어진 제품의 재고 데이터를 분석하여, 재고가 기준치 미안인 제품과 기준치 초과인 제품을 식별하는 프로그램을 작성하세요.

- 데이터:
└ 재고 데이터는 이중 리스트로 제공되며 첫 번째 전달인자로 받습니다
    · 이중 리스트의 각 요소는 [제품명, 현재 재고량] 형식의 리스트입니다.
    · 예: [['Apple', 30], ['Banana', 20], ['Orange', 50]]
└  재고 기준치는 함수에서 두 번째 인자(하나의 기준치)로 받습니다. 기준치 이하면 재고가 부족한 것으로, 기준치 이상이면 재고가 과잉인 것으로 간주합니다.

- 요구사항:
1. 각 제품의 재고량이 주어진 기준치보다 많은지 적은지를 판단합니다.(동일 고려 x)
    1. ex) 기준치를 25로 설정한다면 apple, orange는 과잉, banana는 부족입니다.
2. 재고가 부족한 제품과 과잉인 제품의 목록을 출력합니다.
3. 위 내용을 구현한 함수명을 'check_inventory'로 작성하세요

- 코드

# 재고 데이터 예시
inventory_data = [
    ['Apple', 30],
    ['Banana', 20],
    ['Orange', 50]
]

#코드 예시 
#기준치 20으로 판별하기
check_inventory(inventory_data, 20)

 

 문제 특징

1. 2차원 리스트를 잘 처리해야 함 

 

▶ 제출안 (오답: 재고가 같으면 부족하다고 출력되지 않아야 함)

def check_inventory(inventory_data, standard = 20):
    answer = []
    for name, quantity in inventory_data:
        if quantity > standard:
            answer.append(f'{name}은 재고가 과잉입니다.')
        else:
            answer.append(f'{name}은 재고가 부족합니다.')
    return answer
print(check_inventory(inventory_data))

 

▶ 다시 풀이

def check_inventory(inventory_data:list, standard:int):
    stock = []
    for i in inventory_data:
        product = i[0]
        quantity = i[1]
        if quantity > standard:   #재고가 많을 때
            stock.append(product)
            #print(f'{product}는 재고 과잉입니다')
        elif quantity < standard   #재고가 적을 때
            stock.append(product)
            #print(f'{product}는 재고 부족입니다')
        else:              #재고가 적지도 많지도 않을 때는 pass
            pass
    return stock
print(check_inventory(inventory_data, 20))

 

 

▶ 정답 

def check_inventory(inventory_data, threshold):
    low_stock = []
    high_stock = []
    # threshold = 30
    inven_len = len(inventory_data)
    for i in range(inven_len):
        product = inventory_data[i][0]
        quantity = inventory_data[i][1]
        if quantity > threshold:
            # print(f'{product}는 과잉입니다.')
            high_stock.append(product)
        elif quantity < threshold:
            # print(f'{product}는 부족입니다.')
            low_stock.append(product)
        else: # 동률인경우
            pass
    return high_stock, low_stock
    # print(low_stock, high_stock)
low, high = check_inventory(inventory_data, 30)
print(low, high)

 

 

문제 2. 이메일 주소 유효성 검사

 

- 배경:
당신은 회사의 고객 데이터베이스를 관리하고 있습니다. 데이터베이스에 저장된 고객의 이메일 주소가 유효한 형식을 갖추고 있는지 검증하는 작업이 필요합니다.

 

- 목표:
문자열 형태의 이메일 주소 목록을 분석하여, 각 이메일 주소가 올바른 형식을 갖추고 있는지 판단하는 프로그램을 작성하세요.

- 데이터:
이메일 주소는 문자열 리스트로 제공됩니다.
올바른 이메일 주소의 형식은 다음과 같습니다:
    · 하나의 '@' 기호를 포함해야 합니다.
    · '@' 기호 앞에는 하나 이상의 문자가 있어야 합니다.
    · '@' 기호 뒤에는 도메인명이 와야 하며, 도메인명은 '.'을 포함한 하나 이상의 문자로 구성되어야 합니다.

- 요구사항:
1. 각 이메일 주소가 올바른 형식을 갖추고 있는지 검사합니다. (문자열 메소드 사용)
2. 올바른 형식의 이메일 주소인 경우, "유효한 이메일 주소입니다."를 출력합니다.
3. 올바르지 않은 형식의 경우, "유효하지 않은 이메일 주소입니다."를 출력합니다.
4. 위 내용을 구현한 함수명을 'validate_emails' 로 작성하세요.

 

- 코드

email_list = [
    "example@example.com",
    "wrongemail@.com",
    "anotherexample.com",
    "correct@email.co.uk"
    ]

 

문제 특징

1. 문자열 처리방법을 알아내고 메소드를 활용 (str.split)

2. domain에 . 이 있는 것을 확인하는 방법 (in)

3, 문제 설명에 따르면 .com도 옳은 도메인으로 판단(상식적이진 않지만)

4. (Advanced) re 모듈의 정규 표현식을 이용해 판단할 수도 있다. 

 

▶ 제출안 (오답: wrongemail@.com 은 유효한 이메일로 출력되어야 함)

- try, except는 오류를 제대로 파악할 수 없게 해서 사용을 지양하는 것이 좋음 

def validate_emails(email_list):
    answer = []
    for email in email_list:
        try:
            email_id = email.split('@')[0]
            email_domain = email.split('@')[1].split('.')[0]
            if len(email_id) > 0 and len(email_domain) > 0:
                answer.append('유효한 이메일 주소입니다.')
            else:
                answer.append('유효하지 않은 이메일 주소입니다.')
        except:
            answer.append('유효하지 않은 이메일 주소입니다.')
    return answer
print(validate_emails(email_list))

 

▶ 다시 풀이 

- @로 나눈 후 글자수와 @ 뒷 문자열에 . 포함 여부를 조건절에 추가 

def validate_emails(email_list):
    answer =  []
    for email in email_list:
        if '@' not in email:
            answer.append(f'{email} 유효하지 않은 이메일 주소입니다.')
        else: 
            id = email.split('@')[0]
            domain = email.split('@')[1]
            if len(id) >= 1 and len(domain) >= 2 and domain.split('.'):
                answer.append(f'{email} 유효한 이메일 주소입니다.')
            else: 
                answer.append(f'{email} 유효하지 않은 이메일 주소입니다.')
    return answer
print(answer)

 

▶ 정답 

# continue 이용한 방법
for email in email_list:
    split_list = email.split('@')
    # print(split_list)
    if len(split_list) != 2:
        print(f"{email} 유효하지 않은 이메일입니다.")
        continue
    if '.' in  split_list[1]:
        print(f"{email} 유효한 이메일 입니다.")

# if-else 이용한 방법 
for email in email_list:
    split_list = email.split('@')
    # print(split_list)
    if len(split_list) != 1:
        print(f"{email} 유효하지 않은 이메일입니다.")
    else:
        if '.' in  split_list[1]:
            print(f"{email} 유효한 이메일 입니다.")

 

문제 3. 마라톤 미 완주자 찾기

 

- 배경:
마라톤 대회에서 모든 선수가 경주를 완주하려 했지만, 한 명의 선수만이 완주하지 못했습니다. 주최측은 참가자 명단과 완주자 명단을 가지고 있으며, 누가 완주하지 못했는지 알아내야 합니다.

 

- 목표:
마라톤 참가자 명단과 완주자 명단이 주어졌을 때, 완주하지 못한 선수의 이름을 찾는 함수를 작성하세요.

- 데이터:
'participant': 마라톤 참가자의 이름이 담긴 리스트
 'completion': 마라톤을 완주한 선수의 이름이 담긴 리스트

 

-요구사항:
1. 참가자 명단에서 완주자 명단에 없는 선수를 찾습니다.단 참가자명단에는 동명이인이 있을 수 있습니다.
2. 완주하지 못한 선수의 이름을 반환합니다.
3. 위 내용을 구현한 함수를 `find_non_completer` 로 작성하세요

# 예시 데이터
participant = ["mike", "lisa", "tom", "lisa"]
completion = ["tom", "mike", "lisa"

 

1. 단순한 반복문과 조건문을 통해 체크할 수 있다. 

2. 자료를 적절히 선정해야 한다. 자료형의 중요성 

└ set 자료형을 통해 쉽게 접근하려 했다면 동명이인이 걸림돌

dictionary를 통해 cunt 가능

(Advanced) Counter Module을 이용해 구현할 수도 있음

 

▶ 제출안(정답)

def find_non_completer(participant):
    answer = participant[:]
    for completer in completion:
        if completer in answer:
            answer.remove(completer)
        else:
            pass
    return answer
print(find_non_completer(participant))

 

▶ 다시 풀이 

- 정답의 딕셔너리형 풀이로도 풀어봄

- get은 딕셔너리에 사용하는 함수로, get(x, n)은 key 값에 x가 없으면 value에 n을 넣는다는 의미 

 

▶ 정답

# dictionary 형으로 만들기 
def find_non_completer(participant, completion):
    my_dict = {}
    for name in participant:
        # name이 없으면 values값 0으로 설정
        my_dict[name] = my_dict.get(name,0) + 1
    for name2 in completion:
        my_dict[name2] = my_dict[name2] -1
    for name3 in my_dict:
        if my_dict[name3] == 1:
            return name3   
        
print(find_non_completer(participant, completion))

 

문제 4. 고객 데이터 관리 시스템

 

- 배경:당신은 소매점의 데이터 분석가로, 고객 데이터를 관리하는 시스템을 구축하려고 합니다. 각 고객의 이름, 이메일, 포인트 점수를 관리하고, 포인트 점수를 추가하거나 감소 시킬 수 있는 기능이 필요합니다.

- 목표:
'Customer'클래스를 작성하여, 각  고객의 이름, 이메일, 포인트 점수를 관리하고, 포인트 점수를 추가하거나 감소 시키는 메소드를 구현하세요.

- 데이터:
'Customer'클래스는 고객의 ① 고객의 이름, ② 이메일, ③ 포인트 점수 를 속성으로 가집니다.
포인트 점수를 관리하는 메소드는 다음과 같습니다:
    - 'join_customer': 고객의 이름, 이메일, 포인트를 설정합니다.
    - 'add_points(amount)': 주어진 양만큼 포인트 점수를 추가합니다.
    - 'reduce_points(amount)': 주어진 양만큼 포인트 점수를 감소시킵니다.

- 요구사항:
1. 'Customer' 클래스를 정의합니다.
2. 'join_customer', 'add_points', 'reduce_points'메소드를 구현합니다.
3. 포인트 점수가 감소될 때, 포인트 점수가 음수가 되지 않도록 합니다.

 

▶ 제출안 (??) 

class Customer():
    basic_point = 100
    status = True

    def join_customer(self, name, email, points):
        self.name = name
        self.email = email
        self.points = points
        print(name, email, points)

    def add_points(self, n):
        self.points = self.points + n
        if self.points >= 0:
            print(self.points)

    def reduce_points(self, n):
        self.points = self.points - n
        if self.points < 0:
            print(0)
        else:
            print(self.points)

customer1 = Customer()
customer1.join_customer("Alice", "alice@example.com", 100)
customer1.add_points(50)
customer1.reduce_points(20)
customer1.reduce_points(150)  # 포인트 부족 상황 테스트

 

 

▶ 정답

class Customer():
    #def __init__(self):
    #    self.name = ''
    #    self.email = ''
    #    self.points = 0

    # class안의 def 메소드라고 불리웁니다. (기능)
    def join_customer(self, name, email, points):
        #self.(): # class의 속성(성질)
        self.name = name
        self.email = email
        self.points = points

    def add_point(self, amount):
        self.points = self.points + amount
        print(f'정상적으로 추가되었습니다. 현재 포인트는 {self.points}입니다.')

    def reduce_point(self, amount):
        if amount > self.points:
            self.points = 0 
            print(f'포인트를 모두 사용하였습니다. 현재 포인트는 {self.points}입니다.')
        else:
            self.points = self.points - amount
            print(f'정상적으로 차감되었습니다. 현재 포인트는 {self.points}입니다.')


my_customer = Customer()
my_customer.join_customer('Alice','alice@example.com',100)
my_customer.add_point(50)
my_customer.reduce_point(20)
my_customer.reduce_point(150)

 

(cf) 

- 클래스 안의 def는 메소드라고 불림(기능)

- def 에서 정의한 sefl () : class의 속성(성질)