2016-06-08 5 views
0

Программа, которую я пишу, принимает от пользователя код GTIN-8, ищет его в CSV-файле и запрашивает количество и т. Д. Когда я пишу действительный код GTIN, он все еще действует как если бы я ввел неправильный GTIN и попросил меня снова ввести код. Это в основном делает противоположное тому, что я хочу сделать.Получение ошибки при вводе действительных данных

Мой файл CSV выглядит следующим образом:

GTIN  Name Price 
12312313 Kit-Kat 0.5 
12345670 Mars 0.2 
Bounty 0.3 
34563670 Milky Way 0.4 

И мой код выглядит следующим образом:

def quantityQuestion(): 
    with open("ChocolateCSV.csv", 'r') as file2: 
     for row in csv.reader(file2): 
      if str(gtinNum) in row: 
       receipt.write(str(row) + "\n") 
       receipt.write(str("- Quantity: " + quantity + "\n")) 
       price = float(row[2]) * int(quantity) 
       receipt.write("- Price: " + str("%.2f" % round(price, 2)) + "\n") 
       restart() 
       break 
      elif str(gtinNum) not in row: 
       print("The code entered could not be found - Please re-enter") 
       gtinQuestion() 

def gtinQuestion(): 
    global gtinNum 
    gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") 

    if gtinNum.isdigit() == False or len(gtinNum) != 8: 
     gtinQuestion() 
    elif gtinNum.isdigit() == True and len(gtinNum) == 8: 
     quantityQuestion() 

gtinQuestion() 
+1

Какую версию python вы используете? –

+1

Дикая догадка: положите 'break' сразу после' gtinQuestion() 'в цикле' for row in ...'. В общем, когда вы управляете потоком, если несколько функций рекурсивно вызывают другие функции, возникают проблемы, когда функции, выше в стеке вызовов, не прерываются сразу после вызова другой функции. Если это звучит запутанно, это потому, что это так; тем более причина избежать такого дизайна. – Kevin

+0

Здесь, похоже, много ненужного кода. Пожалуйста, уберите все, что не связано с вашей ошибкой. [mcve] – AndyG

ответ

0

Это erroring потому, что вы проверяете введенный код на каждой строке CSV и показывая подсказка, если любые строк не соответствуют введенному коду.

for row in csv.reader(file2): 
    if str(gtinNum) in row: 
     ... 
     break 
    elif str(gtinNum) not in row: 
     print("The code entered could not be found - Please re-enter") 
     gtinQuestion() 

Вместо этого, вы только хотите, чтобы показать подсказку, если все линии не совпадают введенный код.

for row in csv.reader(file2): 
    if str(gtinNum) in row: 
     ... 
     break 
else: 
    print("The code entered could not be found - Please re-enter") 
    gtinQuestion() 

Здесь, если if внутри цикла никогда не совпадает, управление будет стекать конец цикла for и выполнить else заявление. Если условие if соответствует, оно будет break из цикла, и условие else не будет выполнено.

Это, как говорится, то, как вы рекурсивно называете ту же функцию, если условия не совпадают, вероятно, не очень хороший дизайн.

Вот еще один проект, который не использует рекурсивные вызовы функций и не требует глобальных переменных.

def gtinQuestion(): 
    gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") 
    while not (gtinNum.isdigit() == True and len(gtinNum) == 8): 
     gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") 
    return gtinNum 

def main(): 
    gtinNumber = gtinQuestion() 
    function_that_needs_gtinNumber(gtinNumber) 
+0

Спасибо, первое редактирование работало. Отступ был выключен, и я совершенно новый для Python, так что это очень помогло. – Jordan

0

Использование raw_input вместо input так, что вы получаете строку назад, а не целое число.

gtinNum = raw_input("Please enter the GTIN-8 Code of the product you would like to order:") 

С input, когда вы предоставляете int в качестве входных данных, вы получите int назад, и isdigit() вызовет ошибку ... не знаю, почему ваша реализация просто не проходит тест. (demo)

0

Ваша настоящая проблема заключается в том, что у вас нет четкой отделки вашей программы, либо в вашем сознании, либо в программе.

Чтобы четко определить различные принципы, которые у вас есть:

  1. Получить действительный GTIN # от пользователя
  2. Поиск файла CSV для предоставленному ГНТП #
  3. Если GTIN # действительно, получить действительное количество от пользователя
  4. Если GTIN # недействительно, получить другой номер
  5. дисплея полной стоимости пользователя
  6. Разрешить перезагрузке пользователя.

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

wants_to_continue = True 
while wants_to_continue: 
    answer = input('Would you like to continue? [Y/n]: ') 
    if answer.lower() in ('n', 'no', 'nyet', 'non'): 
     wants_to_continue = False 

Теперь в вашей программы вы получаете ГНТП от пользователя и делает два этапа проверки (или три, на самом деле). Вы сначала проверяете, выглядит ли он как действительный GTIN, а затем вы проверяете, действительно ли он найден. Но если вы вместо вместо загрузите действительные значения GTIN, тогда вы можете просто сделать все это одним махом.

Зная, что, то, я бы вновь сформулировать свои цели:

  1. Считывание данных из файла CSV и конвертировать его в удобном формате
  2. Попросите пользователя для действительного ГНТП #
  3. Попросите пользователя для действительного количества
  4. Compute и показать общую цену
  5. Попросите пользователя, если они хотели бы повторить

Зная, что мы будем загружать данные первыми, вот один из способов сделать это:

import csv 

prices = {} 
with open('prices.csv') as f: # or ChocolateCSV.csv 
    for row in csv.DictReader(f): 
     prices[row['GTIN']] = row 
    # You could replace this, and the prices = {} with 
    # a dict comprehension 
    # prices = {row['GTIN']:row for row in csv.DictReader(f)} 

Если у вас есть массивного базы данных продукта (несколько сот тысяч наименований продукции - даже 100k будет прекрасно сделайте это на разумном компьютере), этот подход будет полностью прекрасен. Теперь, когда у вас есть данные, пришло время, чтобы получить GTIN # от пользователя и увидеть, если он существует:

# Assuming that the prices were loaded by this point 

wants_to_continue = True 
while wants_to_continue: 
    answer = input('Would you like to continue? [Y/n]: ') 
    if answer.lower() in ('n', 'no', 'nyet', 'non'): 
     wants_to_continue = False 
    else: 
     gtin = input('What product number would you like to order? ') 
     product = prices.get(gtin) 
     print(product) 

С этого момента все, что вам нужно нужно сделать, это:

  • дисплей ошибка если товар не найден (if product is None: не был найден)
  • если товар is найдено, пожалуйста, спрашивайте у пользователя действительное количество.
  • Произвести и отобразить итоговое итоговое значение.
Смежные вопросы