Ruby的初学者并建立一个House类来读取恒温器温度。我是否在正确的轨道上,我将如何调用该方法来更新温度?
让我们编写一些代码来模拟房屋及其恒温器的行为。对于此挑战,您应该定义House类。以下是您应该建模的行为:
每个房子都有自己的当前温度 每个房子都有一个名为update_temperature的方法!根据加热器或空调是否打开,温度会升高或降低。它还会将当前温度打印到屏幕上。 当加热器打开时,当前温度增加1个单位 当空调开启时,当前温度下降2个单位
您可以打开/关闭加热器 你可以打开/关闭空调
作为奖励,您可以为智能家居添加此行为:
每个房子都有自己的最低和最高温度 当current_temperature达到最高温度时,空调开启,加热器关闭(如果打开) 当current_temperature达到最低温度时,加热器开启,空调关闭(如果打开) 每个房子都应该有自己的状态,这意味着我可以创建House类的许多不同实例,每个实例都有自己的温度。
class House
def initialize(current_temp, heater, air_cond)
@current_temp = current_temp
@heater = heater
@air_cond = air_cond
end
def update_temperature!
if @heater
puts @current_temp += 1
elsif @air_cond
puts @current_temp -= 2
end
end
end
my_house = House.new(34, false, true)
my_house.update_temperature!
答案 0 :(得分:3)
您正在此处运行模拟。首先为物理单位安装SY gem:
gem install sy
然后,这就是围绕受控环境模拟的方式:
require 'sy' # physical units
module ControlledEnvironment
class Air
SPECIFIC_HEAT_CAPACITY = 1.005.kJ.kg(-1).K(-1)
attr_accessor :volume, :temperature, :humidity, :pressure, :gas_composition
# to simplify things, let's forget about humidity, gas compositions...
def initialize( volume: 500.m(3),
temperature: SY::TRIPLE_POINT_OF_WATER + 20.K,
pressure: 101.3.kPa )
@volume, @temperature, @pressure = volume, temperature, pressure
end
def density
density_of_air_at_0_celsius = 1.205.kg.m(-3)
atmospheric_pressure = 101.3.kPa
density_of_air_at_0_celsius *
SY::TRIPLE_POINT_OF_WATER / temperature *
pressure / atmospheric_pressure
end
def heat!( energy )
@temperature += energy / ( SPECIFIC_HEAT_CAPACITY * volume * density )
end
def cool!( energy ); heat -energy end
end
class ThermalExchanger
attr_accessor :power_output
attr_reader :target
def initialize( power_output, target )
@power_output = power_output
@target = target
end
def act( delta_time, pow=power_output )
target.heat! pow * delta_time
end
end
class Heater < ThermalExchanger
def heat!( delta_time )
act delta_time
end
end
class Cooler < ThermalExchanger
def cool!( delta_time )
act( delta_time, -power_output )
end
end
end
设置了受控环境mixin后,让我们使用它来制作House类。
class House
include ControlledEnvironment # including a mixin
# a house has air, one heater, and one cooler
attr_reader :heater, :cooler, :air
def initialize( heater_power: 1.kW, cooler_power: 1.kW,
air_volume: 500.m(3) )
@air = Air.new volume: air_volume
@heater = Heater.new( heater_power, @air )
@cooler = Cooler.new( cooler_power, @air )
end
# its temperature is defined as air temperature
def temperature
"#{(air.temperature - SY::TRIPLE_POINT_OF_WATER).to_f} centigrade"
end
# and, given current heating / cooling power settings, we can step forward in time
def step( delta_time=1.min )
heater.heat! delta_time
cooler.cool! delta_time
puts "After #{delta_time.in( :min )} minutes, the temperature is #{temperature}"
end
end
现在我们可以玩了:
house = House.new heater_power: 1.5.kW, cooler_power: 1.kW, air_volume: 1500.m(3)
house.temperature
#=> "20.0 centigrade"
house.step 1.h
#=> After 60 minutes, the temperature is 21.040302385090797 centigrade
house.step 1.h
#=> After 60 minutes, the temperature is 22.08429649473362 centigrade
house.heater.power_output = 0.kW # turn off the heater, for instance
#=> #<±Magnitude: 0.W >
house.step 30.min
#=> After 30 minutes, the temperature is 21.013285968306377 centigrade
100.times do house.step end
答案 1 :(得分:2)
如果我正确地阅读您的问题,要调用实例方法,首先必须创建该类的实例。在这种情况下,你有一个House类。
my_house = House.new(72, true, false)
my_house.update_temperature!
话虽如此,您的代码存在一些问题。
首先,在if语句中使用then
通常是不好的做法。相反,您可以通过替换
if @heater then @current_temp += 1
与
@current_temp += 1 if @heater
或
if @heater
@current_temp += 1
end
其次,我可能会将update_temperature!
方法重写为if / else语句。我会留给你学习。
最后,您需要在初始化方法中添加end
,以便初始化方法看起来像
def initialize(current_temp, heater, air_cond)
@current_temp = current_temp
@heater = heater
@air_cond = air_cond
end
我最后会说你应该查看Why's Poignant Guide to Ruby。这将帮助您解决一些您正在处理的问题。