def get_menus_list(self): r = requests.get("https://sites.google.com/site/fedorestbe/menu-fr/menu-noga-fr") soup = BeautifulSoup(r.content, "lxml") current_week = Week.thisweek().week current_year = Week.thisweek().year content = "" content += "Voici les menus disponibles concoctes par les chefs Fedorest. Nous sommes en semaine {}-{} : \n".format(current_year, current_week) link_cells = soup.find_all("td", {"class": "td-file"}) regex = r"noga_fr_(\d+)_(\d+)\.pdf" for cell in link_cells: links = cell.find_all("a") for link in links: url = link.get("href") matches = re.findall(regex, url) if matches: (week, year) = matches[0] content += "* ["+year + "-"+week + "](" + GOOGLE_SITE_BASE + url + ")\n" return content
def generate_header(): dob = dt.datetime(1989, 5, 28, tzinfo=pytz.timezone('utc')) now = dt.datetime.now(tz=pytz.timezone('utc')) last_year = now.year - 1 last_week_of_last_year = Week.last_week_of_year(last_year).week age = relativedelta(now, dob).years my_birthday_happened_this_year = now > dt.datetime( now.year, 5, 28, tzinfo=pytz.timezone('utc')) if my_birthday_happened_this_year: last_birthday = dt.datetime(now.year, 5, 28) weeks_lived_this_year = Week.thisweek().week - Week.withdate( last_birthday).week else: last_birthday = dt.datetime(last_year, 5, 28) weeks_lived_this_year = Week.withdate( now).week + last_week_of_last_year - Week.withdate( last_birthday).week seasons = [ ([3, 4, 5], 'Spring ❀'), ([6, 7, 8], 'Summer ☀'), ([9, 10, 11], 'Fall ☕︎'), ([1, 2, 12], 'Winter ❄'), ] season_week_number = 0 for season in seasons: if now.month in season[0]: current_season = season[1] season_week_number = Week.thisweek().week - Week.withdate( dt.datetime( now.year, season[0][0], 1, tzinfo=pytz.timezone('utc'))).week if now.month in [1, 2]: season_week_number += last_week_of_last_year - Week.withdate( dt.datetime(last_year, 12, 1, tzinfo=pytz.timezone('utc'))).week assert season_week_number > 0 # seasonal loader empty = '░' empty_amount = empty * (13 - (season_week_number - 1)) * 2 filled = '▓' filled_amount = filled * (season_week_number - 1) * 2 # Subtracting one because I generate these at the beginning of the week loader = "{0}{1}".format(filled_amount, empty_amount) weeks_remaining = "/ {} weeks remaining /".format(13 - season_week_number) return "# {0} {1} {2}:13 ㄖ {3}:52\n{4} {5}".format( age, current_season, season_week_number, weeks_lived_this_year, loader, weeks_remaining)
def show_by_due_date(all_tasks, _): this_week = Week.thisweek() next_week = Week.thisweek() + 1 unscheduled_tasks = [] overdue_tasks = [] tasks_this_week = [] tasks_next_week = [] future_tasks = defaultdict(list) for task in all_tasks: if not task["week"]: unscheduled_tasks.append(task) elif task["week"] < str(this_week): overdue_tasks.append(task) elif task["week"] == str(this_week): tasks_this_week.append(task) elif task["week"] == str(next_week): tasks_next_week.append(task) else: future_tasks[task["week"]].append(task) context = "timeframe" print() if overdue_tasks: headline = format_headline("!!! Overdue !!!", color="red") print(headline) print(format_task_block(context, overdue_tasks, print_date=True)) headline = format_headline("This Week", "Week " + str(this_week.week)) print(headline) print(format_task_block(context, tasks_this_week)) headline = format_headline( "Next Week", "Week " + str(next_week.week) + ", " + next_week.monday().isoformat() + "+") print(headline) print(format_task_block(context, tasks_next_week)) for week, tasks in future_tasks.items(): week = Week.fromstring(week) headline = format_headline("Week " + str(week.week), week.monday().isoformat() + "+") print(headline) print(format_task_block( context, tasks, )) headline = format_headline("Backlog") print(headline) print(format_task_block(context, unscheduled_tasks))
def post(self, request, *args, **kwargs): year = kwargs.get('year') or datetime.datetime.now().year week = kwargs.get('week') or Week.thisweek().week if week < 1 or week > Week.last_week_of_year(year).week: raise Http404('Invalid week / year.') next_year, next_week = self.calc_next(year, week) previous_year, previous_week = self.calc_previous(year, week) row_formset = self.form_class(request.POST) if row_formset.is_valid(): row_formset.save() success_url = reverse('home-param', args=(year, week)) return HttpResponseRedirect(success_url) create_row_form = RowModelForm() return render( request, self.template_name, { 'create_row_form': create_row_form, 'row_formset': row_formset, 'week': week, 'year': year, 'next_week': next_week, 'next_year': next_year, 'previous_week': previous_week, 'previous_year': previous_year })
def get(self, request, *args, **kwargs): year = kwargs.get('year') or datetime.datetime.now().year week = kwargs.get('week') or Week.thisweek().week if week < 1 or week > Week.last_week_of_year(year).week: raise Http404('Invalid week / year.') next_year, next_week = self.calc_next(year, week) previous_year, previous_week = self.calc_previous(year, week) rows = RowModel.objects.filter(year=year, week=week) row_formset = self.form_class(queryset=rows) create_row_form = RowModelForm() return render( request, self.template_name, { 'create_row_form': create_row_form, 'row_formset': row_formset, 'week': week, 'year': year, 'next_week': next_week, 'next_year': next_year, 'previous_week': previous_week, 'previous_year': previous_year })
def handle_noargs(self, **options): translation.activate('fr') logging.debug('Command in progress') week_limit = Week.withdate(Week.thisweek().day(settings.VALIDATING_DAY_OF_WEEK) + relativedelta(days=settings.DELAY_BETWEEN_DEFINITON_N_DELIVERY)) # first changed the status of expired deliveries deliveries_canceled = models.Delivery.objects.filter(date__lt=week_limit, status='w', subscription__enabled=True) for delivery in deliveries_canceled: delivery.status = 'e' delivery.save() logging.debug('delivery %d expired' % delivery.id) # secondly, get all the deliveries with a date higher or equal to J+9 and lesser than J+9+7 with a waiting status and a subscription which accepts direct debit. deliveries = models.Delivery.objects.filter(date__gte=week_limit, date__lt=week_limit+1, status='w', subscription__direct_debit=True, subscription__enabled=True) for delivery in deliveries: delivery.status = 'p' try: delivery.save() except ValueError as e: logging.debug('delivery %d not payed' % delivery.id) else: logging.debug('delivery %d payed' % delivery.id) translation.deactivate()
def validate_period(period, first_date): ''' make sure only period is between first_date and today ''' today = datetime.now().strftime('%Y%m%d') # Day yyyyMMdd if type_of_period(period) == 'day': if period >= first_date and period <= today: return True # Week yyyy-Www elif type_of_period(period) == 'week': this_week = Week.thisweek() period_week = Week.fromstring(period) first_date_week = Week.withdate(datetime.strptime(first_date, '%Y%m%d')) if period_week >= first_date_week and period_week <= this_week: return True # Month yyyyMM elif type_of_period(period) == 'month': this_month = datetime.now().strftime('%Y%m') period_month = period[0:6] first_date_month = first_date[0:6] if period_month >= first_date_month and period_month <= this_month: return True return False
def validate_period(period, first_date): ''' make sure only period is between first_date and today ''' today = datetime.now().strftime('%Y%m%d') # Day yyyyMMdd if type_of_period(period) == 'day': if period >= first_date and period <= today: return True # Week yyyy-Www elif type_of_period(period) == 'week': this_week = Week.thisweek() period_week = Week.fromstring(period) first_date_week = Week.withdate(datetime.strptime( first_date, '%Y%m%d')) if period_week >= first_date_week and period_week <= this_week: return True # Month yyyyMM elif type_of_period(period) == 'month': this_month = datetime.now().strftime('%Y%m') period_month = period[0:6] first_date_month = first_date[0:6] if period_month >= first_date_month and period_month <= this_month: return True return False
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) start = self.fields['start'] cw = Week.thisweek() choices = [str(w + cw.week) for w in Week.weeks_of_year(cw.year)] start.choices = zip(choices, choices) start.initial = cw+1
def get_calories(): this_week = Week.thisweek().week included_weeks = [ str(this_week), str(this_week - 1), str(this_week - 2), str(this_week - 3) ] activities = query_activities() acts_by_week = {} cals_by_week = {} for act in activities: iter_date = act.start_date iter_week = iter_date.strftime("%W") if iter_week in included_weeks: if iter_week in acts_by_week: acts_by_week[iter_week].append(act.id) else: acts_by_week[iter_week] = [act.id] print acts_by_week for key, value in acts_by_week.items(): for act_id in value: act_cals = act_by_num(act_id) if key in cals_by_week: cals_by_week[key] += act_cals.calories else: cals_by_week[key] = act_cals.calories return cals_by_week
def make_climate_maps(region_list): logging.debug('starting make_climate_maps') gfw_sync_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) scripts_dir = os.path.dirname(gfw_sync_dir) climate_maps_dir = os.path.join(scripts_dir, 'gfw-climate-glad-maps') python_exe = r'C:\PYTHON27\ArcGISx6410.5\python' current_week = Week.thisweek() for i in range(1, 5): offset = current_week - i year = str(offset.year) week = str(offset.week) for region in region_list: cmd = [python_exe, 'create_map.py', '-y', year, '-w', week, '-r', region] logging.debug('calling subprocess:') logging.debug(cmd) subprocess.check_call(cmd, cwd=climate_maps_dir)
def week_display(): # Default view is the current week. if session.week is None: session.week = Week.thisweek()[1] session.year = date.today().year week = session.week year = session.year # some years end in week 53, others in week 52 lastweekofyear = Week.last_week_of_year(year)[1] # If it is the last week of the year, fix forward button if lastweekofyear == week: forward = {"week":1,"year":year + 1} else: forward = {"week":week + 1,"year":year} # If it is the first week of the year, fix back button if week == 1: back = {"week":Week.last_week_of_year(year - 1)[1],"year":year - 1} else: back = {"week":week - 1,"year":year} # Our startdate will be current week, beginning with monday # set remaining sessions to new values and move on session.startday = Week(year, week).monday() session.back = back session.forward = forward session.week = week session.year = year
def get_last_full_week(): last_week = Week.thisweek() - 1 if int(last_week.week) < 10: return str(last_week.year) + "0" + str(last_week.week) return str(last_week.year) + str(last_week.week) # YYYYWW iso week format
def format_week(week): week = week.lower() if "-" in week: week_list = week.split("-") elif "/" in week: week_list = week.split("/") elif "w" in week: week_list = week.split("w") else: week_list = ["", week] if "w" in week_list[0]: week_number = week_list[0].replace("w", "").rjust(2, "0") year = ("20" + week_list[1]) if len(week_list[1]) == 2 else week_list[1] else: week_number = week_list[1].replace("w", "").rjust(2, "0") year = "20" + week_list[0] if len(week_list[0]) == 2 else week_list[0] if not year: this_week = Week.thisweek() if int(week_number) < this_week.week: year = str(this_week.year + 1) else: year = str(this_week.year) return Week.fromstring(year + "W" + week_number)
def handle_noargs(self, **options): translation.activate('fr') week_limit = Week.withdate(Week.thisweek().day(settings.VALIDATING_DAY_OF_WEEK) + relativedelta(days=settings.DELAY_BETWEEN_DEFINITON_N_DELIVERY)) deliveries = models.Delivery.objects.filter(date__lte=week_limit, status='P', subscription__enabled=True).order_by('subscription__customer__account__email') count=0 for delivery in deliveries: logger_delivery = logging.getLogger('[%d]' % delivery.id) subscription = delivery.subscription customer = subscription.customer logger_delivery.info(delivery.__unicode__()) for content in delivery.content_set.all(): __extent = content.extent logger_content = logging.getLogger('[%d] [%20s] [%c] [%3s%%]' % (delivery.id, content.product.name[:20], '*' if content.customized else ' ', __extent)) for contentproduct in content.contentproduct_set.all(): logger_content.info('%d x %20s (%4d) %s' % (contentproduct.quantity, contentproduct.product.name[:20], contentproduct.product.id, contentproduct.product.main_price.supplier_product_url)) if options['browse']: webbrowser.open(contentproduct.product.main_price.supplier_product_url) count += 1 if count >= options['pages']: count = 0 try: input() except KeyboardInterrupt: print('Interrupted'); sys.exit() logger_delivery.info('') translation.deactivate()
def test_constructors(self): w = Week(2011,1) self.assertTrue(w) self.assertEqual(str(w), "2011W01") w = Week(2011,0) self.assertEqual(str(w), "2010W52") w = Week(2011,-1) self.assertEqual(str(w), "2010W51") w = Week(2011,52) self.assertEqual(str(w), "2011W52") w = Week(2011,53) self.assertEqual(str(w), "2012W01") w = Week(2011,54) self.assertEqual(str(w), "2012W02") w = Week(2009,51) self.assertEqual(str(w), "2009W51") w = Week(2009,52) self.assertEqual(str(w), "2009W52") w = Week(2009,53) self.assertEqual(str(w), "2010W01") w = Week(2009,54) self.assertEqual(str(w), "2010W02") w = Week.thisweek() self.assertTrue(w) w = Week.fromordinal(1) self.assertEqual(str(w), "0001W01") w = Week.fromordinal(2) self.assertEqual(str(w), "0001W02") w = Week.fromordinal(521723) self.assertEqual(str(w), "9999W52") w = Week.fromstring("2011W01") self.assertEqual(str(w), "2011W01") w = Week.fromstring("2011-W01") self.assertEqual(str(w), "2011W01") from datetime import date w = Week.withdate(date(2011, 5, 17)) self.assertEqual(str(w), "2011W20") self.assertEqual(Week.last_week_of_year(2009), Week(2009, 52)) self.assertEqual(Week.last_week_of_year(2010), Week(2010, 52)) self.assertEqual(Week.last_week_of_year(2011), Week(2011, 52)) self.assertEqual(Week.last_week_of_year(9999), Week(9999, 52)) self.assertRaises(ValueError, lambda: Week(0, 0)) self.assertRaises(ValueError, lambda: Week.fromstring("0000W00")) self.assertRaises(ValueError, lambda: Week.fromstring("foo")) self.assertRaises(ValueError, lambda: Week.fromordinal(-1)) self.assertRaises(ValueError, lambda: Week.fromordinal(0)) self.assertRaises(ValueError, lambda: Week.fromordinal(521724)) self.assertRaises(ValueError, lambda: Week.last_week_of_year(0)) self.assertRaises(ValueError, lambda: Week.last_week_of_year(10000))
def w_range(start_date): weeks_list = [] startWeek = Week.withdate(start_date) endWeek = Week.thisweek() int_week = startWeek while int_week < endWeek: int_week = int_week + 1 weeks_list.append(int_week) return weeks_list
def home(request, year=None, week=None): if not year or not week: # use previous week by default week = Week.thisweek() - 1 else: week = Week(int(year), int(week)) date_range = get_date_range(week) # absolute worst titles worst_titles = NewsItem.objects.filter( published__range=date_range, score__isnull=False).order_by('-score')[:5] # worst sites on average site_avg = Site.objects.filter( newsitems__published__range=date_range, newsitems__score__isnull=False).annotate( score=Avg('newsitems__score')).order_by('-score')[:5] # biggest percentage of bad titles sites = Site.objects.filter(newsitems__published__range=date_range, newsitems__score__isnull=False).annotate( bad=Sum( Case(When(newsitems__score__gt=1.0, then=1), output_field=IntegerField())), total=Count('newsitems__score'), ) percentages = [] # calculate percentages for site in sites: bad = float(site.bad if site.bad else 0) total = float(site.total if site.total else 0) percentage = int((bad / total) * 100) percentages.append((percentage, site)) # sort by percentage and take top 5 percentages = list(reversed(sorted(percentages, key=lambda x: x[0])))[:5] context = { 'worst_titles': worst_titles, 'site_avg': site_avg, 'bad_percentages': percentages, 'date_range': { 'week': week, 'start': date_range[0].date(), 'end': date_range[1].date(), } } return render(request, 'home.html', context)
def show_default(all_tasks, _): today = date.today() tomorrow = today + timedelta(days=1) this_week = Week.thisweek() next_week = this_week + 1 tasks_overdue = [] tasks_today = [] tasks_tomorrow = [] tasks_this_week = [] tasks_next_week = [] for task in all_tasks: if task["date"] < today.isoformat() and task["date"]: tasks_overdue.append(task) elif task["date"] == today.isoformat(): tasks_today.append(task) elif task["date"] == tomorrow.isoformat(): tasks_tomorrow.append(task) elif task["week"] < str(this_week) and task["week"]: tasks_overdue.append(task) elif task["week"] == str(this_week): tasks_this_week.append(task) elif task["week"] == str(next_week): tasks_next_week.append(task) is_today_sunday = today == this_week.sunday() if is_today_sunday: tasks_today.extend(tasks_this_week) print() context = "timeframe" if tasks_overdue: headline = format_headline("!!! Overdue !!!", color="red") print(headline) print(format_task_block(context, tasks_overdue)) headline = format_headline("Today", _headline_date_string(today)) print(headline) print(format_task_block(context, tasks_today, print_date=False)) headline = format_headline("Tomorrow", _headline_date_string(tomorrow)) print(headline) print(format_task_block(context, tasks_tomorrow, print_date=False)) if not is_today_sunday: headline = format_headline("This Week", "Week " + str(this_week.week)) print(headline) print(format_task_block(context, tasks_this_week)) headline = format_headline( "Next Week", "Week " + str(next_week.week) + ", " + next_week.monday().isoformat() + "+") print(headline) print(format_task_block(context, tasks_next_week))
def home(request, year=None, week=None): if not year or not week: # use previous week by default week = Week.thisweek() - 1 else: week = Week(int(year), int(week)) date_range = get_date_range(week) # absolute worst titles worst_titles = NewsItem.objects.filter(published__range=date_range, score__isnull=False).order_by('-score')[:5] # worst sites on average site_avg = Site.objects.filter( newsitems__published__range=date_range, newsitems__score__isnull=False ).annotate( score=Avg('newsitems__score') ).order_by('-score')[:5] # biggest percentage of bad titles sites = Site.objects.filter( newsitems__published__range=date_range, newsitems__score__isnull=False ).annotate( bad=Sum(Case(When(newsitems__score__gt=1.0, then=1), output_field=IntegerField())), total=Count('newsitems__score'), ) percentages = [] # calculate percentages for site in sites: bad = float(site.bad if site.bad else 0) total = float(site.total if site.total else 0) percentage = int((bad/total)*100) percentages.append((percentage, site)) # sort by percentage and take top 5 percentages = list(reversed(sorted(percentages, key=lambda x: x[0])))[:5] context = { 'worst_titles': worst_titles, 'site_avg': site_avg, 'bad_percentages': percentages, 'date_range': { 'week': week, 'start': date_range[0].date(), 'end': date_range[1].date(), } } return render(request, 'home.html', context)
def get_week_number(): """Check what the current week is and return the correct week number to display to the user. The function will just return a week number as a string to append to the next route the user will be directed to.""" # TODO refactor this to support multi-year data; program currently assumes the year is 2015. this_week = str(Week.thisweek()) week_num_str = this_week[-2:] week_num_int = int(week_num_str) # need to decrement so we see the last *full week's* data week_num = week_num_int - 1 session['week_viewing'] = week_num return str(week_num)
def get_weekend_dates_for_years(number_of_years): #Calculate the current week number for current year weeks = Week.thisweek().week #For previous years for i in range(1, number_of_years): #calculate the year year = date.today().year - i #Check how many weeks are there in the year calculated above and add it to weeks weeks = weeks + Week.last_week_of_year(year).week # define an empty list to store the week end dates week_array = [] #Now we will have to loops "weeks" number of times and get the week end date dt = date.today() for i in range(1, weeks): strd = dt - timedelta(days=dt.isoweekday() + 1 + (7 * i)) week_array.append(strd.strftime('%m-%d-%Y')) return week_array
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) cw = Week.withdate(Week.thisweek().sunday() + relativedelta(days=9)) start = self.fields['start'] start_choices = [str(w + cw.week - 1) for w in Week.weeks_of_year(cw.year)] start_date_choices = ['%s (%s %s)' % ((w + cw.week - 1).day(settings.DELIVERY_DAY_OF_WEEK).strftime('%d-%m-%Y'), _('Week'), (w + cw.week - 1).week) for w in Week.weeks_of_year(cw.year)] start.choices = zip(start_choices, start_date_choices) start.initial = cw for field in ['size', 'frequency', 'duration', 'start']: self.fields[field].widget.attrs['class'] = 'slidebar-select' for field in ['criterias', 'receive_only_once']: self.fields[field].widget.attrs['class'] = 'checkbox-select' for field in ['carrier']: self.fields[field].widget.attrs['class'] = 'radio-select'
def get_calories(): """ Runs all functions needed to query calories from authenticated user's last 100 activities, filter for activities occurring in the current week and three prior weeks, aggregate recorded calorie expenditures into per-week totals, and return this data in the format of a list containing tuples of week number (str), total calories (numeric) in reverse chronological order. If no calories were recorded in a given week, a zero will be returned in the calorie slot of the respective tuple. Example: [(24, 200), (23, 582.3), (22, 1502.8), (21, 0)]""" this_week = Week.thisweek().week included_weeks = [ str(this_week), str(this_week - 1), str(this_week - 2), str(this_week - 3) ] activities = query_activities() acts_by_week = {} cals_by_week = {} for act in activities: iter_date = act.start_date iter_week = iter_date.strftime("%W") if iter_week in included_weeks: if iter_week in acts_by_week: acts_by_week[iter_week].append(act.id) else: acts_by_week[iter_week] = [act.id] for key, value in acts_by_week.items(): for act_id in value: act_cals = act_by_num(act_id) if key in cals_by_week: cals_by_week[key] += act_cals.calories else: cals_by_week[key] = act_cals.calories return process_calories([cals_by_week, included_weeks])
def get_current_monday(timestamp=False): monday = datetime.combine(Week.thisweek().monday(), dtime.min) if timestamp: return time.mktime(monday.timetuple()) return monday
def get_last_sunday(timestamp=False): sunday = datetime.combine((Week.thisweek() - 1).sunday(), dtime.min) if timestamp: return time.mktime(sunday.timetuple()) return sunday
def filter_cards_by_last_6_weeks(self, cards_by_week_dict): weeks_range = [Week.thisweek() - x for x in range(6)] archived_cards_in_six_weeks_dict = {k: v for (k, v) in cards_by_week_dict.iteritems() if k in weeks_range} return collections.OrderedDict(sorted(archived_cards_in_six_weeks_dict.items(), key=lambda t: t[0]))
def display_current_meal_plan(): """ If no meal plan currently exists, creates one. If meal plan already exits, displays the current week's meal plan Collection attribute 'set_number' is a concat of current year, week of year, i.e. YYYYWW Collection attribute 'set_day' is a single digit indicating the number of the day of the week to which it corresponds, i.e. 1 == Monday, 2 == Tuesday, etc. """ week = datetime.date.today().strftime("%W") thisweek = Week.thisweek().week year = datetime.date.today().strftime("%Y") start_date = datetime.datetime.strptime(year + "-W" + str(thisweek) + "-1", "%Y-W%W-%w") start_day = start_date.strftime("%b %d, %Y") set_number = year + week user_id = session['user_id'] # If Collection does not already exist for the current week, create one if len( Collection.query.filter(Collection.set_number == set_number, Collection.user_id == user_id).all()) == 0: user_prefs = [] prefs = db.session.query(UserPreference.category_id).filter( UserPreference.user_id == user_id).all() for pref in prefs: user_prefs.append(pref[0]) if len(user_prefs) > 0: breakfast = Category.query.filter( Category.category_name.in_(breakfast_list)).all() lunch = Category.query.filter( Category.category_id.in_(user_prefs)).all() dinner = Category.query.filter( Category.category_id.in_(user_prefs)).all() else: breakfast = Category.query.filter( Category.category_name.in_(breakfast_list)).all() lunch = Category.query.filter( Category.category_name.in_(lunch_list)).all() dinner = Category.query.filter( Category.category_name.in_(dinner_list)).all() weekly_breakfasts = meal_plan.make_meal_set(breakfast, user_prefs) weekly_lunches = meal_plan.make_meal_set(lunch, user_prefs) weekly_dinners = meal_plan.make_meal_set(dinner, user_prefs) # Create Collection object from this week's selected breakfast recipes day_num = 0 for item in weekly_breakfasts: day_num += 1 breakfast_recipe = Collection(user_id=session['user_id'], assigned_date=start_day, set_number=set_number, set_day=day_num, meal_type="breakfast", recipe_id=item.recipe_id) db.session.add(breakfast_recipe) # Create Collection object from this week's selected lunch recipes day_num = 0 for item in weekly_lunches: day_num += 1 lunch_recipe = Collection(user_id=session['user_id'], assigned_date=start_day, set_number=set_number, set_day=day_num, meal_type="lunch", recipe_id=item.recipe_id) db.session.add(lunch_recipe) # Create Collection object from this week's selected dinner recipes day_num = 0 for item in weekly_dinners: day_num += 1 dinner_recipe = Collection(user_id=session['user_id'], assigned_date=start_day, set_number=set_number, set_day=day_num, meal_type="dinner", recipe_id=item.recipe_id) db.session.add(dinner_recipe) db.session.commit() # Pull this week's Collection objects to pass into the HTML template & # render in the meal plan page breakfasts = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "breakfast").order_by( Collection.set_day).all() lunches = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "lunch").order_by( Collection.set_day).all() dinners = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "dinner").order_by( Collection.set_day).all() # Get shopping list using Ingredients module final_ingredients = ingredients.get_shopping_list( breakfasts, lunches, dinners) return render_template("meal_plan.html", now=week, breakfasts=breakfasts, lunches=lunches, dinners=dinners, ingredients=final_ingredients, start_day=start_day) # If Collection objects already exist for this week's meal plan, query them # and return them with the HTML template else: breakfasts = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "breakfast").order_by( Collection.set_day).all() lunches = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "lunch").order_by( Collection.set_day).all() dinners = Collection.query.filter( Collection.user_id == user_id, Collection.set_number == set_number, Collection.meal_type == "dinner").order_by( Collection.set_day).all() # Generate shopping list using Ingredients module final_ingredients = ingredients.get_shopping_list( breakfasts, lunches, dinners) return render_template("meal_plan.html", now=week, breakfasts=breakfasts, lunches=lunches, dinners=dinners, ingredients=final_ingredients, start_day=start_day)
def calendar_weeks(self, leading_weeks=True): # session_dates is a list of tuples in this format - # (date, day_start_at, day_end_at, event_count) session_dates = list( db.session.query('date', 'day_start_at', 'day_end_at', 'count').from_statement( db.text(''' SELECT DATE_TRUNC('day', "start_at" AT TIME ZONE :timezone) AS date, MIN(start_at) as day_start_at, MAX(end_at) as day_end_at, COUNT(*) AS count FROM "session" WHERE "project_id" = :project_id AND "start_at" IS NOT NULL AND "end_at" IS NOT NULL GROUP BY date ORDER BY date; ''')).params(timezone=self.timezone.zone, project_id=self.id)) session_dates_dict = { date.date(): { 'day_start_at': day_start_at, 'day_end_at': day_end_at, 'count': count, } for date, day_start_at, day_end_at, count in session_dates } # FIXME: This doesn't work. This code needs to be tested in isolation # session_dates = db.session.query( # db.cast( # db.func.date_trunc('day', db.func.timezone(self.timezone.zone, Session.start_at)), # db.Date).label('date'), # db.func.count().label('count') # ).filter( # Session.project == self, # Session.scheduled # ).group_by(db.text('date')).order_by(db.text('date')) # if the project's week is within next 2 weeks, send current week as well now = utcnow().astimezone(self.timezone) current_week = Week.withdate(now) if leading_weeks and self.schedule_start_at is not None: schedule_start_week = Week.withdate(self.schedule_start_at) # session_dates is a list of tuples in this format - # (date, day_start_at, day_end_at, event_count) # as these days dont have any event, day_start/end_at are None, # and count is 0. if (schedule_start_week > current_week and (schedule_start_week - current_week) <= 2): if (schedule_start_week - current_week) == 2: # add this so that the next week's dates # are also included in the calendar. session_dates.insert( 0, (now + timedelta(days=7), None, None, 0)) session_dates.insert(0, (now, None, None, 0)) weeks = defaultdict(dict) today = now.date() for project_date, _day_start_at, _day_end_at, session_count in session_dates: weekobj = Week.withdate(project_date) if weekobj.week not in weeks: weeks[weekobj.week]['year'] = weekobj.year # Order is important, and we need dict to count easily weeks[weekobj.week]['dates'] = OrderedDict() for wdate in weekobj.days(): weeks[weekobj.week]['dates'].setdefault(wdate, 0) if project_date.date() == wdate: # If the event is over don't set upcoming for current week if wdate >= today and weekobj >= current_week and session_count > 0: weeks[weekobj.week]['upcoming'] = True weeks[weekobj.week]['dates'][wdate] += session_count if 'month' not in weeks[weekobj.week]: weeks[weekobj.week]['month'] = format_date( wdate, 'MMM', locale=get_locale()) # Extract sorted weeks as a list weeks_list = [v for k, v in sorted(weeks.items())] for week in weeks_list: # Convering to JSON messes up dictionary key order even though we used OrderedDict. # This turns the OrderedDict into a list of tuples and JSON preserves that order. week['dates'] = [{ 'isoformat': date.isoformat(), 'day': format_date(date, 'd', get_locale()), 'count': count, 'day_start_at': (session_dates_dict[date]['day_start_at'].astimezone( self.timezone).strftime('%I:%M %p') if date in session_dates_dict.keys() else None), 'day_end_at': (session_dates_dict[date]['day_end_at'].astimezone( self.timezone).strftime('%I:%M %p %Z') if date in session_dates_dict.keys() else None), } for date, count in week['dates'].items()] return { 'locale': get_locale(), 'weeks': weeks_list, 'today': now.date().isoformat(), 'days': [ format_date(day, 'EEE', locale=get_locale()) for day in Week.thisweek().days() ], }
else: with open('files/vorlage-besprechung-pauli.svg', 'r') as file: filedata = file.read() # convert location to human friendly format hlocation = re.sub(r'(\d$)', r' \1', location.title()) filedata = filedata.replace('_location', hlocation) ### BEGIN Calendar # set weeknumber filedata = filedata.replace('_weeknumber', str(datetime.now().isocalendar()[1])) # set current month #filedata = filedata.replace('_month_1', calendar.month_name[int(datetime.now().strftime('%m'))]) thisweek = Week.thisweek() filedata = filedata.replace('_monday', thisweek.monday().strftime('%d')) filedata = filedata.replace('_tuesday', thisweek.tuesday().strftime('%d')) filedata = filedata.replace('_wednesday', thisweek.wednesday().strftime('%d')) filedata = filedata.replace('_thursday', thisweek.thursday().strftime('%d')) filedata = filedata.replace('_friday', thisweek.friday().strftime('%d')) # set month at beginning of week filedata = filedata.replace( '_month_begin', calendar.month_name[int(thisweek.monday().strftime('%m'))]) # set month at end of week filedata = filedata.replace( '_month_end', calendar.month_name[int(thisweek.friday().strftime('%m'))]) ### END Calendar
def page_urls(period): ''' return the next period. e.g. next period of 20140824 is 20140825 next period of 201408 is 201409 next period of 2014-W34 is 2014-W35 ''' page = dict() # 'Day', 'Week', 'Month' link to the current day/week/month today = datetime.now().strftime('%Y%m%d') this_week = Week.thisweek().isoformat()[:4] + '-' + Week.thisweek( ).isoformat()[4:] this_month = datetime.now().strftime('%Y%m') page['day_url'] = url_for('views.leaderboard_period', period=today) page['week_url'] = url_for('views.leaderboard_period', period=this_week) page['month_url'] = url_for('views.leaderboard_period', period=this_month) if type_of_period(period) == 'day': # title today = datetime.strptime(period, '%Y%m%d') page['title'] = custom_strftime(today, '%a, %B {S} %Y') # 'prev' and 'next' links t = time.strptime(period, '%Y%m%d') today = date(t.tm_year, t.tm_mon, t.tm_mday) nextday = today + timedelta(1) prevday = today + timedelta(-1) page['next_url'] = url_for('views.leaderboard_period', period=nextday.strftime('%Y%m%d')) page['prev_url'] = url_for('views.leaderboard_period', period=prevday.strftime('%Y%m%d')) return page elif type_of_period(period) == 'week': # title page['title'] = datetime.strptime(period + '1', '%Y-W%W%w').strftime('Week %W, %Y') # 'prev' and 'next' links # begin_of_next_week = time.strptime('201435 1', '%Y%W %w') # use isoweek instead strptime('%W') since isoweek starts from week 1 # while strptime('%W') returns week number starting from week 0 thisweek = Week.fromstring(period) nextweek = thisweek + 1 # ISO 8610 format is "YYYYWww" while Moves API takes "YYYY-Www" page['next_url'] = url_for('views.leaderboard_period', period=nextweek.isoformat()[:4] + '-' + nextweek.isoformat()[4:]) # next_text = 'Week ' + str(nextweek.week) + ', ' + str(nextweek.year) prevweek = thisweek - 1 page['prev_url'] = url_for('views.leaderboard_period', period=prevweek.isoformat()[:4] + '-' + prevweek.isoformat()[4:]) # prev_text = 'Week ' + str(prevweek.week) + ', ' + str(prevweek.year) elif type_of_period(period) == 'month': #title page['title'] = datetime.strptime(period, '%Y%m').strftime('%B %Y') # 'prev' and 'next' links t = time.strptime(period, '%Y%m') thismonth = date(t.tm_year, t.tm_mon, 1) nextmonth = add_months(thismonth, 1) prevmonth = add_months(thismonth, -1) page['next_url'] = url_for('views.leaderboard_period', period=nextmonth.strftime('%Y%m')) page['prev_url'] = url_for('views.leaderboard_period', period=prevmonth.strftime('%Y%m')) return page
from mailbox import models as mm FREQUENCY_CHOICES = ( (1, _('Once a week')), (2, _('Every two weeks')), (3, _('Every three weeks')), (4, _('Once a month (4 weeks)')), (8, _('Every two months (8 weeks)')), (13, _('Once a quarter (13 weeks)')), (26, _('Every 6 months (26 weeks)')), ) FREQUENCY_DEFAULT = 2 __weeks = [] for y in range(settings.START_YEAR, Week.thisweek().year+2): __weeks += Week.weeks_of_year(y) WEEKS_CHOICES = [(str(w), '%s (%s %s)' % (w.day(settings.DELIVERY_DAY_OF_WEEK).strftime('%d-%m-%Y'), _('Week'), w.week)) for w in __weeks] class Thematic(models.Model): name = models.CharField(_('name'), max_length=100) body = models.TextField(_('body'), blank=True) size = models.ForeignKey('Size', verbose_name=_('size'), null=True, blank=True) locked_size = models.BooleanField(_('locked size'), default=False) carrier = models.ForeignKey('Carrier', verbose_name=_('carrier'), null=True, blank=True) locked_carrier = models.BooleanField(_('locked carrier'), default=False) receive_only_once = models.BooleanField(_('receive only once'), default=False) locked_receive_only_once = models.BooleanField(_('locked receive only once'), default=False) frequency = models.PositiveIntegerField(_('frequency'), max_length=2, choices=FREQUENCY_CHOICES, help_text=_('Delivery made sure Tuesday'), null=True, blank=True) locked_frequency = models.BooleanField(_('locked frequency'), default=False) start_duration = models.CharField(_('start duration'), max_length=7, choices=WEEKS_CHOICES, help_text=_('Here is the beginnig week of the duration.'),
def page_urls(period): ''' return the next period. e.g. next period of 20140824 is 20140825 next period of 201408 is 201409 next period of 2014-W34 is 2014-W35 ''' page = dict() # 'Day', 'Week', 'Month' link to the current day/week/month today = datetime.now().strftime('%Y%m%d') this_week = Week.thisweek().isoformat()[:4] + '-' + Week.thisweek().isoformat()[4:] this_month = datetime.now().strftime('%Y%m') page['day_url'] = url_for('views.leaderboard_period', period=today) page['week_url'] = url_for('views.leaderboard_period', period=this_week) page['month_url'] = url_for('views.leaderboard_period', period=this_month) if type_of_period(period) == 'day': # title today = datetime.strptime(period, '%Y%m%d') page['title'] = custom_strftime(today, '%a, %B {S} %Y') # 'prev' and 'next' links t = time.strptime(period, '%Y%m%d') today = date(t.tm_year, t.tm_mon, t.tm_mday) nextday = today + timedelta(1) prevday = today + timedelta(-1) page['next_url'] = url_for('views.leaderboard_period', period=nextday.strftime('%Y%m%d')) page['prev_url'] = url_for('views.leaderboard_period', period=prevday.strftime('%Y%m%d')) return page elif type_of_period(period) == 'week': # title page['title'] = datetime.strptime(period + '1', '%Y-W%W%w').strftime('Week %W, %Y') # 'prev' and 'next' links # begin_of_next_week = time.strptime('201435 1', '%Y%W %w') # use isoweek instead strptime('%W') since isoweek starts from week 1 # while strptime('%W') returns week number starting from week 0 thisweek = Week.fromstring(period) nextweek = thisweek + 1 # ISO 8610 format is "YYYYWww" while Moves API takes "YYYY-Www" page['next_url'] = url_for('views.leaderboard_period', period=nextweek.isoformat()[:4] + '-' + nextweek.isoformat()[4:]) # next_text = 'Week ' + str(nextweek.week) + ', ' + str(nextweek.year) prevweek = thisweek -1 page['prev_url'] = url_for('views.leaderboard_period', period=prevweek.isoformat()[:4] + '-' + prevweek.isoformat()[4:]) # prev_text = 'Week ' + str(prevweek.week) + ', ' + str(prevweek.year) elif type_of_period(period) == 'month': #title page['title'] = datetime.strptime(period, '%Y%m').strftime('%B %Y') # 'prev' and 'next' links t = time.strptime(period,'%Y%m') thismonth = date(t.tm_year, t.tm_mon, 1) nextmonth = add_months(thismonth, 1) prevmonth = add_months(thismonth, -1) page['next_url'] = url_for('views.leaderboard_period', period=nextmonth.strftime('%Y%m')) page['prev_url'] = url_for('views.leaderboard_period', period=prevmonth.strftime('%Y%m')) return page
def is_past_week(week): if not week: return False return Week.fromstring(week) < Week.thisweek()
def test_constructors(self): w = Week(2011, 1) self.assertTrue(w) self.assertEqual(str(w), "2011W01") w = Week(2011, 0) self.assertEqual(str(w), "2010W52") w = Week(2011, -1) self.assertEqual(str(w), "2010W51") w = Week(2011, 52) self.assertEqual(str(w), "2011W52") w = Week(2011, 53) self.assertEqual(str(w), "2012W01") w = Week(2011, 54) self.assertEqual(str(w), "2012W02") w = Week(2009, 51) self.assertEqual(str(w), "2009W51") w = Week(2009, 52) self.assertEqual(str(w), "2009W52") w = Week(2009, 53) self.assertEqual(str(w), "2009W53") w = Week(2009, 54) self.assertEqual(str(w), "2010W01") w = Week.thisweek() self.assertTrue(w) w = Week.fromordinal(1) self.assertEqual(str(w), "0001W01") w = Week.fromordinal(2) self.assertEqual(str(w), "0001W02") w = Week.fromordinal(521723) self.assertEqual(str(w), "9999W52") w = Week.fromstring("2011W01") self.assertEqual(str(w), "2011W01") w = Week.fromstring("2011-W01") self.assertEqual(str(w), "2011W01") from datetime import date w = Week.withdate(date(2011, 5, 17)) self.assertEqual(str(w), "2011W20") weeks = list(Week.weeks_of_year(2009)) self.assertEqual(len(weeks), 53) self.assertEqual(weeks[0], Week(2009, 1)) self.assertEqual(weeks[-1], Week(2009, 53)) weeks = list(Week.weeks_of_year(2011)) self.assertEqual(len(weeks), 52) self.assertEqual(weeks[0], Week(2011, 1)) self.assertEqual(weeks[-1], Week(2011, 52)) self.assertEqual(Week.last_week_of_year(2009), Week(2009, 53)) self.assertEqual(Week.last_week_of_year(2010), Week(2010, 52)) self.assertEqual(Week.last_week_of_year(2011), Week(2011, 52)) self.assertEqual(Week.last_week_of_year(9999), Week(9999, 52)) self.assertRaises(ValueError, lambda: Week(0, 0)) self.assertRaises(ValueError, lambda: Week.fromstring("0000W00")) self.assertRaises(ValueError, lambda: Week.fromstring("foo")) self.assertRaises(ValueError, lambda: Week.fromordinal(-1)) self.assertRaises(ValueError, lambda: Week.fromordinal(0)) self.assertRaises(ValueError, lambda: Week.fromordinal(521724)) self.assertRaises(ValueError, lambda: Week.last_week_of_year(0)) self.assertRaises(ValueError, lambda: Week.last_week_of_year(10000))
def handle_noargs(self, **options): translation.activate('fr') logging.debug('Command in progress') self.print_interactive_usage() if options['test']: logging.info('[TEST MODE enabled]') logging.info('') week_limit = Week.withdate(Week.thisweek().day(settings.VALIDATING_DAY_OF_WEEK) + relativedelta(days=settings.DELAY_BETWEEN_DEFINITON_N_DELIVERY)) deliveries = models.Delivery.objects.filter(date__lte=week_limit, status='p', subscription__enabled=True) logging.info('Number of deliveries to fullfill: %d' % deliveries.count()) for delivery in deliveries: logger_delivery = logging.getLogger('[delivery %d]' % delivery.id) logger_delivery.info('') logger_delivery.info('Process the delivery: %s' % delivery.__unicode__()) logger_delivery.info('') subscription = delivery.subscription subscription_weight = subscription.size.weight - subscription.size.weight*settings.PACKAGING_WEIGHT_RATE/100 subscription_price = subscription.price().price carrier = subscription.carrier weight_level = carrier.carrierlevel_set.filter(weight__gte=subscription.size.weight) if weight_level: logger_delivery.info('weight level:\t\t%s kg (%s €)' % (weight_level[0].weight, weight_level[0].price)) subscription_price -= weight_level[0].price logger_delivery.info('carrier:\t\t%s' % carrier.name) logger_delivery.info('subscription weight:\t%s kg' % subscription_weight) logger_delivery.info('subscription price:\t%s € (%s €)' % (subscription_price, subscription.price().price)) logger_delivery.info('') for extent in subscription.extent_set.all(): __extent = extent.extent logger_extent = logging.getLogger('[delivery %d] [%s] [%s%%]' % (delivery.id, extent.product.name, __extent)) logger_extent.debug('meta-product: %s, extent: %s' % (extent.product.name, __extent)) if extent.customized: logger_extent = logging.getLogger('[delivery %d] [%s] [%s%%] [custom]' % (delivery.id, extent.product.name, __extent)) logger_extent.info('start fullfilling the delivery cart with a custom content') logger_extent.info('create custom content object') content = delivery.content_set.create(product=extent.product, extent=extent.extent, customized=extent.customized) if not options['test'] else None extent_content = extent.extentcontent_set.get() for ecp in extent_content.extentcontentproduct_set.all(): logger_extent.info('+ %d x %30s\t\t(%d,\t%s€,\t%sg)' % (ecp.quantity, ecp.product.name[:30], ecp.product.id, ecp.product.price().__unicode__(), ecp.product.weight)) if not options['test']: content.contentproduct_set.create(product=ecp.product, quantity=ecp.quantity) continue def get_product_products(product): __products = [] for child in product.products_children.all(): __products += get_product_products(child) __products += product.product_product.filter(status='p').all() return __products products = get_product_products(extent.product) nbr_items = len(products) prices = [p.main_price.get_after_tax_price_with_fee() if carrier.apply_suppliers_fee else p.main_price.get_after_tax_price() for p in products] weights = [int(p.weight or settings.DEFAULT_WEIGHT) for p in products] criterias = [] if subscription.criterias.all(): for p in products: __filter = p.criterias for c in subscription.criterias.filter(enabled=True).all(): __filter = __filter.filter(id=c.id) criterias.append(len(__filter.all())) else: criterias = [0] * nbr_items total_price = round(subscription_price*__extent/100, 2) total_weight = round(subscription_weight*__extent/100*1000, 2) total_criteria = round(sum(criterias), 2) creator.create("Fitness", base.Fitness, weights=(-1.0,-1.0,-1.0,-1.0,)) creator.create("Individual", list, fitness=creator.Fitness) toolbox = base.Toolbox() if options['zero']: toolbox.register("quantity_item", lambda: options['min_quantity']) else: toolbox.register("quantity_item", random.randint, options['min_quantity'], options['max_quantity']) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.quantity_item, nbr_items) toolbox.register("population", tools.initRepeat, list, toolbox.individual) def eval(individual): eval_total_price = 0.0 eval_total_weight = 0.0 eval_total_criteria = 0.0 for i in range(nbr_items): eval_total_price += individual[i] * prices[i] eval_total_weight += individual[i] * weights[i] eval_total_criteria += individual[i] * criterias[i] return \ abs(total_price - eval_total_price),\ abs(total_criteria - eval_total_criteria),\ plt.mlab.entropy(individual, 1),\ abs(total_weight - eval_total_weight),\ # def cx(ind1, ind2): return tools.crossover.cxOnePoint(ind1, ind2) # def mut(individual): return tools.mutation.mutUniformInt(individual, options['min_quantity'], options['max_quantity'], 0.01) def cx(ind1, ind2): site = random.randint(0, min(len(ind1), len(ind2))) ind1[:site], ind2[:site] = ind2[:site], ind1[:site] return ind1, ind2 def mut(individual): pos = random.randint(0, nbr_items-1) individual[pos] = random.randint(options['min_quantity'], options['max_quantity']) return individual, pareto = tools.selNSGA2 if options['pareto'] else tools.selSPEA2 algo = algorithms.eaMuPlusLambda if options['algo'] else algorithms.eaMuCommaLambda toolbox.register("evaluate", eval) toolbox.register("mate", cx) toolbox.register("mutate", mut) toolbox.register("select", pareto) pop = toolbox.population(n=options['pop_size']) hof = tools.ParetoFront() new_pop, logbook = algo(pop, toolbox, options['pop_size'], options['lambda_algo'], options['cxpb'], options['mutpb'], options['max_gen'], halloffame=hof, verbose=0) logger_extent.debug("len(hof): %d" % len(hof)) logger_extent.debug("len(products): %s" % len(products)) logger_extent.debug("prices (€): %s" % prices) logger_extent.debug("weights (g): %s" % weights) logger_extent.debug("criterias: %s" % criterias) logger_extent.debug("total_price: %f €" % total_price) logger_extent.debug("total_weight: %f g" % total_weight) logger_extent.debug("total_criteria: %f" % total_criteria) margin_hof = [] for m in np.arange(options['margin'], 1, options['margin']): logger_extent.debug("trial margin hof with %.2f", m) trial_margin_hof = [] for x in hof: if x.fitness.values[0] <= (total_price*m): trial_margin_hof.append(x) if len(trial_margin_hof) > 0: margin_hof = trial_margin_hof break assert len(margin_hof) > 0 sorted = np.sort(np.array([(i,) + x.fitness.values for i, x in enumerate(margin_hof)], dtype=[('i', int), ('price', float), ('criterias', float), ('diversity', float), ('weight', float)]), order=['criterias', 'diversity', 'weight', 'price']) logger_extent.info('there are %d solutions' % len(sorted)) for i, fitnesses in enumerate(sorted): logger_solution = logging.getLogger('[delivery %d] [%s] [%s%%] [%d]' % (delivery.id, extent.product.name, __extent, i)) sol = hof[ fitnesses[0] ] logger_solution.info('') logger_solution.debug('sol: %s' % sol) logger_solution.info('sol.fitness: %s' % sol.fitness) assert len(sol) == nbr_items for i in range(nbr_items): if sol[i]: logger_solution.info('+ %d x %30s\t(%d,\t%s€,\t%sg)' % (sol[i], products[i].name[:30], products[i].id, prices[i], weights[i])) idx = 0 higherbound = len(sorted)-1 while True: try: idx = int(input('[Select one solution between 0 and %d]$ ' % higherbound)) except TypeError: logger_extent.error('Bad type value passed (a value between 0 and %d)' % higherbound) except ValueError: logger_extent.error('Bad value passed (a value between 0 and %d)' % higherbound) else: if 0 <= idx < higherbound+1: break logger_extent.info('Start fullfilling the delivery cart content with the solution %d' % idx) sol = hof[ sorted[idx][0] ] logger_extent.info('Create content object') content = delivery.content_set.create(product=extent.product, extent=extent.extent, customized=extent.customized) if not options['test'] else None for i in range(nbr_items): if sol[i]: logger_extent.info('+ %d x %30s\t(%d,\t%s€,\t%sg)' % (sol[i], products[i].name[:30], products[i].id, prices[i], weights[i])) if not options['test']: content.contentproduct_set.create(product=products[i], quantity=sol[i]) if not options['test']: logger_extent.info("change delivery status") delivery.status = 'P' delivery.save() logger_extent.info("send a message to the delivery customer") customer = subscription.customer message = mm.Message.objects.create_message(participants=[customer], subject=_('Delivery %(date)s is in progress') % {'date': delivery.get_date_display()}, body=_( """Hi %(name)s, we are pleased to announce your delivery %(date)s content from the subscription %(subscription_id)d has been defined and will be prepared as soon as possible for sending. Your cart will be send to you in 10 days. Best regards, Végéclic. """ ) % {'name': customer.main_address.__unicode__() if customer.main_address else '', 'date': delivery.get_date_display(), 'subscription_id': subscription.id}) translation.deactivate()
def handle_noargs(self, **options): translation.activate('fr') logging.debug('Command in progress') pop_size = 50 max_gen = 50 lambda_algo = 100 cxpb = .7 mutpb = .2 min_quantity = 0 max_quantity = 2 margin = .1 zero = True debug = False if debug: logging.debug('DEBUG MODE') week_limit = Week.withdate(Week.thisweek().day(setting.VALIDATING_DAY_OF_WEEK) + relativedelta(days=settings.DELAY_BETWEEN_DEFINITON_N_DELIVERY)) deliveries = models.Delivery.objects.filter(date__lte=week_limit, status='p', subscription__enabled=True) for delivery in deliveries: logging.debug(delivery.__unicode__()) subscription = delivery.subscription subscription_weight = subscription.size.weight - subscription.size.weight*settings.PACKAGING_WEIGHT_RATE/100 subscription_price = subscription.price().price carrier = subscription.carrier weight_level = carrier.carrierlevel_set.filter(weight__gte=subscription.size.weight) if weight_level: logging.debug('weight_level: %s kg (%s €)' % (weight_level[0].weight, weight_level[0].price)) subscription_price -= weight_level[0].price logging.debug('carrier: %s' % carrier.name) logging.debug('subscription_weight: %s kg' % subscription_weight) logging.debug('subscription_price: %s € (%s €)' % (subscription_price, subscription.price().price)) for extent in subscription.extent_set.all(): __extent = extent.extent logging.debug('meta-product: %s, extent: %s' % (extent.product.name, __extent)) if extent.customized: logging.debug("start fullfilling the delivery cart with a custom content") logging.debug("create custom content object") content = delivery.content_set.create(product=extent.product, extent=extent.extent, customized=extent.customized) if not debug else None extent_content = extent.extentcontent_set.get() for ecp in extent_content.extentcontentproduct_set.all(): logging.debug("add product %s (%d) with a quantity %d (price: %s, weight: %s)" % (ecp.product.name, ecp.product.id, ecp.quantity, ecp.product.price().__unicode__(), ecp.product.weight)) if not debug: content.contentproduct_set.create(product=ecp.product, quantity=ecp.quantity) continue def get_product_products(product): __products = [] for child in product.products_children.all(): __products += get_product_products(child) __products += product.product_product.filter(status='p').all() return __products products = get_product_products(extent.product) nbr_items = len(products) prices = [p.main_price.get_after_tax_price_with_fee() if carrier.apply_suppliers_fee else p.main_price.get_after_tax_price() for p in products] weights = [int(p.weight) for p in products] criterias = [] if subscription.criterias.all(): for p in products: __filter = p.criterias for c in subscription.criterias.filter(enabled=True).all(): __filter = __filter.filter(id=c.id) criterias.append(len(__filter.all())) else: criterias = [0] * nbr_items total_price = round(subscription_price*__extent/100, 2) total_weight = round(subscription_weight*__extent/100*1000, 2) total_criteria = round(sum(criterias), 2) from deap import algorithms, base, creator, tools pareto = tools.selNSGA2 # pareto = tools.selSPEA2 algo = algorithms.eaMuPlusLambda # algo = algorithms.eaMuCommaLambda creator.create("Fitness", base.Fitness, weights=(-1.0,-1.0,-1.0,-1.0,)) creator.create("Individual", list, fitness=creator.Fitness) toolbox = base.Toolbox() if zero: toolbox.register("quantity_item", lambda: min_quantity) else: toolbox.register("quantity_item", random.randint, min_quantity, max_quantity) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.quantity_item, nbr_items) toolbox.register("population", tools.initRepeat, list, toolbox.individual) def eval(individual): eval_total_price = 0.0 eval_total_weight = 0.0 eval_total_criteria = 0.0 for i in range(nbr_items): eval_total_price += individual[i] * prices[i] eval_total_weight += individual[i] * weights[i] eval_total_criteria += individual[i] * criterias[i] return \ abs(total_price - eval_total_price),\ abs(total_criteria - eval_total_criteria),\ plt.mlab.entropy(individual, 1),\ abs(total_weight - eval_total_weight),\ # def cx(ind1, ind2): return tools.crossover.cxOnePoint(ind1, ind2) # def mut(individual): return tools.mutation.mutUniformInt(individual, min_quantity, max_quantity, 0.01) def cx(ind1, ind2): site = random.randint(0, min(len(ind1), len(ind2))) ind1[:site], ind2[:site] = ind2[:site], ind1[:site] return ind1, ind2 def mut(individual): pos = random.randint(0, nbr_items-1) individual[pos] = random.randint(min_quantity, max_quantity) return individual, toolbox.register("evaluate", eval) toolbox.register("mate", cx) toolbox.register("mutate", mut) toolbox.register("select", pareto) pop = toolbox.population(n=pop_size) hof = tools.ParetoFront() new_pop, logbook = algo(pop, toolbox, pop_size, lambda_algo, cxpb, mutpb, max_gen, halloffame=hof, verbose=0) logging.debug("len(hof): %d" % len(hof)) logging.debug("len(products): %s" % len(products)) logging.debug("prices (€): %s" % prices) logging.debug("weights (g): %s" % weights) logging.debug("criterias: %s" % criterias) logging.debug("total_price: %f €" % total_price) logging.debug("total_weight: %f g" % total_weight) logging.debug("total_criteria: %f" % total_criteria) margin_hof = [] for m in np.arange(margin, 1, margin): logging.debug("trial margin hof with %.2f", m) trial_margin_hof = [] for x in hof: if x.fitness.values[0] <= (total_price*m): trial_margin_hof.append(x) if len(trial_margin_hof) > 0: margin_hof = trial_margin_hof break assert len(margin_hof) > 0 sorted = np.sort(np.array([(i,) + x.fitness.values for i, x in enumerate(margin_hof)], dtype=[('i', int), ('price', float), ('criterias', float), ('diversity', float), ('weight', float)]), order=['criterias', 'diversity', 'weight', 'price']) sol = hof[ sorted[0][0] ] logging.debug("sol: %s" % sol) logging.debug("sol.fitness: %s" % sol.fitness) assert len(sol) == nbr_items logging.debug("start fullfilling the delivery cart content") logging.debug("create content object") content = delivery.content_set.create(product=extent.product, extent=extent.extent, customized=extent.customized) if not debug else None for i in range(nbr_items): if sol[i]: logging.debug("add product %s (%d - %d) with a quantity %d (price: %f, weight: %f)" % (products[i].name, i, products[i].id, sol[i], prices[i], weights[i])) if not debug: content.contentproduct_set.create(product=products[i], quantity=sol[i]) if not debug: logging.debug("change delivery status") delivery.status = 'P' delivery.save() logging.debug("send a message to the delivery customer") customer = subscription.customer message = mm.Message.objects.create_message(participants=[customer], subject=_('Delivery %(date)s is in progress') % {'date': delivery.get_date_display()}, body=_( """Hi %(name)s, we are pleased to announce your delivery %(date)s content from the subscription %(subscription_id)d has been defined and will be prepared as soon as possible for sending. Your cart will be send to you in 10 days. Best regards, Végéclic. """ ) % {'name': customer.main_address.__unicode__() if customer.main_address else '', 'date': delivery.get_date_display(), 'subscription_id': subscription.id}) translation.deactivate()