I'm trying to define a function that receive infinite values in dictonary, but the the exit is taking only the characters of the last 2 key and value.
Any suggestion?
def infinityInvent():
infinityInvent = []
while True:
keys = input(f'Enter a item (or blank to stop): ')
values = input(f'What the value? ')
if keys == '':
break
infinityInvent = dict(zip(keys, values)) # or infinityInvent = {k: v for k, v in zip(keys, values)}
infinityInvent()
You need to set an item in the dict, not redefine the dict:
def infinityInvent():
infinityInvent = {}
while True:
key = input(f'Enter a item (or blank to stop): ')
if key == '':
break
value = input(f'What the value? ')
infinityInvent[key] = value
return infinityInvent
print(infinityInvent())
This function will search for anagrams in a list from a .txt file, I want to be able to check for anagrams and return all anagrams of the word that I input, and if it's not an anagram it will return the input, when I do it in the code below, it iterates through the for loop then ignores my first if statement and heads directly to my else statement. How can I fix this?
def find_in_dict():
input_word = input("Enter input string)")
sorted_word = ''.join(sorted(input_word.strip()))
a_word = ''.join((input_word.strip()))
word_file = open("filename", "r")
word_list = {}
for text in word_file:
simple_text = ''.join(sorted(text.strip()))
word_list.update({text.strip(): simple_text})
alist = []
for key, val in word_list.items():
if val == sorted_word:
alist.append(key)
return alist
else:
return "No words can be formed from:" + a_word
you are making a return statement in the if and else branch, that will break the for (because return invoked inside a function do exactly that, interrupt the execution and return the value) , so, don't do that, just ask if the word is equal, and in the end, check if there is none occurrences (empty list)
for text in word_file:
simple_text = ''.join(sorted(text.strip()))
word_list.update({text.strip(): simple_text})
alist = []
for key, val in word_list.items():
if val == sorted_word:
alist.append(key)
if alist == []: print("No words can be formed from: " + a_word)
I am reading data from file, like listed below, it is a .dat file:
1
Carmella Henderson
24.52
13.5
21.76
2
Christal Piper
14.98
11.01
21.75
3
Erma Park
12.11
13.51
18.18
4
Dorita Griffin
20.05
10.39
21.35
The file itself contains 50 records. From this data I need the person number, name and the first number, like so:
1 #person number
Marlon Holmes #Name
18.86 # First number
13.02 # Second Number
13.36 # Third Number
I already have code to read the data however I unable to get the top 10 results based on the #First number
The #First number in the Top 10 currently is in centimeters but needs to be converted to inches, I am unsure on how to combine the top 10 and conversion into one alongside the reading of the data
Code that reads the data:
with open('veggies_2016.txt', 'r') as f:
count = 0
excess_count = 0
for line in f:
if count < 3:
print(line)
count += 1
elif count == 3 and excess_count < 1:
excess_count += 1
else:
count = 0
excess_count = 0
As mentioned the code reads the file, like so #Person number, #name and #first number, but #first number needs to be converted to inches and then all of the data needs to be sorted to find the top 10
This process will also have to be repeated for #second number and #third number however they are separate in terms of their code from #first number
I have tried to read the data then append to a list and sort it and convert it from that but with no success, any help would be appreciated
Whole code:
from collections import OrderedDict
from operator import itemgetter
import pprint
def menu():
exit = False
while not exit:
print("To enter new competitior data, type new")
print("To view the competition score boards, type Scoreboard")
print("To view the Best Overall Growers Scoreboard, type Podium")
print("To review this years and previous data, type Data review")
print("Type quit to exit the program")
choice = raw_input("Which option would you like?")
if choice == 'new':
new_competitor()
elif choice == 'Scoreboard':
scoreboard_menu()
elif choice == 'Podium':
podium_place()
elif choice == 'Data review':
data_review()
elif choice == 'quit':
print("Goodbye")
raise SystemExit
"""Entering new competitor data: record competitor's name and vegtables lengths"""
def competitor_data():
global competitor_num
l = []
print("How many competitors would you like to enter?")
competitors = raw_input("Number of competitors:")
num_competitors = int(competitors)
for i in range(num_competitors):
name = raw_input("Enter competitor name:")
Cucumber = raw_input("Enter length of Cucumber:")
Carrot = raw_input("Enter length of Carrot:")
Runner_Beans = raw_input("Enter length of Runner Beans:")
l.append(competitor_num)
l.append(name)
l.append(Cucumber)
l.append(Carrot)
l.append(Runner_Beans)
competitor_num += 1
return (l)
def new_competitor():
with open('veggies_2016.txt', 'a') as f:
for item in competitor_data():
f.write("%s\n" %(item))
def scoreboard_menu():
exit = False
print("Which vegetable would you like the scoreboard for?")
vegetable = raw_input("Please type either Cucumber, Carrot or Runner Beans:")
if vegetable == "Cucumber":
Cucumber_Scoreboard()
elif vegetable == "Carrot":
Carrot_Scoreboard()
elif vegetable == "Runner Beans":
Runner_Beans_Scoreboard()
def Cucumber_Scoreboard():
exit = True
print("Which year would you like the Scoreboard from?")
scoreboard = raw_input("Please type a year:")
if scoreboard == "2015":
cucumber_veg_2015()
elif scoreboard == "2014":
cucumber_veg_2014()
elif scoreboard == "2016":
cucumber_veg_2016()
def cucumber_veg_2016(cm):
return float(cm) / 2.54
names = OrderedDict([('Competitor Number', int),
('Competitor Name', str),
('Cucumber', cucumber_veg_2016),
('Carrot', float),
('Runner Bean', float)])
data = []
with open('veggies_2016.txt') as fobj:
while True:
item = {}
try:
for name, func in names.items():
item[name] = func(next(fobj).strip())
data.append(item)
except StopIteration:
break
pprint.pprint(sorted(data, key=itemgetter('Cucumber'))[:10])
Solution
Reading the data into a list of dictionaries would work:
from collections import OrderedDict
from operator import itemgetter
import pprint
def to_inch(cm):
return float(cm) / 2.54
names = OrderedDict([('person_number', int),
('name', str),
('first', to_inch),
('second', float),
('third', float)])
data = []
with open('veggies_2016.txt') as fobj:
while True:
item = {}
try:
for name, func in names.items():
item[name] = func(next(fobj).strip())
data.append(item)
except StopIteration:
break
pprint.pprint(sorted(data, key=itemgetter('first'))[:10])
Output:
[{'first': 4.76771653543307,
'name': 'Erma Park',
'person_number': 3,
'second': 13.51,
'third': 18.18},
{'first': 5.897637795275591,
'name': 'Christal Piper',
'person_number': 2,
'second': 11.01,
'third': 21.75},
{'first': 7.893700787401575,
'name': 'Dorita Griffin',
'person_number': 4,
'second': 10.39,
'third': 21.35},
{'first': 9.653543307086613,
'name': 'Carmella Henderson',
'person_number': 1,
'second': 13.5,
'third': 21.76}]
In Steps
This helper function converts centimeters into inches:
def to_inch(cm):
return float(cm) / 2.54
We use an ordered dictionary to hold the names for the different items we want to read in order. The value is a function that we use to convert the read value for each item:
names = OrderedDict([('person_number', int),
('name', str),
('first', to_inch),
('second', float),
('third', float)])
We start with an empty list:
data = []
And open our file:
with open('veggies_2016.txt') as fobj:
We do something without a defined end and create a new dictionary item each time:
while True:
item = {}
We try to read from the file until it is finished, i.e. until we get a
StopIteration exception:
try:
for name, func in names.items():
item[name] = func(next(fobj).strip())
data.append(item)
except StopIteration:
break
We go through the keys and values of our order dictionary names and call each
value, i.e. the function func() on the next line we retrieve with next().
This converts the entry into the desired datatype and does the cm-inch conversion for first. After reading all items for one person, we append the dictionary to the list data.
Finally, we sort by the key first and print out the 10 to entries
(my example file has less than 10 entries):
pprint.pprint(sorted(data, key=itemgetter('first'))[:10])
Integration with your code:
You need to put the code into the function podium_place():
def cucumber_veg_2016(cm):
return float(cm) / 2.54
def podium_place():
names = OrderedDict([('Competitor Number', int),
('Competitor Name', str),
('Cucumber', cucumber_veg_2016),
('Carrot', float),
('Runner Bean', float)])
data = []
with open('veggies_2016.txt') as fobj:
while True:
item = OrderedDict()
try:
for name, func in names.items():
item[name] = func(next(fobj).strip())
data.append(item)
except StopIteration:
break
sorted_data = sorted(data, key=itemgetter('Cucumber'), reverse=True)
for entry in sorted_data[:10]:
for key, value in entry.items():
print key, value
print
menu()
At the end you need to call menu(). Also, if top mean largest first, you need sort reverse (see above).
I would read them as a record at a time. You can put that functionality in a function that you call several times with the same file. It can return a None when you reach the end of the file. It will return a tuple with all values for a given record (including conversions). You can then use sorted to sort the list of records using any one of the values from each record.
def read_record(fid):
id = fid.readline()
# At the end of the file
if id is None:
return None
name = fid.readline()
# Perform the conversion
number1_inches = float(fid.readline()) / 2.54
number2 = float(fid.readline())
number3 = float(fid.readline())
return (id, name, number1_inches, number2, number3)
with open('filename.txt', 'r') as fid:
records = list()
while True
new_record = read_record(fid)
# Stop if we hit the end of the file
if new_record is None:
break
records.append(new_record)
# Now sort the records based on the value of number1
records = sorted(records, key=lambda x: x[2])
This code is showing only the last item of a list of dictionaries:
def chooseOneServer():
dara = websvc()
i=0
for item in dara:
for key,value in item.items() :
if key == '1' :
servers = ( ('i',value), )
i +=1
return servers
I've already answered this in the comments of your last question, but here it is again:
def chooseOneServer():
dara = websvc()
i=0
servers = []
for item in dara:
for key,value in item.items() :
if key == '1':
servers.append(('i',value))
i += 1
return servers
You just add each item to a list, rather than overwriting the same tuple each time.
def parse_actor_data(actor_data):
while 1:
line = actor_data.readline().strip()
if line.count('-') > 5:
break
actor_movie = {}
values = []
actor_name = ''
running_list = []
movie = []
for line in actor_data:
position = line.find(')')
running = line[:position + 1]
value = running.split('\t')
for k in value:
if k != '':
running_list.append(k)
actor_name_list = value[0].split(',')
actor_name = actor_name_list[0] + actor_name_list[-1]
for i in range(len(running_list)):
if value[0] == running_list[i]:
position2 = i
movie = running_list[position2+1:]
actor_movie[actor_name] = movie
check = actor_movie.keys()
for c in range(len(check)):
if len(check[c]) < 1:
actor_movie.pop(check[c])
return actor_movie
Problem I'm having now is that only the first item of movie is added into the actor_movie anyone can help? i tried so long for this already i seriously have no idea why isn't this working...
Every time you run:
actor_movie[actor_name] = movie
you're overwriting the last movie that was associated with that actor. Try something like this instead where you're storing a list of movies, not just a single value:
try:
actor_movie[actor_name].append(movie)
except KeyError:
actor_movie[actor_name] = [movie]
There are other ways (defaultdict, dict.setdefault, etc.) to do the same thing but that should get you up and running.