Start learning free

LESSON 403 OF 404 · PROJECTS: OBJECT-ORIENTED

Vending Machine in Go in Go

Practice

Build a VendingMachine type (a struct with methods) for a machine that sells one kind of item for a fixed price. It keeps the money inserted so far (the credit), sells an item when the credit is enough, and gives the remaining credit back on request. A new object is made with newVendingMachine().

Rules:

  • State. A new machine has credit 0 and price 150 (every item costs 150). Give the struct the fields credit float64 and price float64; newVendingMachine() returns &VendingMachine{price: 150} (the credit starts at Go's zero value, 0).
  • func (machine *VendingMachine) insert(amount float64) adds amount to the credit. Nothing is printed or returned.
  • func (machine *VendingMachine) selectItem() string tries to buy one item and returns a string:
    • If the credit is less than the price, return "Need N more", where N is the missing amount (price - credit) as a whole number, for example "Need 100 more". The credit does not change.
    • Otherwise (the credit is equal to or greater than the price, so exact payment works), subtract the price from the credit and return "Dispensing!". Any extra money stays in the credit.
  • func (machine *VendingMachine) refund() float64 returns the whole credit and sets it back to 0, so asking again right away returns 0.

You start with this driver below your code:

func mainFunction() {
	machine := newVendingMachine()
	machine.insert(50)
	fmt.Println(machine.selectItem())
	machine.insert(150)
	fmt.Println(machine.selectItem())
	fmt.Println("Refunded: " + strconv.Itoa(int(machine.refund())))
	machine.insert(150)
	fmt.Println(machine.selectItem())
	fmt.Println("Refunded: " + strconv.Itoa(int(machine.refund())))
	machine.insert(100)
	fmt.Println(machine.selectItem())
	fmt.Println("Refunded: " + strconv.Itoa(int(machine.refund())))
}

Walk through it: 50 is not enough, so you see Need 100 more. After 150 more the credit is 200, so the machine dispenses and keeps 50 (200 - 150), and the refund is 50. Then 150 is exact payment: it dispenses and the refund is 0. Finally 100 is short by 50, the credit stays 100, and the refund is 100.

Expected output:

Need 100 more
Dispensing!
Refunded: 50
Dispensing!
Refunded: 0
Need 50 more
Refunded: 100

Convert the missing amount with int(machine.price - machine.credit) and turn it into text with strconv.Itoa(...). Do the subtraction only when the item is dispensed, not when the credit is too low. If you forget it, the leftover credit is wrong and the refund is too big.

In the refund method, save the credit first, then reset it to 0, then return what you saved. Return the saved variable, not machine.credit.

type VendingMachine struct {
	credit float64
	price  float64
}

func newVendingMachine() *VendingMachine {
	return &VendingMachine{price: 150}
}

func (machine *VendingMachine) insert(amount float64) {
	machine.credit += amount
}

func (machine *VendingMachine) selectItem() string {
	if machine.credit < machine.price {
		missing := int(machine.price - machine.credit)
		return "Need " + strconv.Itoa(missing) + " more"
	}
	machine.credit -= machine.price
	return "Dispensing!"
}

func (machine *VendingMachine) refund() float64 {
	refunded := machine.credit
	machine.credit = 0
	return refunded
}

STEP 1 OF 17
    Ctrl + Enter to check

    Vending Machine in Go

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free