Menu
Coddy logo textTech

Recap - Vending Machine

Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 21 of 57.

challenge icon

Challenge

Medium

Build a vending machine with error classes UnknownProduct, SoldOut and NotEnoughCredit, all StandardError subclasses. VendingMachine.new(stock) takes a hash { "cola" => [150, 2] } (price in cents, count). credit is readable but set only through a private setter. insert(cents) adds credit. buy(name) raises UnknownProduct (no such product: tea), SoldOut (cola is sold out) or NotEnoughCredit (cola costs 1.50, credit 1.00) in that order; otherwise it takes one item from stock, subtracts the price and returns the name. refund returns the credit and sets it to 0. A private helper money(cents) formats 1.50.

The supplied code reads the stock from the first line (cola:150:2,chips:90:1), then commands insert n, buy name or refund. It prints credit 2.00, bought cola, refund 0.50 or the error message, and finally tries to set credit from outside, printing credit is protected.

Your code goes in unknown_product.rb, sold_out.rb, not_enough_credit.rb and vending_machine.rb. main.rb holds the supplied input/output code and cannot be edited.

Try it yourself

require_relative 'unknown_product'
require_relative 'sold_out'
require_relative 'not_enough_credit'
require_relative 'vending_machine'

# Supplied input/output code: keep it as it is
input = []
while (line = gets)
  input << line.chomp
end
stock = input[0].split(",").to_h do |entry|
  name, price, count = entry.split(":")
  [name, [price.to_i, count.to_i]]
end
machine = VendingMachine.new(stock)
input.drop(1).each do |line|
  command, arg = line.split
  begin
    case command
    when "insert"
      machine.insert(arg.to_i)
      puts format("credit %.2f", machine.credit / 100.0)
    when "buy"
      puts "bought #{machine.buy(arg)}"
    else
      puts format("refund %.2f", machine.refund / 100.0)
    end
  rescue UnknownProduct, SoldOut, NotEnoughCredit => e
    puts e.message
  end
end
begin
  machine.credit = 500
  puts "credit changed"
rescue NoMethodError
  puts "credit is protected"
end

All lessons in Object Oriented Programming

Practice on your own: Online Ruby compiler