Exam 2023-02-15

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

Information

Start by reading through all questions. Peter will not visit the exam. If you find any question unclear, ask one of the exam administrators (tentavakt in Swedish) to call Peter, and he will clarify the question over the phone.

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

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 😞)).

  • ____color = "#"+number+number+number
  • def get_color():
  • number = input("Enter number: ")
  • print(color+" is a nice color.")
  • color = get_color()
  • ____return color

You will get:

  • 1 point for all in correct order

Sample answer

number = input("Enter number: ")
def get_color():
____color = "#"+number+number+number
____return color
color = get_color()
print(color+" is a nice color.")

Marking guidelines

  • 1 point for all in correct order

Question 2 (1p)

Question

How many statements and expressions does the following code contain?

while True:
    if a < b:
        a = a * 2

Number of of statements: ...

Number of expressions: ...

You will get:

  • 1 point for both correct

Sample answer

Number of of statements: 3

Number of expressions: 7

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 2

You will get:

  • 1 point for correct answer

Sample answer

Syntax 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 = 3
b = 3
while a != 0:
    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: 0

The variable b will store: 6

Marking guidelines

  • 1 point for both correct

Question 5 (1p)

Question

What is what in the code below?

radius = 1
def add_with_radius(number):
    return radius + number
result = add_with_radius(5)

Pair each code piece with its corresponding name.

Code pieces:

  • number
  • 5
  • add_with_radius
  • radius

Names:

  • Variable
  • Parameter
  • Argument
  • 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

  • Variable - radius
  • Parameter - number
  • Argument - 5
  • Function - add_with_radius

Marking guidelines

  • 1 point for all correct

Question 6 (1p)

Question

Bart is assigned the task to implement a program that prints this:

B
a
a
r
r
r
t
t
t
t

Bart writes the following code:

name = "Bart"

for i in range(len(name) + 1):
    
    letter = name[i]
    
    for j in range(i):
        print(letter)

Bart's solution does not work as it should. Explain what errors Bart has done, and suggest how to fix them.

Sample answer

One problem is that he has range(len(name) + 1). Because of that, the program will try to print the letter with index 4, which doesn't exist. It should just be range(len(name))

Another problem is that the inner for loop iterates over range(i). Here, he should instead use range(i + 1), so for the first letter (i = 0), it will iterate 1 time, etc.

Marking guidelines

  • 0.25 points for first error
  • 0.25 points for correct solution to first error
  • 0.25 points for second error
  • 0.25 points for correct solution to second error

Question 7 (1p)

Question

The following expression:

range(2, 2, 2)

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

Sample answer

The sum is: 0

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 "d" and "e" 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 ["d", "e"]

You will get:

  • 1 point for both correct

Sample answer

x: 3

y: 5

Marking guidelines

  • 1 point for both correct

Question 9 (1p)

Question

Write the following code:

my_list = [x*2 for x in numbers() if x % 2 == 0]

As statements using a loop instead. Your own code should have the exact same meaning as the code above.

Sample answer

my_list = []
for x in numbers():
    if x % 2 == 0:
        my_list.append(x)

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reduction for errors:
    • -0.1 points for missing :
    • -0.1 points for spelling variable wrong
    • -0.25 points for indentation error

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 runtime of the movie with the name Mission Impossible, i.e. 115.

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

Sample answer

movies["action"][1]["runtime"]

Marking guidelines

  • 0 points for an answer being a statement
  • 1 point for an answer that is an expression that works
    • -0.5 points for not having quotes around action or runtime

Question 11 (1p)

Question

Suggest how the data in the XML code below:

<games>
    <game>
        <title>Super Mario Bros.</title>
        <year>1985</year>
    </game>
    <game>
        <title>The Legend of Zelda: A Link to the Past</title>
        <year>1991</year>
    </game>
</games>

Can be represented in Python (i.e. create a Python variable with a descriptive name that contains the same data as the XML code above does).

Note: This question is not about writing Python code that reads data from the XML code; you should just write Python code that creates a variable that contains the same (hard coded) data that is currently shown in the XML code above.

Sample answer

games = [{
    "title": "Super Mario Bros.",
    "year": 1985
}, {
    "title": "The Legend of Zelda: A Link to the Past",
    "year": 1991
}]

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for errors:
    • -0.25 points for bad variable name (like game instead of games)
    • -0.25 points for a dict (instead of list) that contains dict games
    • -0.25 points for representing year as string

Question 12 (1p)

Question

Suggest how the data in the XML code below:

<games>
    <game>
        <title>Super Mario Bros.</title>
        <year>1985</year>
    </game>
    <game>
        <title>The Legend of Zelda: A Link to the Past</title>
        <year>1991</year>
    </game>
</game>

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

Super Mario Bros.,1985
The Legend of Zelda: A Link to the Past,1991

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 ")

Question 13 (1p)

Question

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

def a(number):
    number = number + 2

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

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

my_list = [0, 1]

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

sum = my_list[0] + my_list[1]

Sample answer

sum: 13

Marking guidelines

  • 1 point for correct answer

Question 14 (1p)

Question

Implement the function get_number_of_digits(), which receives an integer, and should return the number digits that integer contains. The integer the function receives will always be between 1 and 999.

Sample usage:

get_number_of_digits(8)   →   1
get_number_of_digits(9)   →   1
get_number_of_digits(23)   →   2
get_number_of_digits(471)   →   3
get_number_of_digits(892)   →   3

Sample answer

def get_number_of_digits(integer):
    if integer < 10:
        return 1
    elif integer < 100:
        return 2
    else:
        return 3

Marking guidelines

  • 1 point for a solution that works
  • Point reduction for small mistakes or doing weird things:
    • -0.1 points for each forgotten :, =, def etc.
    • -0.1 points for writing =< instead of <=
    • -0.1 points for each bad variable name
    • -1 point for using a loop

OR:

  • 0.25 points for using len to compute the number of digits without converting the number to a string first

Question 15 (2p)

Question

Write a program that keeps asking the user to enter an integer until the user enters stop. The program should count how many odd respective even (the opposite to odd) integers the user entered, and then show that to the user. To check if an_integer is odd, you can use the expression an_integer % 2 == 1. When running the program, it can look like this (bold text represents text entered by the user).

Enter an integer or stop: 8
Enter an integer or stop: 3
Enter an integer or stop: 4
Enter an integer or stop: 9
Enter an integer or stop: 5
Enter an integer or stop: stop
You entered 3 odd integers and 2 even integers.

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).

Sample answer

number_of_odd_integers = 0
number_of_even_integers = 0

entered_text = ""

while entered_text != "stop":
    
    entered_text = input("Enter an integer or stop: ")
    
    if entered_text != "stop":
        
        entered_integer = int(entered_text)
        
        if entered_integer % 2 == 1:
            number_of_odd_integers += 1
        else:
            number_of_even_integers += 1

print("You entered "+str(number_of_odd_integers)+" odd integers and "+str(number_of_even_integers)+" even integers.")

Marking guidelines

  • 2 points for a program that largely works
  • Point reduction for small mistakes or doing weird things:
    • -0.1 points for each bad variable name
    • -0.1 points for each forgotten/wrong :, =, etc.
    • -0.1 points for each misspelled while, print, True etc.
    • -0.25 points for int("stop")
    • -0.25 points for not using quotes around strings
    • -0.25 points for using a variable before it has been assigned a value
    • -0.25 points for not converting the entered number to an int
    • -0.25 point for using print() in each iteration
    • -0.5 points for returning when one shouldn't
    • -1 point for only asking for input once (never in the loop)

Question 16 (2p)

Question

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

  • True if all numbers in the list are equal
  • False otherwise

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

Sample usage:

are_all_equal([1, 1, 1, 1]) → True
are_all_equal([5, 5, 5])    → True
are_all_equal([1, 2, 3])    → False
are_all_equal([7, 7, 8])    → False
are_all_equal([])           → True

Note: If the list is empty, return True.

Sample answer

def are_all_equal(numbers):
    for number in numbers:
        if number != numbers[0]:
            return False
    return True

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

Marking guidelines

  • 0 points for solutions that always return True/False in the first iteration
  • 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 writing =< instead of <=, and similar
    • -0.25 points for crashing if the list is empty
    • -0.25 for not having def
    • -0.25 points for iterating over indexes in the for loop
    • -0.25 points for not initializing iteration variable in while loop

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 first computes which house that has the highest heating cost. Then compute how big heating cost the owner of that house has for all the houses that human owns together, and show that to the user.

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

def get_heating_cost(house):
    return (
        heat_base_cost_per_house +
        heat_cost_per_room * house["number_of_rooms"] +
        heat_cost_per_window * house["number_of_windows"]
    )

# Find the house with the highest heating cost.
highest_heating_cost_house = houses[0] # Assume the first house to start with.

for house in houses:
    
    if get_heating_cost(highest_heating_cost_house) < get_heating_cost(house):
        highest_heating_cost_house = house

# Find the total cost that owner pays.
total_cost = 0

for house in houses:
    if highest_heating_cost_house["owner"] == house["owner"]:
        total_cost += get_heating_cost(house)

# Show the result.
print("The one with the most expensive heating cost for a single house pays "+str(total_cost)+" in heating cost for all houses that one owns.")

Marking guidelines

  • 1.5 point for computing the house with highest heating cost
  • 1.5 point for computing sum of heating the houses owned by that owner
  • 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

Question 18 (2p)

Question

The class Population represents a population of humans.

The class has the following constructor/methods:

Constructor/MethodDescription
Population()Creates a new empty population
add_human(name, is_female)Adds one human to the population with the given name (string) and the given is_female (True for females, False for males)
get_percentage_females()Returns the percentage (a number between 0 and 100) of the population that are females
get_percentage_males()Returns the percentage (a number between 0 and 100) of the population that are males

Write a program making use of the class. In the program, you should continue to ask the user to enter the name, sex and age of a human until the user doesn't want to add any more. Then the program should print how many percentages of the population that are females respective males.

Sample usage:

Enter one more human? (yes/no): yes
Enter name: Alice
Enter sex (female/male): female
Enter one more human? (yes/no): yes
Enter name: Bob
Enter sex (female/male): male
Enter one more human? (yes/no): yes
Enter name: Claire
Enter sex (female/male): female
Enter one more human? (yes/no): yes
Enter name: Denise
Enter sex (female/male): female
Enter one more human? (yes/no): no
75% of the population are females.
25% of the population are males.

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). It is OK if the percentage numbers on the last two lines show decimal numbers.

Note: No error handling is needed; you can expect the user to always enter valid values.

Sample answer

population = Population()

should_continue_to_ask = True

while should_continue_to_ask:
    
    add_one_more_answer = input("Enter one more human? (yes/no): ")
    
    if add_one_more_answer == "yes":
        
        name = input("Enter name: ")
        sex = input("Enter sex (female/male): ")
        
        is_female = (sex == "female")
        
        population.add_human(name, is_female)
        
    else:
        should_continue_to_ask = False

print(str(population.get_percentage_females())+"% of the population are females.")
print(str(population.get_percentage_males())+"% of the population are males.")

Marking guidelines

  • 2 points for an answer that largely works
  • Point reduction for errors:
    • -0.1 points for each bad variable name
    • -0.1 points for While
    • -0.25 points for never exiting the loop

Question 19 (2p)

Question

The class Population represents a population of humans.

The class has the following constructor/methods:

Constructor/MethodDescription
Population()Creates a new empty population
add_human(name, is_female)Adds one human to the population with the given name (string) and the given is_female (True for females, False for males)
get_percentage_females()Returns the percentage (a number between 0 and 100) of the population that are females
get_percentage_males()Returns the percentage (a number between 0 and 100) of the population that are males

Implement the class per the description above.

Sample answer

class Population:
    
    def __init__(self):
        self.humans = []
    
    def add_human(self, name, is_female):
        
        self.humans.append({
            "name": name,
            "is_female": is_female
        })
    
    def get_percentage_females(self):
        
        number_of_females = 0
        
        for human in self.humans:
            if human["is_female"]:
                number_of_females += 1
        
        return number_of_females / len(self.humans) * 100
    
    def get_percentage_males(self):
        return 100 - self.get_percentage_females()

Marking guidelines

  • 0 points to answers not using the self parameter at all, or using class variables instead of instance variables
  • 2 points for a solution that largely works
  • Point reductions for errors:
    • -0.1 points for Class
    • -0.1 points for naming the class wrong
    • -0.25 points for not having def