user6332345
user6332345

Reputation:

wrong number of arguments (given 0, expected 4)

I am getting this error for this set up. My thought is that the file cannot properly access the csv. That I am attempting to import. I've got to import from one csv to create another csv using the model date. What do I put in the controller and views to show the new csv / manipulated data? Basically how can I pass one csv file in a model for manipulation (orders.csv) and out into another csv file (redemption.csv) the code in the model is just telling model to calculate the existing numbers in orders.csv a certain way for export without this argument error?

The controller (I don't really know what to do here)

class OrdersController < ApplicationController
  def index
    orders = Order.new
  end

  def redemptions
    orders = Order.new
  end
end

The View (not confident about this either)

<h1>Chocolates</h1>
puts "#{order.purchased_chocolate_count}"
<%= link_to "CSV", orders_redemptions_path, :format => :csv %>

Model

require 'csv'

# Define an Order class to make it easier to store / calculate chocolate    tallies
class Order < ActiveRecord::Base

  module ChocolateTypes
    MILK      = 'milk'
    DARK      = 'dark'
    WHITE     = 'white'
    SUGARFREE = 'sugar free'
  end

  BonusChocolateTypes = {
    ChocolateTypes::MILK      => [ChocolateTypes::MILK, ChocolateTypes::SUGARFREE],
    ChocolateTypes::DARK      => [ChocolateTypes::DARK],
    ChocolateTypes::WHITE     => [ChocolateTypes::WHITE, ChocolateTypes::SUGARFREE],
    ChocolateTypes::SUGARFREE => [ChocolateTypes::SUGARFREE, ChocolateTypes::DARK]
  }

    # Ruby has this wacky thing called attr_reader that defines the available
    # operations that can be performed on class member variables from outside:
    attr_reader :order_value
    attr_reader :chocolate_price
    attr_reader :required_wrapper_count
    attr_reader :order_chocolate_type
    attr_reader :chocolate_counts

    def initialize(order_value, chocolate_price, required_wrapper_count, order_chocolate_type)
        @order_value            = order_value
        @chocolate_price        = chocolate_price
        @required_wrapper_count = required_wrapper_count
        @order_chocolate_type   = order_chocolate_type

        # Initialize a new hash to store the chocolate counts by chocolate type.
        # Set the default value for each chocolate type to 0
        @chocolate_counts = Hash.new(0);

        process
    end

    # Return the number of chocolates purchased
    def purchased_chocolate_count
        # In Ruby, division of two integer values returns an integer value,
        # so you don't have to floor the result explicitly
        order_value / chocolate_price
    end

    # Return the number of chocolate bonuses to award (which can include
    # multiple different chocolate types; see BonusChocolateTypes above)
    def bonus_chocolate_count
        (purchased_chocolate_count / required_wrapper_count).to_i
    end

    # Process the order:
    #   1. Add chocolate counts to the totals hash for the specified order type
    #   2. Add the bonus chocolate types awarded for this order
    def process
        chocolate_counts[order_chocolate_type] += purchased_chocolate_count

        bonus_chocolate_count.times do |i|
            BonusChocolateTypes[order_chocolate_type].each do |bonus_chocolate_type|
                chocolate_counts[bonus_chocolate_type] += 1
            end
        end
    end

    # Output the chocolate counts (including bonuses) for the order as an array
    # of strings suitable for piping to an output CSV
    def csv_data
        ChocolateTypes.constants.map do |output_chocolate_type|
            # Get the display string (lowercase)
            chocolate_key = ChocolateTypes.const_get(output_chocolate_type)
            chocolate_count = chocolate_counts[chocolate_key].to_i

            "#{chocolate_key} #{chocolate_count}"
        end
    end
  end


  # Create a file handle to the output file
  CSV.open("redemptions.csv", "wb") do |redemption_csv|

    # Read in the input file and store it as an array of lines
        input_lines = CSV.read("orders.csv")

    # Remove the first line from the input file (it just contains the CSV headers)
        input_lines.shift()

    input_lines.each do |input_line|
        order_value, chocolate_price, required_wrapper_count, chocolate_type = input_line

      # Correct the input values to the correct types
        order_value = order_value.to_f
        chocolate_price = chocolate_price.to_f
        required_wrapper_count = required_wrapper_count.to_i

        # Sanitize the chocolate type from the input line so that it doesn't
        # include any quotes or leading / trailing whitespace
        chocolate_type = chocolate_type.gsub(/[']/, '').strip

      order = Order.new(order_value, chocolate_price, required_wrapper_count, chocolate_type)
        order.process()

        puts order.purchased_chocolate_count

        # Append the order to the output file as a new CSV line
        output_csv << order.csv_data
    end
  end

Upvotes: 0

Views: 822

Answers (1)

Nitin
Nitin

Reputation: 7366

In Your initialize method you are not provide default value to argument.

def initialize(order_value, chocolate_price, required_wrapper_count, order_chocolate_type)

When you are trying to run orders = Order.new it is expecting four argument and you haven't provide it.

One more issue. Your local variable name should be order not orders for proper naming convention.

To assign default values properly, you can look here.

Upvotes: 1

Related Questions