Simultaneous Looping?

I have run some tests and determined that nested loops do not perform what I’m looking to do.

Simply put, I am trying to iterate through two separate variables and perform a calculation using the elements of each simultaneously.

I am quite new to coding and haven’t read the entire python encyclopedia, so please forgive me if there is an obvious solution that I am missing.

This code is part of a program to determine if a 9 digit number is valid or not:

def calc(x, y):
    z = []
    if x*y < 9:
        z.append(x*y)
    else:
        z.append(x+y)
    print(z)

x = "130 692 544"
x1 = ''.join(x.split())
y = "121212121"

calc(int(x1[0]), int(y[0]))

This bit works correctly! Now I need to increase the index by one and repeat the process.
While I can probably work out a “x1[0] + 1” type of solution, it occurred to me that there may be a way to pull from both variables at the same time for the iteration.

for x1 and y in range(0, 10):
    calc(int(x1), int(y))
# this seems like it is making the variable the iterator, rather than iterating through both variables
or 
for i and j in x1 and y:
    calc(int(i), int(j))
# this seems better but again, I'm not sure if I can run through both... and then run the result through the function.

So again, is there a way to iterate through multiple variables at once?

Have a look at built-in zip

3 Likes

Are you trying to apply the same index to the lists x1 and y simultaneously as the loop iterates? If so, then perhaps you need this:

def calc(x, y):
    z = []
    if x*y < 9:
        z.append(x*y)
    else:
        z.append(x+y)
    print(z)

x = "130 692 544"
x1 = ''.join(x.split())
y = "121212121"

for i in range(0, min(len(x1), len(y))): # in case the lists differ in length
    calc(int(x1[i]), int(y[i]))

Output:

[1]
[6]
[0]
[8]
[10]
[4]
[5]
[8]
[4]

EDIT:

… or, as @aivarpaalberg suggested, use zip to avoid the need to use indexes entirely.

Thank you for your feedback, It is exactly what I was hoping to do… althought I don’t understand how it works just yet LOL:

The list will not differ in length, they are all 9 digit numbers… so hopefully that will make things easier. I see that you’ve included the variables in the range so that is what I need to understand more.

  1. why are we including a ‘min’ when we’ve specified the 0 at the beginning of the range as the min?
  2. Why do we need to specify ‘len’ of the variable? (doesn’t it stop iterating at the end of the variable?)

this is designed to address a user input field with spaces (although I need to add in a removal of any dashes (regex) and an error message if more than 9 digits are entered).

OK, so plugging the iterator in place of the index removes the need to scale up the index incrementally.

I’m guessing this producing an output vertically because the “Z” variable is inside the function? If I move the z variable outside the function:

  1. will the function still append to a variable outside of the function?
  2. will each append, add to one list?

I have to perform more calculations on ‘Z’ so I would prefer these outcomes to be added to one list.

First, let’s note that we can use zip to simplify the code, as follows:

for a, b in zip(x1, y):
    calc(int(a), int(b))

The use of min was in case the lists differed in length. We would then stop when the shorter list became exhausted. However, you have guaranteed that they will each have 9 digits, so we don’t need min.

That was to limit the upper bound of the range of the indexes. But again, you have guaranteed that 9 will do.

The print function was called once from inside the calc function during each iteration, with a line break occurring after each call to print, so one individual result was displayed on each line. If you would like it all on one line, we can discuss how to do that.

Note that with the use of zip, as in the beginning of this reply, much of the complexity of the code offered above can be avoided. So the discussion about the indexes might now be moot.

1 Like

Thank you all for the guidance! The zip function was definately new to me and was the solution I was looking for.

This is the finished version:

import re

def calc(x, y):
    if x * y < 10:
        z.append(x * y)
    else:
        z.append(x + y)
z = []


y = "121212121"

while True:
    x = input("Enter your 9 digit SIN number: ",)
    pattern = re.findall(r'\d+', x)
    x1 = ''.join(pattern)

    for a, b in zip(x1, y):
        calc(int(a), int(b))

    if (sum(z)) % 10 == 0:
        print("Valid")
        break
    else:
        print("Invalid Number")
    if len(x1) != 9:
        print("Please enter only 9 digits")
    print(z)
    continue

I moved on to test and debug, and I ran a few tests with numbers too long, incorrect character spaces etc in the input and it worked, but when entering a number I knew to be valid It worked correctly but incorrectly at times as well.

So I added the “print(z)” at the end to see what caculations were coming out at the end to be added together (the result has to be evenly divisible by 10) and ran a few tests and the result blew my mind and I have no idea how this happened and is leading me to question everything from my code, to the coding program, and even my computer itself:
image

  1. How in the world did it append “z” with 16 iterations from only 9 numbers?

  2. I love the intuitive editing of PyCharm but it has been buggy for me in the past running code from closed programs etc (albeight I’m a noob so it could easily be user error), but could this be a bug in the editor? I often find myself using multiple editors to pull sections of code out to test separately because of this… can anyone recommend a similar intuitive editor that uses separate tiled windows which function independently of one another?

  3. This may be a dumb question, but is there a way to see the “gray screen” of computations line by line as it runs through your code to see what is happening at what point? I’m assuming not and I should probably build those into the code as I write it with personal markers to take the checks out once I have debugged it, but i thought I would ask :thinking:

You initialized z prior to the while loop. Each time the loop iterates, it appends to what is already there.

Enter your 9 digit SIN number: 134-08-47
Invalid Number
Please enter only 9 digits
[1, 6, 4, 0, 8, 8, 7]
Enter your 9 digit SIN number: 603-257-113
Invalid Number
[1, 6, 4, 0, 8, 8, 7, 6, 0, 3, 4, 5, 9, 1, 2, 3]
Enter your 9 digit SIN number:

Initialize z inside the loop instead. This will be the result:

Enter your 9 digit SIN number: 134-08-47
Invalid Number
Please enter only 9 digits
[1, 6, 4, 0, 8, 8, 7]
Enter your 9 digit SIN number: 603-257-113
Invalid Number
[6, 0, 3, 4, 5, 9, 1, 2, 3]
Enter your 9 digit SIN number:
1 Like