본문 바로가기

공부 일지 #7 | mini-project; 가계부 만들기

@studying:)2025. 7. 22. 18:00

학습 날짜: 2025.07.22 ~ 2025.07.23


오늘부터 파이썬을 함께 공부할 옆사람이 생겼다. 

서로 모르는 부분은 도와주고, 함께 고민하면서 문제를 해결하는 재미가 있었다.

 

첫 미니 프로젝트로 가계부 프로그램을 만들라는 숙제가 주어졌다. 소소하지만 실생활과 연결된 주제라 그런지 더 흥미롭게 다가왔다.

 

함께 설계하고 구현하는 과정 중, 나는 아래와 같은 함수를 만들었다:

1. 입력 함수

from collections import OrderedDict

def input_ac():
  date=input("날짜를 입력하세요 ex) 25-07-14: ")
  time= input("시간을 입력하세요 ex) 06: ")
  income=int(input("수입을 입력하세요: "))
  expense=int(input("지출을 입력하세요: "))
  detail=input("내역을 입력하세요: ")

  date = date+"-"+time

  temp_dict = {
            "income": income,
            "expense" : expense,
            "detail": detail,
            "remain" : 0
            }

  return date, temp_dict

 

2. 잔액 입력

# 잔액 입력
def input_remain(datas):
  datas = OrderedDict(sorted(datas.items(), key = lambda t : t[0]))
  keyList = list(datas.keys())

  for i in range(len(datas)):
    if i == 0:
      remain = datas[keyList[0]]['income'] - datas[keyList[0]]['expense']
      datas[keyList[0]]['remain'] = remain
    else:
      remain = datas[keyList[i-1]]['remain'] + datas[keyList[i]]['income'] - datas[keyList[i]]['expense']
      datas[keyList[i]]['remain'] = remain

  return datas

 

3. 잔액 조회

# 잔액조회
def func_remain(datas, month):
  temp = datas.keys()

  sum_remain = 0

  for i in temp:
    if i[3:5] == month:
      sum_remain += datas[i]["remain"]

  avg_remain = sum_remain//30
  print(f"{month}월의 총 잔액은 {sum_remain}원 입니다.")
  print(f"{month}월의 평균 잔액은 {avg_remain}원 입니다.")

 

4. 그래프 

# 그래프
import matplotlib.pyplot as plt
import pandas as pd

def graphs(datas, month):
    x = list()
    y1 = list()
    y2 = list()
    y3 = list()

    for i in datas:
      if int(i[3:5]) <= int(month):
        x.append(i[3:5])
        y1.append(datas[i]['income'])
        y2.append(datas[i]['expense'])
        y3.append(datas[i]['remain'])

    plt.figure(figsize=(15, 5))

    # 수익 추이
    ax1=plt.subplot(131)
    df1 = pd.DataFrame({'x': x, 'y': y1})
    grouped = df1.groupby('x')['y'].sum()
    ax1.plot(grouped.index, grouped.values, color = "blue")
    plt.title("income_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    # 지출 추이
    ax2=plt.subplot(132)
    df2 = pd.DataFrame({'x': x, 'y': y2})
    grouped = df2.groupby('x')['y'].sum()
    ax2.plot(grouped.index, grouped.values, color = "red")
    plt.title("expense_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    # 잔액 추이
    ax3=plt.subplot(133)
    df3 = pd.DataFrame({'x': x, 'y': y3})
    grouped = df3.groupby('x')['y'].sum()
    ax3.plot(grouped.index, grouped.values,color = "green")
    plt.title("remain_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    plt.subplots_adjust(wspace = 0.3) # 간격 설정

    plt.show()

 

5. 실행 코드

while True:
  try:
    account_book
  except NameError:
    account_book = dict()

  menu = int(input("1. 가계부 입력, 2. 조회, 3. 종료 ex) 1: "))

  if menu == 1:
    date, temp_dict = input_ac()
    account_book[date] = temp_dict
    account_book = input_remain(account_book)
  elif menu == 2:
    check = int(input("1. 수익, 2. 지출, 3. 잔액, 4. 추이: "))
    month = input("몇 월까지 조회할지 입력하세요. ex) 07: ")
    if check == 1:
      pass
    elif check == 2:
      pass
    elif check == 3:
      remain(account_book, month)
    elif check == 4:
      graphs(account_book, month)
    else:
      print("잘못 입력하셨습니다.")
  elif menu == 3:
    break
  else:
      print("잘못 입력하셨습니다.")

혼자서 나머지 함수들도 추가해보고, PyCharm을 활용해 패키지 구조로 정리하고 실행 코드까지 작성해보았다. 패키지를 처음 구성해보는 거라 중간에 막히는 부분도 있었지만, 하나씩 해결해가는 과정이 재미있었다.

 

1. ab_pkg, 함수 모음(all) 파일 생성

from collections import OrderedDict
import matplotlib.pyplot as plt
import pandas as pd

# 가계부 입력
def input_ac(datas):
  date=input("날짜를 입력하세요 ex) 25-07-14: ")
  time= input("시간을 입력하세요 ex) 06: ")
  income=int(input("수입을 입력하세요: "))
  expense=int(input("지출을 입력하세요: "))
  detail=input("내역을 입력하세요: ")

  date = date+"-"+time

  temp_dict = {
            "income": income,
            "expense" : expense,
            "detail": detail,
            "remain" : 0
            }

  datas[date] = temp_dict

  return datas

# 잔액 입력
def input_remain(datas):
  datas = OrderedDict(sorted(datas.items(), key = lambda t : t[0]))
  keyList = list(datas.keys())

  for i in range(len(datas)):
    if i == 0:
      remain = datas[keyList[0]]['income'] - datas[keyList[0]]['expense']
      datas[keyList[0]]['remain'] = remain
    else:
      remain = datas[keyList[i-1]]['remain'] + datas[keyList[i]]['income'] - datas[keyList[i]]['expense']
      datas[keyList[i]]['remain'] = remain

  return datas

# 수입조회
def func_income(datas, month):
  temp = datas.keys()

  sum_income = 0

  for i in temp:
    if i[3:5] == month:
      sum_income += datas[i]["income"]


  avg_income = sum_income//30
  print(f"{month}월의 총 수입은 {sum_income}원 입니다.")
  print(f"{month}월의 평균 수입은 {avg_income}원 입니다.")

# 지출조회
def func_expense(datas, month):
  temp = datas.keys()

  sum_expense = 0

  for i in temp:
    if i[3:5] == month:
      sum_expense += datas[i]["expense"]


  avg_expense = sum_expense//30
  print(f"{month}월의 총 지출은 {sum_expense}원 입니다.")
  print(f"{month}월의 평균 지출은 {avg_expense}원 입니다.")

# 잔액조회
def func_remain(datas, month):
  temp = datas.keys()

  sum_remain = 0

  for i in temp:
    if i[3:5] == month:
      sum_remain += datas[i]["remain"]


  avg_remain = sum_remain//30
  print(f"{month}월의 총 잔액은 {sum_remain}원 입니다.")
  print(f"{month}월의 평균 잔액은 {avg_remain}원 입니다.")

# 그래프
def graphs(datas, month):
    x = list()
    y1 = list()
    y2 = list()
    y3 = list()

    for i in datas:
      if int(i[3:5]) <= int(month):
        x.append(i[3:5])
        y1.append(datas[i]['income'])
        y2.append(datas[i]['expense'])
        y3.append(datas[i]['remain'])

    plt.figure(figsize=(15, 5))

    # 수익 추이
    ax1=plt.subplot(131)
    df1 = pd.DataFrame({'x': x, 'y': y1})
    grouped = df1.groupby('x')['y'].sum()
    ax1.plot(grouped.index, grouped.values, color = "blue")
    plt.title("income_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    # 지출 추이
    ax2=plt.subplot(132)
    df2 = pd.DataFrame({'x': x, 'y': y2})
    grouped = df2.groupby('x')['y'].sum()
    ax2.plot(grouped.index, grouped.values, color = "red")
    plt.title("expense_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    # 잔액 추이
    ax3=plt.subplot(133)
    df3 = pd.DataFrame({'x': x, 'y': y3})
    grouped = df3.groupby('x')['y'].sum()
    ax3.plot(grouped.index, grouped.values,color = "green")
    plt.title("remain_graph")
    plt.xlabel("month")
    plt.ylabel("cost")

    plt.subplots_adjust(wspace = 0.3) # 간격 설정

    plt.show()

2. 실행 파일

import ab_pkg.all as al

if __name__ == "__main__":
  while True:
    try:
      account_book
    except NameError:
      account_book = dict()

    menu = int(input("1. 가계부 입력, 2. 조회, 3. 종료 ex) 1: "))

    if menu == 1:
      account_book = al.input_ac(account_book)
      account_book = al.input_remain(account_book)
    elif menu == 2:
      check = int(input("1. 수익, 2. 지출, 3. 잔액, 4. 추이: "))
      month = input("몇 월까지 조회할지 입력하세요. ex) 07: ")
      if check == 1:
        al.func_income(account_book, month)
      elif check == 2:
        al.func_expense(account_book, month)
      elif check == 3:
        al.func_remain(account_book, month)
      elif check == 4:
        al.graphs(account_book, month)
      else:
        print("잘못 입력하셨습니다.")
    elif menu == 3:
      break
    else:
        print("잘못 입력하셨습니다.")
studying:)
@studying:) :: what i studied

studying:) 님의 학습 여정을 기록하는 블로그입니다.

목차