POO-ITBA / 2024_02

Consultas 2C 2024
3 stars 0 forks source link

Taller11_Ej2 #19

Open Pablo-Goros opened 3 hours ago

Pablo-Goros commented 3 hours ago

Hola que tal? Queria consultar la siguiente resolucion del ej2 del taller de este jueves. Se me ocurrio hacer un Hash, y queria saber si esto era correcto. Y despues querria saber si me pueden ayudar a entender porque no se estan considerando iguales dos productos que justamente son iguales.

class Ticket
  @@ticket_number = 999
  attr_reader :cant

  def initialize
    @map = Hash.new 
    @@ticket_number += 1
  end

  def add(product, cant)
    if @map.key?(product)
      @map[product] += cant
    else
      @map[product] = cant
    end
  end

  def total
    accum = 0
    @map.each do |product, cant|
      accum += product.price * cant
    end
    accum
  end

  def to_s
    output = ""
    output += format("Ticket N %d\n", @@ticket_number)
    output += "##################################\n"
    @map.each { |product, cant| output += format("%s, %d\n", product.to_s, cant)}
    output += "##################################\n"
    output += format("Total: $%.2f\n", total)
    output  # Return the complete ticket string
  end
end

class Product
  def initialize(name, price)
    @name = name
    @price = price
  end

  attr_reader :price, :name

  def to_s
    format("%s,  $%d", name, price)
  end

  def ==(other)
    return false unless other.is_a?(Product)
    @name == other.name && @price == other.price
  end

  alias eql ==

  def hash
    [name, price].hash
  end
end
fmeola commented 3 hours ago

Hola @Pablo-Goros Desde ya que la solución correcta es con un Hash para ahorrarte el recorrido que implica ver si un producto está repetido. La idea del taller es ir probando con diferentes colecciones el mismo ejercicio (array, set, sortedset y por último hash). Si te fijás en la PPT del próximo taller (que está publicada) ahí la versión final de este ejercicio (el último ejercicio) es con Hash.

Y en cuanto al error que planteás, donde dice

  alias eql ==

debe decir

  alias eql? ==
Pablo-Goros commented 2 hours ago

Okay genial. Igualmente el hash no hace un recorrido por atras?

Gracias por la correcion, me estaba volviendo loco :)

fmeola commented 2 hours ago

No, con Hash acordate que hace módulo la dimensión de la tabla de hash para caer en una posición (usa .hash para eso) y después usa .eql? para comparar ese objeto contra todos lo que colisionaron sólo en esa posición. Supongamos un caso ideal de por ejemplo una tabla de hash con 10 posiciones, si hay 100 elementos todos ubicados de manera uniforme compararías sólo con el 10% de los elementos (mientras que con el array siempre comparás contra el 100% de los elementos)

Los errores de ruby son más difíciles de encontrar comparado a Java porque fijate que no te saltaba ningún error, estabas implementando un método en vez de sobreescribir el esperado. Para encontrar más fácil el error acá podrías haber puesto un breakpoint en tu implementación de == y notar que en la invocación a key? no se terminaba invocando tu método == cuando debería

Pablo-Goros commented 17 minutes ago

Ahhh claro. Perfecto muchas gracias!!!