Exam 2022-12-15

Here you find the questions, sample answers and marking guidelines for the exam 2022-12-15.

Information

Start by reading through all questions. Peter will visit the exam 45 minutes after it has started to answer any questions you might have.

Max score is 25 points.

  • For grade 3, 40% of max score (10 points) is required
  • For grade 4, 60% of max score (15 points) is required
  • For grade 5, 80% of max score (20 points) is required

Question 5 is discarded

Question 5 contains an error, and has therefor been discarded. The new max score is therefor 24 points, and the thresholds for the grades are instead:

  • For grade 3, 40% of max score (9.6 points) is required
  • For grade 4, 60% of max score (14.4 points) is required
  • For grade 5, 80% of max score (19.2 points) is required

During the test, you are only allowed to use:

  • The computer you sit at to only answer the questions on this exam (you may not run any other program)
  • A dictionary to translate to/from English from/to your native language
  • Pen and paper to sketch/write notes with (does not need to be submitted)

Write your answers in either English or Swedish. If you write your answers in Swedish, make sure to not introduce any translation confusement. Write proper sentences (spelling, upper/lower case characters, punctuation, etc.). Answers that do not do this good enough/are vague/are ununderstandable cannot receive full score on the questions.

Answers that are more or less copies of sample answers given to you or copies of text found somewhere else will be rewarded 0 points. Use your own words to answer the questions (does not apply to questions where you write code).

Good luck!

Question 1 (1p)

Question

Place the following lines of code in such order they can be executed (read underscores as white-spaces/indentation (Inspera doesn't allow the text to begin with white-spaces ๐Ÿ˜ž)).

  • ____doubled = x * 2
  • print(str(normal)+"*2 = "+str(doubled))
  • doubled = get_doubled(normal)
  • ____return doubled
  • def get_doubled(x):
  • normal = float(input("Enter a number: "))

You will get:

  • 1 point for all in correct order

Sample answer

def get_doubled(x):
____doubled = x * 2
____return doubled
normal = float(input("Enter a number: ")) # Placing this line at the top works too.
doubled = get_doubled(normal)
print(str(normal)+"*2 = "+str(doubled))

Marking guidelines

  • 1 point for all in correct order

Question 2 (1p)

Question

How many statements and expressions does the following code contain?

a = 3 * 100
while a < 400:
    a = a * 2
b = a

Number of of statements: ...

Number of expressions: ...

You will get:

  • 1 point for both correct

Sample answer

Number of of statements: 4

Number of expressions: 10

Marking guidelines

  • 1 point for both correct

Question 3 (1p)

Question

What type of error does the code below contain? Syntax error, Logical error, Runtime error or no error at all? The purpose of the function is to compute the sum of the numbers it receives e.g. get_sum(2, 3) โ†’ 5.

def get_sum(number_1, number_2):
    return number_1 + number_1

You will get:

  • 1 point for correct answer

Sample answer

Logical error

Marking guidelines

  • 1 point for correct answer

Question 4 (1p)

Question

What values will be stored in the variables a and b after the following code has been executed?

a = 0
b = 10
while a < 2:
    a = a + 1
    b = b - 1

The variable a will store: ...

The variable b will store: ...

You will get:

  • 1 point for both correct

Sample answer

The variable a will store: 2

The variable b will store: 8

Marking guidelines

  • 1 point for both correct

Question 5 (1p)

Question

Discarded!

This question contains an error (both 1 and a_list matches expression and argument) and has therefor been discarded.

What is what in the code below?

def add_1_to_list(the_list):
    the_list.append(1)
a_list = []
add_1_to_list(a_list)

Pair each code piece with its corresponding name.

Code pieces:

  • add_1_to_list
  • a_list
  • 1
  • the_list

Names:

  • Argument
  • Parameter
  • Expression
  • Function

Note: Some code pieces may match multiple names, but there is only one way to get all 4 pairs right.

You will get:

  • 1 point for all correct

Sample answer

-

Marking guidelines

All get 0 points on this question, and the threshold scores for the different grades are adjusted to the new max score 24 points.

Question 6 (1p)

Question

Which one of the following statements is a bad suggestion on how to represent data?

  • To represent the names of many students, one can use a list with strings, e.g. student_names = ["Alice", "Bob"]
  • To represent an animal of a certain type and an age (in years), one can use a list containing a string and an integer, e.g. animal = ["cat", 7]
  • To represent the number of humans in a house, one can use an integer, e.g. number_of_humans = 4
  • To represent a cat with a name and an age (in years), one can use a dictionary with a string and an integer, e.g. cat = {"name": "Catty", age: 3}
  • To represent the age of the oldest student in a class, one can use an integer, e.g. highest_age_in_class = 29
  • All other statements are good ways of representing data

Sample answer

To represent an animal of a certain type and an age (in years), one can use a list containing a string and an integer, e.g. animal = ["cat", 7]

Marking guidelines

  • 1 point for correct answer

Question 7 (1p)

Question

The following expression:

range(2, 8, 3)

Creates a range containing some integers. What is the sum of the integers in that range?

Sample answer

The sum is: 7

Marking guidelines

  • 1 point for correct answer

Question 8 (1p)

Question

What non-negative integers should be assigned to the variables x and y to slice out the values "c" and "d" in the code below?

my_list = ["a", "b", "c", "d", "e"]
x = ?
y = ?
my_new_list = my_list[x:y]
# my_new_list should now be ["c", "d"]

You will get:

  • 1 point for both correct

Sample answer

x: 2

y: 4

Marking guidelines

  • 1 point for both correct

Question 9 (1p)

Question

Write the following code:

my_list = []
for c in "hello":
    my_list.append(c+c)

As a list comprehension expression instead. Your own code should have the exact same meaning as the code above.

Sample answer

my_list = [c+c for c in "hello"]

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reduction for errors:
    • -0.1 points for naming the my_list variable wrong
    • -0.25 points for using ยจ instead of "
    • -0.5 points for missing [ and ]
    • -0.75 points for not having =
    • -1 point for not creating the my_list variable

Question 10 (1p)

Question

Here is a quite complex structure with information about different movies:

movies = {
    "action": [
        {"name": "GoldenEye", "runtime": 110},
        {"name": "Mission Impossible", "runtime": 115},
        {"name": "Pearl Harbor", "runtime": 160}
    ],
    "drama": [
        {"name": "Titanic", "runtime": 180},
        {"name": "Love Actually", "runtime": 120}
    ]
}

Given this very structure, write an expression that evaluates to the name of the movie with the runtime 180, i.e. Titanic.

Note: Do not write a statement, and simply writing "Titanic" is of course not OK; the value needs to be retrieved from the structure.

Sample answer

movies["drama"][0]["name"]

Marking guidelines

  • 0 points for an answer being a statement
  • 1 point for an answer that is an expression that works
    • -0.25 points for using ยจ instead of "

Question 11 (1p)

Question

Suggest how the following data in Python:

pets = [{
    "name": "Catty",
    "type": "cat"
}, {
    "name": "Doggy",
    "type": "dog"
}]

Can be expressed in XML format.

Note: This question is not about writing Python code, but XML code.

Sample answer

<pets>
    <pet>
        <name>Catty</name>
        <type>cat</type>
    </pet>
    <pet>
        <name>Doggy</name>
        <type>dog</type>
    </pet>
</pets>

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for errors:
    • -0.25 points for surrounding values with double quotes
    • -0.25 points for closing with <X/> instead of </X>
    • -0.25 points for writing cat as Cat, and similar
    • -0.5 points for using <X> instead of <pet>
    • -0.5 points for using <pet1> and <pet2> instead of <pet>
    • -1 point for missing the <pet> element
    • -1 point for using irrelevant element
    • -1 point for surrounding values with < and >
    • -1 point for surrounding tag names with double quotes

Question 12 (1p)

Question

Suggest how the following data in Python:

pets = [{
    "name": "Catty",
    "type": "cat"
}, {
    "name": "Doggy",
    "type": "dog"
}]

Can be expressed in CSV format.

Note: This question is not about writing Python code, but CSV code.

Note: Do not write any extra characters not needed.

Sample answer

Catty,cat
Doggy,dog

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for errors:
    • -0.25 points for writing extra characters not needed (such as spaces and ")
    • -0.25 points for writing cat as Cat, and similar

Question 13 (1p)

Question

What will be stored in the variable sum after the following code has been executed?

def a(number):
    number = number + 3

def b(list):
    for number in list:
        number = number + 2

def c(list):
    for i in range(len(list)):
        list[i] = list[i] + 1

my_list = [0, 0]

a(my_list[0])
b(my_list)
c(my_list)
a(my_list[1])
b(my_list)

sum = my_list[0] + my_list[1]

Sample answer

sum: 2

Marking guidelines

  • 1 point for correct answer

Question 14 (1p)

Question

Implement the function get_number, which receives the name of a digit in English, and should return the number that digit represents (0 for zero, 1 for one, etc.). You only need to support the digits that are shown in the table below.

Digit nameNumber
zero0
one1
two2
three3
four4

If the name of the digit the function receives is not one of the ones in the table above, return -1.

Sample usage:

get_number('two')   โ†’   2
get_number('three hundred and twenty one')   โ†’   -1

Sample answer

def get_number(digit_name):
    if digit_name == "zero":
        return 0
    elif digit_name == "one":
        return 1
    elif digit_name == "two":
        return 2
    elif digit_name == "three":
        return 3
    elif digit_name == "four":
        return 4
    else:
        return -1

Marking guidelines

  • 0 points for function using input()
  • 1 point for a solution that works
  • Point reduction for small mistakes or doing weird things:
    • -0.1 points for spelling name of function wrong
    • -0.1 points for each bad variable name
    • -0.1 points for each forgotten :, =, etc.
    • -0.1 points for :, =, etc. that shouldn't be there
    • -0.1 points for converting the argument into a string
    • -0.1 points for having the wrong order of the operands in the in operator
    • -0.2 points for having quotes around numbers
    • -0.25 points for converting the argument into an int
    • -0.5 points for printing instead of returning result
    • -0.5 points for strange conditions, like number >= 0 and <= 0
    • -0.5 points for not handling the -1 case

Question 15 (2p)

Question

Write a program that keeps asking the user to enter an integer until the user enters stop. The program should then compute the average value of the integers the user entered. When running the program, it can look like this (bold text represents text entered by the user).

Enter an integer or stop: 0
Enter an integer or stop: 6
Enter an integer or stop: 4
Enter an integer or stop: 10
Enter an integer or stop: stop
The average is 5.

Note: The output should look precisely as in the example above (including white-spaces, but with the exception of the boldness from the input, of course).

Note: You can expect the user to actually enter an integer or stop (no error handling needed).

Note: You can expect the user to enter at least one integer before entering stop.

Sample answer

integers = []

entered_text = ""

while entered_text != "stop":
    
    entered_text = input("Enter an integer or stop: ")
    
    if entered_text != "stop":
        integers.append(int(entered_text))

sum = 0

for number in integers:
    sum += number

average = sum / len(integers)

print("The average is "+str(average)+".")

Marking guidelines

  • 2 points for a program that largely works
  • Point reduction for small mistakes or doing weird things:
    • -0.1 points for each place the output is wrong
    • -0.1 points for each forgotten/wrong :, =, etc.
    • -0.1 points for each misspelled while, print, True etc.
    • -0.25 points for str("a string")
    • -0.25 points for not converting input to int before addition
    • -0.25 points for writing ( instead of input(
    • -0.25 points for not converting input to int
    • -0.25 points for defining a function without calling it (task was to create a program)
    • -0.25 points for not initializing a variable
    • -0.25 points for int("stop")
    • -0.25 points for len(list) when it should be sum(list)
    • -0.25 points for not printing what the average is.
    • -0.25 points for creating a variable outside a function that should be inside the function
    • -0.25 points for not using the first input("Enter an integer or stop: ")
    • -0.25 points for sum.numbers instead of sum(numbers)
    • -0.5 points for print(input(...))
    • -0.5 points for counter += int(userinput)
    • -0.5 points for printing average in each iteration
    • -0.5 points for using return outside function
    • -0.5 points for returning when one shouldn't
    • -1 point for program only creating a function, but never calling it

Question 16 (2p)

Question

Implement the function contains_5, which receives a list of numbers, and returns:

  • True if at least one of the numbers in the list is the number 5
  • False otherwise

Write two different implementations of the function: one using a while loop, and another one using a for loop.

Sample usage:

contains_5([1, 2, 7, 8]) โ†’ False
contains_5([7, 5, 3])    โ†’ True
contains_5([5, 5, 5])    โ†’ True
contains_5([])           โ†’ False

Note: You may not use the in nor the not in operators in your answer.

Sample answer

def contains_5(numbers):
    for number in numbers:
        if number == 5:
            return True
    return False

def contains_5(numbers):
    index = 0
    while index < len(numbers):
        if numbers[index] == 5:
            return True
        index += 1
    return False

Marking guidelines

  • 1 point for the function with the for loop largely working
  • 1 point for the function with the while loop largely working
  • Point reduction for small mistakes or doing weird things:
    • -0.1 points for each bad name (e.g. argument)
    • -0.1 points for unnecessary else/pass
    • -0.1 points for using true/false instead of True/False
    • -0.2 points for indentation error
    • -0.2 using range in while
    • -0.2 points for being inconsistent with variable name convention
    • -0.2 points for forgetting to use len
    • -0.25 for not having def
    • -0.25 points for indentation error
    • -0.25 points for crashing if the list is empty
    • -0.25 points for going out of bounds with index + 1
    • -0.25 points for not incrementing iteration variable in while loop
    • -0.25 points for not initializing iteration variable in while loop
    • -0.25 points for each implementation not handling empty list
    • -0.25 points for iterating over indexes in the for loop
    • -0.25 points for using "5" instead of 5, or "True" instead of True, etc.
    • -0.5 points for iterating over values in the for loop, but using them as indexes
    • -0.75 points for always returning True/False in first iteration
    • -0.8 points for having implemented are_all_5()

Question 17 (3p)

Question

Below is some data about houses owned by some humans.

houses = [
   {"owner": "Alice", "name": "Alice's Palace", "number_of_rooms": 9, "number_of_windows": 20},
   {"owner": "Alice", "name": "Alice's Home",   "number_of_rooms": 3, "number_of_windows": 5},
   {"owner": "Alice", "name": "Alice's Cabin",  "number_of_rooms": 1, "number_of_windows": 4},
   {"owner": "Bob",   "name": "Bob's Home",     "number_of_rooms": 4, "number_of_windows": 16},
   {"owner": "Bob",   "name": "Bob's Cabin",    "number_of_rooms": 1, "number_of_windows": 1}
]

It's cold in the winter, and it costs money to heat the houses. To heat a single house costs:

  • 100 SEK each month...
  • ...+ 10 SEK each month for each room in the house...
  • ...+ 50 SEK each month for each window in the house

Write code that computes and prints the name of the human that must pay the highest heating cost per month for all the houses that human owns combined.

Note: Your code should still work as expected if one adds/removes houses to/from the list. Alice and Bob are not the only ones who can own a house.

Sample answer

heat_base_cost_per_house = 100
heat_cost_per_room = 10
heat_cost_per_window = 50

# Compute the total costs for each human.
costs_by_owner = {} # {"Alice": 123, ...}

for house in houses:
    
    if house["owner"] not in costs_by_owner:
        costs_by_owner[house["owner"]] = 0
    
    costs_by_owner[house["owner"]] += (
        heat_base_cost_per_house +
        heat_cost_per_room * house["number_of_rooms"] +
        heat_cost_per_window * house["number_of_windows"]
    )

# Find the owner with the highest cost.
most_expensive_owner = ""
most_expensive_cost = -1

for owner in costs_by_owner:
    cost = costs_by_owner[owner]
    if most_expensive_cost < cost:
        most_expensive_owner = owner
        most_expensive_cost = cost

print(most_expensive_owner)

Marking guidelines

  • 1.5 point for computing the costs for all owners
  • 1.5 point for finding the owner with the highest cost
  • Point reduction for small mistakes or doing weird things:
    • -0.25 points for each bad name
    • -0.25 points for iterating over indexes instead of values
    • -0.25 points for adding same house cost to an owner twice

Question 18 (2p)

Question

The class Clock represents a time consisting of an hour unit and a minute unit. The hour unit is always between 0 and 23, and the minute unit is always between 0 and 59.

The class has the following constructor/methods:

Constructor/MethodDescription
Clock(hour, minute)Creates a new clock representing the time at the given hour and minute (both integers)
add_one_minute()Adds one minute to the time in the clock. If the minute part becomes 60, it should be set to 0, and the hour part should be increased by one. If the hour part becomes 24, it should be set to 0, and True should be returned. False should be returned in all other cases
get_time_as_string()Returns the current time in the HH:MM format, e.g. 03:08. Note that the hour and minute parts in the string always consists of 2 digits

Write a program making use of the class. In the program, you should first ask the user to enter the start time of the clock as two integers, and then continue to ask the user if she wants to add one minute to the time in the clock until she doesn't want to do that anymore. And if the clock becomes 00:00 after having added a minute to it, print a special text to the user. For the details, see the sample usage below.

Sample usage:

Enter start hour: 23
Enter start minute: 57
Do you want to add one more minute? (y/n): y
Current time is 23:58.
Do you want to add one more minute? (y/n): y
Current time is 23:59.
Do you want to add one more minute? (y/n): y
Starting a new day.
Do you want to add one more minute? (y/n): y
Current time is 00:01.
Do you want to add one more minute? (y/n): y
Current time is 00:02.
Do you want to add one more minute? (y/n): n
The final time is 00:02.

Note: The output should look precisely as in the example above (including white-spaces, but with the exception of the boldness from the input, of course).

Note: No error handling is needed; you can expect the user to always enter two integers in the beginning, and then y or n.

Sample answer

hour = int(input("Enter start hour: "))
minute = int(input("Enter start minute: "))

clock = Clock(hour, minute)

should_continue_to_ask = True

while should_continue_to_ask:
    
    add_one_minute_answer = input("Do you want to add one more minute? (y/n): ")
    
    if add_one_minute_answer == "y":
        
        clock_changed_day = clock.add_one_minute()
        
        if clock_changed_day:
            print("Starting a new day.")
        else:
            print("Current time is "+clock.get_time_as_string()+".")
        
    else:
        should_continue_to_ask = False

print("The final time is "+clock.get_time_as_string()+".")

Marking guidelines

  • 2 points for an answer that largely works
  • Point reduction for errors:
    • -0.25 points for using clock instead of Clock to create new instance
    • -0.25 points for storing the Clock instance in a variable named Clock (as the class!)
    • -0.25 points for clock.get_time_as_string().split(":")[0] == "00" and clock.get_time_as_string().split(":")[1] == "00" instead of using return value from add_one_minute()
    • -0.25 points for using true instead of True
    • -0.25 points for using str() to convert a string into a string (not needed)
    • -0.25 points for output too different from example
    • -0.5 points for not using parentheses after method to call it
    • -0.5 points for using the wrong condition in the loop
    • -0.5 points for not handling the special "new day" case correct (e.g. ignoring it, or also printing 00:00, or calling add_one_minute() twice in each iteration)
    • -0.5 points for never printing the new time in each iteration
    • -1 point for not creating a clock variable

Question 19 (2p)

Question

The class Clock represents a time consisting of an hour unit and a minute unit. The hour unit is always between 0 and 23, and the minute unit is always between 0 and 59.

The class has the following constructor/methods:

Constructor/MethodDescription
Clock(hour, minute)Creates a new clock representing the time at the given hour and minute (both integers)
add_one_minute()Adds one minute to the time in the clock. If the minute part becomes 60, it should be set to 0, and the hour part should be increased by one. If the hour part becomes 24, it should be set to 0, and True should be returned. False should be returned in all other cases
get_time_as_string()Returns the current time in the HH:MM format, e.g. 03:08. Note that the hour and minute parts in the string always consists of 2 digits

Implement the Clock class per the description above.

Sample answer

class Clock:
    
    def __init__(self, hour, minute):
        self.hour = hour
        self.minute = minute
    
    def add_one_minute(self):
        
        self.minute = self.minute + 1
        
        if self.minute == 60:
            
            self.minute = 0
            self.hour = self.hour + 1
            
            if self.hour == 24:
                self.hour = 0
                return True
        
        return False
    
    def get_time_as_string(self):
        
        if self.hour < 10:
            hh = "0"+str(self.hour)
        else:
            hh = str(self.hour)
        
        if self.minute < 10:
            mm = "0"+str(self.minute)
        else:
            mm = str(self.minute)
        
        return hh+":"+mm

Marking guidelines

  • 0 points to answers not using the self parameter at all, or using class variables instead of instance variables
  • 0.5 points for having the constructor correct
  • 0.75 points for having add_one_minute() largely correct
  • 0.75 points for having get_time_as_string() largely correct
  • Point reductions for small mistakes:
    • -0.25 points for each missing self parameter
    • -0.25 points for len(self.hour) < 2, but otherwise logically correct
    • -0.25 points for using elif to see if hour/minute needs an extra 0 at the start (both can need it!)
    • -0.25 points for printing time in get_time_as_string() instead of returning it
    • -0.25 points for having parameters to the class
    • -0.5 points for not creating the hh:mm string correct
    • -0.5 points for creating extra variables not used
    • -0.5 points for not setting minute/hour to 0 when needed in add_one_minute()