시작하며
직전에 포스팅한 smtplib와 datetime을 공부하고, 초초초미니 프로젝트를 한번 만들어 보았습니다. 이번에는 생일을 축하하는 이메일을 자동으로 보내는 초미니 프로젝트를 만들어보려고 합니다.
생일 축하 프로젝트?
프로젝트에서 각 파일들을 봅시다.
letter_templates
: 메일 양식birthdays.csv
: 연명부.name,email,year,month,day
양식으로 되어 있음main.py
: 코드 작성
이제 구현해야 할 기능들을 살펴봅시다. 1. `birthday.csv`에서 현재 생일인 사람을 가져옵니다. 2. `letter_templates`에서 랜덤한 양식을 가져와 빈칸을 채워 넣습니다. 3. 메일을 보냅니다.
코드 전문입니다. 이번에는 좀 빠르게 구현해보려고 구현에만 집중하느라 코드가 좀 예쁘지 않습니다..
import smtplib
import datetime as dt
import pandas as pd
from random import *
my_email = "your_email"
password = "your_password"
def send_email(name, text):
with smtplib.SMTP("smtp.gmail.com") as connection:
connection = smtplib.SMTP("smtp.gmail.com")
connection.starttls()
connection.login(user=my_email, password=password)
connection.sendmail(
from_addr=my_email,
to_addrs="your_email",
msg=f"Subject:To {name}!\n\n{text}"
)
def select_letter(name):
rand = randint(1, 3)
with open(f"Day 032/miniproject/letter_templates/letter_{rand}.txt", "r") as file:
text = file.readlines()
# [NAME]을 name으로 변경
text[0] = text[0].replace("[NAME]", name)
# 처음에 text로 했다가 오류나서 join 사용
return ''.join(text)
# 먼저 설정해야 할 변수들
day_of_month = dt.datetime.now().month
day_of_date = dt.datetime.now().day
# 명단 읽어오기, 인덱스 삭제
df = pd.read_csv("Day 032/miniproject/birthdays.csv", index_col=None)
# 명단에서 생일이 오늘인 사람 추출
today_birth = df.loc[(df.month == day_of_month) & (df.day == day_of_date)]
# 중요! records를 사용해야 dict처럼 바뀜
today_birth = today_birth.to_dict('records')
# 생일이 여러명일 수 있으므로 for문으로 추출
for i in today_birth:
text = select_letter(i['name'])
send_email(i['name'], text)
예쁘지 않은 코드는 추후 정비하는 것으로 하고, 우선 코드를 하나씩 뜯어보겠습니다.
# 먼저 설정해야 할 변수들
day_of_month = dt.datetime.now().month
day_of_date = dt.datetime.now().day
# 명단 읽어오기, 인덱스 삭제
df = pd.read_csv("Day 032/miniproject/birthdays.csv", index_col=None)
여기서부터 시작됩니다. 우선 현재 날짜의 월, 일을 가져오고 csv에서 명단을 가져옵니다.
index_col=None을 넣으면 데이터프레임으로 변환했을 때 맨 앞 index들이 삭제됩니다.
다음 코드에서는 명단에서 생일인 사람을 추출하고, dict으로 바꾼 다음 메인 단계인 편지지를 선택하고 이메일을 보냅니다.
# 명단에서 생일이 오늘인 사람 추출
today_birth = df.loc[(df.month == day_of_month) & (df.day == day_of_date)]
# 중요! records를 사용해야 dict처럼 바뀜
today_birth = today_birth.to_dict('records')
# 생일이 여러명일 수 있으므로 for문으로 추출
for i in today_birth:
text = select_letter(i['name'])
send_email(i['name'], text)
to_dict 인자에 records을 넣으면 우리가 원하는 딕셔너리 형으로 바뀝니다. 링크를 참조해 주세요.
def select_letter(name):
rand = randint(1, 3)
with open(f"Day 032/miniproject/letter_templates/letter_{rand}.txt", "r") as file:
text = file.readlines()
# [NAME]을 name으로 변경
text[0] = text[0].replace("[NAME]", name)
# 처음에 text로 했다가 오류나서 join 사용
return ''.join(text)
우선 letter_1, 2, 3 중에 편지지를 선택해야 하기 때문에 랜덤 함수를 사용해 하나를 골라줍니다. 이 편지지를 읽어 text로 저장한 다음, 편지지의 이름을 바꿔주기 위해 text[0] = text[0].replace("[NAME]", name)
코드를 추가해줍니다.
여기서 text는 리스트 형태로, ['Dear [NAME]',\n, 'Hello!' ...]
형식으로 되어있기 때문에 문자열로 바꾸는 join
함수를 사용해 넘겨주어야 합니다.
def send_email(name, text):
with smtplib.SMTP("smtp.gmail.com") as connection:
connection = smtplib.SMTP("smtp.gmail.com")
connection.starttls()
connection.login(user=my_email, password=password)
connection.sendmail(
from_addr=my_email,
to_addrs="your_email",
msg=f"Subject:To {name}!\n\n{text}"
)
이 부분은 이전 포스팅부터 계속 복붙 형식입니다.
결과물
미니 프로젝트라고 하기도 민망한 초초초초미니 프로젝트지만, 하나를 또 만들었다는 것에 의의를 두면서.. 여기까지 하겠습니다.
어려웠던 점?
아무래도 데이터프레임을 다루지 않은 지 너무 오래 지나 메소드들을 다 까먹은 점..? today_birth = df.loc[(df.month == day_of_month) & (df.day == day_of_date)]
부분이나 records
를 활용하는 부분이나 text에서 NAME이 바뀌지 않아 살짝 구글링의 힘을 빌린 것 같습니다.
'◎ Python > Udemy Python' 카테고리의 다른 글
Day 038 - 구글 시트에 운동 기록 (1) | 2024.03.08 |
---|---|
Day 037 - 습관 추적기 프로젝트 (0) | 2024.03.08 |
Day 036 - 주식시장 알림 프로젝트 (1) | 2024.03.08 |
Day 033 - API 활용 (1) | 2024.03.08 |
Day 032 - SMTP와 Datetime 활용 (0) | 2024.03.08 |
자기계발 블로그