def get_barcode_forecast(data_frame: DataFrame, now: Arrow, for_date: Arrow) -> Series: if not data_frame.empty: last_data_date = arrow.get(data_frame.index.max()) beg_date = now.shift(months=-1) end_date = for_date real = create_df_with_zeroes(data_frame, beg_date.shift(weeks=-1), end_date) old = create_df_with_zeroes(data_frame, beg_date.shift(weeks=-1), end_date, lambda a: a.shift(years=-1)) real_smoothed = smooth_df(real, beg_date, last_data_date) old_smoothed = smooth_df(old, beg_date, end_date) if not real_smoothed.empty: _, diff = compare_df(real_smoothed, old_smoothed, now.shift(days=1), end_date) result_forecast = shift_df(old_smoothed, diff, now.shift(days=1), end_date) return result_forecast['quantity'][now.date():for_date.date()] else: raise Exception('Empty data frame') else: raise Exception('Empty data frame')
def exam_dates(begin: Tuple[int, int]) -> Iterable[Tuple[int, int]]: date = Arrow(2020, begin[0], begin[1], tzinfo=TIMEZONE) while True: yield date.date().month, date.date().day while True: date = date.shift(days=1) if date.isoweekday() < 6: break
def do_harvest(self, start_date: arrow.Arrow, end_date: arrow.Arrow) -> Iterator[Tuple[str, Union[str, dict, bytes]]]: url = furl(self.url) url.args['dateStart'] = start_date.date().strftime('%m/%d/%Y') url.args['dateEnd'] = end_date.date().strftime('%m/%d/%Y') url.args['offset'] = 0 return self.fetch_records(url)
def compare_df(new_df: DataFrame, old_df: DataFrame, beg: Arrow, end: Arrow): new_mean = new_df.loc[beg.date():end.date()].mean().values[0] old_mean = old_df.loc[beg.date():end.date()].mean().values[0] if old_mean != 0.0: percent_diff = (new_mean * 100 / old_mean) - 100 diff = new_mean - old_mean else: raise Exception('No data for past year') return percent_diff, diff
async def process_date(date: arrow.Arrow, extras: dict): if 'FREQ' in extras.keys() and extras['FREQ'] == 'WEEKLY': if 'INTERVAL' in extras.keys(): return True if int(date.date().day - arrow.now().date().day) % int( extras['INTERVAL']) * 7 == 0 else False return True if int(date.date().day - arrow.now().date().day) % 7 == 0 else False else: raise Exception('No FREQ in extras')
def do_harvest(self, start_date: arrow.Arrow, end_date: arrow.Arrow) -> Iterator[Tuple[str, Union[str, dict, bytes]]]: url = furl(self.url) url.args['page[size]'] = 100 url.args['filter[public]'] = 'true' url.args['embed'] = 'affiliated_institutions' url.args['filter[date_modified][gt]'] = start_date.date().isoformat() url.args['filter[date_modified][lt]'] = end_date.date().isoformat() return self.fetch_records(url)
def do_harvest(self, start_date: arrow.Arrow, end_date: arrow.Arrow) -> Iterator[Tuple[str, Union[str, dict, bytes]]]: url = furl(self.url) url.args['page[size]'] = 100 url.args['filter[tags]'] = 'psyarxiv' # temporary - remove with proper preprint harvest url.args['embed'] = 'affiliated_institutions' # temporary - remove with proper preprint harvest url.args['filter[date_modified][gt]'] = start_date.date().isoformat() url.args['filter[date_modified][lt]'] = end_date.date().isoformat() return self.fetch_records(url)
def do_harvest(self, start_date: arrow.Arrow, end_date: arrow.Arrow) -> list: url = furl(self.url) url.args['verb'] = 'ListRecords' url.args['metadataPrefix'] = 'oai_dc' if self.time_granularity: url.args['from'] = start_date.format('YYYY-MM-DDT00:00:00') + 'Z' url.args['until'] = end_date.format('YYYY-MM-DDT00:00:00') + 'Z' else: url.args['from'] = start_date.date().isoformat() url.args['until'] = end_date.date().isoformat() return self.fetch_records(url)
def test_one_arg_date_tzinfo_kwarg(self): da = date(2021, 4, 29) result = self.factory.get(da, tzinfo="America/Chicago") expected = Arrow(2021, 4, 29, tzinfo=tz.gettz("America/Chicago")) assert result.date() == expected.date() assert result.tzinfo == expected.tzinfo
def getFreeTimeBetweenPoints(days: [Day], start: arrow.Arrow, end: arrow.Arrow) -> int: # In Minutes if start == end: return 0 sortedDays = sorted(days, key=lambda d: d.date) startDate = start.date() endDate = end.date() startTime = Time(start.hour, start.minute) endTime = Time(end.hour, end.minute) # Collect time inbetween freeMinutes = 0 for day in sortedDays: # Days before or equal to the start date if day.date < startDate: continue elif day.date == startDate: if day.date == endDate: # If it is ALSO equal to the endDate (i.e. startDate and endDate are the same day) return day.freeTimeInMinutes( after=startTime, before=endTime ) # Return immediately, as this is the only day (since startDate==endDate) else: freeMinutes += day.freeTimeInMinutes(after=startTime) continue # Days after or equal to the end date if day.date > endDate: print( f"WARNING: This scenario [debug-id: schedule_alg:AAA123] should not occur! Last day of time windows was likely not calculated correctly. DayDate: {day.date} | EndDate: {endDate}" ) print(f"Start: {start} | End: {end}") return freeMinutes elif day.date == endDate: freeMinutes += day.freeTimeInMinutes(before=endTime) return freeMinutes # This is the last valid day, return immediately # Normal day freeMinutes += day.freeTimeInMinutes() return freeMinutes
def get_category_forecast(barcode_data_frame: DataFrame, category_data_frame: DataFrame, now: Arrow, for_date: Arrow) -> Series: tomorrow = now.shift(days=1) past_month = now.shift(months=-1) barcode_df = create_df_with_zeroes(barcode_data_frame, past_month, now) barcode_smoothed = smooth_df(barcode_df, past_month, now) category_df = create_df_with_zeroes(category_data_frame, past_month, for_date, lambda a: a.shift(years=-1)) category_smoothed = smooth_df(category_df, past_month, for_date) barcode_series = barcode_smoothed['quantity'][past_month.date():now.date()] category_series = category_smoothed['quantity'][past_month.date():now.date( )] percent, _ = compare_df(barcode_series.to_frame(), category_series.to_frame(), past_month, now) forecast = category_smoothed['quantity'][tomorrow.date():for_date.date()] forecast_normalized = increase_df(forecast.to_frame(), percent, tomorrow, for_date) return forecast_normalized['quantity'][now.date():for_date.date()]
def get_mean_forecast(data_frame: DataFrame, now: Arrow, for_date: Arrow) -> Series: tomorrow = now.shift(days=1) beg = now.shift(days=-6) arr = [] for day in Arrow.range('day', beg, now): try: value = data_frame.loc[day.date()].values[0] except KeyError: value = 0.0 arr.append([day.date(), value]) init_df = create_df_indexed_by_date(create_df(arr)) df = create_df_with_zeroes(init_df, beg, for_date) for day in Arrow.range('day', tomorrow, for_date): yesterday = day.shift(days=-1) past_week = df[yesterday.shift(days=-6).date():yesterday.date()] df.loc[day.date()] = past_week.mean() return df['quantity'][tomorrow.date():for_date.date()]
def get_date(arw: Arrow, is_all_day: bool) -> Union[datetime, date]: """Get datetime. :param arw The arrow object representing the date. :type Arrow :param is_all_day If true, the returned datetime will have the time component set to 0. :type: bool :returns The datetime. :rtype datetime """ # if isinstance(arw, Arrow): if is_all_day: return arw.date() # else: # if arw.tzinfo is None or arw.tzinfo.utcoffset(arw) is None # or is_all_day: # arw = arw.astimezone() # if is_all_day: # return arw.date() # return arw.datetime
def time_ago(time_in: Arrow) -> str: """ returns string saying how long ago the time on input was """ now = arrow.utcnow() diff = now - time_in sec_diff = int(diff.total_seconds()) rules = [ # threshold in seconds, view function, suffix (120, lambda x: "", "<2 minutes"), (7200, lambda x: int(x / 60), "minutes"), (172800, lambda x: int(x / 3600), "hours"), (5184000, lambda x: int(x / 86400), "days"), # we should provide timezone # but it doesn't really matter here (None, lambda x: time_in.date().isoformat(), ""), ] for threshold, func, suffix in rules: if threshold is None or sec_diff < threshold: return "{} {}".format(func(sec_diff), suffix) else: raise RuntimeError("Unexpected error in time_ago filter,")
def scheduleTask(self, task: Task, start: arrow.Arrow, minutes=None, debug=False): # TODO: Consider minBlock if minutes is None: minutesToSchedule = task.maxRemainingTime else: minutesToSchedule = minutes if debug: print(f"Schedule is scheduling {minutesToSchedule}min for task {task}") scheduledMinutes = 0 startTime = util.arrowToTime(start) for day in self.__days: if debug: print("\n") print(day, end=" -> ") if task.maxRemainingTime == 0 or minutesToSchedule == scheduledMinutes: if debug: print("A", end="") return # Skip days prior to the startDate if day.date < start.date(): if debug: print("B", end="") continue # For the start day, consider only the times that lie after the start time if day.date == start.date(): if debug: print("C", end="") freeTimeSlots = day.freeTimeSlots(after=startTime) # Days in the future if day.date > start.date(): if debug: print("D", end="") freeTimeSlots = day.freeTimeSlots() if len(freeTimeSlots) == 0: if debug: print("E", end="") continue # For the valid TimeSlots of the future, fill them with the task until they are either all filled or "minutesToSchedule" minutes are scheduled for ts in freeTimeSlots: if debug: print("F", end="") if task.maxRemainingTime == 0 or minutesToSchedule == scheduledMinutes: if debug: print("G", end="") return # If TimeSlot is <= to what still needs to be scheduled, fill it completely if ts.durationInMinutes <= (minutesToSchedule - scheduledMinutes): if debug: print("H", end="") # Schedule the Task day.scheduleTask(ts, task, debug=debug) # Update the counters task.addCompletionTime(ts.durationInMinutes) # This mutates the ORIGINAL TASK scheduledMinutes += ts.durationInMinutes else: # If TimeSlot is bigger than what needs to be scheduled, fill the first section of it (until "minutesToSchedule" minutes are scheduled) if debug: print("I", end="") # Build the Partial TimeSlot remainingMinutesToSchedule = minutesToSchedule - scheduledMinutes length = Time.fromMinutes(remainingMinutesToSchedule) partialTimeSlot = TimeSlot(ts.startTime, ts.startTime + length) # Schedule the Task day.scheduleTask(partialTimeSlot, task, debug=debug) # Update the counters task.addCompletionTime(partialTimeSlot.durationInMinutes) # This mutates the ORIGINAL TASK scheduledMinutes += partialTimeSlot.durationInMinutes # Unnecessary. ScheduledMinutes will == MinutesToSchedule after this every time. return # Since the TimeSlot was bigger than the remaining minutesToSchedule, we are done here now. raise ImpossibleScheduleException("Unable to schedule task!")
def calculateSchedule(globalDays: [Day], tasks: [Task], currentSchedule: Schedule, start: arrow.Arrow, debug=False) -> Schedule: currentTime = util.smoothCurrentArrow() if start < currentTime: raise Exception("Cannot calculate a schedule for the past") days = currentSchedule.days() oldDays = [day.copy() for day in days if day.date <= start.date() ] # Contains all days PRIOR to start date (last is popped off) oldTimeSlots = [] if oldDays: # On initial creation, there are no old days lastDay = oldDays.pop( ) # This day is changed after the current timeslot and kept the same before. splitTime = Time(start.hour, start.minute) for ts in lastDay.timeSlots: if ts.endTime > splitTime and ts.startTime < splitTime: # Update start time to be the end of the current timeslot # Update Arrow object only if it isn't before the smoothCurrentArrow() splitArrow = arrow.Arrow(start.year, start.month, start.day, hour=ts.endTime.hours, minute=ts.endTime.minutes) if splitArrow >= currentTime: start = splitArrow splitTime = Time(start.hour, start.minute) if ts.startTime < splitTime and ts.taskOrAppointment is not None: oldTimeSlots.append(ts) startIndex = None for i, day in enumerate(globalDays): if day.date == start.date(): startIndex = i break else: raise Exception("Error in schedule_alg 555255GGG") newDays = [day.copy() for day in globalDays[startIndex:]] # Remove TimeSlots prior to start firstNewDay = newDays[0] oldTimeSlotsToRemove = [] for ts in firstNewDay.timeSlots: if ts.startTime < splitTime: oldTimeSlotsToRemove.append(ts) for otstr in oldTimeSlotsToRemove: firstNewDay.timeSlots.remove(otstr) for oldTimeSlot in oldTimeSlots: firstNewDay.addTimeSlot(oldTimeSlot) lastWorkConfirmed = currentSchedule.lastWorkConfirmed if lastWorkConfirmed is None: lastWorkConfirmed = start.clone() # Creates a clean copy of the tasks and days, so that no evil mutation occurs newDays = sorted(newDays, key=lambda d: d.date) tmpTasks = sorted([task.copy() for task in tasks], key=lambda t: t.deadline) if isSolvable(tasks, newDays, start, useMinimum=False): happySchedule = calculateHappySchedule( tmpTasks, newDays, lastWorkConfirmed, start, debug=debug ) # Adds the history (previous schedule) to the newly calculated schedule happySchedule.addHistory(oldDays) return happySchedule elif isSolvable(tasks, newDays, start, useMinimum=True): riskySchedule = calculateSadSchedule(tmpTasks, newDays, lastWorkConfirmed, start, debug=debug) riskySchedule.addHistory(oldDays) return riskySchedule #return calculateRiskySchedule(tmpTasks, newDays, created=start) else: sadSchedule = calculateSadSchedule(tmpTasks, newDays, lastWorkConfirmed, start, debug=debug) sadSchedule.addHistory(oldDays) return sadSchedule
def is_winter(date: arrow.Arrow = arrow.now()) -> bool: """ Returns `True` if the date is considered winter. """ month = date.date().month return (1 <= month <= 4) or (10 <= month <= 12)