Needing help on what I'm doing wrong


#1

you’ll find a data le named cmpt181_midterm.txt which is a tabular file with ctitious data with values separated by commas. The first few lines are as follows:

00000000,key,d,d,b,e,e,d,d,a,d,d,d,b,c,a,b,e,c,c,b,c,c,b,e,c,c,e,d,d,d,d 10021795,Samden Cross,d,d,b,e,e,e,d,a,d,b,d,b,c,a,a,e,c,c,b,c,d,b,e,c,c,e,d,d,d,c 11051158,Jenni Nuxulon,d,d,b,e,e,d,d,a,d,b,b,b,c,a,b,b,c,c,b,c,c,b,a,c,c,e,d,d,d,a

We’ll refer to this kind of le as a response le. It records ctitious responses for all ctitious students who wrote a ctitious multiple choice midterm test for a ctitious course. Each line contains a uSask-like student ID, a student name, and then a bunch of letters representing multiple choice answers. The rst line in the response le is the answer key, i.e., all the correct answers, so the ID for that line is all zeroes, and the name is boring.

This particular midterm had 30 multiple choice questions, but you must not assume every test will have 30 questions. We will assume that every studentanswered every question.

Your job is to write a program to do the following tasks:

  • Grade each student, by comparing their responses to the answer key. The grades will be written to a text le in tabular format. For example, the rst few lines might be:

10021795,Samden Cross,25 10975851,Dannae Evenstar,21 10461276,Sanna Tunna,16

The order of the students in the le is not important for this assignment.

  • Provide a report about the test, in terms of average, minimum and maximum scores, etc, displayed on the console. For example

Scores summary Number of responses: 23 Number of questions: 30

Minimum score: 14 Average score: 22.47826086956522 Median score: 24 Maximum score: 29

There were 10 students who received a score above 80% There were 0 students who received a score below 40%

The questions on this assignment get you to build the app in steps. Some of the steps are pretty easy. Some of the later ones will require good organizational skills. The most time consuming part will be reading the questions carefully.This will appear to be a very long assignment because we have tried to be very clear about what your functions should do. But it is like a recipe — we tell you exactly which functions to write, and how they should work. If you follow the instructions exactly, step-by-step, you’ll be successful, and each question does not require writing a lot of code. The assignment is meant to demonstrate how you can construct a program that does something useful in the real world by de ning small functions that perform subtasks, and then put them all together into a working application. In this case, we’ve done the design work (decomposing the larger problem into small pieces) for you.What to Hand InWhen you’re done, you’ll hand in one document, a5.py, with all your work in it. Make sure you put identi cation information at the top of your program!

Question 1 (4 points):

Purpose: To practice the concept of dictionary as a mapping.Degree of Di culty: Easy.

Writeafunction,calledindex_responses,thattakesalistofmultiplechoiceresponses,e.g.,[’a’, ’b’, ’c’], as an argument, and returns a dictionary of question-response pairs {’Q1’:’a’, ’Q2’:’b’, ’Q3’:’c’}. Your function should work for lists of any size.

Before going on, you want to be sure that your function works properly. Add the following testing code to your program (you can nd this code in A5testing.py):

print(’Testing index_responses()’)print(index_responses([’a’, ’b’, ’c’]))print(index_responses([’a’,’a’,’c’,’b’]))

print(index_responses([’d’,’d’,’b’,’e’,’e’,’e’,’d’,’a’]))

You should see console output like this:

Testing index_responses() {’Q1’: ’a’, ’Q2’: ’b’, ’Q3’: ’c’} {’Q1’: ’a’, ’Q4’: ’b’, ’Q2’: ’a’, ’Q3’: ’c’} {’Q7’: ’d’, ’Q1’: ’d’, ’Q6’: ’e’, ’Q3’: ’b’, ’Q5’: ’e’, ’Q8’: ’a’, ’Q2’: ’d’, ’Q4’: ’e’}

Python decides what order to put the questions, so if you get a di erent ordering, that’s ne. You should check that all the questions are there, and that all the responses are appropriate. When you are con dent that your function works, comment out the above testing code and move on to the next question.

Evaluation

• 1 mark: The function has one parameter.
• 1 mark: The function returns a dictionary.
• 1 mark: The function correctly constructs a mapping between question label and response.• 1 mark: The doc-string is sufficiently descriptive, indicating its purpose and requirements.

I have

def index_responses(numbers):
i=1
response={}
for index in numbers:
ques= index+i
response.update({ques:index})
i=i+1
return response

ques_response = index_responses([‘a’,‘b’,‘c’])
print (ques_response)

can someone help me please?


#2

You should be using the test sequences provided.

print('Testing index_responses()')
print(index_responses(['a', 'b', 'c']))
print(index_responses(['a','a','c','b']))
print(index_responses(['d','d','b','e','e','e','d','a']))

The output will look something like this…

Testing index_responses()
{'Q1': 'a', 'Q3': 'c', 'Q2': 'b'}
{'Q1': 'a', 'Q3': 'c', 'Q2': 'a', 'Q4': 'b'}
{'Q5': 'e', 'Q1': 'd', 'Q8': 'a', 'Q4': 'e', 'Q7': 'd', 'Q6': 'e', 'Q3': 'b', 'Q2': 'd'}

May we expect to hear back from you about how you’re doing?

Notes:

When we look at it, numbers is not very meaningful. The function name describes what is being examined, responses so that would be a reasonable (and meaningful) name to use.

def index_responses(responses):

When we look at the data we see it is not a list of numbers, but a list of letters. Moot now, though, since we know that those letters are responses so the variable accurately describes the inputs.

The key here is that code that is meaningful requires less documentation as it is self-documented in a sense, at least partially. It just makes for easier reading and understanding. Add this point to your Style Guide.

Even when we rewrite this to,

for index in responses:

it doesn’t change the fact that we are not iterating over indexes, but items in the list. The index in your code is the variable i This goes back to the previous statement about accurately describing what the variable refers to. If the list is called responses, then an item could well be called, response, and the temporary dictionary (the return value) could be called, response_dict.

>>> def index_responses(responses):
    index = 0
    response_dict = {}
    for response in responses:
        index += 1
        response_dict["Q" + str(index)] = response
    return response_dict

>>> print(index_responses(['d','d','b','e','e','e','d','a']))
{'Q3': 'b', 'Q4': 'e', 'Q7': 'd', 'Q1': 'd', 'Q8': 'a', 'Q6': 'e', 'Q2': 'd', 'Q5': 'e'}
>>> 

or with, dict.update()

>>> def index_responses(responses):
    index = 0
    response_dict = {}
    for response in responses:
        index += 1
        response_dict.update({"Q" + str(index): response})
    return response_dict

>>> print(index_responses(['d','d','b','e','e','e','d','a']))
{'Q3': 'b', 'Q4': 'e', 'Q7': 'd', 'Q1': 'd', 'Q8': 'a', 'Q6': 'e', 'Q2': 'd', 'Q5': 'e'}
>>> 

Bottom line, our road map begins with a clear understanding and mapping out of the instructions, themselves. Running headlong into coding without first taking time to visulaize and plan will ultimately lead to problems and use up valuable time and effort.


So far I’ve gotten to this point…

============ RESTART: D:/cc/discuss/users/eh112121/exam_grader.py ============
{'10010717': 17, '10826746': 16, '11279454': 28, '10975851': 21, '10832178': 26, '10461276': 16, '10857855': 22, '10935250': 23, '10094446': 27, '11282853': 27, '10021795': 25, '10402918': 22, '10690937': 21, '11004337': 24, '10525083': 25, '10105757': 17, '10042721': 28, '10274304': 28, '10202570': 24, '10630417': 14, '11051158': 25, '10566434': 15, '11257817': 25}
>>> 

This was using the file, ‘cmpt181_midterm.txt’ which I’m assuming is in your workspace folder. I got it off the internet after a little searching. Not interested in their code, just now. Would rather work this one out myself without outside influences. As yet I am not using any libraries.


The data I’m using must be slightly different from yours since the average is different…

============ RESTART: D:/cc/discuss/users/eh112121/exam_grader.py ============
10042721, Xoomio Dahl, 28
11279454, Hep Fass, 28
10274304, Chip Blasterbolt, 28
11282853, Rev Burpo, 27
10094446, Megen Haptron, 27
10832178, Kara Moonlock, 26
11051158, Jenni Nuxulon, 25
10021795, Samden Cross, 25
10525083, Alia Lightside, 25
11257817, Abrahap Gimble, 25
11004337, Keebo Keempo, 24
10202570, Atrish Benson, 24
10935250, Shrim Shrim Ulpax, 23
10857855, Delxia Forice, 22
10402918, Ackley Timpler, 22
10975851, Dannae Evenstar, 21
10690937, Garthur Cola, 21
10105757, Agtem Sorton, 17
10010717, Nikki Solar, 17
10461276, Sanna Tunna, 16
10826746, Mobi Rodrik, 16
10566434, Trumpo Wexler, 15
10630417, Jimmy Scrambles, 14
Score summary
Number of responses: 23
Number of questions: 30
Minimum score:  14
Average:  22.434782608695652
Median:  24
Maximum score:  28
There were 10 students who received a score above 80%. 
There were 0 students who received a score below 40%.
>>> 

#3

Want to know why professors use content that can be found online? To expose cheaters, that’s why. Did their student work out some or all on their own, and then use the web to solve a glitch or two? Or did they search the web first, and follow the examples given there?

One thing is sure, use any of the code that is published in this thread and you will be outed immediately, and your web persona known on campus by your professors.

Better an average grade for own effort than a fail, and possible expulsion for plagiarism. Just saying. Learn from these examples, but explore and reason out your own code. That’s where the real joy is. It’s also where the professor becomes more interested in you as an apt pupil.

Not through genius do we excel, but through honest effort. A teacher who witnesses a student’s struggle will be more inclined to give guidance than if the student is pretending to be ahead of the eight ball. Don’t hide your struggles, ever.

But know that it is only by those struggles that the seeds for betterment are planted. Life is a struggle for everyone. That’s its nature.

def index_responses(responses):
    return {"Q{}".format(i + 1): x for i, x in enumerate(responses)}
def print_sorted_results(data, scores):    
    for x in sorted(scores.items(), key=lambda x: x[1], reverse=True):
        print ("{}, {}, {}".format(x[0], data[x[0]].get('name'), x[1]))
data_dict = get_data_dict()
score_dict = get_score_dict(data_dict)
print_sorted_results(data_dict, score_dict)

After that comes the summary. A collection of simple utility functions fulfills this role.

def get_median(x):
    s = sorted(x.values())
    n = len(s)
    m = n // 2
    return s[m] if n % 2 else (s[m - 1] + s[m]) / 2
def get_min_score(x): return min(x.values())
def get_max_score(x): return max(x.values())
def get_average(x): return sum(x.values()) / len(x)
def get_high_range(x, y):
    return sum([1 for n in x.values() if n > (0.8 * y)])
def get_low_range(x, y):
    return sum([1 for n in x.values() if n < (0.4 * y)])
print ("Score summary")
num_responses = len(score_dict)
print ("Number of responses: {}".format(num_responses))
num_questions = len(data_dict['00000000'].get('responses'))
print ("Number of questions: {}".format(num_questions))
print ("Minimum score: ", get_min_score(score_dict))
print ("Average: ", get_average(score_dict))
print ("Median: ", get_median(score_dict))
print ("Maximum score: ", get_max_score(score_dict))
print ("There were {} students who received a score above 80%. \n\
There were {} students who received a score below 40%.\
".format(get_high_range(score_dict, num_questions), get_low_range(score_dict, num_questions)))

All that’s missing now is the two engines that drive this whole thing. I’m going to spoil that, too, by posting code you’ll never be able to submit but that I hope you will learn from and excel to new ground. Posting this question took a lot of gumption, and one should love for you to gain from it.

def get_data_dict():
    data_dict = {}
    data = open('cmpt181_midterm.txt', 'r')
    for row in data:
        row_items = row.split(',')
        data_dict[row_items[0]] = {'name': row_items[1],\
                                   'responses': index_responses(row_items[2:])}
    data.close()
    return data_dict
def get_score_dict(data_dict):
    score_dict = {}
    key_id = '00000000'
    ans_key = data_dict[key_id].get('responses')
    for x in data_dict:
        if x == key_id: continue
        score_dict[x] = sum([1 if ans_key[k] == data_dict[x].get('responses')[k]\
                             else 0 for k in ans_key.keys()])
    return score_dict

#4

Hold it! We can do this without hard coding the file URL into the open() statement.

def index_responses(responses):
    return {"Q{}".format(i + 1): x for i, x in enumerate(responses)}

class Exam(object):
    def get_data(self):
        data_dict = {}
        data = open(self.file, 'r')
        for row in data:
            row_items = row.split(',')
            data_dict[row_items[0]] = {
                'name': row_items[1],
                'responses': index_responses(row_items[2:])
            }
        data.close()
        return data_dict
    def __init__(self, file):
        self.file = file
        self.data = self.get_data()
        
class Score(Exam):
    pass

a = Score('cmpt181_midterm.txt')         #  print (isinstance(a, Exam)) => True
print (a.data.keys() and True)           #  True
print (a.data['00000000'].get('name'))   #  key

#5

Pretty well self-contained, now…

Spoiler
class Exam:
  '''
  This class houses the exam key and individual responses in a data object.
  '''
  def get_data(self):
    def index_responses(responses):
      return {"Q{}".format(i + 1): x for i, x in enumerate(responses)}
    data_dict = {}
    data = open(self.file, 'r')
    for row in data:
      row_items = row.split(',')
      data_dict[row_items[0]] = {
        'name': row_items[1],
        'responses': index_responses(row_items[2:])
      }
    data.close()
    return data_dict
    
  def __init__(self, file):
    self.file = file
    self.data = self.get_data()
class Score(Exam):
  '''
  This class houses the individual outcomes in a scores object.
  The methods given are to inspect the results and to summarize.
  '''
  def get_scores(self):
    scores = {}
    key = '00000000'
    ans = self.data[key].get('responses')
    for x in self.data:
      if x == key: continue
      scores[x] = sum([1 if ans[k] == self.data[x].get('responses')[k]
                       else 0 for k in ans.keys()])
    return scores
  def __init__(self, file):
    super().__init__(file)
    self.scores = self.get_scores()
  def __str__(self):    
    for y in sorted(self.scores.items(), key=lambda x: x[1], reverse=True):
      print ("{}, {}, {}".format(y[0], self.data[y[0]].get('name'), y[1]))
    return "-" * 32
  def get_summary(self):
    def median(x):
      s, n = sorted(x), len(x); m = n // 2
      return s[m] if n % 2 else (s[m - 1] + s[m]) / 2
    r, s = len(self.data['00000000'].get('responses')), len(self.scores)
    v = self.scores.values()
    q =  "Score summary\n" + "-" * 32
    q += "\nNumber of responses: {}".format(s)
    q += "\nNumber of questions: {}".format(r)
    q += "\nMinimum score: {}".format(min(v))
    q += "\nAverage: {:.1f}".format(sum(v) / s)
    q += "\nMedian: {}".format(median(v))
    q += "\nMaximum score: {}".format(max(v))
    q += "\nThere were {} students who received a score above 80%.\
         ".format(sum([1 for n in v if n > (0.8 * r)]))
    q += "\nThere were {} students who received a score below 40%.\
         ".format(sum([1 for n in v if n < (0.4 * r)]))
    return q

a = Score('cmpt181_midterm.txt')
print (a)
print (a.get_summary())
10042721, Xoomio Dahl, 28
11279454, Hep Fass, 28
10274304, Chip Blasterbolt, 28
11282853, Rev Burpo, 27
10094446, Megen Haptron, 27
10832178, Kara Moonlock, 26
10525083, Alia Lightside, 25
10021795, Samden Cross, 25
11257817, Abrahap Gimble, 25
11051158, Jenni Nuxulon, 25
10202570, Atrish Benson, 24
11004337, Keebo Keempo, 24
10935250, Shrim Shrim Ulpax, 23
10857855, Delxia Forice, 22
10402918, Ackley Timpler, 22
10690937, Garthur Cola, 21
10975851, Dannae Evenstar, 21
10105757, Agtem Sorton, 17
10010717, Nikki Solar, 17
10461276, Sanna Tunna, 16
10826746, Mobi Rodrik, 16
10566434, Trumpo Wexler, 15
10630417, Jimmy Scrambles, 14
Score summary
Number of responses: 23
Number of questions: 30
Minimum score: 14
Average: 22.4
Median: 24
Maximum score: 28
There were 10 students who received a score above 80%.         
There were 0 students who received a score below 40%.         

The numbers above don’t quite agree with the example output in the assignment. Just after data.close I randomly chose a question for which a student gave the wrong answer and changed it to the correct one.

data_dict['10566434']['responses']['Q25'] = 'c'

This gave, Trumpo Wexler, 16, and produced the expected average…

Average: 22.47826086956522

#6

cmpt181_midterm.txt (2.0 KB)

00000000,key,d,d,b,e,e,d,d,a,d,d,d,b,c,a,b,e,c,c,b,c,c,b,e,c,c,e,d,d,d,d
10021795,Samden Cross,d,d,b,e,e,e,d,a,d,b,d,b,c,a,a,e,c,c,b,c,d,b,e,c,c,e,d,d,d,c
11051158,Jenni Nuxulon,d,d,b,e,e,d,d,a,d,b,b,b,c,a,b,b,c,c,b,c,c,b,a,c,c,e,d,d,d,a
10566434,Trumpo Wexler,a,d,b,b,d,b,d,a,b,e,d,b,e,a,c,d,d,b,b,c,b,b,e,c,a,e,e,d,d,a
11257817,Abrahap Gimble,d,d,b,e,e,e,d,a,d,e,d,b,c,a,e,e,c,a,b,c,d,b,e,c,c,e,d,d,d,d
10094446,Megen Haptron,d,d,b,b,e,d,d,a,d,d,d,b,c,a,b,e,c,c,e,c,c,b,e,c,c,e,d,d,d,b
10975851,Dannae Evenstar,d,d,c,c,e,a,d,a,d,c,d,b,e,a,b,c,c,b,e,c,c,b,e,c,c,b,d,d,d,d
10274304,Chip Blasterbolt,d,d,b,e,e,d,d,a,d,b,d,b,c,a,b,e,c,c,b,c,c,b,d,c,c,e,d,d,d,d
11282853,Rev Burpo,d,d,b,e,e,a,d,a,d,c,d,b,c,a,b,e,c,c,b,c,e,b,e,c,c,e,d,d,d,d
10202570,Atrish Benson,d,d,b,e,e,d,d,a,d,a,d,b,c,a,c,c,c,d,b,c,b,b,e,c,c,e,d,d,d,e
10826746,Mobi Rodrik,d,d,b,c,e,c,d,a,a,c,d,b,c,a,a,e,b,b,a,c,e,b,d,a,d,c,d,d,d,e
10690937,Garthur Cola,d,d,b,e,e,c,d,a,d,b,a,b,c,a,b,e,c,a,b,c,a,b,c,b,e,e,d,d,d,e
10832178,Kara Moonlock,d,d,b,e,e,d,d,a,d,d,d,b,c,a,b,d,c,c,b,c,d,b,b,c,c,e,d,d,d,c
10630417,Jimmy Scrambles,e,e,b,e,e,b,d,a,d,a,c,b,a,a,b,a,d,e,d,e,c,b,e,b,e,d,a,d,d,a
10525083,Alia Lightside,d,d,b,a,e,c,d,a,d,a,d,b,c,a,b,e,c,c,b,c,c,b,e,c,d,e,d,d,d,a
11279454,Hep Fass,d,d,b,e,e,c,d,a,d,d,d,b,c,a,b,e,c,c,b,c,c,b,e,c,c,e,d,d,d,b
10935250,Shrim Shrim Ulpax,d,d,a,e,e,b,d,a,d,d,d,b,c,a,b,e,c,e,b,c,d,b,d,c,c,e,b,d,a,d
10402918,Ackley Timpler,d,d,b,d,e,e,d,a,d,d,d,b,c,a,c,e,c,a,c,c,c,b,e,c,e,c,d,d,d,e
11004337,Keebo Keempo,d,d,b,b,e,e,d,a,d,d,d,b,c,a,d,e,c,c,b,c,a,b,e,c,c,b,d,d,d,e
10461276,Sanna Tunna,d,c,d,a,b,e,d,a,d,d,d,b,a,a,b,a,d,c,c,c,e,b,e,b,b,a,d,d,b,d
10105757,Agtem Sorton,a,a,a,e,e,d,d,a,d,e,c,b,c,a,d,c,c,c,a,c,a,b,a,c,c,d,e,d,d,a
10010717,Nikki Solar,d,c,c,d,e,a,d,a,a,c,d,b,c,a,d,e,c,c,c,c,c,b,c,c,b,e,e,d,a,c
10857855,Delxia Forice,b,d,b,b,a,d,d,a,d,d,d,b,e,a,e,e,d,c,b,c,a,b,e,c,c,e,d,d,d,e
10042721,Xoomio Dahl,d,d,b,e,e,d,d,a,d,e,d,b,c,a,b,e,c,c,b,c,c,b,e,c,c,e,d,d,d,d