class print_values:
def __init__(self,username,user_email,displayname):
self.name= username
self.email=user_email
self.DisplayName=displayname
def printing_content(self):
print(f"UserName: {self.name}\n"
f"UserEmail: {self.email}\n"
f"UserDisplayName:{self.DisplayName}\n")
user_one={'username':'userone',
'useremail':'userone#gmail.com',
'displayname':'User One'}
user_two={'username':'usertwo',
'useremail':'usertwo#gmail.com',
'displayname':'User Two'}
user_three={'username':'userthree',
'useremail':'userthree#gmail.com',
'displayname':'User Three'}
users_list=['user_one','user_two','user_three']
obj_name=print_values(user_one['username'],user_one['useremail'],user_one['displayname'])
obj_name.printing_content()
It's working fine, as am getting output as below
UserName: userone
UserEmail: userone#gmail.com
UserDisplayName:User One
Here am only using user_one dict, i want to do the same for multiple dict.
I have tried adding the dict names in list and try to loop through them, like below
for item in user_list:
obj_name=print_values(item['username'],item['useremail'],item['displayname'])
obj_name.printing_content()
But am getting below error
obj_name=print_values(item['username'],item['useremail'],item['displayname'])
TypeError: string indices must be integers
Any one do let me know what am i missing or anyother idea to get this done.
Thanks in advance!
This is because in users_list=['user_one', 'user_two', 'user_three'] you enter the variable name as a string.
class print_values:
def __init__(self,username,user_email,displayname):
self.name= username
self.email=user_email
self.DisplayName=displayname
def printing_content(self):
print(f"UserName: {self.name}\n"
f"UserEmail: {self.email}\n"
f"UserDisplayName:{self.DisplayName}\n")
user_one={'username':'userone',
'useremail':'userone#gmail.com',
'displayname':'User One'}
user_two={'username':'usertwo',
'useremail':'usertwo#gmail.com',
'displayname':'User Two'}
user_three={'username':'userthree',
'useremail':'userthree#gmail.com',
'displayname':'User Three'}
users_list=[user_one,user_two,user_three] # edited
obj_name=print_values(user_one['username'],user_one['useremail'],user_one['displayname'])
obj_name.printing_content()
for item in users_list:
obj_name=print_values(item['username'],item['useremail'],item['displayname'])
obj_name.printing_content()
Explanation
Your users_list=['user_one', 'user_two', 'user_three'] is a string containing the variable names as the string. When you loop on user_list
for item in user_list:
Here item is not the user_one, or user_two as a variable but these are as the string means 'user_one', or 'user_two', so when you try to get values like item['username'], here you got the error because the item is not a dictionary or json or ..., but it is a string here, you can get the only provide an integer inside these brackets [], like 1, 2, 3, 4,..., ∞.
I hope you understand well. Thanks.
Don't make a dictionary for every user.
Use this code
class Users:
def __init__(self) -> None:
self.userList = []
def addUser(self, user):
self.userList.append(user)
class User:
def __init__(self, username, email, name) -> None:
self.username = username
self.email = email
self.name = name
def __str__(self) -> str:
return f"Username = {self.username}\nEmail = {self.email}\nName = {self.name}\n"
users = Users()
users.addUser(User("username1", "email1", "name1"))
users.addUser(User("username2", "email2", "name2"))
# First way of printing
for user in users.userList:
print(user) # Printing user directly prints the formatted output
# Because I have changed the magic `__str__` method in user class
# You can return anything('string data type only') in __str__ it will print when you print the class object.
# Second way of printing.
for user in users.userList:
print("Username = " + user.username)
print("Email = " + user.email)
print("Name = " + user.name)
print() # for adding one extra line
Related
I keep getting the following error and I can't seem to find a solution for it.
if password not in old_passwords:
TypeError: argument of type 'PasswordManager' is not iterable
For clarity, I needed to create a class called 'PasswordManager'. The class should have a list called 'old_passwords'. The list contains all past passwords, the last index of the list should be the current password. The required methods are 'set_password', 'get_password' and 'is_correct'.
'get_password' should return the current password.
'set_password' sets a new password. It should only change the password if the attempted password is different from all the user’s past passwords.
'is_correct' receives a string and returns a boolean True or False depending on whether the string is equal to the current password or not.
class PasswordManager():
old_passwords = []
def get_password(old_passwords):
return old_passwords[len(old_passwords-1)]
def set_password(old_passwords, password):
if password not in old_passwords:
old_passwords.append(password)
def is_correct(old_passwords, password):
if password == old_passwords[len(old_passwords-1)]:
return True
else:
return False
Does anyone have an idea that could help me? Thanks in advance!
I think you need to review how to use classes in python.
Your class needs a constructor, where you can instantiate your class attributes (in your case old_passwords) and you can access them with self.
An example of your use case could be
class PasswordManager():
def __init__(self):
self.old_passwords = []
def get_password(self):
return self.old_passwords[-1]
def set_password(self, password):
if password not in self.old_passwords:
self.old_passwords.append(password)
def is_correct(self, password):
return password == self.old_passwords[-1]
With [-1] you can access the last element of a list.
__init__ is the constructor method in python.
python class methods require first argument as class itself. moreover, you cannot directly access class variables or methods in its methods. need to use something like self.somemethod() or self.somevariable
class PasswordManager():
old_passwords = []
def get_password(self):
return self.old_passwords[-1]
def set_password(self, password):
if password not in self.old_passwords:
self.old_passwords.append(password)
def is_correct(self, password):
if password == self.old_passwords[-1]:
return True
else:
return False
also, you are accessing last item in list wrong way.old_passwords[len(old_passwords-1)] should be old_passwords[len(old_passwords)-1]. but, old_passwords[-1] is better choice.
The following code works fine. But I want to make some modifications.
from pip._vendor.distlib.compat import raw_input
class User():
'''simulates a user for a social network or pc'''
def __init__(self, first_name, last_name, username,location, interests):
'''initialize attributes of user class'''
self.first_name = first_name.title()
self.last_name = last_name.title()
self.username = username
self.location = location.title()
self.interests = interests
#classmethod
def get_userinfo(cls):
'''each attribute of User is defined by a user input'''
return cls(
raw_input("Welcome. PLease Enter Your First Name: "),
raw_input("Please Enter Your Last Name: "),
raw_input("Username: "),
raw_input("What is your location? : "),
raw_input("List some of your interests: ")
)
def __str__(self):
'''returns all attributes of User as strings'''
return str("User: " + self.first_name + self.last_name +
"\nUsername: " + self.username +
"\nLocation: " + self.location +
"\nInterests: " + self.interests)
'''creates an instance of User object'''
user1 = User.get_userinfo()
'''writes each attribute of User into a file'''
filename = r'''C:\Users\User\Documents\dataset1.txt'''
with open(filename, 'r+') as file_object:
contents = file_object.write(str(user1))
I want to make the parameter 'interests' into a tuple or a list. The user should be able to input many interests and decide when to stop through a flag such as 'active = True', and then finally return the results as a string to be able to write it to the file.
Sorry, I don't follow the flag part. But is this what you had in mind? You stop by just entering your items. * I will update if I misunderstood
$ vi test.txt
$ python test.txt
from pip._vendor.distlib.compat import raw_input
class User():
'''simulates a user for a social network or pc'''
def __init__(self, first_name, last_name, username, location, interests):
'''initialize attributes of user class'''
self.first_name = first_name.title()
self.last_name = last_name.title()
self.username = username
self.location = location.title()
self.interests = interests.split(', ')
#classmethod
def get_userinfo(cls):
'''each attribute of User is defined by a user input'''
return cls(
raw_input("Welcome. PLease Enter Your First Name: "),
raw_input("Please Enter Your Last Name: "),
raw_input("Username: "),
raw_input("What is your location? : "),
raw_input("List some of your interests: ")
)
def __str__(self):
'''returns all attributes of User as strings'''
return "User: {0} {1} \nUsername: {2} \nLocation: {3} \nInterests: {4}".format(self.first_name, self.last_name, self.username, self.location, ','.join(self.interests))
'''creates an instance of User object'''
user1 = User.get_userinfo()
print(user1)
$ python test.txt
Welcome. PLease Enter Your First Name: Hi
Please Enter Your Last Name: How
Username: Are
What is your location? : You
List some of your interests: Ball, Tennis, Python
User: Hi How
Username: Are
Location: You
Interests: Ball, Tennis, Python
I want to make the parameter 'interests' into a tuple or a list. The user should be able to input many interests and decide when to stop through a flag such as 'active = True'
I'm not sure how the user is going to set active=True, but the rest of that sentence just screams "I want a loop":
#classmethod
def get_userinfo(cls):
first = raw_input("Welcome. PLease Enter Your First Name: ")
last = raw_input("Please Enter Your Last Name: ")
user = raw_input("Username: ")
location = raw_input("What is your location? : ")
interests = []
print("List some of your interests (just type Return on its own when you're done)")
while True:
interest = raw_input().strip()
if not interest:
break
interests.append(interest)
OK, that gives us a list, not a tuple. We could create a tuple by doing interests = interests + (interest,), but that's clunky and inefficient. If you really need a tuple, it's actually simpler to just build a list and then convert it at the end:
interests = tuple(interests)
And now we can pass all of those variables to the constructor:
return cls(first, last, user, location, interests)
… and then finally return the results as a string to be able to write it to the file.
Hold on; what kind of file are you creating here?
If this file is mean to be read and edited by a human being, and never looked at by Python again, that's easy. You can, e.g., just join them up with spaces, or commas, or newlines, or whatever you want. Or you can manually loop over them to format them more fancily:
def write_to_file(self, filename):
with open(filename, 'w') as file:
file.write('First Name: {}\n'.format(self.first_name))
file.write('Last Name: {}\n'.format(self.last_name))
file.write('Username: {}\n'.format(self.username))
file.write('Location: {}\n'.format(self.location))
file.write('Interests:\n')
for interest in self.interests:
file.write(' {}\n'.format(interest))
But if it's meant to be used for storing data to be read later by Python, you want to write things in a format that's meant to be parsed. Maybe add a method to serialize your objects to and from JSON, for example:
def to_json(self):
return json.dumps({'first': self.first_name, 'last': self.last_name,
'user': self.username, 'location': self.location,
'interests': self.interests})
#classmethod
def from_json(cls, j):
dct = json.loads(j)
return cls(dct['first'], dct['last'], dct['user'],
dct['location'], dct['interests'])
And now, to write it to a file:
with open(filename, 'w') as f:
f.write(user.to_json())
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 6 years ago.
I am trying to incorporate a regex check for user input in my class. I want a scenario where users can't proceed to enter their name until they enter a valid email address. The current code i have isn't working as expected.
I suppose a while-loop is in order here but i am struggling to implement that in this class. Any assistance is much appreciated.
class test:
def __init__(self):
self.email = input("Enter your email: ")
email_check = re.search(r'[\w.-]+#[\w.-]+.\w+', self.email)
if email_check:
print ('email valid')
else:
print ('email not valid')
self.email = input("Enter your email: ")
sys.exit(0)
self.name = input("Enter your name: ")
You can do it like this.
while True:
self.email = input ("Enter email:")
if valid_email:
break
Substitute valid_email with your way of validating the email address.
You may also be interested in Python check for valid email address? for ways to validate an email address.
First of all - you should not implement any activity of this kind into __init__ method, as one is intended for object fields initialization first place. Consider dedicated 'check_email' method, or whatever name applies best.
Now, regarding your case:
class test:
def __init(self):
# whatever initialization applies
pass
def init_emails():
emails = []
proceed = True
# if you really in need of do/while loop
while proceed:
email = self.input_email()
# your logic for input
if email is not None:
emails.append(email)
# invalid input or cancel
else:
proceed = False
return input
def input_email(self):
value = input('Enter your email:')
# TODO: validate/check input
return proper_value
class test:
def __init__(self):
self.email = self.get_name()
def get_name(self) :
while True:
x = input("Enter your email: ")
if (re.search(r'[\w.-]+#[\w.-]+.\w+', x)) :
return x
This script functions as described, in the end printing the name and email. If you need to use python2.7, use raw_input instead of input. I used for i in range instead of while True to avoid an endless loop.
#!/usr/bin/env python3
import re
import sys
class Test(object):
def __init__(self):
self.email = None
self.name = None
def get_email(self):
for i in range(3):
email = input('Enter your email: ')
if re.search('[\w.-]+#[\w.-]+.\w+', email):
return email
print('Too many failed attempts!')
sys.exit(1)
def get_name(self):
for i in range(3):
name = input('Enter your name: ')
if name:
return name
print('Too many failed attempts!')
sys.exit(1)
def initialize(self):
self.email = self.get_email()
self.name = self.get_name()
print('"{}" <{}>'.format(self.name, self.email))
if __name__ == '__main__':
t = Test()
t.initialize()
Instead of input, try to use raw_input. Like this:
self.email = raw_input("Enter your email:")
There'll be no error anymore.
Hope this helps.
I'm fairly new to the world of python and programming in general, and its rare that i get up the nerve to ask questions, but I'm stomped so i thought id suck it up and ask for help.
I'm making an Address book.
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
contact = Person('Mike','1-800-foo-spam','email#email.com')
My question is how would go about storing all these attributes in a dictionary with contact.name as the key and contact.number and contact.email as the values.
Bonus question.
Should the dictionary be outside the class, perhaps in the main function?
or
Does it need to be a class variable(not completely sure how those work)
or an object variable
something like
self.storage = {}
Any help would be greatly appreciated.
Thank you!
If I put this information in a dictionary, I would do it like that:
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
self.storage = {self.name: [self.number, self.email]}
def getStorage(self):
return self.storage
contact = Person('Mike','1-800-foo-spam','email#email.com')
print contact.storage
# or
print contact.getStorage()
But the whole idea of a dictionary is to have a number of keys and corresponding values. In this example, it always will be one only. So, another schema comes to my mind:
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
# creating some example contacts
c1 = Person('Mike','1-800-foo-spam','email#email.com')
c2 = Person('Jim','1-700-foo-spam','e111mail#email.com')
c3 = Person('Kim','1-600-foo-spam','e222mail#email.com')
# creating a dictionary to fill it with c1..cn contacts
contacts = {}
# helper function to automate dictionary filling
def contactToDict(list_of_contacts):
for item in list_of_contacts:
contacts[item.name] = (item.number, item.email)
contactToDict([c1, c2, c3])
"""
expected output:
Mike: ('1-800-foo-spam', 'email#email.com')
Jim: ('1-700-foo-spam', 'e111mail#email.com')
Kim: ('1-600-foo-spam', 'e222mail#email.com')
"""
for key, val in contacts.items():
print str(key) + ": " + str(val)
The answer to the title of the question: a value should be a type of object with allows to have a "list" inside (i.e. list, tuple, another dictionary or custom type object having a number of attributes.)
You can pretty easily have a dictionary with tuples as the values.
a = {}
a["bob"] = ("1-800-whatever","bob#gmail.com")
If you wanted to make it a class variable, you'd just need to create an empty dictionary as part of the Person class:
class Person():
storage = {}
Then in __init__ you can store the new person's info in that dictionary:
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
Person.storage[name] = (number, email)
As you can see class attributes are accessed with the classname, but otherwise like any other attribute. You could store them as a tuple or a list if you need to update them. However if you intend to make changes, it might be better to store the actual Person object, to save having to update Person.storage and the actual person at the same time. This is even easier to do:
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
Person.storage[name] = self
self refers to the instance of Person that's being created with __init__. That's Mike in your example. Then you could access their values by attribute:
Person.storage["Mike"].number
Also as Kevin pointed out in a comment you might want to detect if the key already exists to avoid overwriting an old entry (eg. if there's already a Mike in the dictionary):
self.email = email
if name in Person.storage:
# Make unique name
Person.storage[name] = (number, email)
I'm trying to write a program that creates an address book with contact names, emails, phone numbers, etc. I store each contact as a dictionary and then place each person (dictionary) into a global list. I then convert the list to a string using repr() and write it to a file. When I try to reload the list and write what it contains, I get a list of empty dictionaries. Please help me figure out what is wrong.
Here is my code:
list = []
listfile = 'phonebook.txt'
class bookEntry(dict):
total = 0
def __init__(self):
bookEntry.total += 1
self.d = {}
def __del__(self):
bookEntry.total -= 1
class Person(bookEntry):
def __init__(self, n):
bookEntry.__init__(self)
self.n = n
print '%s has been created' % (self.n)
def addnewperson(self, n, e = '', ph = '', note = ''):
f = file(listfile, 'w')
self.d['name'] = n
self.d['email'] = e
self.d['phone'] = ph
self.d['note'] = note
list.append(self)
listStr = repr(list)
f.write(listStr)
f.close()
I start the program with a startup() function:
def startup():
aor = raw_input('Hello! Would you like to add an entry or retrieve one?')
if aor == 'add':
info = raw_input('Would you like to add a person or a company?')
if info == 'person':
n = raw_input('Please enter this persons name:')
e = raw_input('Please enter this persons email address:')
ph = raw_input('Please enter this persons phone number:')
note = raw_input('Please add any notes if applicable:')
X = Person(n)
X.addnewperson(n, e, ph, note)
startup()
I add these answers to the prompts:
'''
Hello! Would you like to add an entry or retrieve one?add
Would you like to add a person or a company?person
Please enter this persons name:Pig
Please enter this persons email address:pig#brickhouse.com
Please enter this persons phone number:333-333-3333
Please add any notes if applicable:one of three
Pig has been created
'''
When I open phonebook.txt, this is what I see:
[{}]
Why are empty dictionaries being returned?
You're deriving from dict, but storing all the elements in a member d. Hence, repr gives you a string representing an empty dict. If you want to use a bookEntry as a dict, insert the info with
self['name'] = n
instead of
self.d['name'] = n
(But really, you shouldn't be inheriting from dict here. Also, please don't use list as an identifier, it's the name of a builtin.)
you should save self.d instead of self:
alist.append(self.d)
listStr = repr(alist)
f.write(listStr)
btw don't use list as the name of a variable, you are overwritting the keyword list
Your problem is that the X.d dictionary is not the same as the dictionary "bookEntry" is inheriting from. Therefore repr(X) is not showing X.d
A solution might be to override repr in BookEntry:
e.g.
def __repr___(self):
return repr(self.d)