Как указать параметры для ввода

#python

#python

Вопрос:

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

 name_age = []
user_input = []
name_age2 = []
ages = []

while user_input != "":
    try:
        user_input = input("Type 'Name,Age': ")
        name_age.append(user_input)
        print(name_age)
        if "," not in user_input:
            raise ValueError

    except ValueError:
        print("Incorrect try again")


else:
    name_age.remove("")

    for item in name_age:
        name_age2.append(item.split(','))

    for pair in name_age2:
        for val in pair:
            if val.isdigit():
                ages.append(int(val))

    print(name_age2)
    print(ages)
    print("Names amp; Ages: ", name_age2)
    print("Total of ages: ", sum(ages))
    print("Average of ages: ", sum(ages) / len(ages))
    print("Total number of names: ", len(name_age2))
    print("End")
 

Комментарии:

1. не могли бы вы привести пример допустимой строки?

2. @collinsuz ‘джон,24’

Ответ №1:

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

 name_age = []
user_input = []
name_age2 = []
ages = []


def validate(input: str) -> bool:
    decomposed_string: str = input.split(',')
    if decomposed_string[1].isdigit() and not decomposed_string[0].isdigit():
        return True
    return False


while user_input != "":
    try:
        user_input = input("Type 'Name,Age': ")
        name_age.append(user_input) if validate(user_input) else print("Incorrect, try again")
        print(name_age)
        if "," not in user_input:
            raise ValueError

    except ValueError:
        print("Incorrect try again")


else:
    name_age.remove("")

    for item in name_age:
        name_age2.append(item.split(','))

    for pair in name_age2:
        for val in pair:
            if val.isdigit():
                ages.append(int(val))

    print(name_age2)
    print(ages)
    print("Names amp; Ages: ", name_age2)
    print("Total of ages: ", sum(ages))
    print("Average of ages: ", sum(ages) / len(ages))
    print("Total number of names: ", len(name_age2))
    print("End")


 

Комментарии:

1. Чувак, я пробовал anding ранее сегодня вечером и не смог этого сделать, увидев, что ваш пример очень помог, я вставил «если и нет» в свой код и смог удалить исключение, спасибо! if decomposed_string[1].isdigit() and not decomposed_string[0].isdigit():

Ответ №2:

Шаблоны регулярных выражений очень хорошо подходят для такого простого синтаксического анализа строк. Другим решением в сложных случаях было бы обратиться к какой-либо сторонней библиотеке PyParsing или Parsley.

С регулярными выражениями группы и особенно именованные группы очень удобны. Вот простой пример:

 name_age_pattern = re.compile(r'(?P<name>w ),(?P<age>d )')

def parse_name_age(string):
    match = name_age_pattern.match(string)
    if not match:
        raise ValueError('input string didnt match pattern')
    return match.group('name'), int(match.group('age'))

name, age = parse_name_age('Jack,23')
 

Затем несколько дополнительных подсказок. Чтобы сделать ваш код немного более питоническим, вы могли бы использовать некоторые классы. Вот пример:

 import re
from typing import NamedTuple

class Person(NamedTuple):
    name: str
    age: int

    name_age_pattern = re.compile(r'(?P<name>w ),(?P<age>d )')

    @classmethod
    def from_string(cls, string):
        match = cls.name_age_pattern.match(string)
        if not match:
            raise ValueError('input string didnt match pattern')
        return cls(match.group('name'), int(match.group('age')))


class People(list):
    # Inheriting from a list should be made with caution. Overriding
    # native functions could result unwanted side effects. We should
    # be safe here since we don't do so.

    @property
    def names(self):
        return ', '.join((person.name for person in self))

    @property
    def total_age(self):
        return sum((person.age for person in self))
    
    @property
    def avg_age(self):
        return self.total_age / len(self)

people = People()
while True:
    input_str = input('Please give a name and age separated by a comma.')
    if input_str == "":
        break
    try:
        people.append(Person.from_string(input_str))
    except ValueError as e:
        print(e)

print(people.names)
print(f'sum of ages: {people.total_age}')
print(f'avg of ages: {people.avg_age}')
 

Комментарии:

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

Ответ №3:

Здесь я использовал регулярное выражение для вашего условия для проверки ввода:

 import re
name_age = []
user_input = []
name_age2 = []
ages = []

while user_input != "":
    try:
        user_input = input("Type 'Name,Age': ")
        name_age.append(user_input)
        print(name_age)
        if not re.search('^w (s w )*,d ', user_input):
            raise ValueError

    except ValueError:
        print("Incorrect try again")


else:
    name_age.remove("")

    for item in name_age:
        name_age2.append(item.split(','))

    for pair in name_age2:
        for val in pair:
            if val.isdigit():
                ages.append(int(val))

    print(name_age2)
    print(ages)
    print("Names amp; Ages: ", name_age2)
    print("Total of ages: ", sum(ages))
    print("Average of ages: ", sum(ages) / len(ages))
    print("Total number of names: ", len(name_age2))
    print("End")
 

Итак, это регулярное выражение будет принимать имена с пробелами, например «аноша рехан, 12», но если вы ищете имена только из одного слова, используйте это регулярное выражение '(w )*,d '

Ответ №4:

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

Регулярное выражение, определенное ниже, будет соответствовать:

[a-zA-Z] — один или несколько алфавитов (как в нижнем, так и в верхнем регистре)

, — буквальный символ запятой

d{1,3} — диапазон от 1 до 3 цифр. $ должно заканчиваться цифрой

 import re

# input_text_sample = 'john,24'

input_pattern = re.compile(r'[a-zA-Z] ,d{1,3}



)

correct_input = None

while not correct_input:
user_input = input("Type 'Name,Age': ")

correct_input = input_pattern.match(user_input)

if not correct_input:
print("Incorrect try again")
else:
print(correct_input.string)