Issues with a college assignment using Python - python

Im and MSc student who has been lumped with doing python code this year but have no prior experience. I was wondering if someone could help me with this question, i have some parts done.
Q6)
Assignment 6
Grades are classified according to % (ranging from 0 to 100 inclusive), if greater than or equal to the following:-
70 First ; 60 Second Upper ; 50 Second Lower ; 45 Third ; 40 Pass; 0 Fail.
Create a dictionary from the data above, and use it as part of a program to grade marks, from 2 sources:-
1. during development, grade marks in sequence from a hardcoded list of marks = [-1,0,1,49,60,71,100,101],
2. after development, include code to repeatedly request marks for testing, until terminated by entering q or Q.
Marks will be awarded for concise coding, which should run efficiently with minimal use of comparisons tests.
Retain features to take input from both sources above in the final code, i.e. don't delete item '1' after development.
My solution so far looks something like this :
hardcoded_lst = [-1,0,1,49,60,71,100,101]
grade_input=int(input('What grade?')
input_lst= []
while grade_input !=
input_lst.append(grade_input)
grade_input=int(input('What grade?')
print(input_lst)
i need to create a dictionary for the values but currently that isnt working either.
Id appreciate any help, in basic code as i am not very advanced.
Thanks

creating dictionary isn't that tough, its as simple as creating list, which you have already done
For list
mylist = []
#for dictionary
mydictionary = {}
Adding item into dictionary
mylist.append(value)
mydictionary["fail"] = 50
Iterating the list
for item in mylist:
print item
Iterating in dictionary
for key,value in mydictionary.iteritem():
print key,value
I hope this helps you, there might be mistake in iteritem spelling etc you could google it but thats how its done normally
here is updated thing
mydictionary = {}
marks = 0
mydictionary[(0,45)] = "Fail"
mydictionary[(46,59)] = "Lower"
mydictionary[(60,69)] = "Second Lower"
mydictionary[(70,100)] = "First"
marks = 63
for key,value in mydictionary.iteritems():
if marks >= key[0] and marks <= key[1]:
print value
The given code works you could also do it in this way though

The following program should do as you asked. There are several lines that are commented out with the # character. You may uncomment those lines if you wish to see the value of the variable referenced in the call to the debug function. Please take time to study the code so that you understand how and why it works.
import pprint
import sys
RANGE = range(0, 101)
GRADE = {70: 'First', 60: 'Second Upper',
50: 'Second Lower', 45: 'Third',
40: 'Pass', 0: 'Fail'}
MARKS = -1, 0, 1, 49, 60, 71, 100, 101
def main():
"""Grade hardcoded marks and grade marks entered by the user."""
# debug('MARKS')
grade_all(MARKS)
grade_all(get_marks())
print('Goodbye!')
def grade_all(marks):
"""Take an iterable of marks and grade each one individually."""
for mark in marks:
# debug('mark')
if mark in RANGE:
print(mark, 'gets a grade of', grade_one(mark))
else:
print(mark, 'is not a valid mark')
def grade_one(mark):
"""Find the correct grade for a mark while checking for errors."""
# debug('RANGE')
if mark in RANGE:
for score, grade in sorted(GRADE.items(), reverse=True):
if mark >= score:
return grade
raise ValueError(mark)
def get_marks():
"""Create a generator yielding marks until the user is finished."""
while True:
try:
text = input('Mark: ')
except EOFError:
sys.exit()
else:
# debug('text')
if text.upper() == 'Q':
break
try:
mark = round(float(text))
except ValueError:
print('Please enter a mark')
else:
# debug('mark')
if mark in RANGE:
yield mark
else:
print('Marks must be in', RANGE)
def debug(name):
"""Take the name of a variable and report its current status."""
frame, (head, *tail) = sys._getframe(1), name.split('.')
for scope, space in ('local', frame.f_locals), ('global', frame.f_globals):
if head in space:
value = space[head]
break
else:
raise NameError('name {!r} is not defined'.format(head))
for attr in tail:
value = getattr(value, attr)
print('{} {} {} = {}'.format(
scope, type(value).__name__, name, pprint.pformat(value)), flush=True)
if __name__ == '__main__':
main()

You need to create a dictionary using the grade values as keys, and depending on the input populate the key with the input, or reject it as invalid. Maybe something like this:
if input>=70:
grade[first]=input
elif input>=60 and input<70:
grade[secondupper]=input
elif input<0 or input>100:
print 'invalid grade!'
If you have more than one value for each grade then consider using a list to read the values into, and then setting the corresonding dictionarty value to the list as you fill it.

Related

ranking items in a list by user score

What is the Best Thing - Tom Scott
basically trying to imitate this code in python to make code that ranks items based on the users input.
output 2 items from a list, ask user for which is better, add +1 score to that item, add -1 score to the other item, move on to next comparison.
new to coding, so i can understand basics but i don't understand the best way to do this.
import random
file = open('items.txt', 'r')
read = file.readlines()
modified = []
for line in read:
if line[-1] == '\n':
modified.append(line[:-1])
else:
modified.append(line)
for i in range (9999999):
randomint1 = (random.randint(0,498))
randomint2 = (random.randint(0,498))
item1 = modified[randomint1]
item2 = modified[randomint2]
print (item1, '\n'+ item2)
answer = input('item 1 or 2')
this is what i have so far, i don't know how i'd go about linking the list of items to a list of scores
ideally i could read the items in ranking of top to bottom, possibly in a created txt file with the name of items listed next to score? i'm not too sure.
any help is appreciated, thanks
Given a file where each line in the file is some str item label like:
Plate
Fork
Spoon
and you want to write a program that will read all of the items from the file and then continuously ask a user one or the other while keeping tally of those results in the form of a single score value per item which goes +1 or -1 depending on if it was chosen in each decision.
with open("items.txt", "r") as f:
items = f.read().splitlines() # removes the \n # the end vs readlines() see https://stackoverflow.com/questions/12330522/how-to-read-a-file-without-newlines
item_scores = {item: 0 for item in items} # could also use a `collections.defaultdict(int)`
while True:
item_1, item_2 = randomly_select_two_items(items)
raw_input = ""
while raw_input not in {item_1, item_2}:
raw_input = input(f"{item_1} or {item_2}? ")
if raw_input == item_1:
item_scores[item_1] += 1
item_scores[item_2] -= 1
else:
item_scores[item_2] += 1
item_scores[item_1] -= 1
print(f"The highest scored item is: {max(item_scores, key=item_scores.get)}")
print("Good Bye")
For completeness sake, I left a stub above for randomly_select_two_items(items) - here's a possible implementation to consider vs what you have in your example:
def randomly_select_two_items(items: list):
import random
return random.sample(items, 2)

Python dictionary -two or three user input at one time and output in separate lines

I'm nearly done building a dictionary that counts the number of each element entered...Although for example if I input coffee water and then enter, prints 1 coffee water in the same line... I want it to print:
1 coffee
1 water
in separate lines
What am I doing wrong?
dictionary = {}
while True:
user_input = input("Input: ")
dictionary[user_input] = dictionary.get(user_input, 0) + 1
for key, value in sorted(dictionary.items()):
print(value, key.upper())
print("\n")
Okay, here's the thing.
input() ends when Enter is hit.
i.e. - if you type "coffee water" and then press enter, it's gonna think that's the name of the item you're entering. ("coffee water")
Basically, enter one item at a time.
Or, if you want, split by whitespace and support the addition of multiple items at the same time. something like:
dictionary = {}
value = input("Enter item: ")
while value !="":
value = value.split(" ") # split by space.
# if there's no space (i.e. only one item is entered this time, this gives a list with a single item in it. (the word entered)
for item in value:
if item in dictionary.keys(): # if the item exists, add 1 to its counter
dictionary[item] +=1
else: # if the item doesn't exist, set its counter to 1
dictionary[item] = 1
value = input("Enter item: ")
for key, value in sorted(dictionary.items()):
print(value, key.upper())
Entering:
coffee
water
water coffee
gives:
2 COFFEE
2 WATER
Note: this breaks if you have items with spaces in their name. like "water bottle"
also read about the defaultdict module
To solve the problem you mention in your last comment and to provide an escape from the while loop, I would revise your code as follows. This changes lines 2, 5, 6, 8 and 9. I had trouble getting my code in here. Let me know if you have any problems.
dictionary = {}
i = 1
while True:
user_input = input("Input: ")
if user_input == "":
break #provides escape
dictionary[user_input] = dictionary.get(user_input, i)
i = i + 1 #solves numbering problem
for key, value in (dictionary.items()):
print(f"{value} {key.upper()}", end=" ")
print("\n")
I don’t have my PC in front of me so this is kind of pseudo code.
Try something like:
input_list = user_input.split()
for i in input_list:
dictionary[i] = dictionary.get(i, 0) + 1
print(i)
By default the input will be as one string, so you cannot do your operations on it directly, you need to split it.
Edit: check out Yarin_007’s answer, however you can use the default .split() instead so that it gets split on any white space.

python dictionary mydt problems

Write a Python program that will take N names from the user. Create a dictionary from the N names that will hold First_name, Middle_name, and Last_name in separate keys. The inputs will take N at first and then take N names. You can assume that the names will contain less than or equal to 3 words.
Sample Input:
4
Zubayer Ahmed
Sadia Nur Amin
Mehedi Hasan Shawon
Nafis
Sample Output:
{ "Fname" : [“Zubayer”, “Sadia”, “Mehedi”, “Nafis”] , "Mname" : [“Nur”, “Hasan”], "Lname" : [“Ahmed”, “Amin”, “Shawon”] }
This problem requires you to first find the number of names needed, this can be done using a simple input() call.
numNames = int(input("> "))
we can also prepare the dictionary like so
nameDict = {"Fname":[],"Mname":[],"Lname":[]}
Then we need to iterate depending on the number the user has entered
for i in range(numNames):
During each iteration of the above for loop, you need to ask the user for a name, then split it into a list of each names names = input("name {i+1} > ").split(" ")
You can then add them to the dictionary as the problem requires using basic selection
if len(names) >= 1:
nameDict["Fname"].append(names[0])
if len(names) == 2:
nameDict["Lname"].append(names[1])
elif len(names) == 3:
nameDict["Mname"].append(names[1])
nameDict["Lname"].append(names[2])
This solution could be made more efficient if you can find a better way to sort the names into the dictionary.
Although StackOverflow isn't for your entire problems, more so questions about specific areas. Next time have a go at the problem and post if you get suck with details about your attempt.
But anyway, here is my full solution
numNames = int(input('names >'))
nameDict = {'Fname':[],'Mname':[],'Lname':[]}
for i in range(numNames):
names = input(f'name {i+1} > ').split(' ')
if len(names) >= 1:
nameDict["Fname"].append(names[0])
if len(names) == 2:
nameDict["Lname"].append(names[1])
elif len(names) == 3:
nameDict["Mname"].append(names[1])
nameDict["Lname"].append(names[2])
print(nameDict)
Here's my solution:
number_of_entries = int(input("How many entries would you like? "))
first_names = []
middle_names = []
last_names = []
i = 0
while i < number_of_entries:
full_name = input(": ")
names_array = full_name.split(' ')
if len(names_array) >= 1:
first_names.append(names_array[0])
if len(names_array) >= 2:
middle_names.append(names_array[1])
if len(names_array) >= 3:
last_names.append(names_array[2])
i += 1
names_dictionary = { "Fname" : first_names, "Mname" : middle_names, "Lname" : last_names}
print(names_dictionary)
It works by storing every category of name into an array first then adding that to the dictionary in the end.
In this homework, you must handle the initial 4 and read correctly the following input lines.
After that you will have a list of names, I think the best approach is the following
from itertools import zip_longest
names = ["Zubayer Ahmed","Sadia Nur Amin","Mehedi Hasan Shawon","Nafis"]
# split into single words
names = [x.split() for x in names]
# do a zip of the triads and remove None values
filtered = [ list(filter(None,_)) for _ in zip_longest(*names)]
#do the dict:
dict(zip( ("Fname","Mname", "Lname"), filtered))
the output:
{'Fname': ['Zubayer', 'Sadia', 'Mehedi', 'Nafis'],
'Mname': ['Ahmed', 'Nur', 'Hasan'],
'Lname': ['Amin', 'Shawon']}

Why is my function not prompting me to enter input?

I’m using Python IDE 3. My goal is this: If I have a string of text, ‘ABCDEFGHIJKL’, I want to sort it into groups, like three groups (‘ADGJ’,’BEHK’,’CFIL’). I require input for this, but the prompts aren’t showing up and I can’t type in input. Here’s my code:
#data
code_text = input('Text: ').lower()
code_skip = int(input('Shift length: '))
code_list = []
#function
def countSkip(text, shift, listt):
i = 0
group = 1
if group <= shift:
for e in text:
#make sure the set starts at the right place
if e.index()+1 < group:
pass
elif shift != 0:
if i = shift:
listt.append(e)
i = 0
i += 1
else:
listt.append(e)
group += 1
Calling the function
countSkip(code_text, code_shift, code_list)
There's a few things stopping your code from working that people have pointed out in the comments. Instead of trying to dissect your code and get that to work, I wrote a much more concise function that will get you the results you're after
def text_splitter(input_text, set_length):
num_sets = int(len(input_text)/set_length)
split_text = ["".join([input_text[(n * num_sets) + m] for n in range(set_length)]) for m in range(num_sets)]
return split_text
text_to_split = input('Text: ').lower()
len_set = int(input('Set Length: '))
text_list = text_splitter(text_to_split, len_set)
Sorry I was struggling to name the variables in an effective manner but the function above uses a list expression to get you the results you need. Keep in mind that if you use say a 7 letter string and ask for sets of length 2, the last letter won't be appended. However this shouldn't be too hard to check and correct. For example you could add this code to the function or around the initial input for the set length:
while len(input_text) % set_length != 0:
set_length = int(input("The text is length " + str(len(input_text)) + " please enter a different set length: "))

Counting number of characters in a key in a dictionary

For homework I have been set the following:
Build a dictionary with the names from myEmployees list as
keys and assign each employee a salary of 10 000 (as value). Loop over the dictionary
and increase the salary of employees which names have more than four
letters with 1000 * length of their name. Print the dictionary contents before
and after the increase.
I can't figure out how to do it.
This is what I've come up with so far.
employeeDict = {"John":'10,000', "Daren":"10,000", "Graham":"10,000", "Steve":"10,000", "Adren":"10,000"}
say = 'Before increase'
print say
print employeeDict
say1 = 'After increase'
print say1
for x in employeeDict:
x = len(employeeDict)
if x > 5:
print employeeDict[x]
First, change the values to integers/floats.
employeeDict = {"John":10000, "Daren":10000, "Graham":10000, "Steve":10000, "Adren":10000}
After doing this, as you know, you need to loop over the items in the dict.
for x in employeeDict:
x = len(employeeDict)
if x > 5:
print employeeDict[x]
In the code above, your "x" will be the employee name. And as you know, to asign a value to a key in dict, you have to use dict[key] = value, so try to do it in the if x > 5: block statement. Im not trying to give you the full answer, but to push you in to the right direction.
You have some indentation problems, clearly, but the main problems are that you are taking the length of the dictionary (getting the number of keys) not taking the length of the key. You also have some bad logic.
employeeDict = {"John":'10,000', "Daren":"10,000", "Graham":"10,000", "Steve":"10,000", "Adren":"10,000"}
say = 'Before increase'
print say
print employeeDict
say1 = 'After increase'
print say1
for x in employeeDict:
length = len(employeeDict) # <---- indent this
if length >= 5: # <--- greater than 4
# convert string to number, add money, convert back to string
employeeDict[x] = str(int(employeeDict[x]) + 1000 * (length))
print employeeDict[x]
This should give you what your looking for.
employeeDict = {"John":10000, "Daren":10000, "Graham":10000, "Steve":10000, "Adren":10000}
print "Before increase"
print employeeDict
for name, salary in employeeDict.items():
if len(name) > 4:
employeeDict[name] = salary + len(name) * 1000
print "After increase"
print employeeDict
You had a few problems in your version.
Your idention for your for-loop was not correct
You were getting the length of the dictionary and not the length of the keys in the dictionary.
You should make the values in your dictionary floats/integers.
Also note, I believe your homework said if the name was longer than four characters. So i used 4 instead of five.
Give this a try and analyse it :
employees = {"John":10000, "Daren":10000, "Graham":10000}
for name in employees:
if len(name) > 5:
employees[name] += 1000 * len(name)
If you have to stick with the string values you can do this :
employees = {"John":"10000", "Daren":"10000", "Graham":"10000"}
for name in employees:
if len(name) > 5:
employees[name] = str(int(employees[name]) + 1000 * len(name))

Categories