Language/Python Python 주소록 프로젝트
  • 728x90
    반응형

     

     

     

    Python 주소록 프로젝트


     

     

    목차

       

       

      Contact 클래스 만들기

      연락처 프로그램을 살펴보면 연락처에는 이름, 전화번호, 이메일, 주소 등을 입력할 수 있다. 이를 파이썬에서 제공하는 기본 자료형으로 표현하기보다 하나의 클래스로 정의하는 것이 좋다.

       

      Contact 라는 이름의 클래스를 정의하고, 클래스 인스턴스를 생성할 때 이름, 전화번호, 이메일, 주소를 입력받을 수 있게 생성자를 선언하고 인스턴스 변수에 저장된 정보를 화면에 출력하기 위해 print_info 라는 메서드도 정의한다.

       

       

      PyCharm 에서 Ctrl + F9 또는 Ctrl + F5를 눌러 작성한 프로그램이 정상적으로 동작하는지 확인한다.

       

       

       

      사용자로부터 데이터 입력받기

      파이썬에서 사용자로부터 데이터를 입력받을 때는 input() 함수를 사용한다. 사용자로부터 데이터를 입력받는 함수인 set_contact() 함수를 새로 정의 하고 run() 함수에서 set_contact() 함수를 호출하도록 코드를 변경한다.

       

       

      수정한 코드를 실행하면 PyCharm의 아래쪽에 위치하는 실행 창을 통해 데이터를 입력할 수 있다. 데이터 입력이 완료되면 set_contact() 함수의 마지막 라인에 있는 print 코드로 인해 지금까지 입력된 데이터가 출력된다.

       

       

       

       

      메인 메뉴 구성하기

      연락처 프로그램은 기본적으로 연락처 입력, 연락처 출력, 연락처 삭제, 종료 기능을 제공한다. 작성된 연락처 프로그램은 계속 실행 상태를 유지하다가 사용자로부터 종료 명령을 받으면 프로그램이 종료해야 한다.

       

      작성한 프로그램이 한 번 실행됐을 때 종료하지 않은 상태로 계속 실행되게 하려면 무한 루프를 사용해야 한다.

       

       

      run() 함수는 print_menu() 함수를 호출하기 때문에 화면에 메인 메뉴가 출력 된다. print_menu() 함수는 input() 함수를 통해 사용자로부터 메뉴를 입력 받은 후 int()라는 내장 함수를 통해 정수로 변환한 후 반환한다.

       

       

       

       

      연락처 입력 동작 시키기

      사용자가 입력한 연락처 정보를 이용해 Contact 클래스 인스턴스를 생성하고 생성된 인스턴스를 반환하도록 set_contact() 함수를 수정한다. set_Contact() 함수의 마지막 두 줄에서 Contact 클래스의 인스턴스를 생성하고 이를 반환하는 것을 확인할 수 있다.

       

       

      set_contact() 함수는 사용자로부터 연락처를 입력받을 때 사용하는 함수이므로 사용자가 '1. 연락처 입력' 메뉴를 선택했을 때 run() 함수에서 set_contact() 함수를 호출하면 된다.

       

      run() 함수를 수정해 1번 메뉴를 선택했을 때 set_contact() 함수를 호출하고 반환값인 Contact 인스턴스를 저장하기위해 contact_list 라는 이름의 리스트 자료구조를 생성하고 해당 리스트에 생성된 인스턴스를 추가한다.

       

       

      지금까지 작성된 코드는 아래와 같다.

       

      class Contact:
          def __init__(self, name, phone_number, e_mail, addr):
              self.name = name
              self.phone_number = phone_number
              self.e_mail = e_mail
              self.addr = addr
      
          def print_info(self):
              print("Name: ", self.name)
              print("Phone Number: ", self.phone_number)
              print("E-mail: ", self.e_mail)
              print("Address: ", self.addr)
      
      
      def set_contact():
          name = input("Name: ")
          phone_number = input("Phone Number: ")
          e_mail = input("E-mail: ")
          addr = input("Address: ")
          contact = Contact(name, phone_number, e_mail, addr)
          return contact
      
      
      def print_menu():
          print("1. 연락처 입력")
          print("2. 연락처 출력")
          print("3. 연락처 삭제")
          print("4. 종료")
          menu = input("메뉴선택:")
          return int(menu)
      
      
      def run():
          contact_list = []
          while(1):
              menu = print_menu()
              if menu == 1:
                  contact = set_contact()
                  contact_list.append(contact)
              elif menu == 4:
                  break
      
      if __name__ == "__main__":
          run()
       

       

      1번 메뉴를 선택해 연락처를 입력하고 4번 메뉴를 선택해 프로그램을 종료시켜 본다.

       

       

      contact_list는 '테스트1'에 대한 데이터를 가진 인스턴스를 바인딩하게 된다. 4번 메뉴를 통해 프로그램을 종료시키면 메모리에 할당된 모든 데이터가 자동으로 삭제된다.

       

       

       

      연락처 출력하기

      앞서 작성한 코드에서 연락처는 Contact 라는 클래스의 인스턴스 형태로 저장되며, 인스턴스는 contact_list라는 이름의 리스트를 통해 순서대로 저장된다. 입력된 연락처를 출력하려면 contact_list에 있는 인스턴스에 저장된 정보를 출력하면 되는 것이다.

       

       

      ptint_contact() 함수는 Contact 인스턴스를 저장하고 있는 리스트를 인자를 입력받은 후 for 문을 이용해 리스트에 저장된 인스턴스를 순회한다. 이때 각 인스턴스에서 print_info() 메서드를 호출한다.

       

      연락처 출력 기능은 메인 메뉴에서 '2. 연락처 출력' 을 선택했을 때 수행되어야 한다.

       

       

      1번 메뉴룰 선택한 후 임의로 연락처 정보를 입력하고, 2번 메뉴를 선택하여 입력된 정보가 정상적으로 출력되는지 확인한다.

       

       

       

      연락처 삭제하기

      연락처를 삭제하려면 삭제하고자하는 연락처의 이름을 입력받은 후 연락처 리스트에서 해당 이름을 찾아서 지우면 된다.

       

      연락처 리스트에서 연락처를 삭제하기 위해 다음과 같이 delete_contact() 함수를 작성한다. 이 함수는 연락처 리스트와 삭제할 이름을 인자로 입력받는다. delete_contact() 함수는 연락처 리스트에 저장된 인스턴스 중 삭제하고자 하는 연락처 이름과 같은 연락처가 있는지 확인한 후 같은 연락처가 있을 때 해당 연락처를 삭제한다.

       

       

      연락처 삭제는 '3. 연락처 삭제' 메뉴를 선택했을 때 동작 하는데, 이때 삭제할 연락처의 이름(Name)을 한 번 더 입력받는다.

       

       

      주소록 프로젝트 전체 소스 

       

      class Contact:
          def __init__(self, name, phone_number, e_mail, addr):
              self.name = name
              self.phone_number = phone_number
              self.e_mail = e_mail
              self.addr = addr
      
          def print_info(self):
              print("Name: ", self.name)
              print("Phone Number: ", self.phone_number)
              print("E-mail: ", self.e_mail)
              print("Address: ", self.addr)
      
      
      def set_contact():
          name = input("Name: ")
          phone_number = input("Phone Number: ")
          e_mail = input("E-mail: ")
          addr = input("Address: ")
          contact = Contact(name, phone_number, e_mail, addr)
          return contact
      
      
      def print_menu():
          print("1. 연락처 입력")
          print("2. 연락처 출력")
          print("3. 연락처 삭제")
          print("4. 종료")
          menu = input("메뉴선택: ")
          return int(menu)
      
      
      def print_contact(contact_list):
          for contact in contact_list:
              contact.print_info()
      
      
      def delete_contact(contact_list, name):
          for i, contact in enumerate(contact_list):
              if contact.name == name:
                  del contact_list[i]
      
      
      def run():
          contact_list = []
          while(1):
              menu = print_menu()
              if menu == 1:
                  contact = set_contact()
                  contact_list.append(contact)
              elif menu == 2:
                  print_contact(contact_list)
              elif menu == 3:
                  name = input("Name: ")
                  delete_contact(contact_list, name)
              elif menu == 4:
                  break
      
      if __name__ == "__main__":
          run()

       

       

       

      연락처 저장 함수 작성하기

      프로그램이 종료될 때 연락처 정보를 파일로 저장하는 역할을 하는 store_contact()라는 함수이다. 이 함수는 contact_list라는 리스트를 입력받은 후 해당 리스트에 있는 Contact 인스턴스를 순회하면서 데이터를 파일로 저장한다.

       

       

      store_contact() 함수는 함수가 호출될 때 먼저 'contact_db.txt' 라는 이름의 텍스트 파일을 'wt' 모드로 연다. contact_list를 순회하면서 각 인스턴스의 정보를 write 함수를 통해 출력한다.

       

      파일로 저장하는 기능은 프로그램이 종료될 때 호출하면 되므로 기존에 run() 함수를 수정한다.

       

       

      수정된 프로그램을 실행한 후 연락처를 하나 입력하고 프로그램을 종료한다.

       

       

      생성된 contact_db.txt 파일의 내용을 확인한다.

       

       

       

      연락처 불러들이기

      이전에 파일로 저장돼 있던 연락처 정보를 프로그램이 시작될 때 불러들이는 기능을 구현해 본다.

       

      파일로부터 연락처를 로드하는 함수의 이름은 load_contact 이다. 이 함수 역시 contact_list를 인자로 받으며, 함수 내부에서 'contact_db.txt' 파일을 열어서 해당 파일을 라인 단위로 저장된 이름, 전화번호, 이메일, 주소로 읽어 들여 Contact 클래스의 인스턴스를 생성한다. 그런 다음 생성한 인스턴스를 contact_list 에 추가한다.

       

       

      load_contact() 함수는 먼저 readlines() 함수를 이용해 파일에 있는 모든 데이터를 읽는다. 연락처 하나당 4줄의 데이터가 존재하므로 파일에서 읽어들인 전체 라인 수를 4로 나누어 몇 개의 데이터가 존재하는지 확인한다. 나눗셈 연산을 하면 num값이 실수가 되는데 이값을 int() 내장 함수를 사용해 정수형으로 형변환한다.

       

      for 문에서는 num의 개수만큼 루프를 돌면서 lines 리스트에 데이터를 읽어 들여 Contact 클래스의 인스턴스를 생성하고 생성한 인스턴스를 contact_list에 추가한다.

       

      다음과 같이 run() 함수의 시작 부분에서 load_contact() 함수를 호출하면 된다.

       

       

      주소록 프로젝트 최종 코드이다.

       

      class Contact:
          def __init__(self, name, phone_number, e_mail, addr):
              self.name = name
              self.phone_number = phone_number
              self.e_mail = e_mail
              self.addr = addr
      
          def print_info(self):
              print("Name: ", self.name)
              print("Phone Number: ", self.phone_number)
              print("E-mail: ", self.e_mail)
              print("Address: ", self.addr)
      
      
      def set_contact():
          name = input("Name: ")
          phone_number = input("Phone Number: ")
          e_mail = input("E-mail: ")
          addr = input("Address: ")
          contact = Contact(name, phone_number, e_mail, addr)
          return contact
      
      
      def print_menu():
          print("1. 연락처 입력")
          print("2. 연락처 출력")
          print("3. 연락처 삭제")
          print("4. 종료")
          menu = input("메뉴선택: ")
          return int(menu)
      
      
      def print_contact(contact_list):
          for contact in contact_list:
              contact.print_info()
      
      
      def delete_contact(contact_list, name):
          for i, contact in enumerate(contact_list):
              if contact.name == name:
                  del contact_list[i]
      
      
      def store_contact(contact_list):
          f = open("contact_db.txt", 'wt')
          for contact in contact_list:
              f.write(contact.name + '\n')
              f.write(contact.phone_number + '\n')
              f.write(contact.e_mail + '\n')
              f.write(contact.addr + '\n')
          f.close()
      
      
      def load_contact(contact_list):
          f = open("contact_db.txt", "rt")
          lines = f.readlines()
          num = len(lines) / 4
          num = int(num)
      
          for i in range(num):
              name = lines[4*i].rstrip('\n')
              phone = lines[4*i+1].rstrip('\n')
              email = lines[4*i+2].rstrip('\n')
              addr = lines[4*i+3].rstrip('\n')
              contact = Contact(name, phone, email, addr)
              contact_list.append(contact)
          f.close()
      
      
      def run():
          contact_list = []
          load_contact(contact_list)
          while 1:
              menu = print_menu()
              if menu == 1:
                  contact = set_contact()
                  contact_list.append(contact)
              elif menu == 2:
                  print_contact(contact_list)
              elif menu == 3:
                  name = input("Name: ")
                  delete_contact(contact_list, name)
              elif menu == 4:
                  store_contact(contact_list)
                  break
      
      if __name__ == "__main__":
          run()

       

       

       

       

       

       

       

      728x90
      반응형
    상단으로