def get_decay_curve(self, stepping: timedelta) -> Iterable[float]: def calc_decay(t: int) -> float: hl_steps = self.drug.half_life.total_seconds( ) / stepping.total_seconds() factor = 2**(float(t) / hl_steps) return self.amount * factor return map(calc_decay, count())
def draw_wave(self, wave): min_ys, max_ys = zip( *map(juxt(np.min, np.max), np.array_split(wave * 128 + 128, 256))) for object_id in self.wave_canvas.find_all(): self.wave_canvas.delete(object_id) for x, min_y, max_y in zip(count(), min_ys, max_ys): self.wave_canvas.create_line(x, min_y, x, max_y)
def create_surface(space, cars, players, actions): space_surface, space_left, space_bottom, space_width, space_height = _create_space_surface(space) surface = pygame.surface.Surface((800, 640)) font = pygame.font.Font(None, 24) surface.blit(pygame.transform.smoothscale(space_surface, (640, 640)), (0, 0)) pygame.draw.rect(surface, (255, 255, 255), (640, 0, 800, 640)) for i, car, player, action in zip(count(), cars, players, actions): surface.blit(font.render(player.name, True, (0, 0, 0)), (640 + 4, 80 * i + 4)) pygame.draw.line(surface, (64, 64, 64), ((640, 80 * i + 12)), ((car.position.x - space_left) * (640 / space_width), 640 - (car.position.y - space_bottom) * (640 / space_height))) pygame.draw.line(surface, (192, 192, 192), (640 + 24 - 2, 80 * i + 48), (640 + 24 + 130 + 2, 80 * i + 48)) for j, action_value in zip(count(), action): pygame.draw.rect(surface, (128, 128, 128), (640 + 24 + 50 * j, min(80 * i + 48, 80 * i + 48 - int(action_value * 20)), 30, abs(int(action_value * 20)))) return surface
def zip_pluck(d, keys, enumerate=False): args = [pluck(k, d) for k in keys] if enumerate: args = [count(), *args] return zip(*args)
def get_plot_data(self, plot_delta: timedelta = timedelta(days=1), adjusted: bool = False, stddev_multiplier: float = 1.0, offset: float = 0.0, color: bool = False, use_x_date: bool = False) -> \ Tuple[np.ndarray, Dict[str, plot_data_type]]: t_arr = take( self.duration, map( lambda x: x * (self.step.total_seconds() / plot_delta. total_seconds()) + offset, count())) if use_x_date: t_arr = map( lambda x: datetime.combine(self.starting_date, time()) + plot_delta * x, t_arr) t_arr = np.array(list(t_arr)) # print(f't_arr.size()={len(t_arr)}') out = {} drugs = sorted(list(self.drugs_timeline.keys()), key=lambda x: self.drugs[x].name) step_time_d = int(self.step.total_seconds()) steps = ( int( math.ceil( int(timedelta(days=self.step_days[0]).total_seconds()) / step_time_d)), int( math.ceil( int(timedelta(days=self.step_days[1]).total_seconds()) / step_time_d)), int( math.ceil( int(timedelta(days=self.step_days[2]).total_seconds()) / step_time_d))) self.running_average = {} self.running_stddev = {} for n, drug in enumerate(drugs): # print(f"{n}: {drug}") timeline = self.drugs_timeline[drug] drug_name = self.drugs[drug].name_blood # print(f"{steps}/{len(timeline)}") if self.drugs[drug].factor != 1.0: drug_name += f" (x{self.drugs[drug].factor})" if adjusted and drug in self.blood_level_factors and len( self.blood_level_factors[drug]) > 0: # print(self.blood_level_factors) factor_timeline = [] ev_num = 0 for t in range(len(timeline)): t_time = datetime.combine(self.starting_date, time()) + t * self.step if len(self.events) > 0: if len(self.blood_level_factors[drug]) > ev_num + 1: if datetime.combine(self.events[ev_num][0], time())+self.events[ev_num][1] > \ t_time > datetime.combine(self.events[ev_num][0], time()): factor: timedelta = t_time - datetime.combine( self.events[ev_num][0], time()) factor: float = factor / self.events[ev_num][1] factor_timeline.append(( self.blood_level_factors[drug][ev_num + 1][0] * factor + self.blood_level_factors[drug][ev_num][0] * (1 - factor), self.blood_level_factors[drug][ev_num + 1][1] * factor + self.blood_level_factors[drug][ev_num][1] * (1 - factor))) elif datetime.combine( self.events[ev_num][0], time()) + self.events[ev_num][1] <= t_time: ev_num += 1 factor_timeline.append( self.blood_level_factors[drug][ev_num]) else: factor_timeline.append( self.blood_level_factors[drug][ev_num]) else: factor_timeline.append( self.blood_level_factors[drug][ev_num]) else: factor_timeline.append( self.blood_level_factors[drug][0]) self.factor_timeline[drug] = factor_timeline list_avg = lmap(lambda x: x[0] * x[1][0], zip(timeline, factor_timeline)) arr_avg = np.array(list_avg) arr_min = np.array( lmap( lambda x: x[0] * x[1][0] - x[1][1] * stddev_multiplier, zip(timeline, factor_timeline))) arr_max = np.array( lmap( lambda x: x[0] * x[1][0] + x[1][1] * stddev_multiplier, zip(timeline, factor_timeline))) mp_ctx = mp.get_context('fork') statistics_data: List[Tuple[Sequence[int], List[float], int]] statistics_data = [(steps, list_avg, i) for i in range(3)] with mp_ctx.Pool(3) as mp_pool: statistics_results = mp_pool.map( calculate_running_statistics, statistics_data) running_average, running_std_dev = tuple( map(list, list(zip(*statistics_results)))) self.running_average[drug_name] = tuple( map(np.array, running_average)) self.running_stddev[drug_name] = tuple( map(np.array, running_std_dev)) if color: # print(f"{drug}: {n} => {get_color(n)}") out[drug_name] = (arr_avg, arr_min, arr_max, get_color(n)) else: out[drug_name] = (arr_avg, arr_min, arr_max) else: arr = np.array(timeline) * self.drugs[drug].factor if color: out[drug_name] = (arr, arr, arr, get_color(n)) else: out[drug_name] = (arr, arr, arr) # print(f't_arr.size({drug.name})={len(out[drug.name])}') return t_arr, out
def mergesort(filename, output=None, key=None, maxitems=1e6, progress=True): """Given an input file sort it by performing a merge sort on disk. :param filename: Either a filename as a ``str`` or a ``py._path.local.LocalPath`` instance. :type filename: ``str`` or ``py._path.local.LocalPath`` :param output: An optional output filename as a ``str`` or a ``py._path.local.LocalPath`` instance. :type output: ``str`` or ``py._path.local.LocalPath`` or ``None`` :param key: An optional key to sort the data on. :type key: ``function`` or ``None`` :param maxitems: Maximum number of items to hold in memory at a time. :type maxitems: ``int`` :param progress: Whether or not to display a progress bar :type progress: ``bool`` This uses ``py._path.local.LocalPath.make_numbered_dir`` to create temporry scratch space to work with when splitting the input file into sorted chunks. The mergesort is processed iteratively in-memory using the ``~merge`` function which is almost identical to ``~heapq.merge`` but adds in the support of an optional key function. """ p = filename if isinstance(filename, LocalPath) else LocalPath(filename) output = p if output is None else output key = key if key is not None else lambda x: x scratch = LocalPath.make_numbered_dir(prefix="mergesort-") nlines = sum(1 for line in p.open("r")) # Compute a reasonable chunksize < maxitems chunksize = first(ifilter(lambda x: x < maxitems, imap(lambda x: nlines / (2**x), count(1)))) # Split the file up into n sorted files if progress: bar = ProgressBar("Split/Sorting Data", max=(nlines / chunksize)) for i, items in enumerate(ichunks(chunksize, jsonstream(p))): with scratch.ensure("{0:d}.json".format(i)).open("w") as f: f.write("\n".join(map(dumps, sorted(items, key=key)))) if progress: bar.next() if progress: bar.finish() q = scratch.listdir("*.json") with output.open("w") as f: if progress: bar = ProgressBar("Merge/Sorting Data", max=nlines) for item in merge(*imap(jsonstream, q)): f.write("{0:s}\n".format(dumps(item))) if progress: bar.next() if progress: bar.finish()