Converting user input to variable names (python 2.7) - python

Let's say Bob enters his name, 'Bob Jones,' into a Tkinter text entry field. Later, I want to be able to access his name like this:
BobJones = {
'name':'Bob Jones',
'pet\'s name':'Fido'
}
How do I make it so I assign whatever Bob inputs as a new variable without having to manually write it in?
Thanks in advance.

To expand on the comments above, I think you'd want something more like this:
# Define the user class - what data do we store about users:
class User(object):
def __init__(self, user_name, first_pet):
self.user_name = user_name
self.first_pet = first_pet
# Now gather the actual list of users
users = []
while someCondition:
user_name, first_pet = getUserDetails()
users.append(User(user_name, first_pet))
# Now we can use it
print "The first users name is:"
print users[0].user_name
So you're defining the class (think of it as a template) for the Users, then creating new User objects, one for each person, and storing them in the users list.

Related

Python - When to create a Class and when to create a Function

Right, so I'm trying to create a Contacts application using Python OOP. I'm fairly new to OOP and still trying to get my head around the concepts.
I understand that a Class is a blueprint for all objects. I like to think of a Class as an entity and each Object is a record of that entity. I am from a Database background so that's why I interpret it like this, feel free to correct me.
Anyways, in the Contacts app I'm making I've created the Class Contacts as outlined below:
class Contacts():
def __init__(self, firstName, lastName, address, groupType,
telephone, mobile, email, photoField):
self.firstName = firstName
self.lastName = lastName
self.address = address
self.groupType = groupType
self.telephone = telephone
self.mobile = mobile
self.email = email
self.photoField = photoField
def showDetails(self):
print("First Name:\t", self.firstName)
print("Last Name:\t", self.lastName)
print("Address:\t", self.address)
print("Telephone:\t", self.telephone)
print("Mobile:\t", self.mobile)
print("Email:\t", self.email)
Now, if I want to add contacts through the Contacts class into the list I'm using to store each contact object, do I have to create an AddContacts class, or do I create a function instead? I don't know if I'm putting my question across well enough for you to understand what I mean?
What I guess I'm trying to say is that adding contacts is a process and if you look at it from a database point of view you wouldn't create a table called "tbl_AddContacts" since you would do that via a query or a stored procedure, so in my view I would define adding contacts being a function. But asking my colleague who does C# programming he says that adding contacts should be defined by a Class.
This is a confusing concept for me, especially since I don't understand how I would link the AddContacts class with the Contacts class, or even how to define an AddContacts class in the first place!.
Here is the function I defined for adding contacts:
def addContacts():
firstName = input("First Name: ")
lastName = input("Last Name: ")
address = input("Address: ")
telephone = input("Telephone: ")
mobile = input("Mobile: ")
email = input("Email: ")
print("\n")
contact = Contacts(firstName, lastName, address, None, telephone, mobile, email, None)
contactsList.append(contact)
pickle.dump(contactsList, open("save.p", "wb"))
Please help me out, since I will turning this into a GUI application (uni assignment).
Adding a contact is doing something, rather than being something, so it would make sense as a method/function rather than a class. I would suggest that your functionality should actually be in two separate places.
Creating a new contact from user input should be a class method of Contact:
class Contact(object):
...
#classmethod
def from_input(cls):
firstName = input("First Name: ")
lastName = input("Last Name: ")
address = input("Address: ")
telephone = input("Telephone: ")
mobile = input("Mobile: ")
email = input("Email: ")
return cls(firstName, lastName, address, None,
telephone, mobile, email, None)
Adding a new contact to the list of contacts should either be:
An instance method of the e.g. AddressBook or ContactList class (or whatever you have holding the contact list); or
A separate function if you don't have a class to hold the Contact instances.
For example:
class AddressBook(object):
...
def add_contact(self, contact=None):
if contact is None:
contact = Contact.from_input()
self.contacts.append(contact)
Now your UI can create a Contact and pass it straight to address_book.add_contact().
First, your Contacts class is more appropriately called Contact, since it only represents a single contact. Your addContacts options can either be a standalone function, or you could make it part of a ContactList class, which manages your list of Contact objects.
class ContactList():
def __int__(self):
self.contact_list = []
def addContact(firstName, lastName, address, telephone, mobile, email):
contact = Contact(firstName, lastName, address, None, telephone, mobile, email, None)
self.contact_list.append(contact)
pickle.dump(contact_list, open("save.p", "wb"))
I would recommend separating the UI interaction piece (all the input() calls) from your function/method, because as you said, eventually this is going to become a GUI app. You should keep the code that's actually getting input from the user separated so you can change it later without having to change any part of Contact or ContactList.

How to get a filed from self.data in model_formset_factory in clean method

I am using modelformset_factory to edit multiple images on my interface.
I have following fields in each image.
Name
User
City
I have allowed user to select new user that is currently not in the system, (for that case I should get a text "Jack" in my
def clean_user(self) instead of ID.
But using model_formseta_factory, I am getting some wired names in my self.data. and when I try to get self.data.get('user'), I get nothing, obviously there is no key with this name,
the key is formed like form_0_user etc.
fields = ['city', 'name']
note, i do not have user in my fields. if I do, it fails the validation.
def clean(self):
data = self.cleaned_data
data['name'] = data.get('name', '').strip()
return data
Works fine
pic_credits = self.data.get('user')
This does not.
pic_credits = self.data.get('form-0-name')
This works fine too.
Please help.
If you want to use self.data instead of self.cleaned_data, you can construct the "composite prefix" using the fields auto_id and prefix (or at least when the form has been instanced by a formset).
See _construct_form() https://docs.djangoproject.com/es/1.9/_modules/django/forms/formsets/
Your method will look like this:
def clean(self):
# ...
form_prefix_and_autoid = "%s-%d-" % (self.prefix, self.auto_id)
pic_credits = self.data.get(form_prefix_and_autoid + 'name')
# ...
Update:
A lot simpler is calling the method self.add_prefix
pic_credits = self.data.get(self.add_prefix('name'))

Overwritting Data in App Engine

I have a function that gets an image from a form, and put's it into the database along with the username. So, here is my database:
class Imagedb(db.Model):
name = db.StringProperty(required = True)
image = db.BlobProperty()
And here is the code that writes to the database:
class Change_Profile_Image(MainHandler):
def get(self):
if self.user:
self.render('change_profile_image.html', username = self.user.name, firstname=self.user.first_name)
else:
self.render('change_profile_image.html')
def post(self):
imagedb = Imagedb(name = self.user.name)
imageupl = self.request.get("img")
imagedb.image = db.Blob(imageupl)
imagedb.put()
self.redirect('/profile')
Any who, it works awesome. Except for one thing. What i'm trying to accomplish is only storing ONE profile picture. What ends up happening is this:
Say I am the user admin. Ill upload a display pic, that pic shows in the profile. Ill upload another one, that one shows. Cool, except for the fact that I have 2 objects in my database that have the name = admin attribute. I would like to edit this...
def post(self):
imagedb = Imagedb(name = self.user.name)
imageupl = self.request.get("img")
imagedb.image = db.Blob(imageupl)
imagedb.put()
self.redirect('/profile')
so that I can post images to the database, but if one exists, it is overwritten. Could anyone help me with this please? I'm relatively new to python and app engine.
If something is unclear, please let me know.
You want to set the key of the Imagedb entity to "name". Essentially, you don't need the name field, but you'll instantiate it like
imagedb = Imagedb(key_name = self.user.name)
The key is a required field on all entities. By using your user name as the key it means every time you refere to a given key, it's the same entity.

Access a variable in a method under a class in python

class user_management(wx.Panel):
def login(self):
# Login Function can be later integrated to allow users access to your program
username = self.txt_Username.GetValue()
self.frame.SetStatusText("Welcome "+username+" to the system!!")
test = MyApp(0)
test.MainLoop()
How can i access the variable username within another class:
class wizard(wx.wizard.Wizard):
def on_finished(self, evt):
totalscore = self.totalscore
print "Final score: %s" % (totalscore)
user = "c1021358"
db_file="data/data.db"
database_already_exists = os.path.exists(db_file)
con = sqlite3.connect(db_file)
cur = con.cursor()
sql = "INSERT INTO scores (username,totalscore,topic) VALUES ('%s','%s','%s')" % (user,totalscore,tag)
At the moment the user is static, however I want to make this user variable equal to the username taken from the text field box.
Can anyone tell me how I can do this please?
Thank you
Currently username is a local variable and can't be accessed outside of the method. You could make it a member variable by doing something like self.username instead. It would probably be a good idea to initialize it in an __init__ method.
EDIT: katrielalex has the right idea. You probably want to store the username in something that is not part of your user_management panel. This could either be a global variable, or you could make a user class.
class User:
def __init__(self, username):
self.username = username
# Create a global "current_user", with an initial username of None
current_user = User(None)
Then if you can access the username from the global User object:
def login(self):
global current_user
current_user.username = self.txt_Username.GetValue()
Please note this is all very general (for instance, this assumes you can only support one user at a time), but it should be able to get you started.
Well, you need to store the value of username somewhere that both methods can see. The easiest way to do this, but almost certainly not the right one, is to make it a global variable. You can do that using the global keyword:
global username
username = ...
However, you are almost certainly more likely to want to store it as an attribute of some object. I don't know your architecture so I can't tell you where is best to put it, but something like a User or a Settings object would be good.

How to query datastore when using ReferenceProperty?

I am trying to understand the 1-to-many relationships in datastore; but I fail to understand how query and update the record of a user when the model includes ReferenceProperty. Say I have this model:
class User(db.Model):
userEmail = db.StringProperty()
userScore = db.IntegerProperty(default=0)
class Comment(db.Model):
user = db.ReferenceProperty(User, collection_name="comments")
comment = db.StringProperty()
class Venue(db.Model):
user = db.ReferenceProperty(User, collection_name="venues")
venue = db.StringProperty()
If I understand correctly, the same user, uniquely identified by userEmail can have many comments and may be associated with many venues (restaurants etc.)
Now, let's say the user az#example.com is already in the database and he submits a new entry.
Based on this answer I do something like:
q = User.all()
q.filter("userEmail =", az#example.com)
results = q.fetch(1)
newEntry = results[0]
But I am not clear what this does! What I want to do is to update comment and venue fields which are under class Comment and class Venue.
Can you help me understand how this works? Thanks.
The snippet you posted is doing this (see comments):
q = User.all() # prepare User table for querying
q.filter("userEmail =", "az#example.com") # apply filter, email lookup
- this is a simple where clause
results = q.fetch(1) # execute the query, apply limit 1
the_user = results[0] # the results is a list of objects, grab the first one
After this code the_user will be an object that corresponds to the user record with email "az#example.com". Seing you've set up your reference properties, you can access its comments and venues with the_user.comments and the_user.venues. Some venue of these can be modified, say like this:
some_venue = the_user.venues[0] # the first from the list
some_venue.venue = 'At DC. square'
db.put(some_venue) # the entry will be updated
I suggest that you make a general sweep of the gae documentation that has very good examples, you will find it very helpful:
http://code.google.com/appengine/docs/python/overview.html
** UPDATE **: For adding new venue to user, simply create new venue and assign the queried user object as the venue's user attribute:
new_venue = Venue(venue='Jeferson memorial', user=the_user) # careful with the quoting
db.put(new_venue)
To get all Comments for a given user, filter the user property using the key of the user:
comments = Comment.all().filter("user =", user.key()).fetch(50)
So you could first lookup the user by the email, and then search comments or venues using its key.

Categories

Resources