Помогите доработать вывод функций
Есть данные с анкетами клиентов, которые нужно обработать по 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 шт):
Ошибки:
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))
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=москва']