Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Functional Python The Lambda Lambada Reduce

akak
akak
29,445 Points

Functional Python: Create a variable named total.

Ok, I'm officially stuck. "Create a variable named total. Use map() to find the per-product totals for each item in prices, then use reduce (and add) to find the total value."

How do I connect those three to get a total? I know how to get totals from map, but can't figure out how to connect the output it gives with add and reduce.

Thanks in advance.

prices.py
from operator import add
from functools import reduce

prices = [
    (6.99, 5),
    (2.94, 15),
    (156.99, 2),
    (99.99, 4),
    (1.82, 102)
]

def product_sales(tup):
  return tup[0] * tup[1]

total = reduce(add( #what? 

2 Answers

Ryan Ruscett
Ryan Ruscett
23,307 Points

Hey,

Well you came to the right place. Let's break it down.

Working code. Find the Digits. Those are discussed below.

from operator import add
from functools import reduce

prices = [
    (6.99, 5),
    (2.94, 15),
    (156.99, 2),
    (99.99, 4),
    (1.82, 102)
]


def product_sales(tup):   -----------------------------digit 1
   return tup[0] * tup[1]    -----------------------------digit 2


total = reduce(add, map(product_sales, prices)) --------------digit 3

Ok, so 1 and 2, you did right. You had that taken care of. Task 2,3 are just imports. So I don't think we need to cover that. BUT, let's talk about 3.

Digit 3

reducte(func, iterable) 

The iterable in reduce can be any iterable. Think of reduce as a waiting function.

If I use it in simplistic form. It takes the first element in the iterable. Passes it to the function. EXCEPT, unlike map. reduce waits for a second character. So it waits until the iterable returns two elements. It then takes action using both elements.

All reduce cares about is that it gets two elements. The iterable supplies the elements, but reduce doesn't care about how the iterable does that. So we can use map in addition with reduce.

map(func, iterable) 

Map lot like reduce, but returns the value of each item after it's ran through the function, Unlike reduce which waits for 2 items before running the function

I am going to wait for two items before doing the function
reducte(func, iterable) 


I am going to do the function on each item in the iterable
map(func, iterable)

Map, takes an iterable and takes one element of an iterable and runs the function against it one at a time. Then returns it. So for all intensive purposes, it's returning 1 item at a time from the iterable. That is all reduce is looking for. One item at a time until it hits 2, from an iterable.

reduce(func , map(func, iterable)) 

Now map is giving back to reduce a single item at a time. That is all reduce cares about. Now, reduce will wait. It will wait for the second item to come back. Once it gets two items. It will do the function using both.

If you look up add(). It actually takes two arguments.

add(a, b) 

This is almost to perfect. reduce will wait until it has 2 elements given to it from map or the iterable. Same thing in this context.

reduce(add, map(product_sales, prices)) 

Let's read this backwards. Start with prices. I have a list of tuples. Ok cool. A list is definitely an iterable. So I need to take the list of tuples, and pass it to a function, that will get me the first value times the second value. Then return the new item. Ok sweet, we have a function that does that called product_sales. So we call product_sales on every item in the price list using map. Map will take the list, take an element in the list, in this case a tuple. Pass that tuple to product_sales. Which multiplies to the values and returns the new value.

Now, reduce is waiting. When map finishes it's first value, it kicks it back to reduce. When map finishes it's second value. It kicks it back to reduce. Now reduce has two values. And puts them in the add function. Since add takes two values. This works perfectly. This trend continues until there are no more items left in the iterable.

In the simpilist form -

Map takes price and uses product_sales function to multiply price and quantity. Once map does this, it has an iterable of new values. These new values are supplied to reduce as the iterable, and add is the function to run on the iterables. Using reduce allows you to obtain 2 values before running the function, since add takes 2 values, we need to do that.

I hope this makes sense. Please let me know if it doesn't. I would be happy to tease apart different details of this if you still don't understand. Just let me know and I will try my best.

Thanks!

akak
akak
29,445 Points

Thank you for a great explanation. I think your post should be sticky of some sort for everyone to see it when they stumble on this challenge :) (right now it's a given since I think we're first to talk about it :P)

I was very close with what I've tried but I couldn't fit "add()" anywhere. I thought I need to supply arguments to that function manually, and now I know it should be used by reduce to do it's thing. Everything fits perfectly. Thank you!

Ryan Ruscett
Ryan Ruscett
23,307 Points

OH yeah for sure, It's a bit tricky because you don't use () when you call add. It's a reference to add or it's just python mumbo jumbo.

Thanks!

Chris Grazioli
Chris Grazioli
31,225 Points

It would be nice if "add" or even importing "add" was mentioned just once in this reused video! Anyone else having any idea what lambda lambda is supposed to be. Did I miss half dozen videos somewhere or is TreeHouse reusing content from another course out of sequence here.