How can I store the users' data properly? - python

I am restoring data for users' in a nested dictionary as follows:
user_dict = {user_name:{product:amount, product:amount}}
So, user_name is the user's user_name. The product is the what the user put in the basket(e.g. orange juice), and the amount is the amount of a specific product. So, for instance:
user_dict = {"sara" : {"orange juice": 2, "apple juice" : 4}, "ali": {"banana":3}}
what I want to do is that when a user buys some stuff and put them in the (user_dict) then logs out, when the same user logs in again, I want to get the user's basket as follows: let's say sara logged in and put some stuff in her basket(user_dict) then logged out, when sara logs in again, I want to make get sara's information from the (user_dict) in a new dictionary(called basket) like this:
basket = {"orange juice": 2, "apple juice" : 4}
Also, I want to make the basket empty if the user (user_name) who logged in does not have anything in the basket. So, I want to make users' things do not interfere and I do not want to lose any information. I have almost finished my project but this is what I am stuck at, so help me guys, please.
Here are my lines of code for this task:(but the code does not work as I want)
for key in user_dict.keys():
if user_name == key:
key_sto = " "
nested_dict = user_dict[user_name]
val = a.values()
val_in_nested = val[0]
key_in_nested = key_sto.join(a)
basket[key_in_nested] = val_in_nested
elif user_name != key :
basket = {}

I was able to solve the problem, so here is the code.
for key, amount in user_dict.items():
if key == user_name:
basket = amount
if user_name not in user_dict.keys():
basket = {}

Related

Creating a dictionary with multiple user input choices in python

I am creating a dictionary in python in which a user enters his information, such as name and role.
Regarding the last two keys, I would like the user to write a simple letter in the input that corresponds exactly to the options I provide.
Example:
`userData= dict()
userData["name"]=input("Insert your name and last name: ")
userData["role"]=input("What is your role? \nA)Professor \nB) Student [A/B]: ")
#print(userData)`
Then below I'd like to create if statements where if the user enters "A" in the role key, it saves the value as "Professor" in the dictionary, and if he/she/them enters "B" it saves the value as "Student".
I tried writing something like this:
if userData["role"]== "A": userData["role"]== "Professor"
Only, in the dictionary, the value that is saved is "A" and not "Professor".
How can I get the value I want by making the user type only one letter?
Thank you in advance
PS: i'm completely new in Python and this is only an exercise class, please be gentle.
Possible solution is the following:
userData= {}
userData["name"]=input("Insert your name and last name: ")
# start infinite loop until correct role will be entered
while True:
role=input("What is your role? \nA) Professor \nB) Student\n").upper()
if role == 'A':
userData["role"] = "Professor"
break
elif role == 'B':
userData["role"] = "Student"
break
else:
print(f"{role} is incorrect role. Please enter correct role A or B")
continue
print(userData)
Prints
Insert your name and last name: Gray
What is your role?
A) Professor
B) Student
B
{'name': 'Gray', 'role': 'Student'}
Another solution that does not require the use of if statements is using another dictionary for role entries.
# define roles dict
roles_dict = {"A": "Professor", "B":"Student"}
# get user data
userData= dict()
userData["name"]=input("Insert your name and last name: ")
role_letter=input("What is your role? \nA) Professor \nB) Student [A/B]: ")
# update dict
userData.update({"role": roles_dict[role_letter]})
print(userData)
Prints:
Insert your name and last name: Jayson
What is your role?
A)Professor
B) Student [A/B]: A
{'name': 'Jayson', 'role': 'Professor'}

Grab a User ID from a dict (Discord.py)

I've been getting the hang of Discord.py lately. Managing dictionaries, bot arguments, all that jazz. To finish off point management in my bot, I want to make a leaderboard. Following this answer, i structured my code slightly differently from them.
#bot.command(pass_context=True)
async def testboard(ctx, top:int=10):
total=[]
total = sorted(total,reverse=True)
board=discord.Embed(title = f'Top {top} highest awarded monkes.')
index = 1
if index == top:
return
else:
index += 1
for str in points:
userid = points[str]
user= bot.get_user(userid)
if index==1:
badge="\U0001F947"
elif index==2:
badge="\U0001F948"
elif index==3:
badge="\U0001F949"
else:
badge="\U0001F539"
board.add_field(name=f"**{badge}{index}. {user}**",value=(f"{points[str]} points"), inline=False)
await ctx.send(embed=board)
While it does display the points stored in my database, it doesn't do it from greatest to least, and doesn't display the name of the user.
As seen here: Result
I suspect it's because how my dictionary is structured.
{"userid": 0, "userid": 8, "userid": 0, "userid": 35, "userid": 11, "userid": 6}
Perhaps I can grab the name of the variable? If so, how can I do that?
The reason the username is just showing up as "None" is this portion of the code:
userid = points[str]
user= bot.get_user(userid)
If the str variable from the for loop is the user id, then the userid variable you are creating here is the point score for that user, not the id itself, so bot.get_user returns None because it won't find a user with, for example, an ID of 0. Change those lines to the following:
user= bot.get_user(int(str))
Secondly, the points are not in order because dictionaries are not ordered at all, so you would have to sort the objects manually. One way to do that is to get the entries of the dictionary, including both the key (the userid) and the value (number of points), sort it by points, and then iterate through it in a for loop:
for (userid, score) in sorted(points.items(), key=lambda entry: entry[1], reverse=True):
user= bot.get_user(int(userid))
if index==1:
badge="\U0001F947"
elif index==2:
badge="\U0001F948"
elif index==3:
badge="\U0001F949"
else:
badge="\U0001F539"
board.add_field(name=f"**{badge}{index}. {user}**",value=(f"{score} points"), inline=False)
I changed a couple of variable names here, most importantly str which is the class name for the string type, so it could potentially cause conflicts. Also, per your comment, the get_user method seems to require an integer and won't do conversion automatically.

Way to store user input data to be called later in Python?

New to Python and am working on a task my friend gave me. The objective for this portion is to find user information that was previously added to a dictionary. I am trying to find a way that if the user is searching for a particular user, only that user's info will be returned. So far this is the code I have for this portion of the project:
selection = input('Please select an option 1 - 4:\t')
if selection == '1':
print('Add user - Enter the information for the new user:\t')
first_name = input('First name:\t')
last_name = input('Last name:\t')
hair_color = input('Hair color:\t')
eye_color = input('Eye color:\t')
age = input('Age:\t')
user_info = {}
user_info['First name'] = first_name
user_info['Last name'] = last_name
user_info['Hair color'] = hair_color
user_info['Eye color'] = eye_color
user_info['Age'] = age
Skipping code for sake of space on post
if selection == '3':
print('\nChoose how to look up a user')
print('1 - First name')
print('2 - Last name')
print('3 - Hair color')
print('4 - Eye color')
print('5 - Age')
print('6 - Exit to main menu\n')
search_option = input('Enter option:\t')
if search_option == '1' or search_option == 'First name' or search_option == 'first name':
input('Enter the first name of the user you are looking for:\t')
Any and all help is much appreciated!!
Depending on your project, using a dictionary might be difficult in the future. Let's not go down a dark road. Take a moment and assess the situation.
We know that we want to collect some information from the user, such as:
first name
last name
hair color
...etc
We also want to store the User object to retrieve later based on a particular ID. In your code, you search for other users based on attributes, but what if two or more users share the same attribute, for example, first name?
What your asking for are attributes associated with a particular user. Why not create a class called User?
class User:
def __init__(self, id, first_name, last_name, hair_color):
# You can also check if any attributes are blank and throw an exception.
self._id = id
self._first_name = first_name
self._last_name = last_name
self._hair_color = hair_color
# add more attributes if you want
# a getter to access the self._id property
#property
def id(self):
return self._id
def __str__(self):
return f"ID: {self._id} Name: {self._first_name} {self._last_name}
Hair Color: {self._hair_color}"
In your main function, you can now ask for the user details and store them in a class which you can append to a List.
from User import User
def ask_for_input(question):
answer = input(question)
return answer.strip() # strip any user created white space.
def main():
# Store our users
users = []
# Collect the user info
id = ask_for_input(question = "ID ")
first_name = ask_for_input(question = "First Name ")
last_name = ask_for_input(question = "Last Name ")
hair_color= ask_for_input(question = "Hair Color ")
# Create our user object
user = User(id=id, first_name=first_name, last_name=last_name, hair_color=hair_color)
print(user)
# accessing the id property
print(user.id)
users.append(user)
if __name__ == '__main__':
main()
You may also want to improve on the above class, for example, error checking, and adding type hints to make the code more readable.
If you're just storing the user information, a data class might be more appropriate.
If your looking for a broad suggestion, you could use mongob, it makes a great way to store data to be retrieved later, here is an example i built for another question. The prerequisites is that you'd have to get the mongod server running before you can use the pip install:
Here is an example of how to get it going and how easy it easy to retrieve data like yours
pip3 install pymongo
from pymongo import MongoClient
client = MongoClient()
client = MongoClient('localhost', 27017)
db = client.pymongo_test
posts = db.posts
post_data = {
'title': 'The title of this post',
'content': 'pymongo is awesome',
'author': 'Bill'
}
result = posts.insert_one(post_data)
print('One post: {0}'.format(result.inserted_id))
bills_post = posts.find_one({'author': 'Bill'})
print(bills_post)
#One post: 5dc61c0cc2b75ebc458da31f
#{'_id': ObjectId('5dc61bf76071bde943ca262b'), 'title': 'The title of this post', 'content': 'pymongo is awesome', 'author': 'Bill'}

Django: How to query for child, granchildren, etc. records in a non-horrible way

I am trying to return a list/filter of users in my Employees table that have a nested relationship to the user. For example, I have employees tied to their manager, and I want to be able to query for all the employees under that manager (this includes any employees under any other managers that are under the main manager). So, if user Bob has 2 direct reports, Sally and Brian. And Brian has 2 direct reports, and Sally has 3 direct reports. I want Bob to be able to see all 7 employees. Right now, the only way I could get it to work was through a horrible sequence, as displayed below..I'm hoping their is an easier/more efficient way.
manager = Employees.objects.filter(manager_id=request.user.id).values('manager')
employee_ids = list(Employees.objects.filter(manager=manager.first()['manager']).values_list('employee', flat=True))
employees = [User.objects.get(id=i).username for i in employee_ids]
grandchildren = []
for i in employees:
user_id = User.objects.get(username=i).id
child = list(Employees.objects.filter(manager=user_id).values_list('employee', flat=True))
grandchildren.append(child)
children = list(chain.from_iterable(grandchildren))
for i in children:
user_id = User.objects.get(id=i).id
child = list(Employees.objects.filter(manager=user_id).values_list('employee', flat=True))
grandchildren.append(child)
grandchildren = list(chain.from_iterable(grandchildren))
for i in grandchildren:
employees.append(User.objects.get(id=i).username)
employees = list(set(employees))
Sorry, but your code looks really horrible. First of all, I mean too many DB queries (most of them are very non-optimized or not even needed).
According to your description, I suggest to try something like this:
manager_id = request.user.id
children_ids = list(
Employees.objects.filter(manager_id=manager_id).values_list('employee', flat=True)
)
grandchildren_ids = list(
Employees.objects.filter(manager_id__in=children_ids).values_list('employee', flat=True)
)
# If you want to go deeper, do this in a loop and stop once an empty list of IDs is fetched
# (which means that there are no descendants anymore)
# Combine all IDs and finally fetch the actual users
# (do it only once, and fetch all the users in a single query, not one by one)
employees_ids = children_ids + grandchildren_ids
employees = User.objects.filter(id__in=employees_ids)
P.S.: is this a joke user_id = User.objects.get(id=i).id? :)

Query Django models

I am trying to create a query using django models. I have 4 models. The functionality is to display all a person's facebook friends that are not already friends and do not have a friend request waiting.
CustomUserFriends
id,
from_customuser_id,
to_customuser_id,
FacebookProfile
id,
facebook_id,
custom_user_id
CustomUser
id,
name,
FriendRequests
id,
requester (user_id of the person requesting),
requestee (user_id of the person requested),
Now I have a list of facebook ids as a variable example
facebook_ids = [12123,45433,455664,44445]
Essentially the query im trying to create through django models is select all customusers that have a facebook id in the facebookprofile table but do not have the relationship of being a friend with the user already or have a pending friend request.
A friend is defined as having 2 records in the CustomUserFriends table, example
a friend relationship is
CustomUsers
id
1
2
CustomUserFriends
id from_custom_user_id to_custom_user_id
1 1 2
2 2 1
So, I wasn't entirely sure what you were trying to accomplish here. It was a toss up between getting all non-friends for a particular user or having a particular user and trying to find all of his friends who weren't friends with each other. I decided I'd do both and let you decide which one you wanted.
First, there are two functions. One is the main function we'll be using, the other is just for displaying the info.
def get_non_friends_for_user(u, friend_ids_filter=[]):
# Search the friends lists
friend_ids = list(CustomUserFriends.objects.filter(
from_customuser_id=u.pk).values_list('to_customuser_id', flat=True))
friend_ids += list(CustomUserFriends.objects.filter(
to_customuser_id=u.pk).values_list('from_customuser_id', flat=True))
# Search the requests lists
friend_ids += list(FriendRequests.objects.filter(
requester=u.pk).values_list('requestee', flat=True))
friend_ids += list(FriendRequests.objects.filter(
requestee=u.pk).values_list('requester', flat=True))
non_friends = CustomUser.objects.exclude(id__in=friend_ids)
if friend_ids_filter:
non_friends = non_friends.filter(id__in=friend_ids_filter)
return non_friends
def display_user_info(cu, non_friends):
print
print cuf.name
for non_friend in non_friends:
print '\t', non_friend.name
Now, to get all people who are not friends of a particular user we just use that function
# Get all non-friends for custom_user
# Note that custom_user should be defined before as a CustomUsers object
non_friends = get_non_friends_for_user(custom_user)
display_user_info(custom_user, non_friends)
To get the list of a user's friends that aren't friends with another of the user's friends, we can do this:
# Again, custom_user must already be defined as a CustomUsers object
custom_user_non_friends = {}
custom_user_friends = CustomUserFriends.objects.filter(
from_customuser_id=custom_user.pk)
friend_ids = list(custom_user_friends.values_list('to_customuser_id', flat=True))
for cuf in custom_user_friends:
cu = cuf.to_customuser_id
# Add the queryset to the dictionary
custom_user_non_friends[cu] = get_non_friends_for_user(cu, friend_ids)
for cu, non_friends in custom_user_non_friends.items():
display_user_info(cu, non_friends)
And that should do it. I haven't tested any of this and it's all pretty much coming off the top of my head, so there may be some bugs. If it doesn't work for you or it's not what you were looking for, just post a comment and I'll see what I can do.

Categories

Resources