13/15. Product: CodeCademy vs. PyCharm


#1

Hi everyone,

the code below works in PyCharm flawlessly and returns 100. However, CodeCademy throws an error, like so: "Your function fails on product([4, 5, 5]). It returns 20 when it should return 100." Do you have any idea why that is the case? Thanks a lot!

def product(li):
    total = 0
    i = li[0]
    total = total + i
    for num in li[1:]:
        if num != 0:
            total = total * num
            return(total)
        else:
            return 0
            break

#2

Perhaps a simpler algorithm can be fashioned:

def product(n):
    p = 1
    for x in n:
        p *= x
    return p

If one of the elements happens to be a zero, the return value will be zero.


#3

It does not return 100 for that input, you must not have tested it correctly.


#4

Here is a slightly simpler solution which worked for me. Simply define a variable (init) which saves the first index of the list. Then delete it. Loop through the (slightly shortened) list which multiplies on top of init for the rest of the loop and returns it.

That said maybe using "[1:]" in the loop is another way of deleting the first index so it doesn't repeat and give out a bigger number.


#5

Are you referring to the OP? My solution is tested and does work as expected.


#6

Yeah, edited it


#9

Hello,
I used this code and it worked fine, of course, but
when I look at this it seems that, if p = 1 and p *= x
(p equals itself times x), then that would mean 1 * p,
which would just return a copy of whatever numbers
are in the list.
Can you please explain how this works?

Thank you


#10

Given a list, say [2, 5, 7, 9], then the running steps of the program are as follows:

    p = 1
    x = 2
    p *= 2     # 2
    x = 5
    p *= 5     # 10
    x = 7
    p *= 7     # 70
    x = 9
    p *= 9     # 630

The return value is 630.


#11

Right!
So, would that not be the case if p==1?

Thanks again!


#12

Yes, we start with p = 1 so the first multiplication does not alter the outcome. This is an alternative to,

    p = n[0]
    for x in range(1, len(n)):
        p *= n[x]
    return p

#13

Very good.
Thanks so much


#14

Can you explain why deleting the initialized value works? Why can't we just use init = x[0]?


#15

Not sure the member is close at hand, so please permit me to take a shot at this.

In the sample code, the first element is copied to a variable (see note below) then deleted to shorten the list. This permits iterating the remaining list where i is the value in the list element.

Note: This has ramifications that will require testing. In JavaScript when a variable is assigned an array reference, it is a reference to (a pointer), not a copy of the referred element. Not sure how this applies to Python so will need to do some reading and experimenting and return with my findings.

I would be more inclined to use list.pop:

def product(lst):
    x = lst.pop()
    for v in lst:
        x *= v
    return x
product([2,3,5,7])     # 210

In the above, x starts out as 7 and the last element is removed from the list.

We're still making a lot of assumptions, especially that the list consists only of numbers. A proper program would validate the inputs.

Edit. Some findings...

def product(lst):
    x = lst.pop()
    for v in lst:
        x *= v
    return x
    
nums = [2,3,5,7]
print(product(nums))     # 210
print(nums)              # [2, 3, 5]

Note that the original list is now altered. This program is destructive. All fine and good when a literal is passed in, but not so great when it is a global object.

It brings us back to the earlier method that starts out with an initialized variable with unity as its value. Multiply or divide by 1 and nothing changes.

def prodlst(lst):
    p = 1
    for x in lst:
        p *= x
    return p
nums = [2,3,5,7]
print(prodlst(nums))     # 210
print(nums)              # [2, 3, 5, 7]

Original list preserved.

Don't know for sure how long this will be preserved, but here is a sandbox version of the above,

https://repl.it/BkD4


#16

I had the same code as you but it isn't working. The only difference is that I used different variable names. When I tried your code, it worked. My code is the same, why isn't it working then?

def product(i):
    la = 1
    for moo in i:
        la *= moo
    return moo

#17

Try returning la instead. That is the variable that is accumulating.


#20