List+Functions


#1

Can anyone give me an explanation why I get error like this. Which part I was wrong?

Oops, try again. fizz_count([6, 'fizz', 9, 6]) returned 0 instead of the correct answer: 1

This is my code:

# Write your function below!
def fizz_count(x):
    count = 0
    for item in x:
            if item == 'fizz':
                count = count + 1
            return count

#2

The return statement should not be inside the for loop as it should be the final answer that we should be returning so it should be separate block of code.

It introduces a very important concept of python called "Indentation"(spaces) which used to separate blocks of code.

Check the example of the exercise once again!
Take look at final return and also how code blocks are structured!


#3

I just follow the sample code and i see it under the loop, same as what i did.

Sample code:

def count_small(numbers):
    total = 0
    for n in numbers:
        if n < 10:
            total = total + 1
    return total

lost = [4, 8, 15, 16, 23, 42]
small = count_small(lost)
print small

#4

Yeah It means that the return statement is not part/inside the for loop and they will run sequentially(one after another), but if we put it inside the loop, It is child block of for -loop and will run if loop runs!


#5

I see. I removed some spaces/indention and align it in for loop, now it works.
I still don't understand that much about indention spaces.

Thanks!


#6

Look,lets analyse your last code,
In this code..

> def fizz_count(x):
>     count = 0
>     for item in x:
>             if item == 'fizz':
>                 count = count + 1
>             return count

We defined a functionfizz_count() that counts "fizz" string from our list x,
lets look at first iteration of loop,
suppose it loops over x and compares the item with "fizz", if it is fizz then it will add one to count, now as return is just next line so it will run just after

count = count + 1, after this return statement will executed.

This return statement will return some value and as we know that when a function sees return statement it returns value attached to it and halts the function,
so we can see that our function is not able to produce correct count of "fizz",
It indicates that our function have structural problem,
All we have to do is, loop over list and count all numbers of fizz then finally return it, so You can see it simply means that final return should not be part of for loop but indented (structured) as same level as for loop.
Do reply if you get it or not!


#7

So there is no return statement inside the loop, every return should be in another block?

Pardon me, I'm a bit slow in understanding, i don't get things easily by reading. I preferred a demo so I can fully understand. I'm not that good in analyzing. :slight_smile:


#8

Yup! here (EDIT: but It can be anywhere as discussed in posts below) it should be outside of for loop as we can see that we want to catch all the fizz counts then return the total number of count, right?
so suppose if we put return inside the for loop, it will get executed even we don't able to catch the total count, it simply return the count which we don't want.

here the nature of return also plays a crucial role, return is final exit door for function, function sees it and halts its execution after reaching it.

Look at this example..

def myFunction():
    if test:
        #mycode

In the first example #mycode is inside the if-block, so it will run when if statement's test turns out to be True.

def myFunction():
    if test:
        pass
    #mycode

In second example #mycode is completely independent of if block and runs sequentially (one after another).

This shows a very important thing called "indentation"
same indented blocks are executes sequentially but if a block is inside another block, depends on that block(parent block).


#9

Oh thanks! That helps a lot. You enlighten me :smile:


#10

We want to pause for a moment before saying 'yes' to this being a generalization.

In truth, for this instance at least and most common, the return statement is in the same block as the for statement. The block defined by the function header. In Python, a block starts with a colon, immediately following the header line.

Think of an if statement and a for statement as objects, and like all objects, they have self context. The segment of code in their block is in that context, so iterator variables have a sort of scope. Not function scope, so much, just a more localized scope that stays within the context.

It is these localized contexts that indentation signifies to the interpreter.

A general term that is common in referring to the environment is namespace and it refers to the reserved space in which the interpreter, all modules and classes, functions and variables reside. To keep conflicts from arising, functions are given their own scope; that is, their own environment that can look out, but can't be seen from outside.

for, if, while, etc. have a localized form of that environment where transient variables such as the iterator in for are unseen, even in their parent scope unless we let them be seen. Again, it is indentation that let's us demarcate these localized scopes (not really scope, but analogous).

The reason they are localized is because they do not have a return method in their attributes. They are in direct contact with all variables within local and global scope. A function object does have a return method so it can be closed off. Looping and control flow constructs have to be out in the open as it were, but they are still contained in their parent scope.

As for indentation, as Python is concerned it matters not what form the indent takes, spaces (any number) or tabs (likewise). But we should not mix spaces and tabs because that messes with the interpreter. In recent news I read that people who use spaces as a rule earn 20_000 dollars or more a year than those who use tabs. Not my study so I am not going to defend that finding. It is interesting, though.

Generally speaking, even numbers only makes it easier to standardize and adopt typing habits. The norm may be four spaces, but two is just as valid, and equally representative of blocks. (Remember, Python doesn't care, just so it is consistent and accurate.)

In simple terms, if it starts with a colon, the next and succeeding lines have an indent of two or four spaces (choose, and then stick with it) as compared with the header line. The block ends when a line of code is found that matches the indentation of the header. That is why it is so important to indent return statements, else it raises an exception.

Aside

An exception is a run time error. A syntax error happens in parsing the code by the interpreter. A program may run with errors, but they cannot be syntax errors. That stops the pasing process so no code ever executes.


#11

It is an exit, but in answer to the question above that I got segued from with tl/dr, return can appear anywhere in a function, in multiple blocks, and doesn't have to be at the end.

>>> def foo(bar):
    if isinstance(bar, str):
        return "It's a string!"
    if isinstance(bar, int):
        return "It's an integer!"

>>>

Now we run it...

>>> print (foo("Hello World!"))
It's a string!
>>> print (foo(42))
It's an integer!
>>> print (foo(10.89))
None
>>>

None is what the response is when there is not a return statement or no return value sent, even when return is present.

It is not necessary that a function have a return, but if it is supposed to send data back to the caller (the line object (expression) that called it) then it has to have a return. It is the only way of sending data up to the calling scope.


#12

I meant when function reaches the return part then it must halt ,in case of recursion tho,It keeps returning its different instances then it halts too ?


#13

In recursion, the calls are stored in a call stack until a base case is reached that doesn't return a call. That starts the stack unwinding with successive calls that are in waiting. When the stack is empty, the final return takes us back to the caller.

This is a tricky concept because many learners think that values are being stored when in fact it is deferred calls that are stored. They have yet to be even made but sit tight with their parameters intact. When the call is finally made, the dependency they have on the previous calls is satisfied so they have data with which to exercute and return that evaluation to the awaiting call, one register above.

I generally do not fare well when it comes to recusion, perhaps because I avoid it, not why I avoid it. I've hit a lot of walls where coding ideas led to a recursive solution as the most feasible way out. One day...


#14

I'm still going with recursion tho ,I find it amazing even their is performance issues. :smiley: It's challenging at the same time.


#15

def factorial(n):
    return n * factorial(n - 1) if n > 0 else 1

Let's pick 7 as our number.

Call Stack

7 * factorial(6)
6 * factorial(5)
5 * factorial(4)
4 * factorial(3)
3 * factorial(2)
2 * factorial(1)
1 * factorial(0)
0 => not > 0 so return 1

1 is not a call so the stack starts to wind down. Last in is first out. Notice as we go up the stack, the call has the data to work with from the previous call. 1 * factorial(0) is evaluated so can now satisfy, factorial(1) in the call above it in the stack.


#16

Yes! but I still find to fail to implement the recursion theory ,
on other data structures, I'd like to have some suggestions and points to take care while attacking any problem using Recursion, Should I think Mathematical way and try to find pattern in a scenario(Like if a scenario can be defined in term of its different instances , I'm not talking about memory level on goings tho ,that what I do for now for most problems) then I try to translate it, which takes time. I know practice is one way to go but what else apart from that?


#17

The only math that comes into play is what math you are trying to succeed at with the function. Recursion is an algorithm, not math.

Recursion can eat up a lot of memory while it is building the stack (recurring), but it eventually gives it all back when it unwinds. The more memory it is using, the slower things get. If speed is fixed, more distance means more time. In repetitive terms, though, such as the recursion to draw your computer's display 96 tmies a second it knows in advance how much memory is needed, and always keeps within that block of RAM.

But I digress, and have said much that is still over my head, so shouldn't say more. We've disrupted this topic enough, I would say.


#18

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.