Как подсказать пользователю, что он уже сделал выборы в таком состоянии - PullRequest
0 голосов
/ 15 февраля 2020

В конце этого кода я пытаюсь запретить пользователю вводить другую запись для menuID 2. Мне нужно сообщить, что они уже сделали выборы, а затем снова отобразить мою таблицу.

Я знаю, что мое else утверждение неверно.

menuID = -1
totalPrice = 0
while (menuID != 0)
  puts ("Menu ID \tMenu Item")
  puts ("-------\t\t----------")
  puts ("1\t\tAdd Item Charge")
  puts ("2\t\tAdd Labor Charge")
  puts ("3\t\tApply Discount")
  puts ("4\t\tApply Gift Card")
  puts ("5\t\tTotal") 
  puts ("9\t\tNew Transaction")
  puts ("0\t\tExit 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

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

Вот базовая c структура, которую вы можете использовать.

Меню

Сначала давайте создадим вспомогательный метод для отображения меню. Это ускоряет тестирование и упрощает изменение меню в будущем.

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 "-------\t\t----------"
  MENU.each.with_index(1) { |h,i| puts "#{i}\t\t#{h[:label]}" }
  puts "0\t\tExit 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

См. Kernel :: Float . Этот метод получил опцию :exception в Ruby v2.7. Более ранние версии вызывали исключение, если строка не могла быть преобразована в число с плавающей точкой. Это исключение должно быть спасено и 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 

Экономия расходов

Теперь давайте создадим га sh для хранения общей стоимости предметов и стоимость рабочей силы со значениями, инициализированными как nil.

costs = MENU.each_with_object({}) { |g,h| h[g[:type]] = nil }
  #=> {:item=>nil, :labor=>nil}

Это будет первая строка метода enter_costs ниже.

OK для выхода?

Давайте предположим, что мы не хотим разрешать пользователю выходить из приложения до того, как он введет оплату труда и, по крайней мере, один пункт оплаты. Мы могли бы написать отдельный метод, чтобы проверить, отвечают ли они этому требованию:

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         

См. Перечислимый # find .

Допустим ли выбор меню?

Нам нужно проверить, является ли числовое значение, введенное для выбора идентификатора меню (отличным от нуля, который мы уже проверили):

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 # l oop вместе с ключевым словом break , для всех циклов, вместо while, until и (особенно) for петли.

0 голосов
/ 16 февраля 2020

Возможно, вы захотите сохранить массив menu_items и заполнять для них идентификатор меню каждый раз, когда они начинают вводить новый элемент.

Помните, что элементы массива индексируются 0, поэтому вы захотите установить menu_items [0] равно пункту меню с menuID 1, а menu_items [1] равно пункту меню с menuID 2 и т. д.

...