이전 강의에서 물품을 바로 주문하는 것이 아니라 장바구니에 추가하는 것을 구현했습니다. 그렇다면 사용자가 장바구니에 추가한 물품들이 어떤 것인지 알 수 있도록 출력하는 기능인 '장바구니 확인' 기능을 구현해야합니다. 아무것도 생각하지 않고 저번처럼 쉬운 기능부터 생각해봅니다. 사용자 객체의 map형 필드값을 그대로 출력하면 끝이겠죠? 그런데 그냥 출력하지 않고 딱 한가지만 고려합니다. buyer.shoppingbucket을 모두 출력하는 것이 아니라 장바구니에 물품이 없을때는 "장바구니가 비었습니다."라고 출력합니다. 물품이 한 개 이상 있으면 "%s, 수량: %d\n" 포맷으로 출력해봅니다. 물론 buyer.shoppingbucket의 key와 value값을 모두 접근하기 위해 for range문을 사용합니다.
충분히 고민하고 아래 예시 코드를 확인해보세요.
else if menu == 5 { // 장바구니 확인
if len(buyer.shoppingbucket) == 0 {
fmt.Println("장바구니가 비었습니다.")
} else {
for index, val := range buyer.shoppingbucket {
fmt.Printf("%s, 수량: %d\n", index, val)
}
}
fmt.Println()
fmt.Print("엔터를 입력하면 메뉴 화면으로 돌아갑니다.")
fmt.Scanln()
}buyer.shoppingbucket의 길이를 기준으로 길이가 0이면(장바구니에 품목이 없으면) "장바구니가 비었습니다."를 출력하고 아니면 장바구니의 모든 품목의 이름과 수량을 출력합니다. 저는 이 부분을 장바구니가 비었는지 안비었는지 확인하고 출력하는 기능을 한다는 뜻으로 emptyBucket()이라는 이름의 함수로 따로 생성하겠습니다.
func emptyBucket(byr *buyer) {
if len(byr.shoppingbucket) == 0 {
fmt.Println("장바구니가 비었습니다.")
} else {
for index, val := range byr.shoppingbucket {
fmt.Printf("%s, 수량: %d\n", index, val)
}
}
fmt.Println()
}else if menu == 5 { // 장바구니 확인
emptyBucket(buyer)
}장바구니 상품 주문
장바구니에 물품을 담기만 하면 사실 의미가 없습니다. 장바구니에 담은 물품들을 주문할 수 있어야합니다. 따라서 '장바구니 확인' 기능에 '주문' 기능을 추가할 것입니다. 바로 상품들을 한번에 주문하는 '장바구니 상품 주문' 기능입니다. 따라서 장바구니 물품 확인을 선택하면
- 장바구니 물품 주문
- 메뉴로 돌아가기
- 실행할 기능을 입력하시오:
를 출력하고 선택할 수 있게 구현합니다. 물론 for문을 이용해서 틀린 선택을 하면 다시 선택하게끔 구현합니다. 물론 이를 선택하는 번호를 사용자에게 입력받는 변수를 선언합니다. 아래 예시가 있습니다.
else if menu == 5 { // 장바구니 확인
bucketmenu := 0
for {
emptyBucket(buyer) // 장바구니 비었는지 확인, 안비었으면 물품 출력
fmt.Println("1. 장바구니 상품 주문")
fmt.Println("2. 메뉴로 돌아가기")
fmt.Print("실행할 기능을 입력하시오 :")
fmt.Scanln(&bucketmenu)
fmt.Println()
if bucketmenu == 1 {
//장바구니 상품 주문하는 기능
} else if bucketmenu == 2{
fmt.Println()
break
} else {
fmt.Println("잘못된 입력입니다. 다시 입력해주세요.")
}
}
}이제 bucketmenu가 1일 때 즉, 장바구니의 물품을 주문했을 때 기능을 구현할 차례입니다. 그런데 여기서 판별할 것이 있습니다.
- 장바구니에 추가한 물품의 포인트의 총 합이 사용자의 잔여 포인트보다 많을 경우
- '주문'을 해야 포인트가 차감되기 때문에
- 담아놓은 상태에서 바로 주문을 해서 장바구니에 있는 물품의 수량이 잔여 수량보다 많을 경우
- 장바구니에 담을 당시에는 잔여 수량이 20개여서 15개를 담았는데 그 후에 10개를 주문하면 5개가 초과되는 상황이 발생함
따라서 이를 각각 판별하는 기능을 구현해야합니다. 우선 requiredPoint() 함수를 만들어 1. 장바구니의 총 필요 마일리지를 계산하고 2. 필요 마일리지와 보유 마일리지를 출력하고 3. 마일리지가 부족할 시에는 "마일리지가 %d점 부족합니다."라는 메시지와 false를 반환합니다. buyer.shoppingbucket의 품목 이름과 담은 수량을 접근하기 위해 for range문을 사용합니다.
우선 총 필요 마일리지를 구현해봅니다. (내 장바구니의 품목 == 품목 리스트(item[i].name))면 bucketpoint 변수를 선언해 (품목의 포인트*장바구니품목에 수량)을 초기화하고 모두 더합니다. 이는 조금만 생각하면 구현할 수 있습니다.
func requiredPoint(itm []item, byr *buyer) (canbuy bool) {
bucketpoint := 0
for index, val := range byr.shoppingbucket { // 총 필요 마일리지 계산
for i := 0; i < len(itm); i++ {
if itm[i].name == index {
bucketpoint += itm[i].price * val
}
}
}
fmt.Println("필요 마일리지 :", bucketpoint)
fmt.Println("보유 마일리지 :", byr.point)
fmt.Println()
if byr.point < bucketpoint {
fmt.Println("마일리지가 %d점 부족합니다.", bucketpoint - byr.point)
return false
}
return true
}그리고 emptyBucket() 함수가 물품 리스트를 출력하므로 그 밑에 함수를 호출합니다. 그리고 살수 있는지 없는지를 판별하는 변수를 선언 및 초기화합니다.
canbuy := requiredPoint(items, buyer)
// 살수 있는지 없는지 확인하는 canby 선언 및 초기화그럼 이제 장바구니의 물품 수량이 잔여 수량을 초과할 경우를 판별하는 함수를 만듭니다. 저는 excessAmount() 함수를 만들었습니다. 이 함수도 똑같이 true/false 값을 반환합니다. 이 기능은 위 함수 구조와 아주 흡사합니다. 초과한 품목에 따라 "%s, %d개 초과"포맷으로 출력합니다. 물론 초과할 경우 false 그렇지 않을 경우 true를 출력합니다.
func excessAmount(itm []item, byr *buyer) (canbuy bool){
for index, val := range byr.shoppingbucket {
for i := 0; i < len(itm); i++ {
if itm[i].name == index {
if itm[i].amount < val { // 장바구니의 물품 총 개수가 판매하는 물품 개수보다 클 때
fmt.Println("%s, %d개초과", itm[i].name, val-itm[i].amount)
return false
}
}
}
}
return true
}그리고 바로 requiredPoint() 함수 밑에 호출합니다. 이때 똑같은 변수에 반환값을 초기화하는데 이유는 둘중에 한개라도 false가 나오면 어차피 구매가 불가능하기 때문입니다.
emptyBucket(buyer) // 장바구니 비었는지 확인, 안비었으면 물품 출력
canbuy := requiredPoint(items, buyer)
canbuy = excessAmount(items, buyer)