Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 22, 2015 12:55:35

Wannabee
Зарегистрирован: 2014-06-11
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

Всем привет.
Занимаюсь по книге Майкла Доусона, нужно создать игру Блэкджек. Игра состоит из трех отдельных файлов:

  1. 1. Модуль cards.py, в котором определены базовые классы для карточных игр, Card, Hand, Deck
  2. 2. Модуль games.py с базовым классом для создания игрока, Player. И в нем же отдельно 2 функции - ask_yes_no() и ask_number().
  3. 3. blackjack.py с основным кодом для запуска игры, в котором также создаются классы-потомки для игры в блэкджек, основанные на тех, что в cards.py и games.py.

В общем, я пытаюсь прикрутить перехват ValueError в функции ask_number() из модуля games.py.
Вот такая функция была изначально:
def ask_number(question, low, high):
  response = None
  while response not in range(low, high):
      response = int(input(question))
      return response

В основном файле игры blackjack.py эта функция вызывается в таком контексте:
import games
import cards
...
def main(): 
    ...
    names = []
    number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
    for i in range(number):
        name = input("Enter player name: ")
        names.append(name)

Мне нужно чтобы в самой функции перехватывалось исключение ValueError при вводе неправильного значения, и чтобы это происходило до тех пор пока не ввести именно цифру, потому что потом response = int(input) будет пробовать преобразовать значение в число.
Я сделал вот так:
def ask_number(question, low, high):
    response = None
    while response not in range(low, high):
        try:
            response = int(input(question))
        except ValueError:
            print("Looks like it's not a number!")
        else:
            return response

Проблема в том, что когда я вызываю эту функцию непосредственно в модуле games.py и передаю ей неподходящее значение (вместо числа букву или пустую строку, например), ValueError нормально перехватывается и программа просит ввести число, пока его не получит. Но когда функция вызывается в самом файле игры посредством games.ask_number(…), то все равно возникает ошибка ValueError, как если бы в функции не было try/except:
Traceback (most recent call last): 
  File "D:/My Projects/BlackJack.py", line 164, in <module>
    main()
  File "D:/My Projects/BlackJack.py", line 150, in main
    number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
  File "D:/My Projects/games.py", line 21, in ask_number
    response = int(input(question))
ValueError: invalid literal for int() with base 10: 's'

Почему так происходит, и где закралась ошибка? Уж совсем вариантов нет

Отредактировано Wannabee (Июнь 22, 2015 12:56:33)

Офлайн

#2 Июнь 22, 2015 13:17:45

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

1. response not in range(low, high)
Это что такое? Для того чтобы определить, попадает ли число в интервал от 0 до миллиона, вы будете перебирать миллион значений? Конгениально!!!!
2.

Wannabee
вызываю эту функцию непосредственно в модуле games.py и передаю ей неподходящее значение
Вот сигнатура функции
def ask_number(question, low, high)
какое такое такое неподходящее значение вы передаете? Ошибка возникает не на переданном значении, а на введенном с клавиатуры



Офлайн

#3 Июнь 22, 2015 13:18:52

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

Wannabee
Уж совсем вариантов нет
Весь код покажите, можно архивом



Офлайн

#4 Июнь 22, 2015 16:17:37

Wannabee
Зарегистрирован: 2014-06-11
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

1. response not in range(low, high)
Это что такое? Для того чтобы определить, попадает ли число в интервал от 0 до миллиона, вы будете перебирать миллион значений? Конгениально!!!!
1. Я даже не знаю. А зачем мне перебирать миллион значений, не подскажите? Или бывали прецеденты партии в 21 очко на миллион игроков? Тут планируется максимум 7 игроков, и в основном коде границы перебора по-моему довольно четко определены и переданы функции. Будет максимум range(1,8):
number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
Код для игры составлял сам автор книги. Я лишь выполняю задание по этой главе. По заданию надо реализовать перехват ошибок в “уязвимых местах” игры.
Вот сигнатура функции
def ask_number(question, low, high)
какое такое такое неподходящее значение вы передаете? Ошибка возникает не на переданном значении, а на введенном с клавиатуры
2. Это я понял, я неправильно сформулировал мысль. Проблема как раз с вводом с клавиатуры. Вот например когда функция ask_number() из games.py вызывается в главном файле blackjack.py, и она просит ввести число, чтобы установить количество игроков, то можно, допустим, “случайно” ввести букву, которую int(input(question)) не сможет преобразовать в числовой тип, и возникнет ValueError. Я добавил в функцию ask_number(question, low, high) конструкцию перехвата ValueError. То бишь чтобы если ввести букву, ValueError перехватывался и функция из модуля games.py опять просила ввести с клавиатуры число от 1 до 7. И так до тех пор, пока его не получит.
Перехват срабатывает, если например вызвать ask_number() непосредственно в самом модуле games.py, где она и определена, и ввести вместо цифры букву - ValueError перехватывается и функция опять просит ввести число. Но почему-то если функция вызывается в главном файле blackjack.py, то перехвата не происходит и возникает ValueError.

Код с тремя файлами прикрепил.

Отредактировано Wannabee (Июнь 22, 2015 16:24:30)

Прикреплённый файлы:
attachment Blackjack.rar (2,8 KБ)

Офлайн

#5 Июнь 22, 2015 16:34:37

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

Wannabee
А зачем мне перебирать миллион значений, не подскажите?
Я то откуда знаю, ты ж перебираешь, а не я.
Вот скажи, друг, зачем тебе всё это надо? Какова конечная цель? Не игру же написать, вообще, в общем и целом зачем?



Офлайн

#6 Июнь 22, 2015 16:42:17

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

Какая версия питона?



Офлайн

#7 Июнь 23, 2015 00:36:22

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10031
Репутация: +  857  -
Профиль   Отправить e-mail  

Перехват ValueError в функции модуля

Wannabee
Код для игры составлял сам автор книги.
Wannabee
while response not in range(low, high):
Вот это Доусон писал?

while not low <= response <= high:
Это даже не то же самое, потому что range() возьмёт только до high - 1.

Wannabee
Вот такая функция была изначально:
def ask_number(question, low, high):
  response = None
  while response not in range(low, high):
      response = int(input(question))
      return response
Да? И в чём смысл этого while'а? (Допустим, что это учебный while какой-то.)

Wannabee
number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
Надо тебе сменить учебник, а то он научит такой вот бред делать.
Параметр high должен принимать 7 и расчитывать на 7, а не принимать 8 и расчитывать на 7.
Подогнал интерфейс метода под его внутреннее устройство.
Видимо, Доусон очень часто потом ловит баги странного происхождения в своих программах и считает это неотъемлемой частью программирования.



Отредактировано py.user.next (Июнь 23, 2015 00:58:29)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version