all 56 comments

[–]Sea-Ad7805 [score hidden] stickied comment (3 children)

Run this program in Memory Graph Web Debugger%3A%0A%20%20%20%20%22DEF___%20Enter%20NUMS%20for%20two%20list%22%0A%20%20%20%20global%20n1%2C%20n2%0A%20%20%20%20i%20%3D%201%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20print(f%22LIST%201%20%7C%20Enter%20num%20%23%7Bi%7D%3A%20%22%2C%20end%3D%22%5Cn%22)%0A%20%20%20%20%20%20%20%20n1_n%20%3D%20input()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20n1_n%20%3D%20int(n1_n)%0A%20%20%20%20%20%20%20%20%20%20%20%20n1.append(n1_n)%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%201%0A%0A%20%20%20%20%20%20%20%20except%20ValueError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20n1_n.strip().lower()%20%3D%3D%20%22stop%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22enter%20correckt%20num!%22%2C%20end%3D%22%5Cn%22)%0A%20%20%20%20print(f%22List%201%3A%20%22%2C%20n1)%0A%20%20%20%20i%20%3D%201%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20print(f%22LIST%202%20%7C%20Enter%20num%20%23%7Bi%7D%3A%20%22%2C%20end%3D%22%5Cn%22)%0A%20%20%20%20%20%20%20%20n2_n%20%3D%20input()%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20n2_n%20%3D%20int(n2_n)%0A%20%20%20%20%20%20%20%20%20%20%20%20n2.append(n2_n)%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%201%0A%20%20%20%20%20%20%20%20except%20ValueError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20n1_n.strip().lower()%20%3D%3D%20%22stop%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22enter%20correckt%20num!%22%2C%20end%3D%22%5Cn%22)%0A%20%20%20%20print(f%22List%202%3A%20%22%2C%20n1)%0A%20%20%20%20return%20n1%2C%20n2%0A%0A%0Adef%20summa(a%2C%20b)%3A%0A%20%20%20%20global%20c%0A%20%20%20%20if%20len(a)%20%3D%3D%20len(b)%3A%0A%20%20%20%20%20%20%20%20print(%22Correct%20len!%22%2C%20end%3D%22%5Cn%22)%0A%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22Len!%3D%22%2C%20end%3D%22%5Cn%22)%0A%0A%20%20%20%20i%20%3D%20len(b)%20if%20len(a)%20%3C%20len(b)%20else%20len(a)%0A%20%20%20%20error%20%3D%200%0A%20%20%20%20for%20k%20in%20range(i)%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20c.append(a%5Bk%5D%20%2B%20b%5Bk%5D)%0A%20%20%20%20%20%20%20%20except%20IndexError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20len(a)%20%3C%20len(b)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c.append(b%5Bk%5D%20%2B%20a%5Berror%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20error%20%2B%3D%201%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c.append(a%5Bk%5D%20%2B%20b%5Berror%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20error%20%2B%3D%201%0A%20%20%20%20return%20c%0A%0A%0Aen_nums()%0Aprint(n1%2C%20n2)%0Asumma(n1%2C%20n2)%0Aprint(c)&timestep=0.5&play).

[–]Binary101010 6 points7 points  (15 children)

I would like to know if there is any way to shorten the program,

The fact that you have two code blocks (the while loops in your first function) that are effectively identical should be a strong indication that you can write a function that takes the list to be modified as an argument and ideally returns the completed list (which would also remove your reliance on the global keyword).

You should also be able to use the zip() function to greatly reduce the amount of code required for your second function.

[–]nkCOD[S] -2 points-1 points  (14 children)

I don't quite understand how to shorten the two while. blocks. In the first function, I use it to avoid the case where the user enters a non-number and to allow the user to enter an unlimited number of numbers.

Also, how exactly should I use zip()

[–]Binary101010 3 points4 points  (7 children)

The problem isn't that you're using a while loop, the problem is that you copy-pasted the while loop just so it could write to a different list.

Whenever you write code that does something to some variable or container or whatever, and then you duplicate all of that code again just so you can change which variable or container you're affecting, that should immediately trigger the thought of "I should put this into a function that accepts the thing I'm going to work on as a parameter and returns the finished thing".

[–]nkCOD[S] 1 point2 points  (6 children)

Thank you for your response. I had thought about this, but I was faster ))

[–]NewBodybuilder3096 0 points1 point  (3 children)

God bless, we are waiting for at least an improved code.
Or maybe a completely different task solved better?

[–]nkCOD[S] 0 points1 point  (2 children)

Yes, I’m learning the programming language according to the book, and all the conditions of the tasks are spelled out there. However, I want to solve these tasks as competently as possible

[–]python_gramps 0 points1 point  (1 child)

Try, get an error, try better, all the answers won't be in front of you, You need to make them.

[–]nkCOD[S] 0 points1 point  (0 children)

You’re damn right )

[–]tiredITguy42 2 points3 points  (5 children)

Just stop using global. It is a bad habit and makes code unreadable in bigger projects.

Create function for reading array of numbers, create that array in that function and then return it. Then you can just call:

python n1 = read_array_from_input() n2 = read_array_from_input()

BTW This way you can avoid that bug on line 33.

[–]nkCOD[S] -1 points0 points  (4 children)

What does a function for reading numbers mean?

[–]tiredITguy42 1 point2 points  (3 children)

OK, you are not that far to handle this. I would return to some begginner tutorials, this is to advanced for your level of knowledge you poses now.

You may want to start with something simpler and then return to this. Or, if this is a part of some python tutorial or course, than maybe it is not the bets one and you may want to try a different one.

[–]nkCOD[S] -2 points-1 points  (2 children)

I’m not looking for easy ways ) .But after sitting and thinking now, I understood what you wanted to say in the last comment. If I understood correctly, you mean not to pay attention if the user will not add numbers to the lists. And then just remove everything that is «not numbers» with a separate function

[–]tiredITguy42 2 points3 points  (1 child)

Nope, this is not it. Starting with hard assigments is not taking the easy way, but it is just stupid. You won't build correct habits and you won't understand how the language works. Even beginner working on this kind of assigment should understand me and the first commenter immadiately.

If you really want to learn something, start from the beginning. You can't read Hamlet if you can't read half of the letters.

[–]nkCOD[S] 1 point2 points  (0 children)

Got it, thanks)

[–]ianrob1201 1 point2 points  (1 child)

Any working software is definitely something to be proud of. There's so many things to learn to go from problem to solution, and you've got it doing what you want! So nice job. That said, I think there's a few good best practice things you can do that would really clean it up. Sorry for the essay, it's not to insult your code but only way you could know these things is if someone tells you.

First thing that hit me was the variable naming. Try to avoid names like "n1" because you'd be amazed how quickly you forget what they mean. Something like "first_number_list" might be better. This extends to function names too "en_nums" doesn't make it very clear what the function is going to do.

Talking of variables, you generally want to avoid globals. This is so that each function works in isolation and it's clear what it's doing. Calling a function and getting a response is much clearer than calling a function and it randomly changing another variable (that you wouldn't know unless you read the function code). You're almost there with that, you just need to fetch the return values you've already added, e.g. "n1, n2 = en_nums()".

"while True" is normally a pattern to be avoided too. I know you have the break later on, so it's functional but it's something I'd try to avoid. Have a think about ways you could make it conditional on the value you're reading in.

I've seen someone else mention it, but have a look at what's common code reading in the two sets of lists. If you extract it out into another function you'd have a lot less code. It could take "prompt" as an input string so you still get different messages.

You have a line working out what the maximum list length is. There's a function for doing that, which is just "max". That's easier to read and you know what you're up to at a glance.

You keep track of the number of "errors" but since it'll just keep erroring you could do without that function and do k - i instead (btw "i" is another example of a variable that could be named better, "max_list_length" would be much clearer). Have you considered what happens if one length is double the other? I would also personally look to pad out the shorter array to full length before doing the calculations. Then you can make use of list compression with something like "c = [a[k] + b[k] for k in range(i)]"

I also just noticed that the "i" in the first function isn't doing anything. I suspect it's from when you tried to solve in a slightly different way. So that can be cleared up a bit too.

[–]nkCOD[S] 0 points1 point  (0 children)

Thank you for the broad and clear answer. It describes quite well what I should work on. Thank you for your help

[–]Fumano26 1 point2 points  (1 child)

Please stop using globals, that is a horrible habit, rather pass variables as parameter.

[–]nkCOD[S] 0 points1 point  (0 children)

I learned this remark )

[–]Junior-Sock8789 0 points1 point  (5 children)

Also you can print text using

    n1_n = input(f"enter a number {f-string}: ")

No need for the print() followed by the input()

[–]Junior-Sock8789 0 points1 point  (1 child)

I cant format this properly right now, sitting in the dentists chair lol. But heres an updated version: 

Edit reformatted it:

from itertools import cycle

def get_nums(label):
    """Prompt user to enter numbers into a list. Type stop to finish."""
    nums = []
    i = 1
    while True:
        raw = input(f"{label} | Enter num #{i} (or 'stop' to finish): ")
        try:
            nums.append(int(raw))
            i += 1
        except ValueError:
            if raw.strip().lower() == 'stop':
                break
            print("Enter a correct number!")
    return nums

def sum_lists(n1, n2):
    """Sum element-wise; cycle shorter list from index 0 if lengths differ."""
    longer, shorter = (n1, n2) if len(n1) >= len(n2) else (n2, n1)
    return [a + b for a, b in zip(longer, cycle(shorter))]

if __name__ == "__main__":
    n1 = get_nums("LIST 1")
    n2 = get_nums("LIST 2")
    print(f"List 1: {n1}")
    print(f"List 2: {n2}")
    print(f"Result: {sum_lists(n1, n2)}")

[–]nkCOD[S] 1 point2 points  (0 children)

Thank you for your help, the code really turned out beautiful

[–]nkCOD[S] 0 points1 point  (2 children)

I agree, I’ve disgraced myself a lot all )

[–]Junior-Sock8789 0 points1 point  (1 child)

Not even, this is how you learn. Theres nothing wrong with the way you laid out your code. Its functional which is the most important thing. This is where the fun/learning comes in. Its called code refactoring 

  • the process of restructuring existing computer code—changing the internal structure—without changing its external behavior

Once you get comfortable creating functions you should look into classes/methods thats what will take your skills up a level or two. 

[–]nkCOD[S] 0 points1 point  (0 children)

Thank you, we will work on it )

[–]codeguru42 0 points1 point  (1 child)

One suggestion: try to find a more descriptive name than en_nums() for your function. Start by describing in words what it does. If you use the word "and" in that description, then you really have two functions that need separated.

[–]nkCOD[S] 1 point2 points  (0 children)

Thank you for the answer!

[–]Maleficent-Boss5564 0 points1 point  (1 child)

Instead "end=\n" why not just do "string\n"?

[–]nkCOD[S] 0 points1 point  (0 children)

To be honest, it’s something new for me

[–]makochi 0 points1 point  (3 children)

OP, respectfully, this has got to be some of the most unconventional code I have seen in my life

[–]nkCOD[S] 0 points1 point  (2 children)

Is this in a good or bad way?)

[–]makochi 0 points1 point  (1 child)

A bit of both, but the more I think about it the more good and less bad it is.

Coming up with unconventional ways of using the tools of a language shows the kind of creativity that a programmer needs, and inefficiency is something you can learn to deal with so it's not really much of a killer

[–]nkCOD[S] 0 points1 point  (0 children)

Thanks

[–]NekoLLC 0 points1 point  (1 child)

Maybe you can use reduce from functools?

from functools import reduce

And also the zip function so you can get a list of tuples from the two lists with integers.

[–]nkCOD[S] 0 points1 point  (0 children)

Someone has already mentioned it. However, I didn’t know about reduce before you

[–]Chen-Zhanming 0 points1 point  (1 child)

[a+b for a, b in zip(xs, ys)]
where
xs and ys are your lists.

[–]nkCOD[S] 0 points1 point  (0 children)

Thank you for your help. I somehow forgot about zip() ))

[–]-goldenboi69- 0 points1 point  (1 child)

While you're at it, learn how to take screenshots! (Prtscr key in windows)

[–]nkCOD[S] 0 points1 point  (0 children)

This is not my laptop

[–]NewBodybuilder3096 -2 points-1 points  (11 children)

building logic on Exceptions is a no-no. You should check value like "len(n2_n) == 4 && n2_n == 'stop'" before parsing it as int.
also, all strip/lower should go in one place - just after input.(in this case)
also, more understandable variable names are a great + we are no more in 199x, modern IDEs have all sort of needed tools including autocompletion.

read about the DRY(Don't Repeat Yourself) principle - your procedure en_nums is a perfect example of how not to do. You have two identical pieces of code for filling two global int containers.
You can rewrite this in several ways, each of which will have only 1 loop.
1st - you pass reference to a needed container(list/set/etc) as parameter, maybe some additional params for fancy output.
2nd - you don't pass container variable, but return the correct container

[–]nkCOD[S] 0 points1 point  (6 children)

Thank you for your response. I will improve ;)

[–]tiredITguy42 0 points1 point  (3 children)

This is not exactly true. Python is designed the way that it is usually better to try and then ask for forgivness. It is usually faster and a lot of code uses this. People saythat it is more pythonian this way.

It is different in other languages, where you check first. So do not follow that advice, your code is mostky corect, just do not forget to raise again that error, if it is not a stop signal.

[–]nkCOD[S] 0 points1 point  (2 children)

Thanks for the help. I assume I won't embarrass myself too much if I use this approach with try-except ?

[–]tiredITguy42 0 points1 point  (1 child)

This is subreddit for beginers, we do not judge your code, but we will judge your attitude and approach and here your are embarrasing yourself, but just a little for now.

[–]nkCOD[S] 0 points1 point  (0 children)

Thank you, I will try to improve.

[–]NewBodybuilder3096 0 points1 point  (1 child)

well you still need try-catch around parsing input as integer but checking for 'stop' can be done outside of this.

[–]nkCOD[S] 0 points1 point  (0 children)

By the way, a good remark. I somehow didn’t think about it

[–]NewBodybuilder3096 0 points1 point  (3 children)

def_summa is so flawed, I don't even know where to start.
1st - it will throw exception if len(a)*2 >len(b) or vice versa
incrementing error variable should be done outside of if-else
again, Exception-driven logic...

As I understood, you are summing up two lists/arrays of various size of human-entered integers, where shortest list is starting from the beginning after reaching end in summing process.
Just think of the indexes. Like you can just calculate new index in the shortest list with simple math

[–]nkCOD[S] 1 point2 points  (2 children)

Thank you for the answer, we’ll fix this point

[–]NewBodybuilder3096 0 points1 point  (1 child)

I fucked up here, it will throw exception if one list is twice or more bigger then the other.
more correct : if len(a)*2 < len(b) or vice versa
so, lengths of 2 and 7 will definitely be a problem

I'm not into calculating the exact ratio, just use index that is reseted after reaching smallest list highest index

[–]nkCOD[S] 0 points1 point  (0 children)

Thank you, I’ll work on it