Taras Tataryn Taras Tataryn - 1 month ago 6
Ruby Question

Ruby Code-Cutting (few lines as possible)

So the code below is what I'm trying to cut down to as few lines as possible. Any other ruby tricks out there I could use to shorten it? I appreciate all help anyone can offer.

Article Class:

class Article
attr_accessor :id, :price, :quantity
def initialize(id, price, quantity)
@id, @price, @quantity = id, Float(price), quantity.to_i
end
end


Order Class:

class Order
def initialize(name)
@a, i = [], 0
input = File.open(name, "r")
while(id = input.gets.chomp)
j, price = 0, input.gets.chomp
while(j<@a.length)
if(@a[j].id.eql?(id.to_i))
@a[j].quantity += 1
end
end
else
@a[i] = new Article(id,price,1)
i+=1
end
end
end

def orderCost
sum = 0
@a.each { |e| sum+=(e.price * e.quantity)}
sum = ((sum*1.07) + 2.99)
end

def displaySelectArticles
min, max = @a[0], @a[0]
@a.each do |e|
if(min.cost > e.cost)
min = e
end
if(max.cost < e.cost)
max = e
end
sum += e.cost*e.quantity and q += e.quantity
end
puts "Min: #{min.cost} | Max: #{max.cost} | Avg: #{Float(sum)/q}"
end
end

Answer

I did my best here but your initialize method didnt make any logical sense to me. Hopefully this can at least guide you into the right direction. Disclaimer: None of this was tested and I wrote it off of what methods I could remember.

class Order
def initialize(name)
    @a, i = [], 0
    File.readlines(name) do |line|
        # This while loop makes no sense to me
        # Seems like a surefire infiniteloop because if id = 3, it is always true
        # Maybe you meant to do an operator like == for comparison
        while(id = line)
            j, price = 0, line
            while j < @a.length
                @a[j].quantity += 1  if(@a[j].id.eql?(id.to_i))
            end
        else
            @a[i] = new Article(id, price, 1)
            i += 1
        end 
    end 
end

def orderCost
    # I would probably make this two lines because its unreadable
    (@a.inject(0) { |accum, e| accum + (e.price * e.quantity) } * 1.07) + 2.99
end

def displaySelectArticles
    min, max = @a[0], @a[0]
    @a.each do |e|
        min = e if min.cost > e.cost
        max = e if max.cost < e.cost
        sum += e.cost * e.quantity
        q += e.quantity # I have no idea how you got a q
    end
    puts "Min: #{min.cost} | Max: #{max.cost} | Avg: #{Float(sum)/q}"
end 
end