Наибольшее нечетное число

Aug 19 2020

Попросите пользователя ввести 10 целых чисел, а затем вывести наибольшее нечетное число, которое было введено. Если не было введено нечетное число, распечатайте сообщение об этом.

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

counter = 0
odd = []

while counter < 10:
    x = int(input("Enter a number: "))
    if abs(x)%2 != 0:
        odd.append(x)
    counter += 1

if len(odd) == 0:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odd))

Ответы

19 MarioIshac Aug 19 2020 at 07:14

Для вашей текущей программы мы можем улучшить пару вещей:

  1. Переименовать oddв odds(так как это а list).
  2. Используйте not oddsвместо len(odds) == 0(см. Как проверить, пуст ли список? Почему это предпочтительнее).
  3. Удалить counter. Поскольку мы используем только counterв whileусловии, мы можем фактически заменить целое whileна for _ in range(10).
  4. Следуйте PEP 8 . Например, используя 4 пробела для каждого уровня отступа.

С учетом всех этих изменений мы получаем:

odds = []

for _ in range(10):
    x = int(input("Enter a number: "))
    if abs(x) % 2 != 0:
        odds.append(x)

if not odds:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odds))

Но мы также можем повысить эффективность этой программы. Прямо сейчас мы отслеживаем все нечетные числа, прежде чем выбрать максимальное. Это означает, что сложность пространства O (N). Мы можем изменить это значение на O (1), отслеживая наибольшее нечетное число следующим образом:

max_odd = None

for _ in range(10):
    x = int(input("Enter a number: "))

    if abs(x) % 2 != 0:
        max_odd = x if max_odd is None else max(max_odd, x)

if max_odd is None:
    print("No odd number was entered")
else:
    print("The largest odd number is: ", max_odd)

Обратите внимание, что мы используем Noneдля обозначения того, что до сих пор не было введено нечетное число, и в этом случае при вводе нечетного числа мы устанавливаем max_oddего xнапрямую. В противном случае, мы устанавливаем max_oddв max(max_odd, x).

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

Наконец-то есть еще одна вещь, которую вы можете сделать. Если вы хотите, чтобы программа продолжала накапливать числа в случае, если strслучайно набран a , который не может быть проанализирован как число (например, ""), мы можем использовать try/, exceptобернутый whileследующим образом:

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        continue

Это заменит:

x = int(input("Enter a number: "))

в исходном коде. Это будет продолжать предлагать пользователю ввести, strкоторый можно проанализировать как, intпока они не сделают это. Поскольку все это происходит на той же итерации for, количество чисел, которые они набирают (в нашем случае 10), не будет уменьшено.

6 GZ0 Aug 19 2020 at 08:58

Дополнение к предыдущему обзору:

  • Когда xявляется целым числом, abs(x) % 2эквивалентно x % 2Python. Выходные данные оператора по модулю %имеют тот же знак, что и второй операнд.
  • При запуске кода вне метода / класса рекомендуется помещать код внутри основной защиты . См. Здесь для получения дополнительных объяснений.

В Python 3.8 код можно сократить, используя оператор присваивания :=вместе с maxфункцией.

if __name__ == "__main__":
    # Number generator
    num_gen = (o for _ in range(10) if (o := int(input("Enter a number: "))) % 2 != 0)
    max_odd = max(num_gen, default=None)
    if max_odd is None:
        print("No odd number was entered")
    else:
        print(f"The largest odd number is: {max_odd}")

Обертывание int(input("Enter a number: "))функции обеспечивает лучшую читаемость:

def read_input() -> int:
    return int(input("Enter a number: "))

if __name__ == "__main__":
    num_gen = (o for _ in range(10) if (o := read_input()) % 2 != 0)
    max_odd = max(num_gen, default=None)
    if max_odd is None:
        print("No odd number was entered")
    else:
        print(f"The largest odd number is: {max_odd}")

Другой вариант, который обрабатывает недопустимые вводимые пользователем данные, выглядит следующим образом:

def read_input() -> int:
    while True:
        try:
            return int(input("Enter a number: "))
        except ValueError:
            continue

if __name__ == "__main__":
    try:
        max_odd = max(o for _ in range(10) if (o := read_input()) % 2 != 0)
        print(f"The largest odd number is: {max_odd}")
    except ValueError:
        # Since read_input() no longer raises ValueError, the except
        # statement here only handles the cases where max() gets no inputs
        print("No odd number was entered")
3 AlexeyBurdin Aug 19 2020 at 12:56

Могу я спросить, какой язык программирования вы практиковали до Python?
Я хочу упомянуть об этом однострочник:

max(l,key=lambda x:(x%2,x))

предполагая, что вы уже как- lто ввели, например

s='Enter a number: '
l=[int(input(s)) for i in range(10)]

Как работает код? Он ищет максимум key(x)за xв lи возвращает такое x. Ключевым моментом здесь является лямбда-функция, которая возвращает кортеж (1,x)для нечетного xи (0,x)четного x. Кортежи сравниваются слева направо, например, (1,x)>(0,y)для каждого xи y. Итак, мы просто говорим: «Дайте мне максимум l, предполагая, что нечетное число всегда больше четного».

Так вся программа будет выглядеть так

s='Enter a number: '
l=[int(input(s)) for i in range(10)]
m=max(l,key=lambda x:(x%2,x))
if m%2:
    print('The largest odd number is: %d'%m)
else: #the greatest is even, therefore no odd numbers
    print('No odd number was entered')

Коротко, красиво и легко, как питон.

Но я согласен с тем, что блок try-except вокруг int(input())принятого ответа полезен, а также без предварительного сохранения всего списка нечетных значений.

Я только хотел продемонстрировать парадигму функционального программирования на python, когда вы просто говорите python: «Я хочу, чтобы это было сделано (например, максимальное значение)», и он делает это за вас, вам не нужно объяснять, как он должен это делать.

Спасибо за прочтение.

3 EmilioMBumachar Aug 19 2020 at 21:36

Я постараюсь опираться на последнее предложение принятого ответа.

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        continue

Я определенно поддерживаю это предложение, оно позволяет вашей программе корректно обрабатывать неверный ввод, а не просто давать сбой.

Однако это создает проблему удобства использования. Пользователь, который просто ввел букву в число, вероятно, этого не заметил. Они будут думать, что ввели намеченный номер, переходят к следующему, а затем запутаются в конце, когда они думают, что они ввели все числа, но компьютер все еще запрашивает следующий.

Лучше дать им обратную связь:

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        print("Invalid number will be ignored.")
        continue

... или, что еще лучше, напечатайте их набранный номер обратно на них:

while True:
    try:
        inputString = input("Enter a number: ")
        x = int(inputString)
        break
    except ValueError:
        print("Invalid number will be ignored: {}".format(inputString))
        continue

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

print("Numbers provided are: {}".format(all_valid_numbers_inputted))
if not odds:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odds))

Если вы сделаете это, следующим шагом будет избавление от переменной "шансы" и определение наибольшего коэффициента прямо из полного списка.

1 FMc Aug 25 2020 at 12:23

Ключевой момент здесь: на каждом этапе процесса выполняется только одна простая вещь. Таким образом вы строите программы - по одному постепенному, строго определенному шагу за раз. Не смешивайте все в беспорядке - например, цикл, в котором мы взаимодействуем с пользователем, а также выполняем преобразования и вычисления, которые потребуются позже.

def as_int(s):
    try:
        return int(s)
    except Exception:
        return 0

N = 3
MSG = 'Enter number: '

replies = [input(MSG) for _ in range(N)]  # Interact.
nums = [as_int(r) for r in replies]       # Convert.
odds = [n for n in nums if n % 2]         # Compute.

if odds:                                  # Report.
    print(max(odds))