How would I increase a integer value inside this loop?

Question:

Trying to increase an integer value

So basically I’m trying to increase "e" so everytime I input a new line it would go 0, 1 etc

My input would look like this

example1
example2
def no(paths: str):
    e = 0
    for path in paths.split(" "):
        print("            ItemListData(" + str(e) + ")=(ItemDefination=" + path + '")')
        e = e + 1

while True:
    paths = input()
    no(paths)

When I do this I get this:

ItemListData(0)=(ItemDefination=example1")
ItemListData(0)=(ItemDefination=example2")

What I want is this

ItemListData(0)=(ItemDefination=example1")
ItemListData(1)=(ItemDefination=example2")
Asked By: DrewsDoggo

||

Answers:

Assuming you want to have the value e increase every time you execute the function, you can do this:

def no(paths: str, e: int):
    for path in paths.split(" "):
        print("            ItemListData(" + str(e) + ")=(ItemDefination=" + path + '")')

e = 0
while True:
    paths = input()
    no(paths, e)
    e += 1

The first two lines of output, with inputs as follows:

execute1 (enter)
execute2
execute1
    ItemListData(0)=(ItemDefination=execute1")
execute2
    ItemListData(1)=(ItemDefination=execute2")

Note that you have an infinite loop. To not have an infinite loop, you could change the loop condition to something like while e < x to make the loop contents execute x times.

Answered By: Ryan

Firstly, let me just preface this by saying that this is a very basic question and you should really learn some basic debugging skills.

Code Tracing

To see what’s wrong, we need to first understand the code, so let’s trace it to see what’s actually going on.

  1. "example1" gets stored in paths
  2. paths ("example1") is passed into the no() function
  3. e is set to 0
  4. paths ("example1") is split by spaces
  5. there are no spaces in "example1" so split returns ["example1"]
  6. we iterate through the elements of ["example1"]
  7. there is only one element in ["example1"] and that is "example1"
  8. ItemListData(0)=(ItemDefination=example1") is printed
  9. the loop ends because there is only one element in paths
  10. we leave the no() function
  11. "example2" gets stored in paths
  12. paths ("example2") is passed into the no() function
  13. e is set to 0
  14. paths ("example2") is split by spaces
  15. there are no spaces in "example1" so split returns ["example2"]
  16. we iterate through the elements of ["example2"]
  17. there is only one element in ["example2"] and that is "example2"
  18. ItemListData(0)=(ItemDefination=example2") is printed
  19. the loop ends because there is only one element in paths

Solution

It is important to note step 3 and step 13.
e is set to 0 each time you call no()
But we don’t want that to happen, do we? We want to keep track of how many times you enter a path. If we look at our stack trace again, we’ll see that the loop that handles where you enter the path is the while loop outside of the no() function.
So the solution would be to put e = 0, and e = e + 1 around the while loop instead of the for loop.

def no(paths: str, e: int):
    for path in paths.split(" "):
        print("            ItemListData(" + str(e) + ")=(ItemDefination=" + path + '")')

e = 0
while True:
    paths = input()
    no(paths, e)
    e = e + 1

Conventions

  1. no() should be renamed to number_paths() because no is a word that means something else in English.
  2. indexes should usually use the i variable instead of e.
  3. ItemDefinition is misspelt.
  4. unless there is a really good reason to, please don’t manually print a bunch of spaces. use "t" for tabbing instead. print("tt ItemListData(" + str(i) + ")=(ItemDefinition=" + path + '")')
  5. use f-strings for formatted strings. print(f'tt ItemListData({i})=(ItemDefinition="{path}")')
  6. use i += 1 instead of i = i + 1

Conventionally fixed code:

def number_paths(paths: str, i: int):
    for path in paths.split(" "):
        print(f'tt ItemListData({i})=(ItemDefinition="{path}")')

i = 0
while True:
    paths = input()
    number_paths(paths, i)
    i += 1
Answered By: SimonUnderwood

If you want the function itself to modify it’s internal state, you can declare it globally.

But because in your case, e makes sense only as an attribute of the function no… why not making it just that, an attribute?

def no(paths: str):
    for path in paths.split(" "):
        print("            ItemListData(" + str(no.e) + ")=(ItemDefination=" + path + '")')
        no.e += 1

no.e = 0

for example in ["example1", "example2"]:
    no(example)

In this case, no.e is also declared globally (and it could be accessed by other functions, e.g. print(no.e)).

Note that because no is declared (in it’s own def), you don’t get UnboundLocalError, even if no.e wasn’t yet declared, but you’ll get AttributeError if you forget to declare it before using it.

It may be considered and abuse of function attributes, but in my opinion it’s justified here since it makes explicit that e only has meaning as part of no. But if you want a more explicit manipulation of global variables, you can also do

def no(paths: str):
    global E
    for path in paths.split(" "):
        print("            ItemListData(" + str(E) + ")=(ItemDefination=" + path + '")')
        E += 1

E = 0

while True:
    paths = input()
    no(paths)

As a side note, no doens’t seem to make sense outside a for/while loop since it’s assuming the value e needs to be updated. And your while loop is doing little more than calling no. Is it really necessary to dissociate these two?

You could just do

e = 0
while True:
    paths = input()
    for path in paths.split(" "):
        print("            ItemListData(" + str(e) + ")=(ItemDefination=" + path + '")')
        e = e + 1

(Or put all that inside a function)

Answered By: Ignatius Reilly
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.