1
votes

I have this assignment that I need to solve:

Interface

def roundGrade(grades):
    # Insert your code here
    return gradesRounded

Input arguments

grades: A vector (each element is a number between −3 and 12).

Return value

gradesRounded: A vector (each element is a number on the 7-step-scale).

Description

The function must round off each element in the vector grades and return the nearest grade on the 7-step-scale:

7-step-scale: Grades 12 10 7 4 02 00 −3

For example, if the function gets the vector [8.2, -0.5] as input, it must return the rounded grades [7, 0] which are the closest numbers on the grading scale.

I have tried the following code:

import numpy as np

def roundGrade(grades):
    trueGrades = np.array([12, 10, 7, 4, 2, 0, -3])
    matrix = np.array([trueGrades, (len(grades)), 1])
    index = np.argmin(np.abs(matrix.T - grades), axis=0)
    gradesRounded = trueGrades[index]

    return gradesRounded

When I run the code line by line, I get the following error:

index = np.argmin(np.abs(matrix.T - grades), axis=0)

ValueError: operands could not be broadcast together with shapes (3,) (100,) 

How can I solve this problem?

1
Try printing out the shapes of matrix and of grades...Itamar Mushkin
that's because shape of the matrix inside function definition is 3 rows, 1 column. and the grades passed into function is 100, they should be of the same size to make arifmetic operations, like matrix.T - gradesStanislav Lipovenko

1 Answers

0
votes

In general, a first approach to debugging your code should be to print intermediate results and associated metadata (such as array shapes). The error message should also have told you that your intermediate arrays do not have the shape you would expect them to have.

That being said, there are several problems with your code.

matrix = np.array([trueGrades, (len(grades)), 1])

This line does not do what you think it does. All you do here is creating a new array containing [12, 10, 7, 4, 2, 0, -3, 7, 1] (by appending len(grades) and 1 to your trueGrades array).

I assume what you really want is to reshape trueGrades by adding a singleton dimension. This can be done like so:

matrix = trueGrades.reshape(-1, 1)  # matrix has shape (len(trueGrades), 1)

Then, for the broadcasting to work, your grades vector needs the same number of dimensions (2), so you need to reshape that, too:

grades = grades.reshape(-1, 1)

The following works fine, then:

def roundGrade(grades):
    trueGrades = np.array([12, 10, 7, 4, 2, 0, -3])
    matrix = trueGrades.reshape(-1, 1)
    grades = grades.reshape(-1, 1)
    index = np.argmin(np.abs(matrix.T - grades), axis=1)
    gradesRounded = trueGrades[index]
    return gradesRounded
>>> roundGrade(np.arange(-5, 15))
[-3 -3 -3 -3  0  0  2  2  4  4  4  7  7  7 10 10 12 12 12 12]