Testing nested loop... why is this the output?


#1
def find_even_index(arr):
  for x in range(len(arr)):
    for N in arr:
      if N > arr[x-1]:
        print "N is greater than %d" % arr[x-1]

a = [7, 11, 0, 5, 6, 7]

find_even_index(a)

So why is the output below

N is greater than 7
N is greater than 7
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 5
N is greater than 5
N is greater than 5
N is greater than 5
N is greater than 6
N is greater than 6
N is greater than 6

Why does 6 show up three times?


#2

you could run your code here:

http://www.pythontutor.com/visualize.html#mode=edit

this tool allows you to walk through your program in steps


#3

Already using Repl.it

Looking at it live, I still don’t get why it goes through 6 three times. 2 times would make sense, since it goes through the nested loop, but 3?


#4

does repl allow you to execute your code in steps and see the values while the program is running? its what pythontutor is offering

i am very confused by this line:

if N > arr[x-1]:

studying the list with the index:

7   11  0   5   6   7 # values
0   1   2   3   4   5 #indices

the indexes will be the values of x, so x-1 gives:

-1 
0
1
2
3
4

-1 will give you the right most value. (using negative indices, you access the list from the right hand side)

What is this program even suppose to do? Is there an exercise?


#5

You have this list

[7, 11, 0, 5, 6, 7]

And you iterate through its indices.
but you don’t look at the current one, you look at the previous one, so you’re really looking at this list:

[7, 7, 11, 0, 5, 6]  # move last element to beginning

There can’t possibly be any point to that


I don’t see why you print the letter N, wouldn’t it be better to know which value N has?


If you’re trying to compare values pair-wise with the one that follows, why don’t you start with iterating through the following:

(7, 11)
(11, 0)
(0, 5)
(5, 6)
(6, 7)

Note that this is one pass over the list, you would not be nesting loops inside each other


@stetim94
https://www.codewars.com/kata/equal-sides-of-an-array


How does comparing elements to each other relate to the problem?
Again with the example input of all values being equal - this won’t tell you anything

[1, 1, 1, 1, 1]  # this has a solution: 2
[1, 1, 1, 1]     # this has no solution (-1)

The problem statement is about sums there is a condition to check at each position:

find an index N where

the sum of the integers to the left of N is equal to the sum of the integers to the right of N

So for each possible N, you should be testing whether:

the sum of the integers to the left of N

is equal to

the sum of the integers to the right of N


#6

Generally speaking, when iterating over a linear object (a list) we would never use nested loops. Just one loop is sufficient. If we wish to access both the index and the value, then use enumerate…

for i, x in enumerate(arr):

However, if the name of the function is any indication of what’s to be expected in the return value, then we wouldn’t need the values, at all. Just the indices. But let’s for consideration’s sake say we wish to the return the values that are at even indices. Then the above will work just fine.

    result = []
    for i, x in enumerate(arr):
        if i % 2: continue      # ignore odd numbers
        result.append(x)
    return result

#7

So there we go, but 6 is still iterating 3 times, and then suddenly 7 iterates at end for no reason I can fathom.

def find_even_index(arr):
  for x in range(len(arr)):
    for N in arr:
      if N > arr[x]:
        print "N is greater than %d" % arr[x]
N is greater than 7
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 0
N is greater than 5
N is greater than 5
N is greater than 5
N is greater than 5
N is greater than 6
N is greater than 6
N is greater than 6
N is greater than 7

#8

So, why the nested loops? Why doe the code have nothing to do with the function name?


#9

Oh because I’m just trying to make it work right now. It’s part of a larger function.


#10

well, 7, 11 and 7 are greater then 6, so you get N greater then 6 three times

but i agree with mtf, the nested loop doesn’t seem to have value for the program you are building


#11

Pretty sure the bottom line here is that you should test your approach manually before you write any code.


#12

You are going to be given an array of integers. Your job is to take that array and
find an index N where the sum of the integers to the left of N is equal to the sum
of the integers to the right of N. If there is no index that would make this happen,
return -1.

It’s part of a larger function that has to do that.

Oh okay, that makes a lot more sense. I thought it was checking each element in order of the assigned list as it went through, but then I sorted it, and it seems to not be random anymore. That’s cool.

The instructions itself doesn’t require sorting though.


#13

So that function is definitely going to need a name that in some way describes the expected return.

def find_pivot_of_sums(arr):

or something similar. As noted already, don’t sort or that will throw everything off.

The list you are given in the opening post could be considered a special, or balanced case that doesn’t take anything more than a basic function with no conditionals as the following sketch will show. But it is a special case.

>>> def find_pivot_of_sums(arr):
	from_left = 0
	from_right = 0
	n = len(arr) // 2
	for i in range(n):
		from_left += arr[i]
		from_right += arr[-i - 1]
	return from_left, from_right, i

>>> find_pivot_of_sums([7, 11, 0, 5, 6, 7])
(18, 18, 2)
>>> 

#14

That doesn’t find anything though. Equivalent:

def find_pivot_of_sums(arr):
    n = len(arr) // 2  # <--- arbitrary location, why here? Is 3, but the index is 2. Should be i = 2
    left = sum(arr[:n])  # <--- one too many, should be arr[:i]
    right = sum(arr[-n:])  # <--- wrong logic, for example, n=0 won't make it reach. should be arr[i+1:]
    return left, right, n-1

(It’s not in the middle, there are two to the left, three to the right, but middle is equally arbitrary, really, shouldn’t it just say n = 2 ? (In this case it’s 3 but it’s not index 3 that’s looked at so…))

Also, it includes the 0 itself. If that 0 was 3, there would still be a solution at index 2. But this would give sums 21 and 18


The point about not needing greater-than/lesser-than comparisons stands though


#15

Sorting doesn’t change the fact that 3 values are greater than 6.
You’ll get 3 such “hits” either way.
But it’s not just sorting that instructions do not mention, they also do not mention comparing values to each other.

Solve 10 or so of them completely manually. Write them down on paper. Observe what you do. That is what your program should do.
Since you can do it manually you already know what your program should do. Refer to that.


#16

I called it a special case because I knew it would work by looking at the list. It is by no means intended to be more than a plain sketch. And yes, I was going to do slices and sum but our friend needs more naive experience than abstract, as I judge it.

The last thing I wish to do is give away the solution. The member needs to plod on as best he can on the advice he is given. Granted, both you and I can be a tad difficult to follow, but I make no apologies and neither should you. I’m already at the held back stage just so I don’t lose sight of the learner’s difficulties, that is apology enough, IMHO.

This problem is a conditional, for sure, and the algorithm is not the simplest to come up with for anyone who has never tackled it before (like me). I’ve been tied up with other things today so haven’t spent any more time on it, but will over the weekend.

:slight_smile:


#17

Why is it special?
(I don’t think it is)


#18

There I may be mistaken in identifying it that way. It’s misconstrued from the idea of special cases in math, which I cannot give one good example of, just now. One could say it is special because I knew it would work without actually delving deep into more than the simplest algorithm.

Ones supposes asymptotes are a sort of special case.

The idea I’m going to explore is to pivot around one sum reaching the other, which will require inequality for control flow, just to see if the member is onto something. This will permit a floating pivot index, which value cannot be added into either sum.


#19

But on paper, it is!
The solution is given for free for just being human.

Something that’s free is being made difficult by writing code.

This is also a problem with loops. They’re much more difficult to think about than slicing. Slicing is more natural: it’s “from here to there”, loops involve a whole lot of crazy actions that are really difficult to get right!


#20

Which is how I knew that code would work.

A great cautionary note! Definitely going to NB this one.

As a naive learner, this should be endured, and not skipped over in favor of slicing. Eventually they will deduce the slice method that can take its place. It should come with trials and tribulations.