Помогите доработать вывод функций

Есть данные с анкетами клиентов, которые нужно обработать по True/False в соответствии с требованиями:

-Есть контактная информация: номер телефона. -Контактный номер начинается либо с восьмёрки, либо с семёрки и состоит из десяти символов. -Город проживания: Москва.

applications = [
         'name=Аня,phone=8800234 ,city=москва',
         'name=КОЛЯ,phone=8800900871 ,city=МОСКВА',
         'name=Валентина,phone=7950900871 ,city=волгоград',
         'name=,phone=7999901871,city=москва',
         'name=Иван,phone=7999901871,city=москва',
         'name=Инга,phone=,city=москва'
] 
 
# функция проверки валидности номера
def check_phone(phone):
    n = len(phone)
    if n == 0:
        return False
    else:
        first_number = (phone[0] == '8') or (phone[0] == '7')
        length = n == 10
        return True
    
# функция проверки города
def check_city(city):
    m = city.lower()
    i = m.find ('москва')
    if i != -1:
        return True
    else:
        return False
        
 
 
# функция проверки одной анкеты
def check_application(applications):
    if check_phone == True and check_city == True:
        return True
    else:
        return False
 
# функция проверки списка анкет
def find_valid_applications(applications):
    for j in applications:
        print(j, "--", check_application(j))
 
# результат
find_valid_applications(applications)

Программа выдаёт False ко всем ответам


Ответы (2 шт):

Автор решения: Universall

Ошибки:

1:

if check_phone == True and check_city == True: Вы сравниваете функцию с True и получаете False. Вы должны вызвать функцию, передать ей нужные аргументы, получить значение и затем уже проверять его

2:

print(j, "--", check_application(j)) Вы передаёте в функцию проверки сырую строку (name=Аня,phone=8800234 ,city=москва), а функции проверки проверяют конкретный номер и город, так что их сначала нужно получить из данной строки

def find_info(string, var):  # Посик переменная=значение
    result = ""
    var = f"{var}="
    for letter in string[string.find(var) + len(var):]:  # Берём от = до , или пробела
        if letter in " ,":
            break
        result += letter
    return result

res = []
for application in applications:
    name = find_info(application, "name")
    phone = find_info(application, "phone")
    city = application[application.find("city=") + 5:]

3:

first_number = (phone[0] == '8') or (phone[0] == '7')
length = n == 10
return True

Этим вы ничего не проверите и просто вернёте True в любом случае, так как программа никак не отреагирует на то, будет ли в first_number и length True или False. Правильнее будет сделать так:

first_number = (phone[0] == '8') or (phone[0] == '7')
length = n == 10
return first_number and length

Готовый код:

apps = [
    'name=Аня,phone=8800234 ,city=москва',
    'name=КОЛЯ,phone=8800900871 ,city=МОСКВА',
    'name=Валентина,phone=7950900871 ,city=волгоград',
    'name=,phone=7999901871,city=москва',
    'name=Иван,phone=7999901871,city=москва',
    'name=Инга,phone=,city=москва'
]


# функция проверки валидности номера
def check_phone(phone):
    n = len(phone)
    if n == 0:
        return False
    else:
        first_number = (phone[0] == '8') or (phone[0] == '7')
        length = n == 10
        return first_number and length


# функция проверки города
def check_city(city):
    m = city.lower()
    if 'москва' in m:
        return True
    else:
        return False


def check_application(applications):
    def find_info(string, var):  # Посик переменная=значение
        result = ""
        var = f"{var}="
        for letter in string[string.find(var) + len(var):]:  # Берём от = до , или пробела
            if letter in " ,":
                break
            result += letter
        return result

    res = []
    for application in applications:
        name = find_info(application, "name")
        phone = find_info(application, "phone")
        city = application[application.find("city=") + 5:]
        if check_phone(phone) and check_city(city):
            res.append([name, phone, city])
    return res


print(check_application(apps))

→ Ссылка
Автор решения: Namerek
import re
from pprint import pprint

applications = [
    'name=Аня,phone=8800234 ,city=москва',
    'name=КОЛЯ,phone=8800900871 ,city=МОСКВА',
    'name=Валентина,phone=7950900871 ,city=волгоград',
    'name=,phone=7999901871,city=москва',
    'name=Иван,phone=7999901871,city=москва',
    'name=Инга,phone=,city=москва'
]

items_re = re.compile(r'\s*?[=,]\s*')


def record_to_dict(value: str):
    items = items_re.split(value)
    return dict(
        zip(items[::2], items[1::2])
    )


def valid_client(value: dict):
    valid_phone = (
                      phone := value.get('phone', '')
                  ).startswith(
        ('7', '8',)
    ) and len(phone) == 10

    valid_city = value.get('city', '').lower() == 'москва'

    # Если нужно обработать условие по имени клиента ниже
    # значение True заменить на условие
    valid_user = True

    return all(
        [
            valid_phone,
            valid_city,
            valid_user
        ]
    )


apps = [*filter(valid_client, map(record_to_dict, applications))]

pprint(apps)

output

[{'city': 'МОСКВА', 'name': 'КОЛЯ', 'phone': '8800900871'},
 {'city': 'москва', 'name': '', 'phone': '7999901871'},
 {'city': 'москва', 'name': 'Иван', 'phone': '7999901871'}]

По Вашим исходникам работает корректно, едиственный нюанс. В российском номере не 10 а 11 знаков вместе с кодом страны, а у Вас номера из 10-ти 7 (999) 901-871, 8-800-900-871 и так далее. Соответственно в реальном применении не забудте поменять проверку на длину номера 11 смволов

Если нужно вернуть данные в том-же виде, в котором они были получены можно сделать так:

data = [
    ','.join(
        [
            f'{k}={v}' for k, v in elem.items()
        ]
    ) for elem in apps
]

pprint(
    data
)

output

['name=КОЛЯ,phone=8800900871,city=МОСКВА',
 'name=,phone=7999901871,city=москва',
 'name=Иван,phone=7999901871,city=москва']
→ Ссылка