# Buidling classes with user input and calling methods

Learned alot in this first week, following PCC, but biggest leaps came from the community and others giving their time to help, thank you!

All input appreciated!

Objective
Goals were to fill a class with user inputs from multiple users and then be able to call methods to each user input created class. (... did I say that right O.o)

Code

class User():
def __init__(a, first_name, last_name, city, age):
a.first_name = first_name.title()
a.last_name = last_name.title()
a.city = city.title()
a.age = age

def describe_user(a):
print("-----")
print("First Name" + " : " + a.first_name)
print("Last Name" + " : " + a.last_name)
print("City" + " : " + a.city)
print("Age" + " : " + a.age)

user_input = ''
while not user_input:
user_input = input(message)
return user_input

def form_complete(values, placement, length):
placement = []
while len(placement) < length:
first_name = ask_user("Enter First Name: ")
last_name =  ask_user("Enter Last Name: ")
values = User(first_name, last_name, city, age)
placement.append(values)
return placement

if __name__ == '__main__':

users = form_complete('user', 'users', 3)
for a in range(len(users)):
users[a].describe_user()


Output

xenial)vash@localhost:~/pcc/9$python3 3.py Enter First Name: vash Enter Last Name: the stampede Enter City: gunsmoke Enter Age: 131 Enter First Name: spike Enter Last Name: spiegel Enter City: mars Enter Age: 27 Enter First Name: holden Enter Last Name: caulfield Enter City: new york city Enter Age: 16 ----- First Name : Vash Last Name : The Stampede City : Gunsmoke Age : 131 Greetings Vash! ----- First Name : Spike Last Name : Spiegel City : Mars Age : 27 Greetings Spike! ----- First Name : Holden Last Name : Caulfield City : New York City Age : 16 Greetings Holden! (xenial)vash@localhost:~/pcc/9$

• @peilonrayz learned about classes today, tried applying somethings we discussed, I feel I was able to capture some things you taught me, thank you! Aug 24 '18 at 19:41

Python has something called magic methods (sometimes also called dunder methods, but the other name is way cooler).

These methods have special names and enable custom classes to use built-in functionality. If, for example you write a custom numeric class, you would want to be able to do e.g. a + b, with at least one of them being an instance of your class (and the other one either as well or even just a plain number). In order to achieve this, you would just implement an appropriate __add__ method for your class.

Here is a good list going through all available magic methods.

In your class, we can use the __str__ method. It gets used when you call str(obj), print(obj), "{}".format(obj) (unless you also implement the __format__ method):

class User:
def __init__(self, first_name, last_name, city, age):
self.first_name = first_name
self.last_name = last_name
self.city = city
self.age = age

def __str__(self):
s = ["-----",
f"First Name : {self.first_name}",
f"Last Name : {self.last_name}",
f"City : {self.city}",
f"Age : {self.age}"]
return "\n".join(s)


Note that I made some more changes:

• The empty parenthesis after the class name are not needed. You only need parenthesis if you want to inherit from some other class.
• I also called the first argument of the methods self, which is the customary name for it in Python.
• I did not build the string using simple addition, since that is quite slow in Python (strings are immutable objects, so each string addition involves creating a new string of the right length and copying the content of the two strings being added).
• And finally, I used f-strings to make the formatting a bit easier.

In your form_complete function (which IMO should be called complete_form, since that describes an action), you could use a list comprehension:

def complete_form(n_users):
for _ in range(n_users)]


Note that I moved the alls to str.title here, since it should be the responsibility of the user of your class to pass in correct values (for example, what if your user enters a name for which title() does not make sense? There are also names that start with lowercase letters. Etc...)

I also removed values and placement from the signature, since you override them right away anyways.

And finally, I added a keyword argument to ask_user, which allows you to validate that age is actually an integer:

def ask_user(message='', type=str):
user_input = ''
while not user_input:
try:
user_input = type(input(message).strip())
except ValueError:
continue
return user_input


By default, this just calls the str function on whatever your user supplied. If you instead specify type=int, it will call int on the input, which raises a ValueError if it cannot parse the input it received as an int.

This has only one weakness right now: If the user wants to enter something that parses as 0, they are stuck in an infinite loop (so no users under the age of 1 allowed).

I also added a call to str.strip, so user names like (space) and (tab) are not allowed either.

• amazing, its like my python learning book gets a new chapter each time you respond, I'm going to review this, and learn it. Again it really is an understatement, how valuable a tool it is to have people like you that aren't hoarding knowledge and check in on us beginners and boost us. Thank you so much, I was super anxious for a response to learn from yesterday, I have been awake for 5 minutes now this was the first thing I checked ha This made my day so far Aug 25 '18 at 13:33