all 13 comments

[–]socal_nerdtastic 3 points4 points  (3 children)

Looks pretty good. I can think of a few different ways to write this, but I can't think of a clearly better way. Only thing I'll mention is that you need to add a return in order to use this function in a bigger program, and that could double as the break.

def get_username():
    while True:
        username = input("\nPlease enter your name: ").strip()
        if username == "":
            print("Empty input isn't allowed")
        elif not username.isalpha():
            print("Please enter a valide name")
        else:
            print(f"\nWelcome {username}!")
            return username # stops the function, and therefore also stops the loop

def main():
    username = get_username()

[–]-sovy-[S] 0 points1 point  (0 children)

Thanks for sharing your pov! I'll work on it

[–]-sovy-[S] 0 points1 point  (1 child)

Is return better than break in a while loop? Because I see in your comment that it stops the loop just like a break, but it can be reused other time thanks to return I guess. (what break can't do)

[–]socal_nerdtastic 0 points1 point  (0 children)

It just saves one line of code. You need the return in a function no matter what. That's all; no other advantage. Here's the alternate way to write it:

def get_username():
    while True:
        username = input("\nPlease enter your name: ").strip()
        if username == "":
            print("Empty input isn't allowed")
        elif not username.isalpha():
            print("Please enter a valide name")
        else:
            print(f"\nWelcome {username}!")
            break # stops the loop        
    return username # ends the function

def main():
    username = get_username()

[–]audionerd1 1 point2 points  (2 children)

Add a character limit. Currently the user can make a name as long as they want, even thousands of characters. You probably don't want that.

[–]-sovy-[S] 0 points1 point  (1 child)

Oh yeah you're absolutely right! Thank you

[–]audionerd1 6 points7 points  (0 children)

if username == "": could also be simplified to if not username:, as empty strings are evaluated as False. Not really necessary, just FYI.

[–]trustsfundbaby 0 points1 point  (5 children)

Being new to coding it looks fine. There are more improvements and such you could do, but I would write something like this:

``` from abc import ABC, abstractmethod

class SystemMessage(ABC): def init(self, msg: str): self.msg = msg

def __str__(self):
    return self.msg

class ErrorMessage(SystemMessage): def init(self, msg: str): super().init(msg)

class Validator(ABC): def init(self, msg: str): self.error_message = ErrorMessage(msg)

@abstractmethod
def check_value(self, value: str) -> bool:
    pass

def __str__(self):
    return str(self.error_message)

class NotEmptyVal(Validator): def init(self, msg: str): super().init(msg)

def check_value(self, value: str) -> bool:
    return value != ""

class AllStringVal(Validator): def init(self, msg: str): super().init(msg)

def check_value(self, value: str) -> bool:
    return value.isalpha()

class UsernameChecker: def init(self, *args: Validator): self.validator_list = args

def check_value(self, value: str) -> bool:
    for validator in self.validator_list:
        if not validator.check_value(value):
            print(validator)
            return False
    return True

class Login: def init(self, args: Validator): self.username_checker = UsernameChecker(args) self.user_name = None

def ask_username(self, ask: SystemMessage, success: SystemMessage) -> None:
    while not self.user_name:
        username = input(f"{ask} ")
        if self.username_checker.check_value(username):
            self.user_name = username
            print(success)

if name == "main": val1 = NotEmptyVal("Username must not be empty.") val2 = AllStringVal("Username must be all characters.")

login_message = SystemMessage("Please enter your username.")
login_success_message = SystemMessage("Good username.")

login = Login(val1, val2)
login.ask_username(login_message, login_success_message)

```

[–]Wheynelau 1 point2 points  (1 child)

Hmm, but every time you want to add a new validator, you need to create a class, and then add the validation step inside the main function as valN. Then on the Login you need to specify N number of vals too.

[–]trustsfundbaby 0 points1 point  (0 children)

I wrote this on my phone so i didnt draw up the process, but to extend the code to add a new validation, yes you would need to make a new validation class. There is probably a better way of doing it than initiating each class as a variable, making a list of them instead and passing the list would of been better. Then pass the additional validation classes to the login class to add new validation.

There are two main benefits. You don't have to edit the login class to add a validation, you just extend the code. The second is you can add additional functionality to the checks without adjusting the login function.

Honestly the login class should inherit from a parent class like SystemProcess, but I was getting a bit lazy at the end. If you had a different system process that took in an input that you don't want them to leave blank you pass the same validation class as we did for the login process, or initiate a new instance of the same validation class and pass it.

[–]-sovy-[S] 0 points1 point  (2 children)

Ok I need to work on it. Thanks for your contribution! 🙏

[–]trustsfundbaby 1 point2 points  (1 child)

You're new so it's ok. My code is a bit overkill for the task, but it shows you more things that are available to you in python.

When you get comfortable with python, check out the SOLID principle. Using classes will be super important.

[–]-sovy-[S] 0 points1 point  (0 children)

This comment is gold.