0

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")
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
DrewsDoggo
  • 11
  • 1
  • @mkrieger1 When I try putting it outside ```no``` I get this error ```UnboundLocalError: cannot access local variable 'e' where it is not associated with a value``` – DrewsDoggo Apr 03 '23 at 17:08
  • Does this answer your question? [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function) – mkrieger1 Apr 03 '23 at 17:09
  • What do you enter as input? If you enter `example1 example2` I think you should already get what you want. – mkrieger1 Apr 03 '23 at 17:10
  • `e` is a local variable. It is created and initialized with `0` every time you call this function. So that's not gonna work this way. You can have a global variable and inside the `no` function, use `global` keyword. – S.B Apr 03 '23 at 17:11
  • If the string has spaces, do you also want each word to have a different `e` value, or should they all have the same one? – Barmar Apr 03 '23 at 17:17
  • Your example input suggest one word per input, but your function is splitting. Can the input have the form `"example1 example2"`? If so, wht's the expected output. – Ignatius Reilly Apr 03 '23 at 18:36
  • Possible duplicate of [How to maintain state in Python without classes?](https://stackoverflow.com/questions/11866419/how-to-maintain-state-in-python-without-classes) – Ignatius Reilly Apr 03 '23 at 18:44

3 Answers3

0

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("\t\t ItemListData(" + str(i) + ")=(ItemDefinition=" + path + '")')
  5. use f-strings for formatted strings. print(f'\t\t 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'\t\t ItemListData({i})=(ItemDefinition="{path}")')

i = 0
while True:
    paths = input()
    number_paths(paths, i)
    i += 1
SimonUnderwood
  • 469
  • 3
  • 12
0

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)

Ignatius Reilly
  • 1,594
  • 2
  • 6
  • 15
-2

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.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Ryan
  • 1,081
  • 6
  • 14
  • 1
    If the loop should execute `x` times you should use `for e in range(x):` – Barmar Apr 03 '23 at 17:18
  • What does the output look like if the following string is entered (in one line): example1 example2 – DarkKnight Apr 03 '23 at 18:28
  • @Barmar while True is good for an infinite loop – DarkKnight Apr 03 '23 at 18:29
  • @DarkKnight The input seem to be constrained by the OP in their question to only one word, but it's true it wouldn't make sense to split it. I asked this in comments to the OP. Maybe they want each `path` to be considered at the same level as a separated input? – Ignatius Reilly Apr 03 '23 at 18:38
  • @DarkKnight I know. My comment was referring to the last line that says `while e < x:` – Barmar Apr 03 '23 at 19:51
  • @Barmar I know that, but the person who posted this used a while loop. I just suggested a slight change to their format. If they had used a for loop I would have suggested it. – Ryan Apr 04 '23 at 19:16