+2

Can you, please, comment on this?

Hi, do you think this is professional? If not, please, tell me a proper way of getting input using function and also havning exceptions handled. def get_username(): counter = 0 # keep track of recursive steps username = None # string to be returned try: temp = input("Username: ") assert not temp[0].isdigit() #check so the first character is not a digit print("-|Input Complete!") username = temp # if this line is executed input is complete, setting value except AssertionError: print("-|Username can't start with a number!") print("-|Input Failed!") print("---------------") counter += 1 #incrementing step username = get_username() # recursive call finally: if(counter == 0): #Used this part to avoid $counter$ times repeat of this line print("-|Processing...") #if(counter == 0): print("-|Processing...") return username

2/15/2020 6:51:28 AM

Temp Name

7 Answers

New Answer

+5

Hello. I suggest next time post your code bits on the playground and attach to your question. I think your approach is fine, although I probably wouldn't use recursion for this, more like an infinite while loop. When there is no exception, you can return the result from within the try block. You might want to add other assertions too, for example the username cannot be empty (in this case you currently get IndexError) or can't contain whitespaces or special characters. Using a regexp is handy in these cases. Here is a refactored version of your code. https://code.sololearn.com/cSNku0LjKqZ0/?ref=app

+1

Thank you so much. I am sorry, first time posting here. Will, definitely add more assertions. ^^

+1

I am a newb, so I just took this as an excuse to see if I could do some of the things Tibor Santa mentioned. Forgive me for jumping into an already solved situation, but here is something I came up with based on the above published code: https://code.sololearn.com/cJY9uHpiFx24 One anomaly I find is that if I lead the username with spaces after I have typed some failed attempts, the username does not print on the function exit. I haven't spent a lot of time trying to use the debugger, because I am at work, but I am very interested in what you think, and if my solution is "pythonic" as it were, or if I am making things too hard. Thanks. AND Thank you Tibor Santa for sharing your code, I have learned a lot trying to walk thru it. I have only really been studying Python for maybe a month or so, but contributions like yours make a world of difference to my studies. Thanks!

+1

Code Crasher thanks, I am glad my example was helpful. Your additional assertion looks ok, but it seems you are trying to combine the while loop with the recursive call, you wouldn't need both. And the 'finally' clause is really not needed here. We typically use it when we want to make sure that some resource we have opened, like a file or database, is closed properly at the end, regardless if there was an exception or not. I added a recursive version to my code so you can try it. Here is it: # recursive version def get_username_recursive(): try: username = input("Username: ") assert not username[0].isdigit() print("-|Input Complete!") return username except AssertionError: print("-|Input Failed!") return get_username_recursive() The last line is the key, because when you make a recursive function, the control flow will eventually come back to the place from where you recurse. Username returned, will propagate back to each recursive call.

+1

excellent!!! I get it... I added the split and check for the null string and it works. I know what I was doing wrong now. I was placing the assert to check for the null string before the assert for the digits and it was bombing out. I didn't understand the index error before, but if I am thinking right it was failing because a null string has nothing to index so it can't check for a digit on null and gets confused (Am I right?). I added the two lines to your code to get it to work the way I envisioned it to work: # recursive version def get_username_recursive(): try: username = input("Username: ") username = username.strip() # added assert not username == '' # added assert not username[0].isdigit() print("-|Input Complete!") return username except AssertionError: print("-|Input Failed!") return get_username_recursive() print(username) print(get_username_recursive()) Seriously, Thank You SO much. This helped me grasp assert better, and made me rethink the way I debug loops. I was thinking before that 2 asserts could not be used with in the same branch of a loop, and somehow the checks had to be on the same line, but I see now that the order of things come into play (I should know this already, but I still forget what I learned with if/elif loops, and that is why I reverted to that with my solution, cause I beat my head up against the wall debugging code that I had things in the wrong order with that too.). This has been a really awesome exercise, and it would have taken me much longer without your as reference. Learning to use stepping in the debugger has been an incredibly awesome discovery too. I can not thank you enough. I really feel this is going to help me progress a lot faster now!!! /me passes Tibor Santa a cold one! Cheers!

+1

OK... I may have spoke too soon? I run the code in VSCode and Thonny and it works the way I expect, but when I run it on SL ( https://code.sololearn.com/cJY9uHpiFx24 ) I get the following errors: Username: -|Input Failed! Username: Traceback (most recent call last): File "./Playground/file0.py", line 14, in get_username_recursive assert not username[0].isdigit() AssertionError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "./Playground/file0.py", line 22, in <module> print(get_username_recursive()) File "./Playground/file0.py", line 19, in get_username_recursive return get_username_recursive() File "./Playground/file0.py", line 11, in get_username_recursive username = input("Username: ") EOFError: EOF when reading a line Is this because SL can not jump back to the beginning of the loop? Interesting?! (I think I answered my own question? I think it is the way SL executes code in the Playground. I step through it in VSCode, and it is doing exactly what it is supposed to.) :(

+1

Code Crasher I'm happy for your progress ;) Your logic about the indexerror is almost right, only a slight technical detail is that input() will always return a string type object - which may be an empty string with 0 length, if the user does not enter anything. So yes in this case username[0] tries to access the first character that doesn't exist. No need to panic about SoloLearn, it's just how the input works here in non-interactive way. You have to enter all inputs for the program upfront in the same dialog box, in separate lines, like: 1wronginput correctusername You can play this code that explains in detail https://code.sololearn.com/WhiNb9BkJUVC/?ref=app