728x90
반응형

주제 : 고객 정보 관리 시스템
진행인원 : 1명
 

1. 주요 내용
지난 실습에 작성한 기존의 메인 로직에 데이터 저장 기능 추가하기
 
2. 요구사항
- 'S' 메뉴 > 고객 정보를 파일로 저장하는 기능 추가
- 프로그램 실행시 자동으로 저장된 고객정보 읽어와 복원
- 프로그램 종료시 자동으로 고객 정보 파일로 저장
 

이전 실습코드에 따로 추가한 내용

- 함수를 따로 작성하여 import 해 오는 방법을 사용해  더욱 간단한 코드로 변경한 상태이다. 이렇게 함수를 따로 작성하면 오류가 어디서 나는지 바로 알 수 있어서 수정하는데 유용하다.

from cust.common import print_menu
from cust.insert.do_insert import do_I
from cust.delete.do_delete import do_D
from cust.update.do_update import do_U
from cust.read.do_n import do_N
from cust.read.do_p import do_P
from cust.read.do_c import do_C

# Main
def main():
    customers = list()
    index = -1

    while True:
        menu = print_menu()
        if menu == 'I':
            index = do_I(customers, index)
            # print('index : ', index)
            # print('customers : ', customers)
        elif menu == 'P':
            do_P(customers, index)
        elif menu == 'C':
            do_C(customers, index)
        elif menu == 'N':
            do_N(customers, index)
        elif menu == 'U':
            do_U(customers, index)
        elif menu == 'D':
            index = do_D(customers, index)
        elif menu == 'Q':
            print('안녕히가세요~')
            break
        else:
            print('잘못 입력하셨습니다. 다시 입력 해주세요')
            
if __name__ == '__main__':
    main()

따로 작성해둔 함수들을 import 해오는 방식을 쓴다.

 
- do_insert.py 코드

     > lambda 함수 사용

from cust.common import chk_input_data

def do_I(customers, index):
    print('고객정보 입력')
    customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
    customer['name'] = chk_input_data('이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False) # 조건식이 참일 때 True리턴 거짓일때 False리턴
    customer['gender'] = chk_input_data('성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M','F') else False)
    customer['email'] = chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if '@' in x else False)
    customer['year'] = chk_input_data('출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
    customers.append(customer)
    index = len(customers) - 1
    
    return index

 
요구사항을 반영해 적어 본 코드
 

- do_save.py 코드
     > pickle 라이브러리 사용

import pickle

def do_S(customers, index):
    print('고객 정보 저장')
    with open('cust/custInfo.pickle', 'wb') as info:
        pickle.dump(customers, info)

 
※ pickle 설명
https://mzero.tistory.com/26

 

[Digital Boot] 파이썬 수업 5일차

range() - range()로 반복 횟수를 전달하면 range()가 자동으로 순차적인 정수들을 생성해준다. - range( start = 0, stop, strp = 1 ) > start : 시작값 > stop : 종료값이지만 stop은 포함되지 않는다. > step : 한번에

mzero.tistory.com

 
- do_s() 적용한 코드

import pickle
from cust.common import print_menu
from cust.insert.do_insert import do_I
from cust.delete.do_delete import do_D
from cust.update.do_update import do_U
from cust.save.do_save import do_S
from cust.read.do_n import do_N
from cust.read.do_p import do_P
from cust.read.do_c import do_C

# Main
def main():
    customers = list()
    index = -1

    with open('cust\\custInfo.pickle', 'rb') as info:
        a = pickle.load(info)
        customers.extend(a)
        print(customers)

    while True:
        menu = print_menu()
        if menu == 'I':
            index = do_I(customers, index)
            # print('index : ', index)
            # print('customers : ', customers)
            a.extend(customers)
            print(customers)
        elif menu == 'P':
            do_P(customers, index)
        elif menu == 'C':
            do_C(customers, index)
        elif menu == 'N':
            do_N(customers, index)
        elif menu == 'U':
            do_U(customers, index)
        elif menu == 'D':
            index = do_D(customers, index)
        elif menu == 'S':
            do_S(customers, index)
        elif menu == 'Q':
            do_S(customers, index)
            print('안녕히가세요~')
            break
        else:
            print('잘못 입력하셨습니다. 다시 입력 해주세요')

if __name__ == '__main__':
    main()
728x90
반응형
728x90
반응형

자료구조

자료들을 저장하는 여러 가지 구조들을 자료구조(Data Structure), 또는 데이터구조라 부른다.

시퀀스

- 요소(element)로 구성
- 요소 간에는 순서가 있다
- 시퀀스의 요소들은 번호가 붙여져 있다.
- 내장 시퀀스 (str, bytes, bytearrary, list, tuple, range)
- 동일한 연산을 지원
     > 인덱싱(indexing),  슬라이싱(slicing), 덧셈연산, 곱셈연산
- 내장함수 적용가능 : 시퀀스의 길이를 반환하는 len()함수, 최대값과 최소값을 찾는 max()와 min()함수
 

튜플 패킹과 언패킹

- 패킹
     t = ('apple', 'banana', 'grape')
- 언패킹
     (s1, s2, s3) = t
- 결과
      s1 = 'apple'     s2 = 'banana'     s3 = 'grape'
 

enumerate함수

- 순서가 있는 자료형(list, set, tuple, dictionary, string)을 입력으로 받았을 때, index와 값을 포함하여 리턴
- for문과 함께 자주 사용
- index와 값을 동시에 접근하면서 루프를 돌리고 싶을 때 사용

["apple", "banana", "grape"] enumerate( ) 사용(1, "apple")
(2, "banana")
(3, "grape")

 
Site Package  위치 확인하기

- Python에서 Site Packages가 설치되어 있는 경로를 출력하는 방법
- Terminal에서 다음 명령을 입력

python -m site --user-site

 
라이브러리

- 다른 사람들이 만들어 둔 함수들의 모음
- 자주 사용하는 기능을 쉽게 재사용할 수 있고 다른 사람과도 공유
- 표준 라이브러리 :  파이썬이 설치 될 때 같이 자동으로 설치 되는 라이브러리
- 외부 라이브러리 : 기본 외에 별도로 설치해서 사용하는 라이브러리
- 외부 라이브러리 설치 : pip install 라이브러리명, conda install 라이브러리명
- 사용법 : import 라이브러리명
- 현재 설치 되어있는 라이브러리 확인 : pip list
- Pandas : 파이썬의 데이터 분석 라이브러리
 
- 표준 라이브러리 날짜/ 시간 함수 정리 
https://mzero.tistory.com/28

[Python] 파이썬 표준 라이브러리 (날짜/시간) - datetime, timedelta, relativedelta

datetime() 현재 시간, 날짜를 가져온다. from datetime import datetime print(datetime.now()) timezone() timezone으로 설정한 기준의 시간과 날짜를 가져온다. from pytz import timezone print(datetime.now(timezone('UTC'))) datetime.no

mzero.tistory.com

 

728x90
반응형
728x90
반응형

datetime()

현재 시간, 날짜를 가져온다.

from datetime import datetime
print(datetime.now())

 

timezone()

timezone으로 설정한 기준의 시간과 날짜를 가져온다.

from pytz import timezone
print(datetime.now(timezone('UTC')))

 

datetime.now(timezone())으로 불러온 값을 변수에 할당한 뒤 필요한 값만 불러와서 사용 할 수 있다.

 

strftime()

datetime을 str으로 변환한다.

 

strptime()

str에서 datetime으로 변환한다.

 

timedelta()

두 날짜의 차이를 계산할 때 사용하는 함수로 원하는 기간(초, 분, 시간, 일, 주)을 더하거나 뺄 수 있다.

아래에서 보면 현재 날짜/시간에서 8일을 뺀 결과를 볼 수 있다.

 

relativedelta()

두 날짜의 차이를 계산할 때 사용하는 함수로  원하는 기간(초, 분, 시간, 일, 주, 월, 년)을 더하거나 뺄 수 있다.

아래에서 보면 현재 날찌/시간에서 2년을 더한 결과를 볼 수 있다.

728x90
반응형
728x90
반응형

주제 : 고객 정보 관리 시스템

진행 인원  : 2명

진행 방법 : 짝 프로그래밍

 

짝 프로그래밍

- 중간 지점에 하나의 컴퓨터를 둔다.

- 10분 간격으로 서로 옮겨 가면서 코드를 작성한다. 

- 네비게이터(navigator)가 전략을 제시하고 드라이버(driver)가 실제 코드를 작성한다.

 

1. 주요 내용

지난 실습에 작성한 기존의 메인 로직을 함수형으로 변형시켜 로직 자체를 더욱 간단하게 만들기

 

작성한 코드

def customI():
    global index
    print('고객정보 입력')
    customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
    customer['name'] = input('이름을 입력하세요 : ')
    customer['gender'] = get_gender()
    customer['email'] = get_email()
    customer['year'] = get_birth_year()
    print(customer)
    customers.append(customer)
    index = len(customers) -1
    print(customers)

def get_gender():
    while True:
        gender = input('성별 (M/F)를 입력하세요 : ').upper()
        if gender in ('M', 'F'):
            return gender
        else:
            print('잘못입력하셨습니다. 다시 입력해 주세요.')
def get_email():
    while True:
        email = input('이메일 주소를 입력하세요 : ')
        if '@' in email:
            return email
        else:
            print('"@"를 포함한 이메일 주소를 입력하세요.')
def get_birth_year():
    while True:
        year = input('출생년도 4자리 입력하세요 : ')
        if len(year) == 4 and year.isdigit():
            return year
        else:
            print('다시 입력해주세요.')
customers = []

def customP(index):
    print('이전 고객 정보 조회')
    if index <= 0:
        print('이전 고객 정보가 없습니다.')
        print(index)
    else:
        index -= 1
        print(f'{index + 1}번째 고객 정보 입니다.')
        print(customers[index])
    return index

def customC(index):
    print('현재 고객 정보 조회')
    if index >= -1:
        print(f'{index + 1}번째 고객 정보 입니다.')
        print(customers[index])
    else:
        print('입력된 정보가 없습니다. 정보 입력은 I를 선택하세요.')

def customN(index):
    print('다음 고객 정보 조회')
    if index > (len(customers) - 1) :
        print('다음 고객 정보가 없습니다.')
        print(index)
    else:
        index += 1
        print(f'{index + 1}번째 고객 정보 입니다.')
    return index

def customU(index):
    print('현재 고객 정보 수정')
    customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
    customer['name'] = input('이름을 입력하세요 : ')
    customer['gender'] = get_gender()
    customer['email'] = get_email()
    customer['year'] = get_birth_year()
    print(customer)
    customers[index] = customer

def customD():
    print(f'현재 고객 정보{customers[index]["name"]} 삭제')
    del customers[index]

def customQ():
    print('안녕히가세요~')

customers = list()
index = -1
while True:
    menu = input('''
        다음 중에서 하실 작업의 메뉴를 입력하세요.
        I - 고객 정보 입력
        P - 이전 고객 정보 조회
        C - 현재 고객 정보 조회
        N - 다음 고객 정보 조회
        U - 현재 고객 정보 수정
        D - 현재 고객 정보 삭제
        Q - 프로그램 종료
    ''').upper()

    if menu == 'I':
        customI()

    elif menu == 'P':
        customP(index)

    elif menu == 'C':
        customC(index)

    elif menu == 'N':
        customN(index)

    elif menu == 'U':
        customU(index)

    elif menu == 'D':
        customD()

    elif menu == 'Q':
        customQ()
    else:
        print('잘못 입력하셨습니다. 다시 입력 해주세요')

오류사항

- 'I'를 눌러 고객 정보를 입력한 뒤 정보 조회를 했을때 오류가 발생한다. 기존에 구현하고자 했던 프로그램은 고객 정보를 입력하고 이전 또는 다음 고객 정보를 조회하려할때 입력한 데이터 값의 길이보다 넘어가면 '이전 고객 정보가 없습니다' 또는 '다음 고객 정보가 없습니다.'가 뜨게 하는 것이다.

 위의 코드를 실행하면 현재 고객 정보 조회, 이전 고객 정보 조회는 실행이 잘 되는데 다음 고객 정보 조회 실행시 입력된 데이터의 길이를 넘어가면 '다음 고객 정보가 없습니다.'가 아닌 현재 고객 정보가 계속 뜨게 된다.

728x90
반응형
728x90
반응형

range()

- range()로 반복 횟수를 전달하면 range()가 자동으로 순차적인 정수들을 생성해준다.

 
- range( start = 0, stop, strp = 1 )
     > start : 시작값
     > stop : 종료값이지만 stop은 포함되지 않는다.
     > step : 한번에 증가되는 값이다.

 
조건제어반복

- 어떤 조건이 만족 되는 동안 반복한다.
- ex) 투자금이 목표에 도달하는 기간을 계산해보자

 
무한루프와 break, continue

- 무한루프는 실제코드에서 많이 사용된다. 특히 반복을 빠져나가는 조건이 까다로운 경우에 많이 사용된다. 예를 들어서 사용자가 입력한 수가 3의 배수이거나 음수의 경우에 while 루프를 빠져나가야 한다고 하자.
이는 다음과 같이 while 루프의 조건문을 만드는 것보다,

while (x%3 == 0) or (x < 0) :
    ...
    ...
    ...

 
 
아래 나온 것 처럼 루프를 만들고 그 안에서 루프를 벗어나는 조건을 검사하는 편이 이해하기 쉽다.

while True:
    if x%3 == 0:
        break
    if x<0 :
        break
    ...

 
리스트 내포

- 리스트 내포(List Comprehension)는 원하는 자료들을 조회 또는 추출하여 리스트로 변환하는 현식
- 리스트 내포는 조건식을 이용하여 같은 연산을 전체 항목이나 일부 항목에 적용할 수 있음
- 리스트 내포를 이용하여 항목들을 대문자나 소문자로 바꾸는 등의 작업을 처리할 수 있음
- 리스트 내포 처리 과정
     ① → ② → ③ 에서 ①로 이동하여 반복 수행, 더 이상 꺼내 올 항목이 없으면 종료함.
     ① 항목들에서 순차적으로 하나씩 꺼내온다.
     ② 조건식을 적용하여 해당 조건에 맞는 항목은 추출하고 조건에 맞지 않으면 무시한다.
     ③ 위에서 추출한 항목은 리스트에 추가한다.
- 기본적인 리스트 내포 형식
     > 항목들에서 순차적으로 꺼내 온 자료는 변수에 저장한 후 표현식에 적용하여 리스트에 추가함


함수

- 입력값, 출력값(반환값)이 있다.
- 코드의 반복을 줄이기 위해 사용한다.
- def 함수명(변수1, 변수2, ...): 실행문1 실행문2 ... return 결과값
- (변수1, 변수2) <= 변수 생략 가능
- return 문 생략 가능
- 함수명은 동사 + 명사 형태로 적는 것이 좋다.
- ex. getId, deleteId


- 함수에 return을 여러개 찍으면 첫번째 return까지만 실행되고 멈춘다. 즉, 함수의 중단지점을 선언 할때 return을 쓴다

def add_minus(x, y):
    return x + y
    return x - y

- 함수에 쓰는 변수의 범위


- 변수에 default 값 설정
     > default값을 지정한 파라미터가 먼저 나오면 오류가 난다. 즉, 파라미터 종류 별 순서가 중요하다


 

- global 변수 선언
     > 로컬 변수, 글로벌 변수 구분하는게 중요
     > 파이썬에서는 글로벌 변수일 경우 변수명에 global을 씀

     > 아래의 경우는 로컬변수와 글로벌 변수를 함께 사용 하였으므로 함수내에 글로벌 변수 선언을 해준다.


lambda 함수

- lambda 변수1, 변수2, …: 결과값


파이썬 내에서 파일 생성 및 읽어오기

 
Pickle 라이브러리 사용

- 텍스트 상태의 데이터가 아닌 파이썬 객체 자체를 파일로 저장
- 기존의 텍스트 파일 저장과 다른점
     > w, r 텍스트 모드
     > wb, rb는 바이너리 모드(텍스트가 아닌 상태)
     > 저장할 때는 wb 읽을때는 rb로 지정
     > pickle 쓸때는 무조건 wb랑 rb라고 작성
- Pickle 사용법

728x90
반응형
728x90
반응형

주제 : 고객 정보 관리 시스템

진행 인원  : 4명

진행 방법 : 짝 프로그래밍

 

짝 프로그래밍

- 중간 지점에 하나의 컴퓨터를 둔다.

- 10분 간격으로 서로 옮겨 가면서 코드를 작성한다. 

- 네비게이터(navigator)가 전략을 제시하고 드라이버(driver)가 실제 코드를 작성한다.

지금 까지 배운 내용을 토대로 고객의 정보를 관리하는 프로그램을 만듭니다.
고객의 정보를 관리하는 프로그램에서 사용하는 고객 정보를 저장하는 자료구조는 자신 있는 것을 이용합니다.
 
1. 주요 내용
- 고객의 정보는 이름, 성별, 이메일, 출생년도가 있습니다.
- 고객의 정보를 입력받아 본인이 선택한 자료구조에 저장해야 합니다.
- 이름은 문자열로 저장
- 성별은 남자는 M, 여자는 F로 저장
- 이메일은 문자열로 저장
- 태어난 연도는 정수로 저장
 
2. 요구사항
- 고객 관리 프로그램은 고객의 정보를 저장, 조회, 수정, 삭제 할 수있는 기능이 있어야 합니다.
- 고객 정보를 파일에 저장하는 기능을 구현하지 않아도 됩니다.
- “ I ”를 눌러 고객의 정보를 입력받도록 합니다.
- 저장된 고객 정보는 “ P ” 또는 “ N ”을 눌러 이전 고객정보 또는 다음 고객정보를 조회할 수 있어야 합니다.
- 조회한 고객 정보는 “ U ”를 눌러 새로운 정보로 수정할 수 있어야 합니다.
- “ D ”를 누르면 조회한 고객 정보를 삭제해야 합니다.
- 프로그램의 종료는 “ Q ”를 누릅니다.
 

실습 시작 전 주요내용 정리하기

# 이름, 성별, 이메일, 출생년도
# 이름 - 문자열
# 성별 - M / F
# 이메일 - 문자열
# 출생년도 - 정수

# 저장, 조회, 수정, 삭제
# I - 사용자가 이름, 성별, 이메일, 출생년도를 순차적으로 입력할 수 있게한다.
# P, N - 입렭받은 여러명의 정보를 조회 (이전, 이후)
# U - 현재 위치의 고객정보를 수정해야 한다.
# D - 현재 위치의 고객정보를 삭제해야 한다.
# Q - 종료
 
 

작성한 코드

import re

# clientData = list()
# 기본으로 입력된 데이터 입니다.
clientData = [{'name' : 'aaa', 'gender' : 'M', 'email' : 'abc@gmail.com', 'birth' : '2000'},
              {'name' : 'bbb', 'gender' : 'F', 'email' : 'bbb@gmail.com', 'birth' : '2001'},
              {'name' : 'ccc', 'gender' : 'M', 'email' : 'ccc@gmail.com', 'birth' : '2002'}]
gender_pattern = re.compile(r'^[MFmf]$')

while True:
    yourInput = input('I, R, U, D, Q 중에 입력하시오 : ')
    
    if 'I' == yourInput:
        while True:
            name = input('이름을 입력하세요 : ')
            if name.isalpha():
                pass
            else:
                print('올바른 이름을 입력하세요.')
                continue
            gender = input('성별을 입력하세요(M / F) : ')
            if gender_pattern.match(gender):
                pass
            else:
                print('올바른 성별을 입력하세요.')
                continue
            email = input('이메일을 입력하세요 : ')
            if email.isalpha():
                pass
            else:
                print('올바른 이메일을 입력하세요.')
                continue
            birth = input('태어난 연도를 입력하세요 : ')
            if birth.isdecimal():
                pass
            else:
                print('올바른 태어난 연도를 입력하세요.')
            dic = {'name' : name, 'gender' : gender, 'email' : email, 'birth' : birth}
            clientData.append(dic)
            print('입력완료 되었습니다.')
            break
            
    elif 'R' == yourInput:
        count = -1
        print('고객 정보를 조회하세요.')
        while True:
            search = input('이전정보를 조회하려면 P 다음 정보를 조회하려면 N을 입력하세요 : ')
            if 'N' in search:
                count += 1
                print(clientData[count], f'당신의 번호는 {count}')
                continue
            elif 'P' in search:
                count -= 1
                print(clientData[count], f'당신의 번호는 {count}')
                continue
            elif 'Q' in search:
                break
            else :
                print('N, P, Q중에 입력하세요 : ')
                continue
                
    elif 'U' == yourInput:
        print('고객 정보를 수정하세요.')
        user_count = input('당신의 번호를 입력하세요 : ')
        print(f'현재 당신이 가지고있는 고객정보{clientData[int(user_count)]}')
        rename = input('변경할 이름을 입력하세요 : ')
        regender = input('변경할 성별을 입력하세요(M / F) : ')
        reemail = input('변경할 이메일을 입력하세요 : ')
        rebirth = input('변경할 태어난 연도를 입력하세요 : ')
        dic = {'name' : rename, 'gender' : regender, 'email' : reemail, 'birth' : rebirth}
        clientData[int(user_count)]=dic
        print('입력완료 되었습니다.')
        break
        
    elif 'D' == yourInput:
        print('삭제하시겠습니까?')
        userDelCount=input('삭제할 번호를 입력하세요. 나가시려면 Q를 입력해주세요 : ')
        if 'Q' in userDelCount:
            continue
        print(f'당신의 개인정보는 다음과 같습니다{clientData[int(userDelCount)]}')
        real = input('정말 지우겠습니까?(Y / N) : ')

        if 'Y' in real:
            del clientData[int(userDelCount)]
        continue

    elif 'Q' == yourInput:
        break

오류사항

- 고객 정보 조회 시 List에 존재하는 데이터 count을 넘어가면 오류가 난다.

- 이메일 입력시 isalpha()함수를 써서 문자형인지 확인하는데 정확한 이메일 형식을 입력하면 '@'와 '.' 등의 기호가 들어가기 때문에 문자 형식에 맞지 않아 오류가 난다.

 

 

728x90
반응형

+ Recent posts