I am trying to read values that were stored in mydict. I keep getting invalid response when running the program. The Excel sheet is formatted by year, location, id, power, and isload. My goal is to print the information associated all the information based off the year and location number.
data = list(csv.reader(open(LOAD_GEN_DATAFILE)))
# read the entire CSV into Python.
# assume CSV has columns as described in the doc string
keyinput=input("Select Year of Study: ")
year=keyinput
mydict={"locA":1,"locb":2}
keyinput2=input(" Select the number associated to the TLA Pocket Location:")
if keyinput2 in mydict:
location=keyinput2
else:
print("Invalid Number")
for year,location,bus,change,isload in data:
# convert the types from string to Python numbers
change= float(change)
bus = int(bus)
if isload.isdigit() and int(isload):
print()
else:
exit
I suspect that you are putting in a number (example 2) and expecting the dictionary to tell you if that value is in the dict or not. However the dictionaries "in" operator works on keys, not values.
Consider this:
mydict = {"a" : 1, "b": 2}
print("Is 1 in mydict? ", 1 in mydict)
print("Is a in mydict? ", "a" in mydict)
print("Is 1 in mydicts values? ", 1 in mydict.values())
Output:
Is 1 in mydict? False
Is a in mydict? True
Is 1 in mydicts values? True
Keep in mind that asking whether a value is in a dict or not is a O(n) operation, the program may have to look at every value in order to determine if that value is in the dictionary or not. However asking if a key is in a dictionary is O(1) (very fast).
If you are always looking up the location based on the number, consider switching the keys/values of your dict around like this:
mydict={1:"locA",2:"locb"}
I don't know much about reading from an excel document or about the nature of the data you have, but assuming your for loop works, here is how you might load the values into the dict:
data = list(csv.reader(open(LOAD_GEN_DATAFILE)))
mydict = {}
for row in data:
year,location,bus,change,isload = row[0:5]
# convert the types from string to Python numbers
change= float(change)
bus = int(bus)
# If this is a year not seen before, add it to the dictionary
if year not in mydict:
mydict[year] = {}
busses_in_year = mydict[year]
if location not in busses_in_year:
busses_in_year[location] = []
# Add the bus to the list of busses that stop at this location
busses_in_year[location].append((bus, change, isload))
# assume CSV has columns as described in the doc string
year = input("Select Year of Study: ")
location = input(" Select the number associated to the TLA Pocket Location:")
if year in mydict and location in mydict[year]:
busses_in_year = mydict[year]
print("Here are all the busses at that location for that year: ")
for bus in busses_in_year[location]:
print(bus)
else:
print("Invalid Year or Location")
Since you are using two keys to group/access the data, you can use nested dictionaries to solve this. Note the syntax to put things into and access things from a dictionary is dict_name[key] = value and value = dict_name[key] respectively.
Related
The first piece of code works great to make a user input dictionary. In the code below and after that I try to make a list that includes only the users whose age is under 20 years old from out of the input dictionary to return a message that references their name to say "[name] is under 20 years old."
#Make a dictionary for 5 users' input
user_info = {}
for i in range(5):
name, user_info[name] = input('Enter name: '), int(input('Enter age: '))
print(user_info)
Here's where I'm hung up. I keep getting:
TypeError: '<' not supported between instances of 'str' and 'int'
I'm trying to iterate through the list of keys and separate out the data I want from that I don't need.
#Print a message for all users under age 20
under_users = []
for user_info[name] in user_info:
if user_info[name]< 20:
under_users.append(user_info[name])
continue
else:
break
print(f"{name} is younger than 20 years old.")
I am still learning how to apply while loops. Any help much appreciated.
You need to traverse through the dictionary. Don't use the dictionary itself to traverse. Use a separate variable like i.
for i in user_info:
if user_info[i]< 20:
print(f"{i} is younger than 20 years old.")
If you need to make a list. You can still do that.
When you are traversing through a dictionary, you are accessing its key. In your case, name of the person is key itself. And when u pass that key to dictionary, you get to access the value. In your case the age is the value itself.
Note that i is the key in my code. I am using it to traverse the dictionary. And user_info[i] is the value I get after passing the key i to the dictionary user_info.
Dictionary class has an inbuilt method items(). This method produces an iterable object which can be traversed using two variables to acces both key and value at the same time.
for key, value in user_info.items():
if value < 20:
print(f"{key} is younger than 20 years old.")
If u don't like passing the key to the dictionary again & again!
There's a pythonic way of doing this:
print(*[f'{key} is younger than 20 years old' for key, value in user_info.items() if value < 20], sep='\n')
You cannot apply a string as a index in python.
When you do user_info[name] you mean "name"
Instead do dictionary..items() functions to get key and value of each index.
See what we'll do here is we'll take each pair in the dictionary into key and value variables and then used them to operate over them
user_info = {}
for i in range(0,5):
name, user_info[name] = input('Enter name: '), int(input('Enter age: '))
print(user_info)
under_users = []
for key,value in user_info.items():
if user_info[key]< 20:
under_users.append(user_info[key])
continue
else:
print(f"{key} is younger than 20 years old.")
print(under_users)
Try this
under_users = []
for name, age in list(user_info.items()):
if age < 20:
under_users.append(name)
print(f"{name} is younger than 20 years old.")
The problem with your code are the following.
for user_info[name] in user_info - If user_info = {"Anne": 25, "Bob":3}, then the first time you enter the loop, user_info[name]
becomes the first key of the dictionary, i.e. user_info[name] = 'Anne' So in the if-condition, you are comparing 'Anne' to 20.
Next is that if you break at else, the first time you encounter
someone aged >= 20, you will exit the loop without going through the
rest of the dictionary. So you do not need the else.
Lastly, the print(f"{name} is younger than 20 years old.") will
need to be nested under the if age < 20. Otherwise you will print
just the age of the last person in the dict. On that note, you do
not need the continue there because no code after the continue
will be executed for that iteration of the loop and the even without
the continue, the loop will continue as long as the condition is
true, which in this case means that as long as there are elements in
user_info.
You can't compare a string and an integer. If I ask you, which is greater, 100 or 50? You'll obviously answer 100.
But if I ask you, which is greater, "Hello World!" or 127, what will you say?
Check whether the age is less than 20, you can't check whether the name is less than 20.
#Make a dictionary for 5 users' input
infos = []
for i in range(5):
inputs = {"name": input("Name:"), "age": input("Age: ")}
infos.append(inputs)
#Print a message for all users under age 20
under_users = []
for i in infos:
if i["age"] < 20:
under_users.append(i["name"])
print("The people under 20 are:")
print(under_users)
Also, in your second loop, you ran break under the else block. So if somebody would have been more than 20, it would stop checking and other people younger than 20 would have been ignored.
Read these:
Dictionaries in Python
Break statements in Python
Python control flow tools
This question already has answers here:
convert tuple keys of dict into a new dict
(3 answers)
Closed 6 years ago.
Apologies it appears my original explanation wasn't clear so I've updated the below as best I can.
I have created a dictionary from a list of fields and a fixed width file of data by slicing the data file up.
data_format_keys = {
("CURRENT-RATIO", 120, 127),
("ACID-TEST", 127, 134),
("NOTES", 134, 154
}
When printing this out I get the following...
Current Ratio = 1234
Acid Test = 5678
Notes = These are my notes
For the data in Current Ratio (1234) and Acid test (5678) I need to convert the strings to numerics and insert decimal points for use in calculations (these fields are from a mainframe file so are so need to be converted to the correct formats).
The expected output is...
Current Ratio = 12.34 #This is an integer/float
Acid Test = 5.678 #This is an integer/float
Notes = These are my notes #This is still a string
I've created a list of fields that need to be converted from the original list but I'm struggling with how to apply the conversion
for k,v in data_format_keys.items():
if k in data_format_keys == headerdict[i[1]]:
line = line.replace(k, v)
fo.write(line)
print(headerdict)
Where headerdict is the initial dictionary created and data_format_keys is the list of fields for converting.
Any thoughts?
Thanks
You can use formatted output if you like.
Here is an example:
#Inputs
meal_cost = float(input("Enter meal price: "))
drink_cost = float(input("Enter drinks cost: "))
#Calculation
total_cost = meal_cost + drink_cost
#Output
print("Your total bill is {:.2f} USD".format(total_cost))
Your output will look like this:
Enter meal price: 7.49
Enter drinks cost: 2.99
Your total bill is 10.48 USD
Let me know if this helped. :)
Try this:
#createlist from current output
thelist = [('Current Ratio', 1234), ('Acid Test', 5678), ('Notes', 'These are my notes') ]
#create dict with just notes
notes = dict([i for i in thelist if i[0] == "Notes"])
#create list without notes
thelist = [i for i in thelist if i[0] != "Notes"]
#create list of keys
thelist1 = [i[0] for i in thelist]
#create list of formatted numbers
thelist2 = [float(i[1]/100) for i in thelist]
#merge into dict
thelist = dict(zip(thelist1, thelist2))
#create empty dict
desired = {}
#update dict with previously created dicts
desired.update(thelist)
desired.update(notes)
print (desired)
Someone better at python may be able to write more efficient code, but this should be a good starting point.
bank = {'id':{'moneys':{}}}
with open(bankID.txt, 'r') as a:
for key in a.readlines():
bank['id']=[str(key)[0:3]]
with open(banknumbers.txt) as b:
for value in b.readlines():
bankID = value[0:3]
bankMoney = int(value[4:9])
if bank['id'] == bankID:
bank['id]['money']= bankMoney
#bank[bankID] = bankMoney <--this one kinda works but it isnt right.
#an example of the 2nd txt file would look like
#234 8763 so id number and money respectively
How come my first forloop does not assign all my id with a key. when I print (bank['id']) the only value that comes out is the first key read.
In my first txt file it only has the bank id and the second txt file has the bank id and the amount of money after it. I cant seem to figure out how to compare the bank id of my dictionary and the bank id of the 2nd txt file and assign the value for money.
So I want the output to look like {'875': 234,'576': 345, '676': 8837}
How come my first forloop does not assign all my id with a key.
Because you're telling it to assign the key "id" the value [str(key)[0:3]]
So you wind up with exactly one key, the string literal "id" and whatever the last value of [str(key)[0:3]] was.
You don't actually need a dictionary within a dictionary unless you have 3 values to keep track of, like a bankId, transactionId and amount.
Suppose banknumbers.txt looked like this instead:
# 234 8763 44.55 -- so a bank number, a transaction number and some money.
This would give you a dictionary within a dictionary for that:
bank = {}
with open(bankID.txt, 'r') as a:
for key in a.readlines():
bank[str(key)[0:3]] = {}
with open(banknumbers.txt) as b:
for value in b.readlines():
bankID = value[0:3]
transactionId = int(value[4:9])
money = float(value(9:19))
bank[bankID][transactionId] = money
You should probably go read the relevant section of the python tutorial: https://docs.python.org/2/tutorial/datastructures.html#dictionaries
I think you're misunderstanding dictionaries. You're overwriting bank['id'] every iteration in the for loop. I'm not exactly sure what you want, but you may want to have a list of banks. The code would be:
bank = []
with open(bankID.txt, 'r') as a:
for key in a.readlines():
bank.append({'id':[str(key)[0:3]], 'moneys': 0})
with open(banknumbers.txt) as b:
for value in b.readlines():
bankID = value[0:3]
bankMoney = int(value[4:9])
for bnk in bank:
if bnk['id'] == bankID:
bnk['money'] = bankMoney
I run into a problem when attempting to solve this task so I'm here after failing a few times, I was wondering how could I only print the highest value(score) for a key (name) when a key stores multipile values such as:
Rob Scored: 3,5,6,2,8
Martin Scored: 4,3,1,5,6,2
Tom Scored: 7,2,8
The name being the key and the scores being the values. Now I wish to get an output of
Martin Scored: 6
Rob Scored: 8
Tom Scored: 8
However when I attempted the max function it would ignore the alphabetical order. Just as a side not that is a requirement as well as the fact that the other scores must be kept stored for later stages.
from collections import OrderedDict
dictionary = {}
for line in f:
firstpart, secondpart = line.strip().split(':')
dictionary[firstpart.strip()] = secondpart.strip()
columns = line.split(": ")
letters = columns[0]
numbers = columns[1].strip()
if d.get(letters):
d[letters].append(numbers)
else:
d[letters] = list(numbers)
sorted_dict = OrderedDict(
sorted((key, list(sorted(vals, reverse=True)))
for key, vals in d.items()))
print (sorted_dict)
This does what you want:
# You don't need to use an OrderedDict if you only want to display in
# sorted order once
score_dict = {} # try using a more descriptive variable name
with open('score_file.txt') as infile:
for line in infile:
name_field, scores = line.split(':') # split the line
name = name_field.split()[0] # split the name field and keep
# just the name
# grab all the scores, strip off whitespace, convert to int
scores = [int(score.strip()) for score in scores.split(',')]
# store name and scores in dictionary
score_dict[name] = scores
# if names can appear multiple times in the input file,
# use this instead of your current if statement:
#
# score_dict.setdefault(name, []).extend(scores)
# now we sort the dictionary keys alphabetically and print the corresponding
# values
for name in sorted(score_dict.keys()):
print("{} Scored: {}".format(name, max(score_dict[name])))
Please give this document a read: Code Like a Pythonista. It has a lot of suggestions for how to write better code, and it is where I learned the dict.setdefault() method for dealing with dictionaries where the values are lists.
On another note, in your question, you referred to an attempt to use the max function, but that function isn't anywhere in the code you provided. If you refer to failed attempts to accomplish something in your question, you should include the failed code as well so we can help you debug it. I was able to give you some code that accomplishes your task along with some other suggestions, but I can't debug your original code if you don't provide it. Since this is obviously a homework question, you should definitely spend some time figuring out why it didn't work in the first place.
I'm trying to complete a Project that will show total annual sales from an specific list contained in a .txt file.
The list is formatted this way:
-lastname, firstname (string)
-45.7 (float)
-456.4 (float)
-345.5 (float)
-lastname2, firstname2 (string)
-3354.7 (float)
-54.6 (float)
-56.2 (float)
-lastname3, firstname3 (string)
-76.6 (float)
-34.2 (float)
-48.2 (float)
And so on.... Actually, 7 different "employees" followed by 12 set of "numbers" (months of the year)....but that example should suffice to give an idea of what I'm trying to do.
I need to output this specific information of every "employee"
-Name of employee
-Total Sum (sum of the 12 numbers in the list)
So my logic is taking me to this conclusion, but I don't know where to start:
Create 7 different arrays to store each "employee" data.
With this logic, I need to split the main list into independent arrays so I can work with them.
How can this be achieved? And also, if I don't have a predefined number of employees (but a defined format :: "Name" followed by 12 months of numbers)...how can I achieve this?
I'm sure I can figure once I get an idea how to "split" a list in different sections -- Every 13 lines?
Yes, at every thirteenth line you'd have the information of an employee.
However, instead of using twelve different lists, you can use a dictionary of lists, so that you wouldn't have to worry about the number of employees.
And you can either use a parameter on the number of lines directed to each employee.
You could do the following:
infile = open("file.txt", "rt")
employee = dict()
name = infile.readline().strip()
while name:
employee[name] = list()
for i in xrange(1, 12):
val = float(infile.readline().strip())
employee[name].append(val)
name = infile.readline().strip()
Some ways to access dictionary entries:
for name, months in employee.items():
print name
print months
for name in employee.keys():
print name
print employee[name]
for months in employee.values():
print months
for name, months in (employee.keys(), employee.values()):
print name
print months
The entire process goes as follows:
infile = open("file.txt", "rt")
employee = dict()
name = infile.readline().strip()
while name:
val = 0.0
for i in xrange(1, 12):
val += float(infile.readline().strip())
employee[name] = val
print ">>> Employee:", name, " -- salary:", str(employee[name])
name = infile.readline().strip()
Sorry for being round the bush, somehow (:
Here is option.
Not good, but still brute option.
summed = 0
with open("file.txt", "rt") as f:
print f.readline() # We print first line (first man)
for line in f:
# then we suppose every line is float.
try:
# convert to float
value = float(line.strip())
# add to sum
summed += value
# If it does not convert, then it is next person
except ValueError:
# print sum for previous person
print summed
# print new name
print line
# reset sum
summed = 0
# on end of file there is no errors, so we print lst result
print summed
since you need more flexibility, there is another option:
data = {} # dict: list of all values for person by person name
with open("file.txt", "rt") as f:
data_key = f.readline() # We remember first line (first man)
data[data_key] = [] # empty list of values
for line in f:
# then we suppose every line is float.
try:
# convert to float
value = float(line.strip())
# add to data
data[data_key].append(value)
# If it does not convert, then it is next person
except ValueError:
# next person's name
data_key = line
# new list
data[data_key] = []
Q: let's say that I want to print a '2% bonus' to employees that made more than 7000 in total sales (12 months)
for employee, stats in data.iteritems():
if sum(stats) > 7000:
print employee + " done 7000 in total sales! need 2% bonus"
I would not create 7 different arrays. I would create some sort of data structure to hold all the relevant information for one employee in one data type (this is python, but surely you can create data structures in python as well).
Then, as you process the data for each employee, all you have to do is iterate over one array of employee data elements. That way, it's much easier to keep track of the indices of the data (or maybe even eliminates the need to!).
This is especially helpful if you want to sort the data somehow. That way, you'd only have to sort one array instead of 7.