在此代码的末尾,我试图阻止用户输入menuID
2 的另一个条目。我需要提示他们已经进行了选举,然后重新显示我的表格。
我知道我的else
陈述不正确。
menuID = -1
totalPrice = 0
while (menuID != 0)
puts ("Menu ID tMenu Item")
puts ("-------tt----------")
puts ("1ttAdd Item Charge")
puts ("2ttAdd Labor Charge")
puts ("3ttApply Discount")
puts ("4ttApply Gift Card")
puts ("5ttTotal")
puts ("9ttNew Transaction")
puts ("0ttExit Application")
print ("Enter Menu ID: ")
menuID = gets().to_i()
if (menuID == 1)
print ("Enter item's charge amount: $")
chargeAmount = gets().to_f()
chargeAmount = chargeAmount.round(2)
totalPrice += chargeAmount
if (chargeAmount <= 0)
puts ("Item charge amount must be greater than 0. You entered $#{chargeAmount}")
end
elsif (menuID == 2)
print ("Enter labor charge amount: $")
laborCharge = gets().to_f()
laborCharge = laborCharge.round(2)
if (laborCharge <= 0)
puts ("Labor charge amount must be greater than 0. You entered $#{laborCharge}")
else
puts ("Labor charge has already been applied")
end
end
end
这是您可以使用的基本结构。
菜单
首先,让我们创建一个帮助程序方法来显示菜单。这样做可以加快测试速度,并使将来更容易更改菜单。
MENU = [{ label: "Add Item Charge", text: 'item', type: :item },
{ label: "Add Labor Charge", text: 'labor', type: :labor}]
def display_menu
puts "Menu ID tMenu Item"
puts "-------tt----------"
MENU.each.with_index(1) { |h,i| puts "#{i}tt#{h[:label]}" }
puts "0ttExit application"
end
让我们试试吧。
display_menu
Menu ID Menu Item
------- ----------
1 Add Item Charge
2 Add Labor Charge
0 Exit application
请注意,要更改菜单项,只需更改MENU
。
现在,请忽略:text
和:type
MENU
中的密钥。
添加费用
如果用户希望添加项目费用,则将使用作为费用类型的标签的参数调用以下方法,并将返回有效的美元金额:
def item_charge(charge_type)
loop do
print "Enter #{charge_type} amount: $"
case (amt = Float(gets, exception: false))
when nil
puts " Entry must be in dollars or dollars and cents"
when -Float::INFINITY...0
puts " Entry cannot be negative"
else
break amt
end
end
end
请参阅内核::浮动。此方法在 Ruby v2.7 中被赋予了:exception
选项。如果字符串无法转换为浮点数,则早期版本会引发异常。必须挽救这一例外,并nil
归还。
以下是可能的对话:
item_charge('labor')
Enter labor amount: $213.46x
Entry must be in dollars or dollars and cents
Enter labor amount: $-76
Entry cannot be negative
Enter labor amount: $154.73
#=> 154.73
节省费用
现在,让我们创建一个哈希来保存项目的总成本和人工成本,其值初始化为nil
。
costs = MENU.each_with_object({}) { |g,h| h[g[:type]] = nil }
#=> {:item=>nil, :labor=>nil}
这将是下面enter_costs
的方法的第一行。
可以退出了吗?
假设我们不希望允许用户在输入人工费用和至少一个项目费用之前退出应用程序。我们可以编写一个单独的方法来查看它们是否满足该要求:
def ok_to_exit?(costs)
h = MENU.find { |h| costs[h[:type]].nil? }
puts " You have not yet entered a #{h[:text]} cost" unless h.nil?
h.nil?
end
请参阅枚举#查找。
菜单选择有效吗?
我们需要查看为菜单 id 选择输入的数值(除了我们已经检查过的零(是否有效:
def menu_selection_valid?(menu_id)
valid = (1..MENU.size).cover?(menu_id)
puts " That is not a valid menu id" unless valid
valid
end
menu_selection_valid?(4)
That is not a valid menu id
#=> false
menu_selection_valid?(-3)
That is not a valid menu id
#=> false
menu_selection_valid?(2)
#=> true
身体
我们现在可以把所有东西放在一起。
def enter_costs
costs = MENU.each_with_object({}) { |g,h| h[g[:type]] = nil }
loop do
display_menu
print ("Enter Menu ID: ")
menu_id = gets().to_i
if menu_id.zero?
ok_to_exit?(costs) ? break : next
end
next unless menu_selection_valid?(menu_id)
h = MENU[menu_id-1]
case h[:type]
when :labor
if costs[h[:type]].nil?
costs[h[:type]] = item_charge(h[:text])
else
puts " You have already entered the labor charge"
next
end
when :item
costs[h[:type]] = (costs[h[:type]] ||= 0) + item_charge(h[:text])
end
end
costs
end
这是一个可能的对话框。
enter_costs
Menu ID Menu Item
------- ----------
1 Add Item Charge
2 Add Labor Charge
0 Exit application
Enter Menu ID: 0
You have not yet entered a item cost
< menu redisplayed >
Enter Menu ID: 1
Enter item amount: $2.50
< menu redisplayed >
Enter Menu ID: 0
You have not yet entered a labor cost
< menu redisplayed >
Enter Menu ID: 9
That is not a valid menu id
< menu redisplayed >
Enter Menu ID: 2
Enter labor amount: $1345.61
< menu redisplayed >
Enter Menu ID: 1
Enter item amount: $3.12
< menu redisplayed >
Enter Menu ID: 2
You have already entered the labour charge
< menu redisplayed >
Enter Menu ID: 0
#=> {:item=>5.62, :labor=>1345.61}
请注意,菜单中项的编号是在代码中完成的,因此对MENU
的更改不需要更改代码中其他位置的菜单项编号。
我建议对所有循环使用 Kernel#loop 和关键字 break,而不是while
、until
和(尤其是(for
循环。
您可能希望维护一个menu_items
数组,并在每次它们开始输入新项目时填写它们的 menuID。
请记住,数组项是 0 索引的,因此您需要将 menu_items[0] 设置为菜单 ID 为 1 的菜单项,menu_items[1] 等于菜单 ID 为 2 的菜单项,依此类推。