① 5번 - 이메일 유효성 검사
1) 문제 요구 조건
- @ 하나 포함
- @ 전에 하나 이상의 문자
- @ 이후 .을 포함한 문자 2개 이상
2) 상식적으로 생각했을 때 유효하지 않을 것 같은 경우
- 도메인명에 . 가 연속으로 나오는 경우, 맨 앞뒤에 오는 경우
- 공백
2)번 처리하느라 조금 오래걸렸다..
def validate_emails(email_list):
for email in email_list:
if ((email.count('@') != 1) | (' ' in email)): #@ 하나 포함, 공백 미포함
print(f'{email} 유효하지 않은 이메일 주소입니다.')
continue
private, domain = email.split('@')
detail = domain.split('.') #2)번 조건 확인을 위해 .을 기준으로 나누기
if ((len(private) >= 1) & ('.' in domain) & all(len(d2) > 0 for d2 in detail) == True):
print(f'{email} 유효한 이메일 주소입니다.')
continue
else:
print(f'{email} 유효하지 않은 이메일 주소입니다.')
② 6번 - 중복 문자 빈도수 세기
★ 문제 풀이 흐름 ( = 오류 없앤 순서 ^^ )
(우선 감대로(?) 풀어보면서 개념부터 공부하기 위해 쉬운 예제를 만들었다.)
- 첫 번째 문제 : argument 1개 와야 하는데 2개 왔다는 오류 발생
- 괄호로 묶어주면서 해결
- 두 번째 문제 : 알파벳 순서대로~ 중복값 그대로~
해결 방법1. 중복 없이 저장할 new list 만들어주기
a = 'heeello'
def solution(string):
dup_list = []
dup_list_only = []
for i in string:
if ((string.count(i) > 1) & (i not in dup_list_only)):
dup_list_only.append(i)
dup_list.append((i, string.count(i)))
return dup_list
result = solution(a)
print(result)
해결 방법2. set 활용해서 중복 제거
set
▶ 리스트의 중복을 제거해줌
▶ 딕셔너리 형태로 저장됨
▶ ... (중요) (밑에 나옴)
a = 'heeello'
def solution(string):
dup_list = []
for i in a:
if (a.count(i) > 1):
dup_list.append((i, a.count(i)))
return dup_list
result = list(set(solution(a)))
print(result)
개념 익혔으니
이제 진짜 문제 풀자!
호기롭게 작성했으나
바아로 문제 발생했죠?
- 문제 : 중복값 없이 처리는 됐는데요. 순서가 엉진망창이에요.
- 원인 : set은 순서 지키지 않는다. 고로 방법1대로 진행하면 원래 문자열 순서 지키면서 출력된다.
- 그러나 일반 리스트를 만드는 것보다 set을 만드는 게 속도 측면에서 훨씬 빠르다.
- 주의할 점 !! : set은 append 매서드 대신 add을 사용해야 한다.
def remove_duplicates_and_count(s):
result_with_frequency = []
fornotdup = set()
for i in s:
if i not in fornotdup:
fornotdup.add(i)
result_with_frequency.append((i,s.count(i)))
return result_with_frequency
input_string = "abracadabra123321"
result = remove_duplicates_and_count(input_string)
print(result)
③ 7번 - 유클라이드 거리
방법1. 파이썬 기초 문법
- 첫 번째 문제 : 반복문 중첩해서 써야한다는 것까지는 생각해냈으나, 두 번째 반복문에서 변수 지정하는 거 생각 못 함.
이거 말이다. 참 쉬운 건데..
문제를 더 많이 풀자.
- 두 번째 문제 : 결과값을 보니까 마지막에 10.0 으로 출력되는 게 이상해보였다. 나는 10.00 이렇게 다 출력하고 싶은데..
- 원인 : round는 소수점이 0일 때 하나까지만 출력한다.
- 해결방법 : distance 뒤에 :.2f 붙여주기
- 셋째짜리까지 원한다? → .3f , 넷째? → .4f ,.....
def calculate_total_distances(player_positions):
result = []
for k,v in player_positions.items():
distance = 0
for i in range(len(v)-1):
x1,y1 = v[i]
x2,y2 = v[i+1]
distance += (((x2-x1)**2 + (y2-y1)**2)**0.5)
result.append(f'{k}의 총 누적 이동 거리: {distance:.2f} 미터')
return result
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)
방법2. math 모듈
- from math import sqrt"math에서 sqrt만 불러올게" (sqrt : 루트 씌워주는 함수)
from math import sqrt
def calculate_total_distances(player_positions):
result = []
for k,v in player_positions.items():
distance = 0
for i in range(len(v)-1):
x1,y1 = v[i]
x2,y2 = v[i+1]
distance += sqrt((x2-x1)**2 + (y2-y1)**2) # 뒤에 **0.5 대신 sqrt하나로 해결!
result.append(f'{k}의 총 누적 이동 거리: {distance:.2f} 미터')
return result
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)
방법3. numpy
np.linalg.norm(p2 - p1)
▶ numpy 라이브러리에서 유클리드 거리 구하는 함수 (p2, p1 사이의 직선 거리)
▶ p2 - p1 = 두 좌표의 차이 / np.linalg.norm() = 두 좌표의 차이의 크기 (=거리)
▶ 좌표 형식임을 이미 알고 있기 때문에 자동으로 x끼리, y끼리 계산해줌 (훨씬 간단하다!)
- 주의 : 리스트나 튜플은 np.array 이용해서 넘파이배열로 변환 해줘야 한다.
import numpy as np
result = []
def calculate_total_distances(player_positions):
for k,v in player_positions.items():
distance = 0
for i in range(len(v)-1):
pre = np.array(v[i]) # 넘파이 배열로 변환
fol = np.array(v[i+1]) # 넘파이 배열로 변환
distance += np.linalg.norm(fol-pre)
result.append(f'{k}의 총 누적 이동 거리: {distance:.2f} 미터')
return result
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)
④ 8번 - 아라비아 숫자로 치환
방법1. 딕셔너리 2개
korea_num = {'영': 0, '일' : 1, '이' : 2, '삼': 3, '사' : 4, '오' : 5,
'육' :6, '칠':7, '팔': 8, '구':9}
english_num = {'zero': 0, 'one' : 1, 'two' : 2, 'three': 3, 'four' : 4,
'five' : 5, 'six' :6, 'seven':7, 'eight': 8, 'nine':9} # 한국어 버전, 영어 버전
def password_decryptor(password_list):
result = []
for password in password_list:
kor_count = 0
eng_count = 0
rtan_password = password
for kor, num in korea_num.items():
kor_count += password.count(kor)
password = password.replace(kor,str(num))
for eng, num in english_num.items():
eng_count += password.count(eng)
password = password.replace(eng,str(num))
numeric_password = password
print(f'[{rtan_password}]에 대한 암호는 [{numeric_password}]로, 한글은 [{kor_count}]개, 영어는 [{eng_count}]개 입력되었습니다.')
방법2. 딕셔너리 1개
count += 1 부분을 count수만큼 더해주는 걸로 바꾸면 안되나? 똑같지 않나?
싶어서 돌려봤는데 같은 답이 나왔다.
근데도 뭔가 자꾸 찝찝해서
다른 예시 넣어주면서 확인해봤더니
- 역시나 중복제거하고 카운트를 해주고 있다.
- 결론 : count += 1로 하면 중복값을 한 번만 처리한다.
- 해결 : password.count(' ')를 사용해서 중복값에 대해서도 모두 count될 수 있도록 처리
def password_decryptor(password_list):
numbers = {'0' : ['영','zero'],
'1' : ['일','one'],
'2' : ['이','two'],
'3' : ['삼', 'three'],
'4' : ['사', 'four'],
'5' : ['오', 'five'],
'6' : ['육', 'six'],
'7' : ['칠', 'seven'],
'8' : ['팔', 'eight'],
'9' : ['구', 'nine']} # [한국어 버전, 영어 버전] 리스트로 묶어주기
for password in password_list:
kor_count = 0
eng_count = 0
rtan_password = password #르탄이가 준 패스워드를 rtan_password 변수에 담아둘게
for numeric, kor_eng in numbers.items():
if kor_eng[0] in password: #르탄이가 준 패스워드 뜯어봤을 때 한글이면
kor_count += password.count(kor_eng[0])
password = password.replace(kor_eng[0],numeric)
if kor_eng[1] in password: #르탄이가 준 패스워드 뜯어봤을 때 영어면
eng_count += password.count(kor_eng[1])
password = password.replace(kor_eng[1],numeric)
#조건에 맞춰서 replace된 새로운 password를
numeric_password = password # numeric_password 변수에 담아둘게
print(f'[{rtan_password}]에 대한 암호는 [{numeric_password}]로, 한글은 [{kor_count}]개, 영어는 [{eng_count}]개 입력되었습니다.')
'내배캠 Data > Python' 카테고리의 다른 글
[day40] 프로젝트 마무리..! & 시각화 작업하면서 학습한 코드 정리 (0) | 2025.03.27 |
---|---|
[day26] python 라이브세션 2회차 복습+응용 (0) | 2025.03.13 |
[day3] Python - map / lambda / filter (0) | 2025.02.19 |
[파이썬 문법 기초] 리스트 / 딕셔너리 (0) | 2025.02.14 |