Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This sounds like a fine job for <em>functional approach</em>. At the end there is a full working example, but I just want to emphasize the elegance and simplicity of the core function, written in FP style:</p> <pre><code>def find_best_two_months(orders): first = lambda x: x[0] second = lambda x: x[1] orders_by_year_and_month = [ ("%04d-%02d" % (date.year, date.month), amount) for date, amount in orders] sorted_orders = sorted(orders_by_year_and_month, key=first) totals_by_month = [ (ym, sum(map(second, groupped_orders))) for ym, groupped_orders in groupby(sorted_orders, key=first)] totals_two_months = [ ( "%s - %s" % (m1[0], m2[0]), m1[1]+m2[1] ) for m1, m2 in zip(totals_by_month, totals_by_month[1:]) ] return max(totals_two_months, key=second) </code></pre> <hr> <p>Here is a full working example with comments:</p> <pre><code>#!/usr/bin/python from random import randint from datetime import date, timedelta from itertools import groupby """ finding best two months the functional way """ def find_best_two_months(orders): """ Expect a list of tuples of form (date_of_order, amount): [ (date1, amount1), (date2, amount2), ...] """ " helper functions for extracting first or second from tuple " first = lambda x: x[0] second = lambda x: x[1] " converts [(date, amount)] -&gt; [(YYYY-MM, amount)] " orders_by_year_and_month = [ ("%04d-%02d" % (date.year, date.month), amount) for date, amount in orders] " Sorts by YYYY-MM. This step can be omitted if orders were already sorted by date" sorted_orders = sorted(orders_by_year_and_month, key=first) " Compresses orders from the same month, so ve get [(YYYY-MM), total_amount_of_orders]" totals_by_month = [ (ym, sum(map(lambda x:x[1], groupped_orders))) for ym, groupped_orders in groupby(sorted_orders, key=first)] " Zips orders to two month periods" totals_two_months = [ ("%s - %s" % (m1[0], m2[0]), m1[1]+m2[1]) for m1, m2 in zip(totals_by_month, totals_by_month[1:]) ] " Returns two-month period with maximum total amount. If there were many periods with max amount, only the first is returned " return max(totals_two_months, key=second) """ this code is for generating random list of orders and is not a part of the solution """ MIN_AMOUNT=70 MAX_AMOUNT=500 MAX_DAY_SPREAD=5 def gen_order(last_date): """ returns (order_date, amount) """ days = timedelta() return ( last_date+timedelta(days=randint(0, MAX_DAY_SPREAD)), # new date randint(MIN_AMOUNT, MAX_AMOUNT)) # amount def gen_orders(total, start_date): orders = [] last_date = start_date for i in range(total): order = gen_order(last_date) orders.append(order) last_date = order[0] return orders if __name__ == "__main__": orders = gen_orders(300, date(2010,1,1)) print find_best_two_months(orders) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload