https://www.codeit.kr/topics/programming-preview
프로그래밍 프리뷰 - 강의 | 코드잇
일단 코딩 공부는 시작했지만, 공부하고 있는 내용이 어디서 어떻게 쓰일지 잘 모르겠나요? 실제 코드와 완성된 결과물을 구경하면서, 코딩으로 무엇을 할 수 있는지 함께 확인해 봅시다. 따로
www.codeit.kr
프로그래밍을 배우는 사람들이 많아졌다. 개발자가 아니더라도 주변을 둘러보면 프로그래밍을 배우고자 하는 사람들이 점점 늘어나고 있다. 하지만 처음 코딩을 배울 때는 "내가 이걸 왜 하고 있지?"라는 질문을 던지게 되는 순간이 오기 마련이다. 주로 첫 단계에서 배우는 'Hello, World!' 출력이나 단순한 수학 연산, 별 찍기 같은 내용은 실제로 무언가를 만들고 싶어 하는 사람들에게는 지루하게 느껴질 수 있다.
프로그래밍을 배우는 목표는 사람마다 다를 수 있다. 개발자가 되려는 사람도 있을 것이고, 본인의 업무 효율을 높이기 위해 배우려는 사람도 있을 것이다. 혹은 아이디어를 현실로 구현해 창업을 꿈꾸는 사람도 있을 것이다. 하지만 많은 경우 막연한 생각으로 공부를 시작하다 보니, 자신이 배우는 내용이 실제로 어떤 일을 할 수 있게 해줄지 와닿지 않아서 어려움을 겪는다.
이 글에서는 프로그래밍을 통해 실제로 무엇을 할 수 있는지, 간단한 예시를 통해 알아보고자 한다. 부담 없이 편하게 읽으면서 프로그래밍으로 가능한 일들을 상상해 보고, 필요한 부분에서 영감을 얻어보자.
1. 이메일 자동 발송하기
단순하지만 시간이 많이 소요되는 업무 중 하나는 대량의 이메일을 발송하는 것이다. 42명에게 각각 다른 이름을 포함한 이메일을 보내야 한다면, 수작업으로는 너무나 번거롭고 시간이 걸린다. 이럴 때 파이썬의 판다스(Pandas) 라이브러리와 이메일 모듈을 활용해 CSV 파일에 저장된 연락처 정보를 불러와 자동으로 이메일을 보낼 수 있다. 이를 통해 반복적인 작업을 컴퓨터에 맡기고, 더 중요한 일에 집중할 수 있다.
import yagmail
email = "xxxxxx"
name = "기쁨"
subject = f'{name}님 수료를 축하해요!'
body = f'{name}님 본문'
yag = yagmail.SMTP(
user="xxxxxx",
password="xxxxxx"
)
yag.send(
to=email,
subject=subject,
contents=body,
)
import pandas as pd
import yagmail
from time import sleep
yag = yagmail.SMTP(
user="xxxxxx",
password="xxxxxx"
)
contacts_df = pd.read_csv('./contacts.csv')
print(contacts_df.head())
for index, contact in contacts_df.iterrows():
name = contact["Given Name"]
email = contact["E-mail 1 - Value"]
subject = f'{name}님 수료를 축하드려요!'
body = (
f'{name}님 안녕하세요.\n'
f'캠프 매니저 김우주입니다.\n'
f'\n'
f'코딩 첫걸음 캠프 수료 축하드려요!\n'
f'수료증은 다음 주 중에 우편으로 발송될 예정입니다 :)\n'
f'\n'
f'좋은 하루되세요.\n'
f'감사합니다.\n'
f'\n'
f'김우주 드림\n'
)
yag.send(
to=email,
subject=subject,
contents=body,
)
print(f'{name}님 전송 완료')
sleep(30)
2. 이력서 자동 분류하기
300개의 이력서를 각 팀의 채용 담당자에게 전달하기 위해 포지션별로 분류해야 한다면 어떻게 할까? 수동으로 파일을 옮기는 것은 비효율적이고 시간 낭비다. 이럴 때 파이썬을 사용하면 파일명을 기준으로 자동으로 폴더를 생성하고, 파일을 정리할 수 있다. 이렇게 하면 반복적인 업무를 자동화하여 효율성을 높일 수 있다.
import os
from shutil import copy
for root, dirs, files in os.walk("./data"):
for file in files:
src = os.path.join(root, file)
file, ext = file.split(".")
name, position = file.split("__")
dest_path = f"./data/{position}"
if not os.path.exists(dest_path):
os.makedirs(dest_path)
dest = f"{dest_path}/{name}.{ext}"
# copy(src, dest)
3. 예매 자동화 만들기
많은 작업이나 빠른 클릭이 요구될 때, 프로그래밍을 활용해볼 수 있다. 파이썬의 셀레니움(Selenium) 라이브러리를 사용하면 웹 브라우저를 자동으로 제어하여 특정 시간에 필요한 과정을 자동화할 수 있다. 이를 통해 1초도 안 되는 시간 안에 많은 업무 수행이 가능해진다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
options = webdriver.ChromeOptions()
options.binary_location = "./chromedriver"
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
# 티켓 예매 페이지
driver.get('http://localhost:5500/0101_web_automation/ticket-site/index.html')
date_element = driver.find_element(
By.CSS_SELECTOR, '[data-date="2025-08-18 (월)"]')
date_element.click()
time_element = driver.find_element(By.CSS_SELECTOR, '[data-time="19:30"]')
time_element.click()
submit_element = driver.find_element(By.CSS_SELECTOR, '#book-button')
submit_element.click()
# 로그인 페이지
wait.until(EC.url_matches('/login'))
username_element = driver.find_element(By.CSS_SELECTOR, '#username')
password_element = driver.find_element(By.CSS_SELECTOR, '#password')
username_element.send_keys('codeit')
password_element.send_keys('love2learn')
submit_element2 = driver.find_element(By.CSS_SELECTOR, '[type="submit"]')
submit_element2.click()
# 좌석 선택 페이지
wait.until(EC.url_matches('/seat'))
seat_element = driver.find_element(By.CSS_SELECTOR, '[data-seat="r"]')
seat_element.click()
submit_element3 = driver.find_element(By.CSS_SELECTOR, '#book-button')
submit_element3.click()
# 예매 완료 페이지
sleep(5)
4. 그래프를 통한 대량 데이터 분석하기
데이터가 너무 커서 엑셀로 다루기 어려울 때는 파이썬을 사용해 보자. 파이썬의 판다스(Pandas)와 맷플롯립(Matplotlib) 라이브러리를 활용하면 대량의 데이터를 편리하게 조작하고 분석할 수 있다. 예를 들어 신용카드 소비 데이터를 분석하여 월별 소비 패턴을 그래프로 시각화하고, 연령대별 소비 패턴의 차이를 확인할 수 있다. 이를 통해 엑셀로는 처리하기 어려운 대량의 데이터를 효율적으로 분석하고 인사이트를 도출할 수 있다.
# In[ ]:
# 필요한 모듈을 준비하고, 몇가지 세팅을 해 주겠다
# 데이터를 다룰 때 쓰는 pandas와 그래프를 그릴 때 쓰는 seaborn이랑 matplotlib이라는 걸 불러오겠다
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.rc('font', family='AppleGothic')
plt.rcParams['figure.figsize'] = (10, 5)
# In[ ]:
# CSV 파일 불러와서 확인
jeju_df = pd.read_csv('data/jeju_card.csv')
jeju_df.head()
# In[ ]:
# 연월별 이용금액 묶어서 보기
groupby_ym = jeju_df.groupby('연월').sum(numeric_only=True).reset_index()
groupby_ym
# In[ ]:
sns.barplot(data=groupby_ym, x='연월', y='이용금액')
# In[ ]:
# 그래프로 표현
# 코드가 좀 복잡해 보일 수 있는데, 사실 가장 위에 있는 코드 한 줄이 실제로 그래프를 그리는 데 사용되는 코드고,
# 나머지 코드는 그래프에 제목을 넣는다던지, 여기 축에 있는 값들의 표기 방법을 바꾼다던지... 그래프를 꾸미는 데 쓰는 코드다
sns.barplot(data=groupby_ym, x='연월', y='이용금액')
plt.xticks(rotation=90)
plt.title('연월별 카드 이용 금액')
plt.gca().yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'{x/100000000:,.0f}'))
plt.ylabel('이용금액(억)')
# - 그래프 해석 간단히 해보기
# - 전체적으로 날씨가 좋은 4-5월이랑 여름 휴가철 7-8월에 카드 이용금액도 늘어나고, 2월에는 이용금액이 줄어듦
# - 연령대별로 차이가 있는지도 한번 확인해보자!
# In[ ]:
# 데이터를 연령대별, 연월별로 묶어주기
# 다양한 방식으로 데이터를 묶어서 요약할 수 있다!
# 역시나 복잡 -> 그래프로 그려서 보자!
groupby_age_ym = jeju_df.groupby(['연령대', '연월']).sum(numeric_only=True).reset_index()
groupby_age_ym
# In[ ]:
# 이렇게 연령대별로 그래프를 하나씩 그려서 볼 수도 있다
# 빠르게 훑어보자
# 20대는 7~8월 휴가철에 집중됨
# 20대 미만은 20대랑 다르게 5월, 10월에 집중
# 50대는 2월에 좀 줄어드는 거 말고는, 다른 연령대에 비해 연월별 변동이 거의 없는 편
# 이렇게 같은 데이터라도 보는 각도에 따라 새로운 발견을 할 수도 있다!
for age in groupby_age_ym['연령대'].unique():
data = groupby_age_ym[groupby_age_ym['연령대'] == age]
sns.barplot(data=data, x='연월', y='이용금액')
plt.title(f'{age} 연월별 카드 이용 금액')
plt.xticks(rotation=90)
plt.gca().yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'{x/100000000:,.0f}'))
plt.ylabel('이용금액(억)')
plt.show()
# In[ ]:
# 이런 막대그래프 말고, 다른 형태의 그래프를 그릴 수도 있다
# 일단 이번에는 연령대 값을 기준으로 데이터를 묶어 보겠다
# 각 연령대가 전체 이용금액에서 어느 정도 비중을 차지하는지 보고 싶다고 하자 -> 이렇게 복잡한 숫자만 봐서는 바로 머릿속에 그림이 그려지지 않는다
# 이것도 그래프로 그려보자
groupby_age = jeju_df.groupby('연령대').sum(numeric_only=True).sort_values(by="이용금액", ascending=False).reset_index()
groupby_age
# In[ ]:
# 이렇게 연령대별 카드 이용금액의 비중을 한눈에 볼 수 있는 그래프를 그릴 수 있다
# 이건 파이 조각들로 이루어진 것처럼 생겼다고 해서, 파이차트라고 부른다
# 이번에 그린 파이차트랑 막대그래프 말고도 다양한 그래프를 몇줄의 코드로 그릴 수 있다
groupby_age.plot(kind='pie', y='이용금액', labels=groupby_age['연령대'], autopct='%.1f%%')
plt.title('연령대별 카드 이용 금액 비중')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
# In[ ]:
groupby_sector = jeju_df.groupby('업종명').sum(numeric_only=True).sort_values(by="이용금액", ascending=False).reset_index()
groupby_sector.plot(kind='pie', y='이용금액', labels=groupby_sector['업종명'], autopct='%.1f%%')
plt.title('업종별 카드 이용 금액 비중')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
5. SQL을 활용한 데이터 쿼리하기
데이터베이스에 저장된 데이터를 직접 조회하고 분석하기 위해서는 SQL을 사용할 수 있다. SQL은 데이터베이스와 상호작용할 수 있는 언어로, 데이터를 조회하고 수정하며 분석할 수 있다. 회사에서 필요한 데이터를 빠르게 조회하고 인사이트를 얻기 위해 SQL을 배운다면, 개발자나 데이터 분석가에게 매번 요청하지 않고도 필요한 데이터를 스스로 처리할 수 있게 된다. 이를 통해 데이터에 기반한 의사결정을 더 효과적으로 내릴 수 있다.
6. 머신러닝으로 손글씨 인식하기
머신러닝을 활용하면 손글씨 숫자를 인식하는 프로그램을 만들 수 있다. 파이썬의 사이킷런(scikit-learn) 라이브러리를 사용하여 손글씨 이미지를 학습시켜 모델을 만든 후, 새로운 이미지를 입력받아 어떤 숫자인지 예측할 수 있다. 이와 같은 머신러닝 모델은 간단한 이미지 분류부터 복잡한 데이터 예측까지 다양한 문제를 해결하는 데 활용될 수 있다.
7. 넷플릭스 클론 코딩
웹 개발에 관심이 있다면, 넷플릭스 같은 사이트를 클론 코딩해 보는 것도 좋은 방법이다. 웹페이지의 구조를 분석하고 HTML, CSS, JavaScript를 사용하여 페이지를 구현해볼 수 있다. 개발자 도구를 활용해 웹사이트의 소스 코드를 분석하고, 필요한 리소스를 가져와서 비슷한 디자인과 기능을 구현할 수 있다. 클론 코딩을 통해 웹 개발의 기본적인 원리를 배우고, 실제로 동작하는 웹사이트를 만들어 볼 수 있다. 이를 통해 웹 개발 기술을 보다 실전적으로 익힐 수 있다.
8. 자바스크립트로 틱택토 게임 만들기
간단한 게임을 통해 자바스크립트를 익혀보는 것도 좋은 방법이다. 틱택토 같은 게임을 만들어 보면 HTML, CSS, JavaScript를 사용하여 화면에 게임판을 그리고, 사용자와 상호작용할 수 있는 기능을 구현할 수 있다. 이러한 프로젝트를 통해 자바스크립트의 기본적인 동작 원리를 이해하고, 웹사이트에 생동감을 불어넣는 방법을 배울 수 있다.
<!DOCTYPE html>
<html>
<head>
<title>Tic Tac Toe</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@500;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<h1>Tic Tac Toe</h1>
</header>
<main>
<div class="scoreboard">
<div id="player1">
<div class="score-container">
<span id="player1-score">0</span>
<div class="player-name">
Player
<img class="player-icon" src="assets/o.svg" alt="Player 1" />
</div>
</div>
</div>
<div class="versus">:</div>
<div id="player2">
<div class="score-container">
<span id="player2-score">0</span>
<div class="player-name">
Player
<img class="player-icon" src="assets/x.svg" alt="Player 2" />
</div>
</div>
</div>
</div>
<div class="turn">
<span class="turn-icon player1"></span>
<span id="turn-message">Turn</span>
</div>
<div class="gameboard">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
html {
font-family: Poppins, sans-serif;
}
body {
margin: 0;
display: flex;
min-height: 100vh;
background: #d2bea7;
flex-direction: column;
justify-content: center;
}
header {
text-align: center;
}
h1 {
margin: 9px 0;
color: #6a4d4d;
font-size: 34px;
font-weight: 800;
letter-spacing: -1.02px;
}
main {
margin: 0 auto;
overflow: hidden;
width: fit-content;
border-radius: 20px;
background: #efe1d1;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1);
}
.scoreboard {
gap: 8px;
display: flex;
font-size: 32px;
padding: 50px 87px;
background: #e1d1be;
align-items: center;
justify-content: center;
}
.score-container {
color: #806464;
line-height: 1;
font-size: 28px;
min-width: 70px;
font-weight: 500;
padding: 21px 25px;
position: relative;
text-align: center;
border-radius: 10px;
background: #efe1d1;
box-shadow: 1px 1px 3px 0px #987c7c inset;
}
.versus {
color: #987c7c;
}
.player-name {
left: -50%;
color: #987c7c;
font-size: 14px;
font-weight: 700;
position: absolute;
top: calc(100% + 8px);
letter-spacing: -0.14px;
transform: translateX(50%);
}
.player-icon {
width: 15px;
height: 15px;
margin-left: 5px;
vertical-align: middle;
}
.turn {
gap: 10px;
display: flex;
color: #987c7c;
font-size: 24px;
min-width: 160px;
font-weight: 700;
width: fit-content;
padding: 10px 30px;
border-radius: 10px;
align-items: center;
margin: 25px auto 0;
justify-content: center;
letter-spacing: -0.24px;
border: 2px solid #e1d0be;
}
.turn-icon {
width: 25px;
height: 25px;
display: none;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.turn-icon.player1,
.turn-icon.player2 {
display: inline-block;
}
.turn-icon.player1 {
background-image: url('assets/o.svg');
}
.turn-icon.player2 {
background-image: url('assets/x.svg');
}
.gameboard {
gap: 5px;
display: grid;
padding: 20px;
width: fit-content;
grid-template:
repeat(3, 110px) /
repeat(3, 110px);
}
.cell {
cursor: pointer;
border-radius: 5px;
background-color: #fef2e6;
background-size: 50px 50px;
background-position: center;
background-repeat: no-repeat;
}
.cell.player1 {
background-image: url('assets/o.svg');
}
.cell.player2 {
background-image: url('assets/x.svg');
}
let currentPlayer = 'player1';
let score = {
player1: 0,
player2: 0,
};
let gameboard = [null, null, null, null, null, null, null, null, null];
let isGameEnd = false;
let winner = null;
document.querySelectorAll('.cell').forEach((el, idx) => {
el.addEventListener('click', () => handleCellClick(idx));
});
function handleCellClick(idx) {
if (isGameEnd) {
gameboard = [null, null, null, null, null, null, null, null, null];
isGameEnd = false;
winner = null;
currentPlayer = currentPlayer === 'player1' ? 'player2' : 'player1';
} else {
if (gameboard[idx] !== null) return;
gameboard[idx] = currentPlayer;
checkGameEnd();
if (!isGameEnd) {
currentPlayer = currentPlayer === 'player1' ? 'player2' : 'player1';
}
}
render();
}
function render() {
document.getElementById('player1-score').textContent = score.player1;
document.getElementById('player2-score').textContent = score.player2;
document.querySelectorAll('.cell').forEach((cellEl, idx) => {
cellEl.className = `cell ${gameboard[idx]}`;
});
const turnIcon = document.querySelector('.turn-icon');
const turnMessage = document.getElementById('turn-message');
if (!isGameEnd) {
turnIcon.classList.toggle('player1', currentPlayer === 'player1');
turnIcon.classList.toggle('player2', currentPlayer === 'player2');
turnMessage.textContent = 'Turn';
} else if (winner) {
turnIcon.classList.toggle('player1', currentPlayer === 'player1');
turnIcon.classList.toggle('player2', currentPlayer === 'player2');
turnMessage.textContent = 'Win';
} else {
turnIcon.classList.toggle('player1', false);
turnIcon.classList.toggle('player2', false);
turnMessage.textContent = 'Draw';
}
}
const conditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
function checkGameEnd() {
const currentPlayerWon = conditions.some((condition) =>
condition.every((idx) => gameboard[idx] === currentPlayer)
);
if (currentPlayerWon) {
score[currentPlayer] += 1;
isGameEnd = true;
winner = currentPlayer;
}
if (gameboard.every((cell) => cell !== null)) {
isGameEnd = true;
}
}
9. 디스코드 ChatGPT 봇 만들기
디스코드(Discord) 채널에 자동으로 대답하는 ChatGPT 봇을 만들어 볼 수 있다. 파이썬의 디스코드 API와 오픈AI의 GPT API를 활용해 간단한 챗봇을 개발할 수 있다. 디스코드 봇을 통해 사용자가 채팅 창에 입력한 내용에 대해 GPT-3가 자동으로 응답하도록 만들 수 있으며, 이를 통해 재미있고 유용한 커뮤니티 도구를 개발할 수 있다. 이 프로젝트는 파이썬 기초와 API 사용법을 익히는 데 도움이 되며, 실제로 사용자와 상호작용하는 프로그램을 만들 수 있는 좋은 경험이 된다.
import openai
openai.api_key = 'XXXXXXX'
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "당신의 이름은 지피티입니다. 디스코드 채팅방에서 코딩을 도와주는 봇입니다."},
{"role": "user", "content": "파이썬에서 별표를 삼각형으로 찍는 방법은?"}
]
)
print(response.choices[0].message.content)
import discord
import openai
openai.api_key = 'XXXXXXX'
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print(f'{client.user}로 로그인 완료')
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('지피티야'):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "당신의 이름은 지피티입니다. 디스코드 채팅방에서 코딩을 도와주는 봇입니다."},
{"role": "user", "content": message.content}
]
)
reply = response.choices[0].message.content
await message.channel.send(reply)
client.run('xxxxx')
프로그래밍의 가능성
위의 예시들에서 보았듯이, 프로그래밍은 단순한 학습을 넘어 실제로 업무와 일상생활에서 큰 도움을 줄 수 있다. 반복적이고 지루한 작업을 자동화하고, 사람의 실수를 줄이며, 효율성을 극대화할 수 있다. 개발자가 아니더라도 프로그래밍을 배우면 업무에서 더 나은 성과를 내거나 자신의 아이디어를 현실로 구현할 수 있는 강력한 도구를 갖게 되는 것이다.
코딩을 배우면서 처음에는 기초 개념들이 지루하게 느껴질 수 있다. 하지만 이러한 기본기를 쌓으면 이후에 훨씬 더 흥미롭고 창의적인 작업들을 할 수 있게 된다. 프로그래밍을 통해 자신이 해보고 싶은 것들을 상상해 보고, 이를 실제로 구현할 수 있는 능력을 기르길 바란다.
'일상 > 컴퓨터' 카테고리의 다른 글
[GitHub] Git 깃허브 공개 저장소 비공개로 복제/포크 (0) | 2024.10.13 |
---|---|
[JavaScript 프로그래밍] 컴퓨터 사이언스의 기본 (3) | 2024.10.11 |
[JavaScript 프로그래밍] 프로그래밍이란? (5) | 2024.10.10 |
[JavaScript 프로그래밍] 함수 (2) | 2024.10.10 |
[Tableau 태블로] 스토리 기능을 활용한 데이터 스토리텔링 (0) | 2024.10.09 |