Python

Python 예제#2

s2h15 2023. 11. 17. 16:58
728x90

<예제> 전화번호를 전달받아서, 뒤 4자리를 제외하고 별(*)로 표시하는 함수 만들어서 출력까지

  • 함수명 : solution
  • 예시 : 010-1234-5678 => ********5678

 

나의 풀이

def solution(phone):
    phone = phone.replace('-','')
    phone = phone.replace(phone[:7],'********')
    return phone

solution('010-1234-5678')

 

'********5678'
def solution2(phone):
    phone = phone.replace('-','')
    phone = '********'+phone[7:]
    return phone

solution2('010-1234-5678')

▶  결과는 동일하므로 생략

def solution3(phone):
    phone = phone.replace('-','')
    for i in phone[:len(phone)-4]:
       phone = phone.replace( i , '*')
    return phone
solution3('010-1234-5678')

▶  결과는 동일하므로 생략

 

import re

def solution4(phone):
    pattern = re.compile(r"[\d]{2,3}-[\d]{4}-[\d]{4}")
    
    if re.fullmatch(pattern,phone):
        phone = phone.replace('-','')
        phone = '********'+phone[7:]
        return phone
    else:
        print('올바르게 작성하세요')

solution4('010-1234-5678')

▶  작성하며 전날 배운 정규표현식을 사용하면 좋을 것 같다는 생각이 들어 정규표현식을 추가한 내용

 

강사님 풀이

# 강사님 풀이
def solution_t(phone_number):
    rs_number = "*" * len(phone_number[ : -4]) + phone_number[-4 : ]
    return rs_number
print(solution_t('010-1234-5678'))m
print(solution_t('02-1234-5678'))

▶ 인덱스에 -4 와 같이 음수 값을 이용하여 맨 끝 자리부터 세는 방법을 생각해내지 못했다. 

내가 사용한 len(phone) - 4 보다 훨씬 간결한 것 같다.

 

 

 

<예제> 연속된 정수 리스트 데이터 제거하기

  • 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하기
  • 단, 제거된 후 남은 숫자들은 원본 데이터 타입으로 출력하기
  • 함수명 : solution
  • 예시 : [1,1,3,3,0,1,1] -> [1,3,0,1]

 

성공하지는 못했지만~ㅎ

나의 풀이

def solution(num_list):
    i = 0
    while i < len(num_list)-1:
        if num_list[i] == num_list[i+1]:
            num_list.remove(num_list[i+1])
            print(f'list = {num_list},i={i}')
        else:
            print(f'i={i}')
            i += 1
    return num_list

solution([1,1,3,3,0,1,1])

 

list = [1, 3, 3, 0, 1, 1],i=0
i=0
list = [1, 3, 0, 1, 1],i=1
i=1
i=2
list = [3, 0, 1, 1],i=3
[116]:[3, 0, 1, 1]

▶ remove를 사용하니까 마지막 1,1 을 비교해서 1 을 제거해야하는데 맨 처음 값에 있는 1이 제거되는 것을 알 수 있었다.

list = [1, 3, 3, 0, 2, 2],i=0
i=0 list = [1, 3, 0, 2, 2],i=1
i=1
i=2
list = [1, 3, 0, 2],i=3
[125]:[1, 3, 0, 2]

▶num_list = [1,1,3,3,0,2,2] 를 넣으면 맨 처음에 있는 1의 값과 동일하지 않기 때문에 마지막 2 값이 제거되는 것을 알 수 있다.

 

def solution(num_list):
    result = []
    i=0
    while i < 6:
        if num_list[i+1] != None:
            if num_list[i] == num_list[i+1]:
                i +=1
                print(f'ifresult= {result},i1={i-1},i2={i}')
            else : 
                result.append(num_list[i])
                i += 1
                print(f'elseresult= {result},i1={i-1},i2={i}')
        else:
            result.append(num_list[i])
        
    return result
solution([1,1,3,3,0,1,1])

 

ifresult= [],i1=0,i2=1
elseresult= [1],i1=1,i2=2
ifresult= [1],i1=2,i2=3
elseresult= [1, 3],i1=3,i2=4
elseresult= [1, 3, 0],i1=4,i2=5
ifresult= [1, 3, 0],i1=5,i2=6
[126]:[1, 3, 0]

▶ remove를 사용하는 것은 실제 데이터를 바꿔버리는 것이기 때문에 위험할 수 있다고 하셔서 데이터를 추출해서 새로운 리스트에 넣는 방식으로 바꾸어보았는데 마지막 1,1 을 비교한 뒤 같기 때문에 result 리스트에 들어가지 않고 끝나는 것을 확인 할 수 있었다. 따라서 무조건 마지막 숫자는 append 할 수 있도록 하려고 if 문을 하나 더 추가했으나 실패했다^^

 

 

 

강사님 풀이

 

 

# 강사님 풀이
def solution(num_list) :
    rs_list = []
    last_num = -1
    for i in num_list:
        if i == last_num:
            continue
        rs_list.append(i)
        last_num = i
    return rs_list
solution([1,1,3,3,0,1,1])

 

[1, 3, 0, 1]

▶ 강사님께서도 추출하는 방법을 사용하셨는데 last_num  이라는 임의의 변수를 생성해서 첫번째 숫자는 무조건 rs_list에 append하고 , 그 후에 비교할 수 있도록 하셨다. 

 

 

< 도서관리 프로그램 회원기능 추가>

● 요구사항
<최초 메뉴>
 : 회원번호는 문자열 무엇이든 상관없이 등록
 : 서비스 종료 시 프로그램 자체 종료
 
 [서비스 이용을 위한 회원 인증]
 1. 회원번호 등록
 2. 회원 인증
 3. 서비스 종료

<회원인증이 된 경우 메뉴>
 : 도서 정보 : 도서번호, 도서제목, 재고 권수
 : 도서 상태 확인 : 특정 도서에 대한 정보 조회(도서번호, 도서제목 , 현재 권수/전체권수)
 [도서 서비스 메뉴]
 1. 도서 입고
 2. 도서 대출
 3. 도서 반납
 4. 도서 상태 확인
 5. 도서 전체 목록 확인
 6. 도서 서비스 종료(회원 인증 메뉴로 갑니다.)

 

●  추가 요구사항 > 아직 진행중

1. 정규표현식 사용 유효성검사 > 아직 진행중

2. 파일 불러오기 읽기를 통해 데이터 저장

 

회원가입 class

class LibraryMember : 
    def __init__(self):
        self.members = {}
        
    def signin_decorator(func):
        def wrapper(self,member_id,dic):
            func(self,member_id,dic)
        return wrapper
    @signin_decorator
    def signin(self,member_id,dic):
        self.members = dic
        if member_id in self.members:
            print("이미 존재하는 회원번호 입니다. 다른 회원번호를 입력하세요")
        else:
            self.members[member_id] = {"id" : member_id}
            print(f"회원 번호:{member_id} 회원가입 완료")
            print(self.members)

    def login_decorator(func):
        def wrapper(self,member_id,dic):
            func(self,member_id,dic)
        return wrapper
    @login_decorator
    def login(self,member_id,dic):
        self.members = dic
        if member_id in self.members:
            print(f"회원 번호:{member_id}  로그인 완료")
            main1()
        else:
            print(f"회원번호 {member_id}가 존재하지 않습니다. ")

    # def check_decorator(func):
    #     def wrapper(self,msg,func_lam):
    #         func(self,msg,func_lam)
    #     return wrapper
    # @check_decorator
    # def check(self,msg,func_lam):
    #     while True:
    #         x = input(msg)
    #         if func_lam(x):
    #             break
    #         else:
    #             print("잘못 입력하셨습니다. 다시 입력하세요")
    #     return x


    
    
    def save_file(self):
        with open('member.pickle','wb') as f:
            pickle.dump(self.members,f)
    def read_file(self):
        with open('member.pickle','rb') as f:
            a = pickle.load(f)
            return a

▶ 위의 회원가입 요구사항 수행 read_file로 이전에 저장된 내용을 불러와 self.members 딕셔너리에 저장

 

 

도서 기능 class


### 기능을 수행할 클래스(모듈 or 라이브러리) 정의
class LibraryKiosk :
    ### 클래스 생성자 정의
    def __init__(self) :
        ### 도서 목록을 저장할 딕셔너리 변수 생성
        # - 도서번호, 도서제목, 도서재고수량 정보 담기
        self.books = {}

     ### 도서 입고 데코레이터 함수 정의하기
    def add_book_decorator(func):
        def wrapper(self, book_id, title, quantity,dic):
            func(self, book_id, title, quantity,dic)
        return wrapper
          
    @add_book_decorator
    def add_book(self, book_id, title, quantity,dic):
        self.books = dic
        if book_id in self.books:
                self.books[book_id]["current_quantity"] += quantity
        else :
            self.books[book_id] = {"title":title,"quantity":quantity,"current_quantity":quantity}
        print(f"도서번호:{book_id} / 제목:{title} / 입고수량:{quantity} 입고 성공!!") 
        
    
    def borrow_book_decorator(func):
        def wrapper(self, book_id,dic):
             func(self, book_id,dic)
        return wrapper
            
    @borrow_book_decorator
    def borrow_book(self, book_id,dic):
        self.books = dic
        if (book_id in self.books) and (self.books[book_id]["current_quantity"] > 0) :
            self.books[book_id]["current_quantity"] -= 1
            print(f"도서번호:{book_id} / 제목:{self.books[book_id]['title']} / 남은재고수량:{self.books[book_id]['current_quantity']}")
        else :
            print("도서가 존재하지 않거나, 대출할 재고가 없습니다.")

    
    def return_book_decorator(func):
        def wrapper(self, book_id,dic):
            func(self, book_id,dic)
        return wrapper
    @return_book_decorator
    def return_book(self, book_id,dic):
        self.books = dic
        if book_id in self.books and self.books[book_id]['current_quantity'] < self.books[book_id]['quantity'] :
            self.books[book_id]["current_quantity"] += 1
            print(f"도서번호:{book_id} / 제목:{self.books[book_id]['title']} / 남은재고수량:{self.books[book_id]['current_quantity']}")
        else :
            print("해당 도서 번호의 반납할 도서가 없거나 해당 도서가 존재하지 않습니다.")
            
    def check_book_decorator(func):
        def wrapper(self, book_id,dic):
            func(self, book_id,dic)
        return wrapper
    @check_book_decorator
    def check_book(self, book_id,dic):
        self.books = dic
        if book_id in self.books :
            print(f"도서번호:{book_id} / 제목:{self.books[book_id]['title']} / 현재권수/전체권수:{self.books[book_id]['current_quantity']}/{self.books[book_id]['quantity']}")
        else :
            print("해당 도서가 존재하지 않습니다.")
    
    def list_book_decorator(func):
        def wrapper(self,dic):
            func(self,dic)
        return wrapper
    @list_book_decorator
    def list_book(self,dic):
        self.books = dic
        result = []
        for i in self.books.keys():
            print(f'도서번호 : {i} / 제목 : {self.books[i]["title"]} / 재고 권수 :{self.books[i]["current_quantity"]} ')
            
    def save_file(self):
        with open('library.pickle','wb') as f:
            pickle.dump(self.books,f)
    def read_file(self):
        with open('library.pickle','rb') as f:
            a = pickle.load(f)
            return a

▶ 위의 도서 요구사항 수행 , read_file로 이전에 저장된 내용을 불러와 self.books 딕셔너리에 저장

도서 전체 목록을 출력하기 위해 self.books의 key값들 즉 book_id들을 모두 불러와서 각각 for문으로 print되게 하였다

 

 

 main 함수 실행 


   ### 2. 최초에 실행할 기능(함수) 정의
def main():
    member = LibraryMember()
    dic = member.read_file()
    
    while True:
        print("<회원 인증 메뉴>")
        print("1. 회원 가입")
        print("2. 회원 인증")
        print("3. 종료")
        
        choice = input("원하는 번호(1~3)를 선택하세요 : ")
        if choice == "1" :
            member_id = input("회원 번호를 입력해 주세요 : " )
            member.signin(member_id,dic)
        elif choice == "2" :
             member_id = input("회원 번호를 입력해 주세요 : ")
             member.login(member_id,dic)
             
        elif choice == "3" :
            print("종료 선택")
            member.save_file()
            break
        else :
            print("잘못 선택...다시 선택해 주세요!!")

def main1() :
    ### 클래스 생성하기
    # - 최초 한번 : 프로그램이 종료되면 클래스는 소멸(메모리 공간 삭제)됩니다.
    kiosk = LibraryKiosk()
    dic = kiosk.read_file()

    #print("main 함수 호출!!")
    ### 3. 메뉴 선택 보여주기
    while True :
        print("<도서 키오스크 메뉴>")
        print("1. 도서 입고")
        print("2. 도서 대출")
        print("3. 도서 반납")
        print("4. 도서 상태 확인")
        print("5. 도서 전체 목록 확인")
        print("6. 종료")

        choice = input("원하는 번호(1~6)를 선택하세요 : ")

        if choice == "1" :
            #print("입고 선택")
            book_id = input("도서 번호를 입력해 주세요 : ")
            title   = input("도서 제목를 입력해 주세요 : ")
            quantity= int(input("입고할 권수를 입력해 주세요 : "))
            #print(f"{book_id} / {title} / {quantity}")

            # - 클래스 내부의 입고 기능 호출하기
            kiosk.add_book(book_id, title, quantity,dic)

        elif choice == "2" :
            #print("대출 선택")
            book_id = input("대출할 도서번호를 입력해주세요 : ")

            ### 클래스 내부의 대출 기능 호출하기
            kiosk.borrow_book(book_id,dic)

        elif choice == "3" :
            #print("반납 선택")
            book_id = input("반납할 도서번호를 입력해주세요 : ")

            
            ### 클래스 내부의 반납 기능 호출하기
            kiosk.return_book(book_id,dic)
        elif choice == "4" :
            book_id = input("확인할 도서번호를 입력해주세요 : ")

            
            ### 클래스 내부의 도서 상태 확인 기능 호출하기
            kiosk.check_book(book_id,dic)
        elif choice == "5" :
            
            ### 클래스 내부의 전체 목록 확인 기능 호출하기
            kiosk.list_book(dic)

        elif choice == "6" :
            print("종료 선택")
            kiosk.save_file()
            break
        else :
            print("잘못 선택...다시 선택해 주세요!!")


### 1. 최초 코드 시작
if __name__ == "__main__" :
    ### 최초에 실행할 기능(함수) 호출
    main()

 

<회원 인증 메뉴> 1. 회원 가입 2. 회원 인증 3. 종료
원하는 번호(1~3)를 선택하세요 : 2
회원 번호를 입력해 주세요 : cd
회원 번호:cd
로그인 완료
<도서 키오스크 메뉴> 1. 도서 입고 2. 도서 대출 3. 도서 반납 4. 도서 상태 확인 5. 도서 전체 목록 확인 6. 종료
원하는 번호(1~6)를 선택하세요 : 5
도서번호 : 1 / 제목 : 가 / 재고 권수 :4 도서번호 : 2 / 제목 : 나 / 재고 권수 :3
<도서 키오스크 메뉴> 1. 도서 입고 2. 도서 대출 3. 도서 반납 4. 도서 상태 확인 5. 도서 전체 목록 확인 6. 종료
원하는 번호(1~6)를 선택하세요 : 2
대출할 도서번호를 입력해주세요 : 2
도서번호:2 / 제목:나 / 남은재고수량:2
<도서 키오스크 메뉴> 1. 도서 입고 2. 도서 대출 3. 도서 반납 4. 도서 상태 확인 5. 도서 전체 목록 확인 6. 종료
원하는 번호(1~6)를 선택하세요 : 6
종료 선택
<회원 인증 메뉴> 1. 회원 가입 2. 회원 인증 3. 종료
원하는 번호(1~3)를 선택하세요 : 3
종료 선택

 

▶ 결과는 위에 보는 것처럼 제대로 작동하는 것을 알 수 있고 추가로 read_file을 함수 시작부분에 추가하고 이를 각 함수마다 매개변수로 (dic) 추가해줬다

한번 실행한 후 저장된 내용을 토대로 도서 전체 목록에 도서 정보가 출력되는것을 확인 할 수 있다

main 함수로 회원가입을 실행하고 main1 함수를 로그인 성공했을때 실행하도록 했다

 

728x90