Skip to content

boddhisattva/vending_machine_kata_ruby

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vending Machine (Ruby)

About

Solves for building a Vending Machine based on this problem statement

Diagrammatic Representation of Key Program workflow scenarios

Please refer to the cli_flow_diagrams for Key workflows involving the Vending Machine usage including

  • Happy path to purchase an item
  • Load(new item) & Reload(existing item & coins) functionality
  • Initial Partial payment and being prompted to pay more to complete transaction
  • Auto cancel payment & issue refund when machine has insufficient balance to render change to complete purchase

Architecture & Design

Core Architecture Principles

Separation of Concerns

  ┌─────────────────┐
  │   CLI Layer     │  (User Interface)
  │  bin/ & lib/cli/│
  └────────┬────────┘
          │
  ┌────────▼────────┐
  │  Business Logic │  (Core Domain)
  │      lib/       │
  └────────┬────────┘
          │
  ┌────────▼────────┐
  │   Data Layer    │  (State Management)
  │  Items, Balance │
  └─────────────────┘

Key Components of the Vending Machine CLI

Core Components:

  • VendingMachine: Main orchestrator, delegates to specialized components

  • PurchaseSessionOrchestrator: CLI-specific coordinator that manages the interactive payment collection loop, handling user input and payment parsing until purchase completion

  • PaymentProcessor: Handles all payment transactions and change calculation

  • SessionManager: Manages multi-step purchase sessions

  • ChangeReloader: Handles change reloading

  • ItemLoader: Handles adding a new item & reloading existing items

  • Validators: Dedicated classes for each validation concern

    • PaymentValidator: Validates denominations and amounts
    • ReloadValidator: Validates reload operations
    • ChangeValidator: Ensures change can be made
  • Formatters: Consistent formatting across the application

    • CurrencyFormatter: Euro formatting

CLI-Specific Components:

  • PurchaseExecutor: Orchestrates the item selection phase of a CLI purchase

  • ItemSelector: Handles item selection by number with validation and display

  • UserInputHandler: Captures and sanitizes user keyboard input

  • VendingMachineDisplay: Renders all UI output (menus, status, messages)

  • PaymentInputParser: Parses string input like "{100 => 2}" into payment hashes

  • MenuRouter: Routes menu choices to appropriate actions

  • ItemLoadHandler: Handles CLI flow for loading items interactively

  • ChangeReloadHandler: Handles CLI flow for reloading change interactively

Session-Based Purchase Flow

The session-based implementation provides a realistic vending machine experience:

1. START SESSION
   
2. ACCUMULATE PAYMENTS (multiple insertions allowed)
   
3. VALIDATE CHANGE AVAILABILITY
   
4. COMPLETE or AUTO-CANCEL WITH REFUND

Features

  • Default currency: Euro (€)
  • Check machine status(of remaining items & balance) at anytime
  • Check machine balance at any point in time
  • Supports session-based purchase flow
  • Add reload functionality for
    • Existing and New Items
    • To Add change
  • Coin denominations supported: 1, 2, 5, 10, 20, 50 cents, €1, €2 coin
  • Displays available change and coin breakdown in plain English

Performance Optimizations

  • O(1) Item Lookup using Hashes instead of using Array based Linear Search to find each matching item

Assumptions

  • A user can purchase only one item at a time through the Vending Machine

Usage

Prerequisities

  • Ruby version 3.3.4

Running the Vending Machine CLI

  • From the project Root directory
ruby bin/vending_machine_cli.rb

CLI Options

  • 1. Display available items
    • Shows all items with prices and quantities available
  • 2. Purchase item with session
    • Select item by number
    • Enter payment as a hash, e.g. {100 => 2, 50 => 1} for €2.50
    • You can insert more coins until the price is met
    • Type cancel to cancel the session
  • 3. Display current balance
    • Shows available change in the machine with coin breakdown
  • 4. Display machine status
    • Shows complete machine status including balance and inventory
  • 5. Reload or add new items
    • Add quantity to existing items or add new items with prices
  • 6. Reload change
    • Add coins to the machine's balance
  • q. Quit (also accepts quit or exit)

Example Payment Format

  • {100 => 2, 50 => 1} means 2 €1 coins and 1 50-cent coin (total: €2.50)
  • Valid denominations: 1, 2, 5, 10, 20, 50, 100, 200 (all in cents)

Initial Machine Balance

The machine starts with the following coins:

{
  50 => 6,
  10 => 10,
  20 => 10,
  100 => 2,
  200 => 1,
  5 => 10,
  2 => 10,
  1 => 2
}

Initial Items in Vending Machine

  { name: 'Coke', price: 150, quantity: 5 },
  { name: 'Chips', price: 100, quantity: 3 },
  { name: 'Candy', price: 75, quantity: 8 },
  { name: 'Water', price: 125, quantity: 2 }

Notes

  • All currency is displayed as Euro (€) with two decimals (e.g., €1.50)
  • Only the session-based purchase flow is supported
  • Coin breakdown is always shown in plain English

Areas of Improvements

  • Refactor specs further
  • Refactor existing validation logic across different places/classes to remove duplication where applicable & feasible
  • Current end to end specs have room for improvement to go through the complete session flow
  • UI flow can be further improved to auto cancel

Enhancements/Features to Add

  • Add a more cleaner ability to abort adding a new item(right now we have to give some invalid values while inserting a new item for the menu to reset)
  • If there is no quantity available to purchase an item, it should not display it in the list of available items to purchase
  • Add the ability to purchase multiple quantities of an item at a time

About

Solving the Vending Machine Kata in Ruby

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages