1. 아래 코드는 1부터 100까지의 수를  입력/출력 하는 기능을 예이다. 코드와 메모리 구조를  보고 문제에 답하시오. 

코드

  • 10개의 정수를 입력하는 메모리 10개를 정의하여 2차원 배열을 구현하였다.
  • 메모리 접근 코드를 배열로 작성하였다. 
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int **arr = (int **)malloc(sizeof(int *) * 10);
    if(arr == NULL) return 1;

    for(int i = 0; i < 10; i++) {
        arr[i] = (int *)malloc(sizeof(int) * 10);
        if(arr[i] == NULL)  return 1;
    }

    int num = 1;
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            arr[i][j] = num++;
        }
    }

    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            printf("%3d ", arr[i][j]);
        }
        printf("\n");
    }

    for(int i = 0; i < 10; i++)
        free(arr[i]);

    free(arr);
    return 0;
}

 

메모리 구조

1-1. arr[0][0]을 포인터 변수를 이용하여 출력하시오. 

printf("%d\n", ________);
 

1-2. arr[1][0]을 포인터 변수를 이용하여 출력하시오.  .

printf("%d\n", ________);

 

1-3 arr[2][4]를  포인터 변수를 이용하여 출력하시오. 

printf("%d\n", ________);
 

1-4 arr[9][9]를 포인터 변수를 이용하여 출력하시오. 

printf("%d\n", ________);
 

1-5. arr[0][0]의 값을 포인터 변수를 이용하여  999로 변경하시오.

________ = 999;
 

1-6  arr[1][2]의 값을 포인터 변수를 이용하여 777로 변경하시오.

________ = 777;
 

1-7. arr[3]이 가리키는 행의 시작 주소를 포인터 변수를 이용하여 출력하시오.

printf("%p\n", ________);

 

1-8 arr[2][5]의 주소를 포인터 변수를 이용하여 출력하시오.

printf("%p\n", ________);
 

1-9  다음 코드에서 arr + 4는 무엇을 가리키는가?

arr + 4
 

보기:

① arr[4][0]의 값
② arr[4]의 주소를 저장하는 공간
③ 5번째 행의 시작 주소
④ arr[0][4]의 주소
 

1-10 다음 배열 표현을 포인터 표현으로 바꾸시오.

arr[i][j]
 

 

________
 
 
풀이

 

더보기

1. *(*(arr + 0) + 0)

2. *(*(arr + 1) + 0)

3. *(*(arr + 2) + 4)

4. *(*(arr + 9) + 9)

5. *(*(arr + 0) + 0) = 999;

6. *(*(arr + 1) + 2) = 777;

7. *(arr + 3)

8. (*(arr + 2) + 5)

9. ② arr[4]의 주소를 저장하는 공간
   단, *(arr + 4)는 5번째 행의 시작 주소

10. *(*(arr + i) + j)

 

 

정리하면, arr[i][j] == *(*(arr + i) + j)

0. 시작 전 확인

Claude Code는 유료 플랜(Pro / Max / Team / Enterprise)에서만 사용 가능합니다.
계정 만들기 → https://claude.ai

 

1. macOS 설치 가이드

Claude.ai 계정 & 유료 플랜

STEP 1. claude.ai (https://claude.ai) 에 접속해서 계정을 만든다.

  • Pro / Max / Team / Enterprise 중 하나의 유료 플랜이 필요해요.
  • 계정에 로그인 한다.

Node.js 설치

STEP 2. nodejs.org (https://nodejs.org) 에 접속한다. 

  • 사이트에서 "macOS Installer (.pkg)" — LTS 버전 버튼을 클릭하여 다운로드한다. 

STEP 3. 다운로드한 .pkg 파일 설치

  • 다운로드 폴더에서 .pkg 파일을 더블클릭한다. 
  • 설치 안내에 따라 계속 → 계속 → 설치 를 눌러 완료한다. 
  • 설치 중에 Mac 비밀번호를 입력하라면, 로그인 비밀번호를 입력한다.

터미널 열기

STEP  4. 터미널(Terminal) 앱 열기

  • 키보드에서 [Command(⌘) + Space]를 누르면 Spotlight 검색창이 열린다.
  • "Terminal" 또는 "터미널" 을 입력하고 Enter를 누른다.
  • ※ Finder → 응용 프로그램 → 유틸리티 → 터미널 로 찾을 수 있다. 

STEP  5. Node.js 설치 확인

터미널에 아래를 입력하고 Enter를 누른다. 

$ node --version
  • v22.0.0 같은 숫자가 나오면 성공! 
  • 오류가 뜨면 CMD를 닫고 다시 열어 버전 정보 확인
  • 그래도 오류가 뜨면 Node.js 설치가 안 된 것이니 STEP 2로 이동

Claude Code 설치

STEP  6. 터미널에 아래를 복사해서 붙여넣고 Enter를 누른다. 

$ npm install -g @anthropic-ai/claude-code
  • 설치는 1~2분 걸린다. 화면에 글자가 올라가는 건 정상

STEP  7. 권한 오류(EACCES)가 날 경우
   "EACCES: permission denied" 오류가 나면 cmd 창에 아래 스크립트를 복사해 넣고 enter를 누른다. (아래 스크립트로 대신 설치한다.)

$ curl -fsSL https://claude.ai/install.sh | bash

 

로그인 & 최종 확인

 

STEP  8. Claude 계정으로 로그인

아래 명령어를 실행하면 브라우저가 자동으로 열린다.  Claude.ai 로그인 후 브라우저 창을 닫는다. 

$ claude login

 

STEP  9. 설치 상태 최종 확인

$ claude --version
$ claude doctor
  • 버전 숫자가 나오면 설치 완료!

프로젝트에서 시작하기

STEP  10. 내 프로젝트 폴더로 이동 후 실행

$ cd ~/Desktop/my-project
$ claude

 

Finder에서 해당 폴더를 터미널 창으로 드래그하면 경로가 자동 입력된다. 

0. 시작 전 확인

Claude Code는 유료 플랜(Pro / Max / Team / Enterprise)에서만 사용 가능합니다.
계정 만들기 → https://claude.ai

 

1. Windows 설치 가이드

Claude.ai 계정 & 유료 플랜

STEP 1. claude.ai (https://claude.ai) 에 접속해서 계정을 만든다.

  • Pro / Max / Team / Enterprise 중 하나의 유료 플랜이 필요해요.
  • 계정에 로그인 한다.

Node.js 설치

STEP 2. nodejs.org (https://nodejs.org) 에 접속한다. 

  • 사이트에 들어가면 큰 초록 버튼으로 "LTS (권장)" 버전이 보여요.
  •  버튼을 클릭하면 .msi 파일이 자동으로 다운로드된다. 

STEP 3. 다운로드된 설치 파일 실행하기

  • 다운로드 폴더에서 node-vXX.XX.X-x64.msi 파일을 더블클릭하여 실행한다. 
  • 설치 마법사가 뜨면 Next → Next → Install → Finish 순서로 눌러주어 인스톨한다.
  • 체크박스는 기본값 그대로 둔다.
  • "이 앱이 디바이스를 변경하도록 허용하시겠어요?" 팝업이 뜨면 [예]를 누른다. 

명령 프롬프트(CMD) 열기

STEP 4. CMD 창을 연다. 

  • 키보드에서 [Windows 키 + R]을 동시에 누른다.
  • 화면 왼쪽 아래에 작은 "실행" 창이 뜨면 열기(O): 칸에  cmd  를 입력하고 Enter를 누른다.
  • ※ 또는 작업 표시줄 검색창에 "명령 프롬프트" 또는 "cmd"를 검색해서 열어도 된다. 

STEP 5. Node.js 설치 확인

  • 2번에서 설치한 Node.js를 확인한다.
  • CMD 창에 아래 명령어를 입력하고 Enter를 누른다.
node --version

 

  • 버전 정보가 나오면 성공 -> v18 이상이면  ok
  • 오류가 뜨면 CMD를 닫고 다시 열어 버전 정보 확인
  • 그래도 오류가 뜨면 Node.js 설치가 안 된 것이니 STEP 2로 이동

Claude Code 설치

STEP 6. cmd 창에서 아래 명령어를 그대로 복사해서 붙여넣고 Enter를 누른다.

npm install -g @anthropic-ai/claude-code
  •  설치에 1~2분 정도 걸린다.  화면에 글자가 계속 올라가는 건 정상

로그인 & 최종 확인

 

STEP 7. cmd 창에서 Claude 계정으로 로그인

cmd 창에 아래 명령어를 실행하면 브라우저가 자동으로 열린다. Claude.ai에 로그인하면 인증이 완료된다.

claude login
  • 브라우저가 안 열리면, 터미널에 출력된 URL을 복사해서 브라우저 주소창에 직접 붙여넣으세요.

 STEP 8. cmd 창에서 설치 상태 최종 확인

> claude --version
> claude doctor
  • 버전 숫자가 나오고 doctor가 이상 없다고 하면 설치 완료!

프로젝트에서 시작하기

STEP 9. cmd 창에서 내 프로젝트 폴더로 이동 후 실행

> cd C:\Users\사용자이름\my-project
> claude
  • 폴더 경로를 모르면? 파일 탐색기에서 해당 폴더를 열고 주소창을 클릭하면 전체 경로를 복사할 수 있어요.

 

1. 문제 설명

4단계까지 구현한 키오스크 프로그램은 커피 메뉴와 디저트 메뉴를 구조체 배열로 저장하고, 메뉴 등록 / 조회 / 변경 / 삭제 / 주문 / 재고관리(선택) 기능을 수행할 수 있다.  이번 5단계에서는 고정 크기의 구조체 배열을 사용하지 않고, 메뉴 리스트를 동적으로 관리하도록 수정한다. 

 

5단계는 두 부분으로 구성된다.

  • 5-1단계: 동적 메모리 할당 기반 메뉴 리스트(필수)
  • 5-2단계: 링크드 리스트 기반 메뉴 리스트 (심화 선택)

 

2. 목표

  • 메뉴 정보를 고정 크기 배열이 아닌 동적 메모리로 관리할 수 있다.
  • malloc(), realloc(), free()를 사용하여 메뉴 리스트 크기를 실행 중에 조정할 수 있다.
  • 메뉴 등록 시 필요한 만큼 메모리를 확장할 수 있다.
  • 메뉴 삭제 시 동적 메모리의 데이터를 정리할 수 있다.
  • 프로그램 종료 시 할당한 메모리를 해제할 수 있다.
  • 심화 단계에서는 링크드 리스트를 사용하여 메뉴를 노드 단위로 관리할 수 있다.

 

5-1단계: 동적 메모리 할당 기반 메뉴 리스트 (필수)

 

3. 요구사항

3.1 데이터 구조 수정

기존 고정 배열을 제거하고 포인터 변수를 사용하시오.

기존 코드 예:

MenuItem coffee_menu_list[10];
MenuItem dessert_menu_list[10];
 

수정 코드 예:

MenuItem* coffee_menu_list;
MenuItem* dessert_menu_list;

int coffee_count;
int dessert_count;

int coffee_capacity;
int dessert_capacity;
 

 

3.2 메뉴 리스트 초기화 기능 추가

프로그램 시작 시 메뉴 리스트를 동적 할당하시오. 초기 용량은 배열과 마찬가지로 커피 5개, 디저트 5개로 설정한다.

#define INIT_CAPACITY 5
 

예:

coffee_menu_list = malloc(sizeof(MenuItem) * INIT_CAPACITY);
dessert_menu_list = malloc(sizeof(MenuItem) * INIT_CAPACITY);
 

요구사항:

  • 메모리 할당 실패 시 오류 메시지를 출력한다. ( malloc() 리턴값 체크)
  • 초기 count는 0으로 설정한다.
  • 초기 capacity는 5로 설정한다.

3.3 메뉴 등록 기능 수정 - register_menu_item()

메뉴 등록 시 현재 저장된 메뉴 개수가 capacity와 같으면 메모리 크기를 확장하시오.

 

요구사항:

  • 커피 메뉴인지 디저트 메뉴인지 선택한다.
  • 메뉴명, 가격, 재고수량을 입력받는다.
  • menu_id는 자동 증가로 설정한다.
  • status는 기본값 판매중으로 설정한다.
  • 재고수량이 0이면 status를 품절로 설정한다.
  • 현재 배열이 가득 찼으면 realloc()을 사용하여 capacity를 2배로 확장한다.
  • 새 메뉴를 리스트에 저장한다.

출력 예:

메뉴구분 (1. 커피, 2. 디저트): 1
메뉴명 입력: 아메리카노
가격 입력: 3000
재고수량 입력: 20

[메모리 확장] coffee_menu_list capacity: 5 -> 10
[등록 완료]
 

 

3.4 메뉴 삭제 기능 수정 - delete_menu_item()

동적 메모리에서 메뉴를 삭제할 수 있도록 수정하시오.

 

요구사항:

  • 전체 메뉴를 출력한다.
  • 삭제할 메뉴 번호를 입력한다.
  • 해당 메뉴를 찾는다.
  • 메뉴가 존재하지 않으면 오류 메시지를 출력한다.
  • 삭제할 메뉴 뒤에 있는 메뉴들을 한 칸씩 앞으로 이동한다.
  • count를 1 감소시킨다.

출력 예:

삭제할 메뉴 번호 입력: 102

[삭제 완료]
 

 

3.5 메뉴 조회 기능 수정 - retrieve_menu_item()

동적 메모리에 저장된 메뉴 목록을 출력하시오.

 

요구사항:

  • coffee_count, dessert_count만큼 반복하여 출력한다.
  • capacity 크기 전체를 출력하지 않는다.
  • 재고수량도 함께 출력한다.

출력 예:

====================[Coffee]============================
No   Name                  Price    Status       Stock
========================================================
101  Americano              3000     AVAILABLE    20
102  Cafe Latte             4000     AVAILABLE    15

현재 저장 개수: 2
현재 배열 크기: 5
 

 

3.6 프로그램 종료 시 메모리 해제

프로그램 종료 전에 동적 할당한 메모리를 해제하시오.

 

요구사항:

  • free(coffee_menu_list);
  • free(dessert_menu_list);
  • free() 후 포인터를 NULL로 설정한다.

출력 예:

[프로그램 종료]
동적 메모리를 해제했습니다.
 

 

5-2단계: 링크드 리스트 기반 메뉴 리스트

4. 요구사항

4.1 데이터 구조 수정

메뉴 정보를 링크드 리스트 노드로 관리하시오. 

typedef struct menu_node {
    MenuItem data;
    struct menu_node* next;
} MenuNode;
 

커피 메뉴와 디저트 메뉴의 시작 노드를 각각 관리한다. 

MenuNode* coffee_head;
MenuNode* dessert_head;
 

 

4.2 메뉴 등록 기능 수정

메뉴 등록 시 새 노드를 동적 생성하여 리스트의 마지막에 추가하시오.

 

요구사항:

  • malloc()을 사용하여 새 노드를 생성한다.
  • 새 노드의 data에 메뉴 정보를 저장한다.
  • 새 노드의 next는 NULL로 설정한다.
  • 리스트가 비어 있으면 head가 새 노드를 가리키도록 한다.
  • 리스트가 비어 있지 않으면 마지막 노드 뒤에 새 노드를 연결한다.

출력 예:

메뉴구분 (1. 커피, 2. 디저트): 2
메뉴명 입력: 치즈케이크
가격 입력: 5000
재고수량 입력: 5

[노드 생성 완료]
[등록 완료]
 

 

4.3 메뉴 조회 기능 수정

링크드 리스트를 순회하면서 메뉴 정보를 출력하시오.

 

요구사항:

  • head부터 시작한다.
  • 현재 노드가 NULL이 될 때까지 반복한다.
  • 각 노드의 data를 출력한다.

출력 예:

====================[Coffee]============================
No   Name                  Price    Status       Stock
========================================================
101  Americano              3000     AVAILABLE    20
102  Cafe Latte             4000     AVAILABLE    15
 

 

4.4 메뉴 변경 기능 수정

링크드 리스트에서 메뉴 번호를 검색하여 메뉴 정보를 수정하시오.

 

요구사항:

  • 전체 메뉴를 출력한다.
  • 수정할 메뉴 번호를 입력한다.
  • head부터 순회하며 menu_id가 일치하는 노드를 찾는다.
  • 메뉴명, 가격, 판매상태, 재고수량 중 수정 항목을 선택한다.
  • 재고수량이 0이면 판매상태를 품절로 변경한다.
  • 재고수량이 1 이상이면 판매상태를 판매중으로 변경할 수 있다.

4.5 메뉴 삭제 기능 수정

링크드 리스트에서 특정 메뉴 노드를 삭제하시오.

 

요구사항:

  • 삭제할 메뉴 번호를 입력한다.
  • 삭제할 노드를 찾는다.
  • 삭제할 노드가 head인 경우 head를 다음 노드로 변경한다.
  • 중간 또는 마지막 노드인 경우 이전 노드의 next를 삭제할 노드의 next로 연결한다.
  • 삭제한 노드는 free()로 해제한다.

출력 예:

삭제할 메뉴 번호 입력: 101

[삭제 완료]
노드 메모리를 해제했습니다.
 

 

4.6 프로그램 종료 시 전체 노드 해제

프로그램 종료 전에 모든 노드를 해제하시오.

 

요구사항:

  • 커피 리스트의 모든 노드를 해제한다.
  • 디저트 리스트의 모든 노드를 해제한다.
  • 노드를 하나씩 순회하면서 free()를 수행한다.

출력 예:

[프로그램 종료]
커피 메뉴 리스트 메모리를 해제했습니다.
디저트 메뉴 리스트 메모리를 해제했습니다.
 

 

5. 제출 형식

분할된 소스코드 파일을 제출한다.

main.c
kiosk_ui.c
kiosk_ui.h
menu_item.c
menu_item.h
order.c
order.h

 

5-2단계 링크드 리스트까지 구현한 경우, menu_item을 linked list로 정의하고 리스트에 추가/삭제/항목 가져오는 등의 기능을 구현한 파일을 별도 파일로 (예: menu_list.c, menu_list.h) 관리할 수 있다. 

3단계 주문관리가 포함된 클래스 다이어그램을 기반으로 결제 기능을 추가한 시퀀스 다이어그램과 클래스 다이어그램을 완성하고, 코드를 구현하시오.

1. 주문-결제 기능 추가 Use Case Description

2. 주문-결제 Class Diagarm

콘솔키오스크 with Payment.drawio
0.25MB

 

[실습과제] 주문 하기의 결제기능 추가 설계 구현하기 

 

[제출 1] 3단계의 주문에서 결제기능이 추가된 주문하기 시퀀스 다이어그램

[제출 2] 결제기능이 추가된 주문 코드

* 단, 코드는 클래스별로 또는 기능군으로 분할한 파일로 제출한다. 

아래 1, 2의 use case description과 class diagram을 참조하여 주문하기의 sequence diagram을 작성하고 이를 기반으로 주문하기 기능을 코드로 구현하시오. 코드는 2단계까지 진행한 코드에 주문하기 기능을 추가하시오. 

1. 주문하기 Use Case Description


 

2. 주문관리 클래스 다이어그램

 

 

[실습과제] 주문 하기 기능 동적 설계(Sequence Diagram) 및 구현 하기

[제출 1]  주문하기 시퀀스 다이어그램

[제출 2]  주문하기 기능이 추가된 키오스크 코드

KioskUI,

MenuController, MenuRepository, MenuItem, Coffee, Dessert,

OrderController, OrderRepository, Order, OrderItem 클래스 포함

 

콘솔키오스크_with Order.drawio
0.24MB

[실습과제] Dessert 클래스 추가하기

 

위 1번의 클래스 다이어그램과 2번의 예시코드를 기반으로 MenuItem에 Dessert 클래스를 추가하고 코드를 완성하시오. 단, 메뉴 관리는 등록/수정/조회 기능을 필수로 구현하고 삭제 기능은 등록/수정/조회 기능이 완성 된 후에 구현하시오. 

 

[제출 1]  메뉴관리 클래스 다이어그램 (Dessert 클래스 추가)

 

[제출 2]  메뉴관리  구현 코드

 

KioskUI, MenuController, MenuRepository, MenuItem, Coffee, Dessert 클래스 포함

class MenuItem:
    def __init__(self, menu_id, menu_type, name, price, description, status):
        self.__menu_id = menu_id
        self.__menu_type = menu_type
        self.__name = name
        self.__price = price
        self.__description = description
        self.__status = status

    @property
    def menu_id(self):
        return self.__menu_id

    @property
    def menu_type(self):
        return self.__menu_type

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        self.__name = value

    @property
    def price(self):
        return self.__price

    @price.setter
    def price(self, value):
        self.__price = int(value)

    @property
    def description(self):
        return self.__description

    @description.setter
    def description(self, value):
        self.__description = value

    @property
    def status(self):
        return self.__status

    @status.setter
    def status(self, value):
        self.__status = value

    def to_dict(self):
        return {
            "menu_id": self.__menu_id,
            "menu_type": self.__menu_type,
            "name": self.__name,
            "price": self.__price,
            "description": self.__description,
            "status": self.__status
        }


class Coffee(MenuItem):
    def __init__(self, menu_id, name, price, description, status, bean_type, temp_type):
        super().__init__(menu_id, "Coffee", name, price, description, status)
        self.__bean_type = bean_type
        self.__temp_type = temp_type

    @property
    def bean_type(self):
        return self.__bean_type

    @bean_type.setter
    def bean_type(self, value):
        self.__bean_type = value

    @property
    def temp_type(self):
        return self.__temp_type

    @temp_type.setter
    def temp_type(self, value):
        self.__temp_type = value

    def to_dict(self):
        menu_data = super().to_dict()
        menu_data["bean_type"] = self.__bean_type
        menu_data["temp_type"] = self.__temp_type
        return menu_data


class Dessert(MenuItem):
    def __init__(self, menu_id, name, price, description, status, allergy, calories):
        super().__init__(menu_id, "Dessert", name, price, description, status)
        self.__allergy = allergy
        self.__calories = calories

    @property
    def allergy(self):
        return self.__allergy

    @allergy.setter
    def allergy(self, value):
        self.__allergy = value

    @property
    def calories(self):
        return self.__calories

    @calories.setter
    def calories(self, value):
        self.__calories = int(value)

    def to_dict(self):
        menu_data = super().to_dict()
        menu_data["allergy"] = self.__allergy
        menu_data["calories"] = self.__calories
        return menu_data


class MenuRepository:
    def __init__(self):
        self.__menu_list = []
        self.__next_menu_id = 1

    def generate_menu_item_id(self):
        menu_id = self.__next_menu_id
        self.__next_menu_id += 1
        return menu_id

    def add_menu_item(self, menu_item):
        self.__menu_list.append(menu_item)

    def find_all(self):
        return self.__menu_list

    def find_by_id(self, menu_id):
        for menu_item in self.__menu_list:
            if menu_item.menu_id == menu_id:
                return menu_item
        return None

    def find_by_type(self, menu_type):
        result = []

        for menu_item in self.__menu_list:
            if menu_item.menu_type == menu_type:
                result.append(menu_item)

        return result


class MenuController:
    def __init__(self):
        self.__menu_repository = MenuRepository()

    def check_mandatory_field(self, name, price, status):
        return all([name, price, status])

    def register_menu_item(self, menu_type, name, price, description, status,
                           bean_type=None, temp_type=None, allergy=None, calories=None):

        menu_id = self.__menu_repository.generate_menu_item_id()

        if menu_type == "Coffee":
            menu_item = Coffee(menu_id, name, int(price), description, status, bean_type, temp_type)

        elif menu_type == "Dessert":
            menu_item = Dessert(menu_id, name, int(price), description, status, allergy, calories)

        else:
            menu_item = MenuItem(menu_id, menu_type, name, int(price), description, status)

        self.__menu_repository.add_menu_item(menu_item)

    def retrieve_menu_list(self):
        menu_items = self.__menu_repository.find_all()
        result = []

        for item in menu_items:
            result.append(item.to_dict())

        return result

    def retrieve_menu_by_id(self, menu_id):
        menu_item = self.__menu_repository.find_by_id(int(menu_id))

        if menu_item is None:
            return None

        return menu_item.to_dict()

    def retrieve_menu_by_type(self, menu_type):
        menu_items = self.__menu_repository.find_by_type(menu_type)
        result = []

        for item in menu_items:
            result.append(item.to_dict())

        return result

    def modify_menu_item(self, menu_id, field, new_value):
        menu_item = self.__menu_repository.find_by_id(int(menu_id))

        if menu_item is None:
            return False

        if field == "1":
            menu_item.name = new_value

        elif field == "2":
            menu_item.price = new_value

        elif field == "3":
            menu_item.description = new_value

        elif field == "4":
            menu_item.status = new_value

        elif field == "5":
            if isinstance(menu_item, Coffee):
                menu_item.bean_type = new_value
            elif isinstance(menu_item, Dessert):
                menu_item.allergy = new_value
            else:
                return False

        elif field == "6":
            if isinstance(menu_item, Coffee):
                menu_item.temp_type = new_value
            elif isinstance(menu_item, Dessert):
                menu_item.calories = new_value
            else:
                return False

        else:
            return False

        return True


class MainUI:
    def __init__(self):
        self.__menu_controller = MenuController()

    def run(self):
        while True:
            self.__print_main_menu()
            selected_menu = input("메뉴를 선택하세요: ")

            if selected_menu == "11":
                self.__select_register_menu()

            elif selected_menu == "12":
                self.__select_modify_menu()

            elif selected_menu == "13":
                self.__select_delete_menu()

            elif selected_menu == "14":
                self.__select_retrieve_menu()

            elif selected_menu == "21":
                self.__select_order()

            elif selected_menu == "0":
                print("프로그램 종료")
                break

            else:
                print("잘못된 입력")

    def __print_main_menu(self):
        print("\n============= 카페 키오스크 =============")
        print("메뉴관리(관리자)       주문관리(고객)")
        print("11. 메뉴 등록          21. 주문[TODO]")
        print("12. 메뉴 수정")
        print("13. 메뉴 삭제[TODO]")
        print("14. 메뉴 조회")
        print("0. 종료")
        print("========================================")

    def __select_register_menu(self):
        print("\n[메뉴 등록]")
        print("1. Coffee")
        print("2. Dessert")

        menu_type_input = input("유형 선택: ")

        if menu_type_input == "1":
            menu_type = "Coffee"

        elif menu_type_input == "2":
            menu_type = "Dessert"

        else:
            print("잘못된 입력")
            return

        name = input("메뉴명: ")
        price = input("가격: ")
        description = input("설명: ")
        status = input("상태(1. 판매중, 2. 품절): ")

        bean_type = None
        temp_type = None
        allergy = None
        calories = None

        if menu_type == "Coffee":
            print("\n원두 종류")
            print("Arabica, Robusta, Ethiopia, Colombia, Kenya AA, Blend")
            bean_type = input("원두 종류 입력: ")

            print("\n온도 선택")
            print("hot, ice")
            temp_type = input("선택: ")

            if temp_type not in ["hot", "ice"]:
                print("잘못된 입력")
                return

        elif menu_type == "Dessert":
            allergy = input("알레르기 정보: ")
            calories = input("칼로리: ")

        if not self.__menu_controller.check_mandatory_field(name, price, status):
            print("누락된 정보를 입력하세요.")
            return

        self.__menu_controller.register_menu_item(
            menu_type, name, price, description, status,
            bean_type, temp_type, allergy, calories
        )

        print("등록 완료")

    def __display_menu_list(self, menu_list):
        print(
            f"{'ID':<5}"
            f"{'Type':<10}"
            f"{'이름':<15}"
            f"{'가격':<10}"
            f"{'상태':<10}"
            f"{'설명':<20}"
            f"{'원두':<15}"
            f"{'온도':<10}"
            f"{'알레르기':<15}"
            f"{'칼로리':<10}"
        )
        print("-" * 130)

        for m in menu_list:
            print(
                f"{m['menu_id']:<5}"
                f"{m['menu_type']:<10}"
                f"{m['name']:<15}"
                f"{m['price']:<10}"
                f"{m['status']:<10}"
                f"{m['description']:<20}"
                f"{m.get('bean_type', ''):<15}"
                f"{m.get('temp_type', ''):<10}"
                f"{m.get('allergy', ''):<15}"
                f"{m.get('calories', ''):<10}"
            )

        print("=" * 130)

    def __select_modify_menu(self):
        print("\n[메뉴 수정]")

        menu_list = self.__menu_controller.retrieve_menu_list()

        if not menu_list:
            print("메뉴 없음")
            return

        self.__display_menu_list(menu_list)

        menu_id = input("수정할 메뉴 ID 입력: ")
        menu_item = self.__menu_controller.retrieve_menu_by_id(menu_id)

        if menu_item is None:
            print("존재하지 않는 ID입니다.")
            return

        print("\n[현재 메뉴 정보]")
        print(f"메뉴명 : {menu_item['name']}")
        print(f"가격   : {menu_item['price']}")
        print(f"설명   : {menu_item['description']}")
        print(f"상태   : {menu_item['status']}")

        print("\n수정 항목")
        print("1. 메뉴명")
        print("2. 가격")
        print("3. 설명")
        print("4. 상태")

        if menu_item["menu_type"] == "Coffee":
            print(f"원두   : {menu_item['bean_type']}")
            print(f"온도   : {menu_item['temp_type']}")
            print("5. 원두")
            print("6. 온도")

        elif menu_item["menu_type"] == "Dessert":
            print(f"알레르기 : {menu_item['allergy']}")
            print(f"칼로리   : {menu_item['calories']}")
            print("5. 알레르기")
            print("6. 칼로리")

        field_no = input("선택: ")
        field_value = input("새로운 값 입력: ")

        result = self.__menu_controller.modify_menu_item(menu_id, field_no, field_value)

        if result:
            print("수정 완료")

        else:
            print("수정 실패")

    def __select_retrieve_menu(self):
        print("\n[메뉴 조회]")
        print("1. 전체 조회")
        print("2. Coffee 조회")
        print("3. Dessert 조회")

        selected_menu = input("선택: ")

        if selected_menu == "1":
            menu_list = self.__menu_controller.retrieve_menu_list()

        elif selected_menu == "2":
            menu_list = self.__menu_controller.retrieve_menu_by_type("Coffee")

        elif selected_menu == "3":
            menu_list = self.__menu_controller.retrieve_menu_by_type("Dessert")

        else:
            print("잘못된 입력")
            return

        if not menu_list:
            print("메뉴 없음")
            return

        self.__display_menu_list(menu_list)

    def __select_delete_menu(self):
        print("[TODO] 메뉴 삭제")

    def __select_order(self):
        print("[TODO] 주문 기능")


if __name__ == "__main__":
    ui = MainUI()
    ui.run()

+ Recent posts