HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Creating simulated items sold at a store into a hash

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
creatingintostorehashitemssoldsimulated

Problem

I am writing code that creates a hash for a store that has an item, price, and sku. The hash is inserted into an array. I also create another hash based on the sku that holds the amount of inventory for that item. I am new to Ruby and am looking for ways to improve my code.

class SimStore
      def item_info
        random = Random.new
        price = random.rand(1.00 ... 75.00).round(2)
        item = 1.times.map { RandomWord.nouns.next }
        sku_random = Random.new
        sku = sku_random.rand(1000 ... 1000000)
        sum_store_hash = {:item => item, :price => price, :sku => sku}
      end

  def stock array_items_stock
    stock_hash = {}
    array_items_stock.each do |inventory|
       random = Random.new
       quantity = random.rand(10 ... 100)
       stock_hash[inventory[:sku]] = quantity
     end
    stock_hash
  end
end

items = 15;
array_items = []
hash_inventory = []
while items > 0
  items = items - 1
  sim_store = SimStore.new
  items_hash = sim_store.item_info
  array_items.push(items_hash)
end

hash_inventory = sim_store.stock array_items

Solution

The SimStore class doesn't seem to do much except create a hash and create an item. These seem like separate concerns

You really could use an Item class with a static method for stubbing out an Item.

First, let's start with an "Item" class:

class Item
  attr_accessor :price, :name, :sku, :quantity

  def initialize(name, sku, price, quantity)
    self.name = name
    self.sku = sku
    self.price = price
    self.quantity = quantity
  end

  def self.stub
    price = Random.new.rand(1.00 ... 75.00).round(2)
    name = 1.times.map { RandomWord.nouns.next }
    sku = Random.new.rand(1000 ... 1000000)
    quantity = Random.new.rand(10 ... 100)

    self.new name, sku, price, quantity
  end

  def to_h
    { name: name, price: price, sku: sku, quantity: quantity }
  end
end


It has a price, name and sku that is a getter and setter. A static, or class level method called Item.stub generates a fake item based on the code you are using. Lastly, it has a to_hash method for converting the Item into a Hash.

Now we can take one step back and think about your SimStore, which at this point doesn't simulate anything so we can rename it to Store:

class Store
  def items
    @items ||= []
  end

  def self.stub(number_of_items)
    store = self.new

    number_of_items.times do |i|
      store.items = 2.1
    items.map { |item| [item.sku, item.quantity] }.to_h
  end
end


It has an array of Items and a to_hash method that converts the entire store into a Hash. Additionally, it also has a class method called stub, which accepts the number of items that should be stubbed out.

You wanted to convert the items into a Hash of SKUs for the keys, and quantities for the values, so explicitly creating a sku_hash method seems to be more appropriate.

And to use it:

store = Store.stub 15
store_hash = store.to_hash # => [{name: '...', sku: 123, price: 23.99}, ...]
sku_hash = stsore.sku_hash # => { 'sku1' => 2, 'sku2' => 55 }


By separating the Item from the Store and adding class methods to stub items and entire stores, you get two classes that can actually be used in a real context, but also can be used just for playing around.

Code Snippets

class Item
  attr_accessor :price, :name, :sku, :quantity

  def initialize(name, sku, price, quantity)
    self.name = name
    self.sku = sku
    self.price = price
    self.quantity = quantity
  end

  def self.stub
    price = Random.new.rand(1.00 ... 75.00).round(2)
    name = 1.times.map { RandomWord.nouns.next }
    sku = Random.new.rand(1000 ... 1000000)
    quantity = Random.new.rand(10 ... 100)

    self.new name, sku, price, quantity
  end

  def to_h
    { name: name, price: price, sku: sku, quantity: quantity }
  end
end
class Store
  def items
    @items ||= []
  end

  def self.stub(number_of_items)
    store = self.new

    number_of_items.times do |i|
      store.items << Item.stub
    end

    store
  end

  def to_h
    items.map { |item| item.to_hash }
  end

  def sku_hash
    # For Ruby < 2.1
    array = items.map { |item| [item.sku, item.quantity] }
    Hash[array]

    # For Ruby >= 2.1
    items.map { |item| [item.sku, item.quantity] }.to_h
  end
end
store = Store.stub 15
store_hash = store.to_hash # => [{name: '...', sku: 123, price: 23.99}, ...]
sku_hash = stsore.sku_hash # => { 'sku1' => 2, 'sku2' => 55 }

Context

StackExchange Code Review Q#109594, answer score: 3

Revisions (0)

No revisions yet.