-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind.py
146 lines (116 loc) · 4.68 KB
/
find.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import datetime
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
DB_PATH = "sqlite:///sochi_athletes.sqlite3"
Base = declarative_base()
class Athelete(Base):
"""
Описывает структуру таблицы athelete, содержащую данные об атлетах
"""
__tablename__ = 'athelete'
id = sa.Column(sa.Integer, primary_key=True)
age = sa.Column(sa.Integer)
birthdate = sa.Column(sa.Text)
gender = sa.Column(sa.Text)
height = sa.Column(sa.Float)
weight = sa.Column(sa.Integer)
name = sa.Column(sa.Text)
gold_medals = sa.Column(sa.Integer)
silver_medals = sa.Column(sa.Integer)
bronze_medals = sa.Column(sa.Integer)
total_medals = sa.Column(sa.Integer)
sport = sa.Column(sa.Text)
country = sa.Column(sa.Text)
class User(Base):
"""
Описывает структуру таблицы user, содержащую данные о пользователях
"""
__tablename__ = 'user'
id = sa.Column(sa.String(36), primary_key=True)
first_name = sa.Column(sa.Text)
last_name = sa.Column(sa.Text)
gender = sa.Column(sa.Text)
email = sa.Column(sa.Text)
birthdate = sa.Column(sa.Text)
height = sa.Column(sa.Float)
def connect_db():
"""
Устанавливает соединение к базе данных, создает таблицы, если их еще нет и возвращает объект сессии
"""
engine = sa.create_engine(DB_PATH)
Base.metadata.create_all(engine)
session = sessionmaker(engine)
return session()
def request_data():
"""
Запрашивает у пользователя данные и добавляет их в список users
"""
print("Давай поищем атлетов похожих на одного из пользователей.")
user_id = input("Ввети идентификатор пользователя: ")
return int(user_id)
def convert_str_to_date(date_str):
"""
Конвертирует строку с датой в формате ГГГГ-ММ-ЧЧ в объект datetime.date
"""
parts = date_str.split("-")
date_parts = map(int, parts)
date = datetime.date(*date_parts)
return date
def nearest_by_bd(user, session):
"""
Ищет ближайшего по дате рождения атлета к пользователю user
"""
athletes_list = session.query(Athelete).all()
athlete_id_bd = {}
for athlete in athletes_list:
bd = convert_str_to_date(athlete.birthdate)
athlete_id_bd[athlete.id] = bd
user_bd = convert_str_to_date(user.birthdate)
min_dist = None
athlete_id = None
athlete_bd = None
for id_, bd in athlete_id_bd.items():
dist = abs(user_bd - bd)
if not min_dist or dist < min_dist:
min_dist = dist
athlete_id = id_
athlete_bd = bd
return athlete_id, athlete_bd
def nearest_by_height(user, session):
"""
Ищет ближайшего по росту атлета к пользователю user
"""
athletes_list = session.query(Athelete).filter(Athelete.height != None).all()
atlhete_id_height = {athlete.id: athlete.height for athlete in athletes_list}
user_height = user.height
min_dist = None
athlete_id = None
athlete_height = None
for id_, height in atlhete_id_height.items():
dist = abs(user_height - height)
if not min_dist or dist < min_dist:
min_dist = dist
athlete_id = id_
athlete_height = height
return athlete_id, athlete_height
def main():
"""
Осуществляет взаимодействие с пользователем, обрабатывает пользовательский ввод
"""
session = connect_db()
user_id = request_data()
user = session.query(User).filter(User.id == user_id).first()
if not user:
print("Такого пользователя не нашлось:(")
else:
bd_athlete, bd = nearest_by_bd(user, session)
height_athlete, height = nearest_by_height(user, session)
print(
"Ближайший по дате рождения атлет: {}, его дата рождения: {}".format(bd_athlete, bd)
)
print(
"Ближайший по росту атлет: {}, его рост: {}".format(height_athlete, height)
)
if __name__ == "__main__":
main()