-
Notifications
You must be signed in to change notification settings - Fork 6
/
person.py
167 lines (151 loc) · 5.98 KB
/
person.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from random import random, choice
class Person:
"""
Represents people who can be in one of six states:
'Quit smoking' - smoked earlier but now does not (Yaroslav Romanus since 15.06.2021,
Bodya Hlovatskyi since 01.06.2021,
Volodya Fedynyak since [choose your date])
'Senior smoker' - smokes more than 10 years
'Junior smoker' - smokes less than 10 years
'Non-smoker_high' - does not smoke but has many chances to start
'Non-smoker_low' - does not smoke and has little chance to start
"""
def __init__(self, age: int, smoker: bool, smoking_parents: bool, smoking_period: int = 0, position: tuple = None):
self.position = position
self.age = age
self.smoking_parents = smoking_parents
self.smoker = smoker
self.smoking_period = smoking_period
self.state = None
def influence_weight(self, people_influence):
"""
Return a coefficient how much surrounding
influence on person depending on his age.
"""
if self.age < 16:
return people_influence[0]
if 15 < self.age < 26:
return people_influence[1]
if self.age < 46:
return people_influence[2]
if self.age < 66:
return people_influence[3]
return people_influence[4]
def get_person_age_type(self):
"""
Return the name of age group
depending on the person age.
"""
if self.age < 16:
return 'children'
if self.age < 26:
return 'teen'
if self.age < 46:
return 'young'
if self.age < 66:
return 'adult'
return 'elderly'
def check_neighbors(self, grid):
"""
Return tuple where the first element is
the number of smokers around the person,
the second one - the number of nonsmokers
around the person in the square 3x3, where
the person is in the centre.
"""
x, y = self.position
smokers = 0
nonsmokers = 0
for i in range(x - 1, x + 2):
for j in range(y - 1, y + 2):
if (i, j) in grid.filled_cells:
if grid.filled_cells[(i, j)].smoker == True:
smokers += 1
else:
nonsmokers += 1
return smokers, nonsmokers
def chances_to_die(self, grid):
"""
Return the constant value if the person
is not a smoker and the higher one if he is.
Chances depends on how many years the person
smokes. If the person smokes more than 10 years,
every new year has more influence than first 10
years.
"""
chances = grid.chances_to_die
weight_of_smoking_period = grid.weight_of_smoking_year_die[0]
weight_of_smoking_period_pro = grid.weight_of_smoking_year_die[1]
if self.smoking_period:
if self.state != 'smoker_pro':
chances = self.smoking_period * weight_of_smoking_period
else:
chances = 10 * weight_of_smoking_period + \
(self.smoking_period - 10) * weight_of_smoking_period_pro
return chances
def chances_to_start_smoking(self, grid):
"""
Return float between 0 and 1 that means
chances of person to start smoking depending on
the surrounding and the fact if his parents were
smokers.
"""
if self.smoking_parents:
weight_of_smoking_parents = grid.weight_of_smoking_parents
else:
weight_of_smoking_parents = 1
smokers, nonsmokers = self.check_neighbors(grid)
percent_of_smokers = smokers / (smokers + nonsmokers)
chances = percent_of_smokers * \
self.influence_weight(grid.people_influence) * \
weight_of_smoking_parents
return min(chances, 1)
def chances_to_stop_smoking(self, grid):
"""
Return float between 0 and 1 that means
chances of person to stop smoking depending on
the surrounding and the period how long he smokes.
"""
weight_of_smoking_period = grid.weight_of_smoking_year_stop
smokers, nonsmokers = self.check_neighbors(grid)
percent_of_nonsmokers = nonsmokers / (smokers + nonsmokers)
chances = percent_of_nonsmokers * \
(1 - self.smoking_period * weight_of_smoking_period)
return max(chances, 0)
def check_death(self, grid):
"""
Return True if the person has dead.
"""
random_death = random()
if random_death <= self.chances_to_die(grid) or self.age >= 100:
x, y = self.position
grid.filled_cells.pop((x, y))
return True
return False
def __str__(self):
"""
Return info about the person.
"""
return f'Position: {self.position}, age: {self.age}, \
smoker: {self.smoker}, smoking_period: {self.smoking_period}, \
smoking_parents: {self.smoking_parents}, state: {self.state}'
def move(self, grid):
"""
Move the person to the new cell from the square 3x3, where
he is in the centre for now.
"""
directions = [(-1, -1), (0, -1), (1, -1), (-1, 0),
(0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
while True:
random_direction = choice(directions)
new_x = self.position[0] + random_direction[0]
new_y = self.position[1] + random_direction[1]
new_position = (new_x, new_y)
if new_position == self.position:
break
if grid.is_occupied(new_position) or new_x not in range(grid.size[0]) or new_y not in range(grid.size[1]):
continue
grid.filled_cells.pop(self.position)
self.position = new_position
grid.filled_cells[self.position] = self
break