문제 1
배경
전자 상거래 플랫폼에서 고객의 평균 주문을 계산해야 합니다. 이를 위해 숫자 리스트의 평균을 계산하는 방법을 연습합니다.
목표
주어진 숫자 리스트의 평균을 계산하는 함수를 작성하세요.
데이터
numbers: 숫자가 담긴 리스트
풀이
numbers = [10, 20, 30, 40, 50]
def calculate_avg(numbers):
total_avg = sum(numbers)/len(numbers)
return total_avg
총합을 개수로 나누는 평균 구하는 방법으로 간단하게 해결할 수 있다.
함수 실행 결과
total_avg = calculate_avg(numbers)
print("숫자들의 평균:", total_avg)
# 출력 -> 숫자들의 평균: 30.0
문제 2
배경
기상청에서는 하루 동안의, 가장 높았던 기온과 가장 낮았던 기온을 확인하고 일교차를 보고하고자 합니다.
목표
하루 동안 기록된 기온 목록을 받아, 가장 낮은 기온과 가장 높은 기온을 활용하여 일교차를 함수를 작성하세요.
데이터
하루 동안 기록된 기온의 리스트
풀이
numbers = [10, 20, 30, 40, 50]
def calculate_diff_temperature(numbers):
diff_temp = max(numbers) - min(numbers)
return diff_temp
리스트에서 최댓값과 최솟값을 구해서 빼주면 되는 간단한 문제
함수 실행 결과
diff_temp= calculate_diff_temperature(numbers)
print("일교차:", diff_temp)
# 출력 -> 일교차: 40
문제 3
배경
한 소매점에서는 다양한 제품을 판매하고 있습니다. 매월 판매된 제품들의 목록과 각 제품의 판매 수량이 기록됩니다. 이 데이터를 분석하여 가장 많이 판매된 제품을 찾아내려고 합니다.
목표
제품 명과 판매 수량이 담긴 목록을 받아, 가장 많이 판매된 제품의 이름을 반환하는 함수를 작성하세요.
데이터
제품 이름과 해당 제품의 판매 수량을 담은 딕셔너리로 구성되어 있음
풀이
def find_top_seller(sales_data):
for product, sales in sales_data.items():
if sales == max(sales_data.values()):
return product
이번엔 딕셔너리를 이용하는 문제.
for문 내에서 product 와 sales라는 변수로 sales_data 딕셔너리의 key, value를 받아주었다.
조건문으로 value 중에서 가장 큰 값을 가질 때의 sales를 선택해서, 그때의 key인 product를 반환해주면 끝
함수 실행 결과
sales_data = {"apple": 50, "orange": 2, "banana": 30}
print(find_top_seller(sales_data))
# 출력: apple
문제 4
배경
컴퓨터 과학 수업에서 학생들은 기본적인 프로그래밍 원리를 익히고, 실제 생활에 적용할 수 있는 간단한 프로그램을 만드는 연습을 합니다. 간단한 계산기를 만들어서 사칙연산을 수행할 수 있는 프로그램을 구현하는 것은 기본적인 프로그래밍 실습에 적합합니다.
목표
두 숫자와 연산자를 입력받아, 해당 연산을 수행하고 결과를 반환하는 함수를 작성하세요.
데이터
num1, num2: 숫자 입력값 operator: 문자열 형태의 연산자('+', '-', '*', '/')
풀이
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"
return num1 / num2
처음에는 operator를 문자열에서 연산자로 바꿔야만 한다고 생각해서 좀 헤맸는데,
그냥 조건문을 여러개 걸면 끝나는 문제였다.
나누기에서만 '0으로 나눌 수 없다'는 조건을 한번 더 추가 해주었다.
함수 실행 결과
# 테스트
print(simple_calculator(10, 5, '+')) # 출력: 15
print(simple_calculator(10, 5, '-')) # 출력: 5
print(simple_calculator(10, 5, '*')) # 출력: 50
print(simple_calculator(10, 0, '/')) # 출력: 'Cannot divide by zero'
문제 5
배경
당신은 회사의 고객 데이터베이스를 관리하고 있습니다. 데이터베이스에 저장된 고객의 이메일 주소가 유효한 형식을 갖추고 있는지 검증하는 작업이 필요합니다.
목표
문자열 형태의 이메일 주소 목록을 분석하여, 각 이메일 주소가 올바른 형식을 갖추고 있는지 판단하는 프로그램을 작성하세요.
데이터
이메일 주소는 문자열 리스트로 제공됩니다.
올바른 이메일 주소의 형식은 다음과 같습니다:
- 하나의 '@' 기호를 포함해야 합니다.
- '@' 기호 앞에는 하나 이상의 문자가 있어야 합니다.
- '@' 기호 뒤에는 도메인명이 와야 하며, 도메인명은 '.'을 포함한 하나 이상의 문자로 구성되어야 합니다.
요구사항
- 각 이메일 주소가 올바른 형식을 갖추고 있는지 검사합니다. (문자열 메소드 사용)
- 올바른 형식의 이메일 주소인 경우, "유효한 이메일 주소입니다."를 출력합니다.
- 올바르지 않은 형식의 경우, "유효하지 않은 이메일 주소입니다."를 출력합니다.
풀이
def validate_emails(email_list):
answer = ""
for i in email_list:
if i.count("@") == 1:
if len(i.split("@")[0]) > 0:
if ('.' in i.split("@")[1]) and (len(i.split("@")[1]) > 0):
answer += f"{i}" + " 유효한 이메일 주소입니다. \n"
continue
answer += f"{i}" + " 유효하지 않은 이메일 주소입니다. \n"
return print(answer)
요구사항을 1개라도 만족하지 않으면 "유효하지 않은 이메일 주소입니다."를 출력하는데,
이걸 if문마다 else에 적어주기에는 너무 번거로워서 가장 바깥에만 적어주었다.
중첩된 조건문에 해당하지 않는다면 돌던 조건문을 빠져나와서 " 유효하지 않은 이메일 주소입니다. " 가 출력될 수 있도록한 것.
이때 유효한 조건을 모두 만족했다면, "유효한 이메일 주소입니다."만 실행되고 다음으로 넘어가야 한다.
그러기 위해서 continue를 사용해 주었다.
처음에는 pass를 넣었는데, 그렇게 하니까 유효한 이메일일때, 유효하다는 메세지와 유효하지 않다는 메세지 총 2개가 출력되었다. 알고보니 pass는 그 다음 연산을 이어서 진행하기 때문이었다. 따라서 continue를 사용해야 다음 연산을 수행하지 않고 다시 처음으로 돌아간다. (첫번째 반복 돌다가 continue를 만나면 곧바로 두번째 반복이 시작되는 것)
요구사항이 여러개라 조건문을 여러개 적었는데, 하나씩 보자면
- 처음으로 email에 @를 1개만 가지고 있는지 count()를 사용해서 확인한다. (1개만 가졌다면 다음 조건문으로 넘어간다.)
- 다음은 email을 split()함수를 이용하여 @를 기준으로 나누었다. 이전 조건문에서 @는1개만 포함한다는 조건을 만족했으니, 이 실행 결과는 무조건 @ 앞, 뒤 2개의 요소를 가지는 리스트를 출력한다. 따라서 @앞의 문자열의 길이가 1개 이상인지 조건을 걸어 확인한다.
- 마지막으로 @뒤에 '.'을 가지고 있는지 확인하기 위해 in을 이용했다. in은 해당 문자가 1개 이상 포함되어 있으면 True를 반환한다. 그리고 @뒤의 문자의 길이가 1개 이상인지 확인하는 조건을 걸고, 두 조건을 and로 묶어주어서 둘 다 해당 되어야만 조건문을 통과하게 만들었다.
=> 따라서 이 모든 조건을 만족해야만 "유효한 이메일 주소입니다."가 반환될 수 있다.
그리고 이메일과 판단 결과를 함께 보여주는 결과를 리턴하기 위해서 answer 문자열을 만들었다.
유효하다 or 유효하지 않다 결과가 나오면, 포맷팅을 이용하여 해당 이메일과 결과를 함께 answer 문자열에 추가하도록 했다.
마지막 return에 print를 넣은 이유는 줄바꿈 이스케이프 문자가 print()로 출력해야 실행되기 때문이다. print()를 안하고 그냥 return answer 로 출력하면 줄바꿈이 아니라 문자 '\n'이 출력된다.
(물론 함수 실행결과를 저장해서 결과를 프린트 해줘도 되지만, 함수를 실행하면 자동으로 줄바꿈으로 나오게 하고 싶어서 저렇게 만들었다.)
함수 실행 결과
# 이메일 목록
email_list = [
"example@example.com",
"wrongemail@com",
"anotherexample.com",
"correct@email.co.uk"
]
# 이메일 유효성 검사 실행
validate_emails(email_list)
#출력 결과
# example@example.com 유효한 이메일 주소입니다.
# wrongemail@com 유효하지 않은 이메일 주소입니다.
# anotherexample.com 유효하지 않은 이메일 주소입니다.
# correct@email.co.uk 유효한 이메일 주소입니다.
문제 6
배경
당신은 대규모 텍스트 데이터를 분석하는 프로젝트를 진행하고 있습니다. 텍스트 데이터에서 특정 패턴을 찾아내는 작업을 수행해야 합니다. 이번 작업에서는 중복된 문자를 제거하고 각 문자가 한 번씩만 나타나게 하는 프로그램을 작성하는 것이 목표입니다. 하지만 각 문자는 처음 등장한 순서를 유지해야 하며, 추가적으로 각 문자가 등장하는 빈도를 함께 계산해야 합니다.
목표
주어진 문자열에서 중복된 문자를 제거하고, 각 문자가 처음 등장한 순서대로 한 번씩만 나타나게 하며, 각 문자가 등장하는 빈도를 함께 출력하는 프로그램을 작성하세요.
데이터
입력 문자열은 알파벳 대문자와 소문자, 숫자, 공백으로 구성될 수 있습니다.
요구사항
- 주어진 문자열에서 중복된 문자를 제거합니다.
- 각 문자가 처음 등장한 순서를 유지합니다.
- 각 문자가 등장하는 빈도를 함께 출력합니다.
- 결과는 (문자, 빈도수) 형태의 튜플 리스트로 반환합니다.
풀이
def remove_duplicates_and_count(s):
indexing = []
string = []
for i in s:
if s.index(i) in indexing:
continue
else:
indexing.append(s.index(i))
string.append(i)
string_count = []
for j in string:
string_count.append(s.count(j))
result_with_frequency = list(zip(string, string_count))
return result_with_frequency
for문을 두번 작성했는데, 일단 첫번째 for문부터 보면,
문자열에서 같은 문자가 여러번 나오더라도, index()함수는 첫번째로 나타나는 자리를 출력해준다는 성질을 이용했다.
그래서 만약 이미 나온 문자라면 이미 한번 나온 동일한 인덱스가 나올 것이고, 이때는 아무것도 하지않고 지나간다.
처음 나온 문자만 '문자의 자리'와 해당 '문자'를 각각 indexing과 string이라는 리스트에 저장해 주었다.
그리고 각각의 문자가 문자열에서 몇 번 나왔는지 세기 위해서 두번째 for문을 만들었다.
첫번째 for문을 통해서 string은 이미 중복되지 않는 문자들로 이루어져 있다.
따라서 이 string의 문자들을 돌리면서, 문자열에서 몇 번 나오는지 count()함수를 이용하여 개수를 string_count라는 리스트에 넣어주었다. string의 문자의 개수를 순서대로 string_count에 넣어주었기 때문에, 두 리스트의 요소들은 서로 매칭된다.
마지막으로 zip()함수를 이용해서 string과 string_count의 요소들을 순서대로 매칭해서 뽑아주어 반환했다.
함수 실행 결과
# 예시 문자열
input_string = "abracadabra123321"
# 함수 실행
result=remove_duplicates_and_count(input_string)
print(result)
#실행 결과
# [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1), ('1', 2), ('2', 2), ('3', 1)]
문제 7
배경
축구 경기 데이터 분석가로서, 선수들의 위치 데이터를 활용하여 그들의 활동 범위와 이동 효율성을 계산하는 것은 팀 전략을 세우는 데 중요합니다. 선수들의 이동 패턴을 분석하고 이를 통해 그들의 총 누적 이동 거리를 계산하여 선수의 활동량을 평가할 수 있습니다.
목표
선수들의 위치 데이터가 주어졌을 때, 해당 데이터를 분석하여 경기 동안 각 선수가 이동한 총 누적 거리를 계산하는 프로그램을 작성하세요.
데이터
- 위치 데이터는 선수의 이름과 그에 따른 위치 좌표의 리스트를 포함하는 딕셔너리 형태로 제공됩니다. 각 좌표는 (x, y) 튜플로 표현됩니다.
- 선수는 경기 동안 여러 번 위치가 변경될 수 있으며, 각 위치는 이전 위치에서의 이동 거리를 기록합니다.
요구사항
- 유클리드 거리 공식을 사용하여 각 위치 변경 시 이동 거리를 계산합니다.
- 각 선수별로 경기 동안 이동한 총 누적 거리를 출력합니다.
풀이
def calculate_total_distances(player_positions):
sum_dist=[]
answer = ""
for j in player_positions.values():
dist=[]
for k in range(len(j)-1):
x=(j[k+1][0]- j[k][0])**2
y=(j[k+1][1]- j[k][1])**2
dist.append((x+y)**0.5)
sum_dist.append(round(sum(dist),2))
for i,s in zip(player_positions.keys(),sum_dist):
answer += f"{i}의 총 누적 이동 거리: {s} \n"
return print(answer)
참고로 유클리드 거리 공식은 그냥 피타고라스 정리라고 생각하면 된다.
선수의 위치좌표는 value에 존재하므로, values()로 value만 순회하도록 한다.
그리고 유클리드 거리를 구하기 위해서는 x축의 거리차, y축의 거리차 를 각각 구해야 한다.
위치좌표는 항상 x,y 2개로 주어지므로 x = j[k][0] , y= j[k][1] 으로 정의할 수 있다.
다음 좌표와 이전의 좌표의 차이를 구해야 하기 때문에 j[k+1] - j[k] 로 다음 인덱스 값에서 이전 인덱스 값을 빼주도록 하였다.
(다음 인덱스에서 이전 인덱스를 빼기 위해서 범위는 range(len(j)-1)로 설정했다 k+1이 최대 len(j)-1 의 값을 가지기 때문)
x좌표와 y좌표 모두 거리차를 구하고 이를 제곱한 뒤, 더한 값에 루트를 씌워줬다.
이렇게 구한 이동 거리를 모두 더한뒤, 소수점 2번째 자리까지 반올림한 값을 sum_dist에 넣어주었다.
선수마다 총 이동 거리를 알아야 하기 때문에 sum_dist에 선수별 누적합을 넣어준다.
마지막으로 선수와 누적 이동 거리를 알려주는 문자열을 반환하기 위해서,
zip()으로 '선수들 모음'과 '누적 이동 거리' 를 매칭해서 문자열 포맷팅으로 반환했다.
함수 실행 결과
# 선수별 위치 데이터
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)]
}
# 함수 실행
calculate_total_distances(player_positions)
# 실행 결과
# John Doe의 총 누적 이동 거리: 7.07
# Jane Smith의 총 누적 이동 거리: 9.08
# Mike Brown의 총 누적 이동 거리: 10.0
'문제풀이 > 스파르타 - 파이썬 문제' 카테고리의 다른 글
[Python] 데이터 전처리 & 시각화 | 실습문제(Matplotlib) (1) | 2024.07.24 |
---|---|
[Python] 데이터 전처리 & 시각화 | 실습 문제(Pandas) (0) | 2024.07.22 |
[Python 과제] Lv3. 단어 맞추기 게임 (1) | 2024.05.28 |
[Python 과제] Lv2. 스파르타 자판기 (0) | 2024.05.27 |
[Python 과제] Lv1. 랜덤 닉네임 생성기 (0) | 2024.05.24 |