POO-ITBA / 2024_02

Consultas 2C 2024
2 stars 0 forks source link

Parcial 2 2024 1C Ej3 #28

Open AugustoOspal opened 2 weeks ago

AugustoOspal commented 2 weeks ago

Buenas noches, hice bastante diferente a la solución oficial el ejercicio 3 del segundo parcial del primer cuatrimestre del 2024. Yo lo pensé con SortedSet en vez de Hash, y me funciona bien. Lo único que no me cierra del mio es que no hace falta crear dos tipos de museos diferentes. Lo hice así porque vi que los pabellones tenían que estar ordenados. Me gustaría saber si está bien.

Saludos y gracias

museum.rb

# frozen_string_literal: true
require 'sorted_set'
require_relative 'pavilion'
require_relative 'exhibition'

class Museum

  attr_reader :pavilions

  def initialize
    @pavilions = SortedSet.new
  end

  def add_exhibition(pavilion, title, theme)
    @pavilions.add?(pavilion)
    @pavilions.each do |pav|
      if pav == pavilion
        pav.add_exhibition(title, theme)
        return
      end
    end
  end

  def pavilion_exhibits(pavilion)
    @pavilions.each do |pav|
      if pavilion == pav
        return pav.exhibitions
      end
    end
    nil
  end
end

pavilion.rb

# frozen_string_literal: true

class Pavilion
  include Comparable

  attr_reader :exhibitions

  def initialize(name, exhibition_capacity)
    @name = name
    @exhibitions_capacity = exhibition_capacity
    @exhibitions = []
  end

  def add_exhibition(name, theme)
    raise "Cannot add exhibition" if full?
    @exhibitions << Exhibition.new(name, theme)
  end

  def to_s
    "Pavilion #{@name} with cap #{@exhibitions_capacity}"
  end

  def <=>(other)
    return nil unless other.is_a? Pavilion
    to_s <=> other.to_s
  end

  private def full?
    @exhibitions_capacity == @exhibitions.size
  end

end

themed_pavilion.rb

# frozen_string_literal: true
require_relative 'pavilion'

class ThemedPavilion < Pavilion

  def initialize(name, exhibition_capacity, theme)
    super(name, exhibition_capacity)
    @theme = theme
  end

  def add_exhibition(name, theme)
    raise "Theme does not match" if @theme != theme
    super(name, theme)
  end

  def to_s
    return "#{@theme} Themed #{super}"
  end

end

tester.rb

require_relative 'museum'
require_relative 'pavilion'
require_relative 'themed_pavilion'

# Se instancia un museo que contará con pabellones
# donde se verifica que la cantidad de exhibiciones no supere el máximo del pabellón
field_museum = Museum.new

# Se instancia un pabellón "Dinosaurs" con capacidad de 2 exhibiciones
dinosaurs_pavilion = Pavilion.new('Dinosaurs', 2)

# Se agrega la exhibición "Dinosaurs of Antarctica 3D" al pabellón "Dinosaurs"
field_museum.add_exhibition(dinosaurs_pavilion, 'Dinosaurs of Antarctica 3D', 'Nature')

field_museum.add_exhibition(dinosaurs_pavilion, 'Inside Ancient Egypt', 'History')

begin
 # Falla pues se alcanzó el máximo de exhibiciones del pabellón
 field_museum.add_exhibition(dinosaurs_pavilion, 'SUE the T. rex', 'Nature')
rescue => e
 puts e.message # Cannot add exhibition
end

# Se itera por todas las exhibiciones del pabellón en orden de inserción
field_museum.pavilion_exhibits(Pavilion.new('Dinosaurs', 2)).each { |exh| puts exh }
# Exhibition Dinosaurs of Antarctica 3D of theme Nature
# Exhibition Inside Ancient Egypt of theme History

p field_museum.pavilion_exhibits(Pavilion.new('Egypt', 3)) # nil

egypt_pavilion = Pavilion.new('Egypt', 3)

field_museum.add_exhibition(egypt_pavilion, 'Inside Ancient Egypt', 'History')
field_museum.add_exhibition(egypt_pavilion, 'Inside Ancient Egypt', 'History')

field_museum.pavilion_exhibits(Pavilion.new('Egypt', 3)).each { |exh| puts exh }
# Exhibition Inside Ancient Egypt of theme History
# Exhibition Inside Ancient Egypt of theme History

# Se itera los pabellones en orden alfabético por su representación simbólica (to_s)
field_museum.pavilions.map { |pav| pav.to_s }.sort.each { |pav| puts pav }
# Pavilion Dinosaurs with cap 2
# Pavilion Egypt with cap 3
# Se instancia un museo que contará con pabellones temáticos
# donde se verifica que la cantidad de exhibiciones no supere el máximo del pabellón
# y que la temática de las exhibiciones coincida con la temática del pabellón
themed_field_mus = Museum.new

# Se instancia un pabellón temático "Dinosaurs" con capacidad de 3 exhibiciones
# y la temática "Nature"
themed_dinosaurs_pav = ThemedPavilion.new("Dinosaurs", 3, "Nature")

themed_field_mus.add_exhibition(themed_dinosaurs_pav, 'Dinosaurs of Antarctica 3D', 'Nature')

begin
 # Falla pues la temática de la exhibición no coincide con la temática del pabellón
 themed_field_mus.add_exhibition(themed_dinosaurs_pav, 'Inside Ancient Egypt', 'History')
rescue => e
 puts e.message # Theme does not match
end

themed_field_mus.add_exhibition(themed_dinosaurs_pav, 'SUE the T. rex', 'Nature')
themed_field_mus.add_exhibition(themed_dinosaurs_pav, 'Griffin Halls', 'Nature')

begin
 # Falla pues se alcanzó el máximo de exhibiciones del pabellón temático
 themed_field_mus.add_exhibition(themed_dinosaurs_pav, 'Birds of America', 'Nature')
rescue => e
 puts e.message # Cannot add exhibition
end

themed_field_mus.pavilion_exhibits(themed_dinosaurs_pav).each { |exh| puts exh }
# Exhibition Dinosaurs of Antarctica 3D of theme Nature
# Exhibition SUE the T. rex of theme Nature
# Exhibition Griffin Halls of theme Nature

# Se instancia un pabellón temático "Egypt" con capacidad de 5 exhibiciones
# y la temática "History"
themed_egypt_pav = ThemedPavilion.new("Egypt", 5, "History")

themed_field_mus.add_exhibition(themed_egypt_pav, 'Inside Ancient Egypt', 'History')

themed_field_mus.pavilions.map { |pav| pav.to_s }.sort.each { |pav| puts pav }
# History Themed Pavilion Egypt with cap 5
# Nature Themed Pavilion Dinosaurs with cap 3
fmeola commented 2 weeks ago

Hola @AugustoOspal No está bien haber usado SortedSet en vez de Hash porque con SortedSet siempre hacés un recorrido tanto en add_exhibition como en pavilions_exhibits cuando el pavilion es una clave de búsqueda. Es ineficiente. Además no necesitás que esté ordenado porque justamente se invoca a sort en el tester y el orden es alfabético por lo que devuelve to_s, nunca se habla de un orden natural de los pabellones. Estás implementado comportamiento que no se pedía. Al no usar un mapa terminás guardando las exhibiciones dentro de los pabellones cuando en la solución es el museo que tiene un mapa de clave pabellón y valor colección de exhibiciones, por eso no necesitaste el segundo tipo de museo. Esto viene de arrastre del error anterior.

AugustoOspal commented 2 weeks ago

Perfecto, gracias!