Coverage for C:\Users\svjatoslavsmatvejevs\AppData\Local\Programs\Python\Python39\Lib\site-packages\report\race.py: 31%

68 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-13 09:58 +0200

1"""Use for creating Race class 

2 

3Class: 

4 Race 

5""" 

6 

7from dataclasses import dataclass, field 

8from datetime import datetime, time, date, timedelta 

9 

10 

11@dataclass() 

12class Race: 

13 """Class represents race. 

14 

15 Use either log_file or racers parameter to 

16 creating instance of race class 

17 

18 Args: 

19 log_files: Log file paths. 

20 racers: dictionary of racers participated in the race. 

21 """ 

22 log_files: dict[str: str] = field(default_factory=dict) 

23 racers: dict[str: dict[str: str]] = field(default_factory=dict) 

24 

25 def __post_init__(self): 

26 """Init dictionary of racers if none was passed. 

27 

28 Raises: 

29 ValueError: If no parameter are passed when create 

30 instance of the Race class. 

31 """ 

32 # Check if dictionary was passed 

33 if not self.racers: 

34 # Check if log file paths was passed 

35 if not self.log_files: 

36 raise ValueError("Either log_files or racers should be passed.") 

37 else: 

38 self.get_racers_from_log_files() 

39 

40 def get_racers_from_log_files(self): 

41 """Gets racers dictionary from log files. 

42 

43 Read all log files and abbreviation file and fill 

44 racers dictionary with data. Each racer have one entry in each file. 

45 """ 

46 # Get the explanation of abbreviations. 

47 for line in open(self.log_files["abbreviations"], encoding="utf8"): 

48 line = line.strip() 

49 # If not a blank line. 

50 if line: 

51 # Info about racer is split with underscore: 

52 # "abbreviation_name of the racer_racer team". 

53 racer = line.split("_") 

54 # Abbreviation is the key in racers dictionary. 

55 self.racers[racer[0]] = {"name": racer[1], "team": racer[2]} 

56 

57 # Get the start time of racers best lap. 

58 for line in open(self.log_files["start"]): 

59 line = line.strip() 

60 if line: 

61 # First three chars in the line is abbreviation - key, 

62 # rest is 1st qualification start time of the lap 

63 self.racers[line[:3]]["q1_start"] = datetime.strptime( 

64 line[3:].strip(), "%Y-%m-%d_%H:%M:%S.%f") 

65 

66 # Get the finish time of racers best lap 

67 for line in open(self.log_files["end"]): 

68 line = line.strip() 

69 if line: 

70 # First three chars in the line is abbreviation - key, 

71 # rest is 1st qualification finish time of the lap 

72 self.racers[line[:3]]["q1_end"] = datetime.strptime( 

73 line[3:].strip(), "%Y-%m-%d_%H:%M:%S.%f") 

74 

75 def get_number_of_racers(self) -> int: 

76 """Get number of the racers in the race. 

77 

78 Returns: 

79 Number of the racers in the race. 

80 """ 

81 number_of_racers = len(self.racers.keys()) 

82 return number_of_racers 

83 

84 def get_data_of_race(self) -> date: 

85 """Get date in which race took place. 

86 

87 Date of the race is located in any racers q1_start or q1_end time. 

88 

89 Returns: 

90 Date of the race. 

91 """ 

92 race_date = self.racers[list(self.racers.keys())[0]]["q1_start"].date() 

93 return race_date 

94 

95 def get_start_time_of_q1(self) -> time: 

96 """Get start time of 1st qualification. 

97 

98 Loop through all racers q1_start time and find the earliest one. 

99 

100 Returns: 

101 1st qualifications start time. 

102 """ 

103 q1_start_time = None 

104 for racer in self.racers.values(): 

105 racer_start_time = racer["q1_start"].time() 

106 if q1_start_time: 

107 # Check if racer_stat_time is earlier than q1_start_time. 

108 if q1_start_time > racer_start_time: 

109 q1_start_time = racer_start_time 

110 else: 

111 # If q1 start time is None assign with first racers start time. 

112 q1_start_time = racer_start_time 

113 return q1_start_time 

114 

115 def get_names_of_racers(self, reverse=False) -> list[str]: 

116 """Get all racer names. 

117 

118 Collect all racer names who are participating in the race 

119 by asc or desc order. 

120 

121 Args: 

122 reverse: Defines order of racer names in the list. 

123 If True than order of the racer names is reverse. 

124 

125 Returns: 

126 List of racer names in asc or desc order. 

127 """ 

128 racers_names = [racer["name"] for racer in self.racers.values()] 

129 racers_names.sort(reverse=reverse) 

130 return racers_names 

131 

132 def get_teams(self, reverse=False) -> list[str]: 

133 """Get all team names. 

134 

135 Collect all team names which are participating in the race 

136 by asc or desc order. 

137 

138 Args: 

139 reverse: Defines order of team names in the list. 

140 If True than order of the team names is reverse. 

141 

142 Returns: 

143 List of team names in asc or desc order. 

144 """ 

145 teams_in_race = {racer["team"] for racer in self.racers.values()} 

146 teams_in_race = sorted(teams_in_race, reverse=reverse) 

147 return teams_in_race 

148 

149 def build_report(self) -> list[list[str, str, timedelta]]: 

150 """Build result of the 1st qualification. 

151 

152 Returns: 

153 Racers name, team, lap time. 

154 """ 

155 race_report = [ 

156 [racer["name"], 

157 racer["team"], 

158 (racer["q1_end"] - racer["q1_start"])] 

159 for racer in self.racers.values()] 

160 # Sort report by lap time. 

161 race_report = sorted(race_report, key=lambda x: x[2]) 

162 return race_report 

163 

164 def get_racer(self, name: str) -> list: 

165 """Get racer data. 

166 

167 Args: 

168 name: Name of the racer. 

169 

170 Returns: 

171 List of racer's data. 

172 

173 Raises: 

174 UserWarning when racer's name is not in racers dictionary. 

175 """ 

176 for key, racer in self.racers.items(): 

177 if racer["name"] == name: 

178 racer_data = [key, racer["name"], racer["team"], 

179 str(racer["q1_end"] - racer["q1_start"])[3: -3]] 

180 return racer_data 

181 raise UserWarning(f"Can't find racer with name: {name}") 

182 

183 def get_racers_in_team(self, team: str, order=False) -> list[list]: 

184 """Get racers from the team. 

185 

186 Args: 

187 team: Name of the team. 

188 order: Defines order of racer names in the list. 

189 If True than order of the racer names is reverse. 

190 

191 Returns: 

192 List of racers data. 

193 

194 Raises: 

195 UserWarning when team is not in racers dictionary. 

196 """ 

197 racers_in_team = [] 

198 for key, racer in self.racers.items(): 

199 if racer["team"] == team: 

200 racer_data = [key, racer["name"], racer["team"], 

201 str(racer["q1_end"] - racer["q1_start"])[3: -3]] 

202 racers_in_team.append(racer_data) 

203 racers_in_team = sorted(racers_in_team, key=lambda x: x[0], reverse=order) 

204 if racers_in_team: 

205 return racers_in_team 

206 raise UserWarning(f"Can't find team with name: {team}")