9 Solutions

9.1 Chapter 1. Introduction

9.2 Chapter 2. Variables, values and types

9.2.1 Exercise 1. Operators

x = 2
y = 1.0
print(x + y)
## 3.0
x = 4.0
y = x + 1
print(x + y)
## 9.0
x = 1
y = "1.0"
print(x + y)
x = 4
y = 4.0
print(x == y)
## True
x = 12
y = x / 2
print(y >= 5)
## True

9.2.2 Exercise 2. Values

Statements 2 and 4 are true

  • Each value exclusively belongs to one data type
  • Variables can be assigned any type of value

9.2.3 Exercise 3. Mini programs

x = "1.0"
y = "1"
print(x + y)
## 1.01
x = 5
y = 2
print((x / y) == 2.5)
## True
x = 1
x = x + 1
x = x - 2
print(x)
## 0

9.2.4 Exercise 4. Debugging

What goes wrong in the following code snippets?

x = 1
2x = 2
print(x + 2x)
  • An illegal variable name is used
x = 3
y = "3"
print(x = y)
  • The assignment operator is used instead of a comparative operator
name = "Colin"
print(This is + name)
  • The content inside the brackets of the print statement lacks quotation marks

9.2.5 Exercise 5. String concatenation

  • The statement ‘Veni, vidi, vici.’ was coined by Gaius Julius Caesar.
  • The statement ‘Veni, vidi, vici.’, ‘I came, I saw, I conquered.’, was coined by Gaius Julius Caesar.
  • The statement ‘Veni, vidi, vici.’ was coined by Gaius Julius Caesar, supposedly around 47 BC. Alternatively, it is also correct to say that the execution stops before the print statement due to the errornous string concatenation in the line before.
  1. The + operator joins two strings, resulting in one string. The string at the left side of the operator precedes the string at the right side of the operator in the resulting string.

  2. myString = myString + s1 + s2 + year + s3: the variable yearis of type int which causes a TypeError during concatenation; integer objects and string objects cannot be concatenated. The error can be solved by either explicit typecasting or changing the variable year into a string to start with.

myString = myString + s1 + s2 + str(year) + s3

year = "47"

9.2.6 Exercise 6. Variable names

  • 2ndMan: the variable name starts with a digit
  • m@n3: the @ signs is an illegal character
  • man 5: the space between manand 5 is illegal
  • man_no._7: the fullstop is illegal. Python will think that man_no is a class (which it is not by default) and therefore throw a NameError
  • 8thMan: starting with a digit

9.2.7 Exercise 7. Stroop task welcome message

Note: The below description of what the specified code does is not expected from students. The intention is that they think about what happens internally in PyGame when implementing a task such as ‘printing something to the screen’.

text_surface = font.render(msgText,True,msgColor,BACKGR_COL)
text_rectangle = text_surface.get_rect()
text_rectangle.center = (SCREEN_SIZE[0]/2.0,225)
screen.blit(text_surface,text_rectangle)
  • Line 1 initializes a new Surface object with the pre-defined message msgText and color msgColor rendered on it and assigns it to the variable text_surface. PyGame draws text on a new Surface to create an image (Surface) of the text, then blit this image onto another Surface.
  • Lines 2 and 3 transform the surface to rectangular shape and specify the center of this rectangular shape in relation to the screen size of the program window.
  • Line 4 copies the text Surface and position to the screen Surface, making it visible.

For further clarification, consult the PyGame documentation.

9.2.8 Exercise 8. Printing

participants = 52
trials = 200
experimental_sessions = 3
trials_pp = trials * experimental_sessions
conditions = 4

condition1 = "easy/limited"
condition2 = "easy/unlimited"
condition3 = "difficult/limited"
condition4 = "difficult/unlimited"


print("In total,", participants, "participants participated in the study.")
## In total, 52 participants participated in the study.
print("A 2x2 factorial between-subjects design was employed.")
## A 2x2 factorial between-subjects design was employed.
print("The study examined the interaction of two independent variables: ")
## The study examined the interaction of two independent variables:
print("task difficulty (easy, difficult) and time (limited, unlimited).")
## task difficulty (easy, difficult) and time (limited, unlimited).
print(conditions, "conditions were devised, plus a control condition.")
## 4 conditions were devised, plus a control condition.
print("The conditions were:",condition1,",",condition2,",",condition3,"and",condition4)
## The conditions were: easy/limited , easy/unlimited , difficult/limited and difficult/unlimited
print("Participants were tested in", experimental_sessions, "experimental sessions.")
## Participants were tested in 3 experimental sessions.
print("Each session consisted of",trials,"trials.")
## Each session consisted of 200 trials.
print("In total, each partcipant thus completed", trials_pp, "trials.")
## In total, each partcipant thus completed 600 trials.
  1. Initially, the variable trialsis a string. Multiplying the variable by three thus results in a string consisting of three times the value of trials. This can be fixed either by initializing trials as an integer or using explicit typecasting.
trials_pp = int(trials) * experimental_sessions

9.2.9 Exercise 9. Using Python as calculator

n1 = 37
n2 = 456
n3 = 1027%n1
n2 = n2/n3
n2 += 4
n4 = n2%5
n4 -= 17
n4 = 65%n4/float(2)

print(n4)
## -0.9285714285714306

9.2.10 Exercise 10. A Boolean puzzle

n1 = 238
n2 = 17

print(n1 > n2)
## True
print(n1/17 == 14)
## True
print(n1*n2/float(n1) == n2)
## True
print(n1+(-n1) == n2 - n2 and n1+(-n1) == 972%243 and n2-n2 == 0)
## True
print(n2*(n1*47/n2) == n1*47)
## True
print(n1/4 == n2/1*3 or n1/4 == n2/17*59)
## False

Hardcoded results are also valid, for example

print(n1+(-238) == n2 - 17 and n1+(-238) == 972%243 and n2-17 == 0)

Only for n1*n2/float(n1) == n2 hardcoding will not work.

9.3 Chapter 3. Conditionals

9.3.1 Exercise 1. Boolean logic

What is the output of the following code snippets?

a = True
b = False

print(a and b)
## False
a = True
b = False
print(not a and b)
## False
a = True
b = False
print((not a) or b)
## False
a = True
b = False

print(not (a and b))
## True
a = True
b = False

print(not (a or b))
## False
a = 1
b = 2
c = 4

print(a >= b and c > a + b)
## False
a = 1
b = 2
c = 3

print(b % a >= c - (a + b))
## True

9.3.2 Exercise 2. State charts

# Variables
STATE = "A"
number_of_trials = 0

while True:
  #ITC
  for event in pygame.event.get():
      if STATE == "A":
          number_of_trials = number_of_trials + 1
          if event.type==KEYDOWN and event.key == K_SPACE:
              STATE = "C"
      elif STATE == "C":
          if event.type==KEYDOWN and event.key == K_A or event.key == K_D:
              arrival_at_B = time()
              STATE = "B"
            
  #ATC
  if STATE == "B":
      if time() - arrival_at_B > 3:
          if number_of_trials < 15:
              STATE = "A"
          else:
              pygame.quit()
              sys.exit()

9.3.3 Exercise 3. Transition tables

For the following code snippet, make a transition table.

STATE = "A"

while True:
    #ITC
    for event in pygame.event.get():                        
        if STATE == "A":
            count = 0
            if event.type == KEYDOWN and event.key == K_w:
                STATE = "B"
                print(STATE)
        elif STATE == "B":
            count = count + 1
            if event.type == KEYDOWN and event.key == K_a:
                timer = time()
                STATE = "C"
                print(STATE)
        elif STATE == "D":
            if event.type == KEYDOWN and event.key == K_SPACE:
                if count < 10:
                    STATE = "B"
                else:
                    STATE = "quit"
                print(STATE)

    #ATC
    if STATE == "C":
        present_picture()
        if time() - timer > 3:
            STATE = "D"
        print(STATE)
    elif STATE == "quit":
        pygame.quit()
        sys.exit()
A B C D quit
FROM A w
B a
C after 3s
D SPACE AND count < 10 SPACE AND count >= 10
quit

9.3.4 Exercise 4. Mini programs

What is the output of the following mini programs?

x = 5
y = 0

if x >= 5 and y != False:
    print(y/x)
  • Nothing
x = 12

if x%3 == 0:
    print("x is divisible by 3")
elif x%4 == 0:
    print("x is divisible by 4")
  • x is divisible by 3
x = 2
y = 0

if y + 1 == x or not x * 1 <= y:
   print(x + y)
  • 2

9.3.5 Exercise 5. Following the control flow

myString = "Hello, World!"
if len(myString) >= 13 or "ello" in myString:
    myString = "Hi, programming aspirant!"
elif len(myString) <= 12 and "ello" in myString:
    myString = "Hello, from the other side."
print(myString)
## Hi, programming aspirant!
if "Hi" in myString:
    if len(myString) < 25:
        myString = "Wow, my computer seems to answer!"
    elif len(myString) > 25:
        myString = myString + " -- Your computer"
    else:
        myString = myString + " How are you?"
else:
    if len(myString) <= 29:
        myString = "How are you, my computer?"
    elif len(myString) == 27 and "Hello" in myString:
        myString = myString + " I must have called a thousand times."
    else:
        myString = myString + " -- Adele"
print(myString)
## Hi, programming aspirant! How are you?
if "computer" in myString or len(myString) == 38 or "HI" in myString:
    myString = myString + " I myself am doing fine."
else:
    myString = myString + " I am doing just fine."
print(myString)
## Hi, programming aspirant! How are you? I myself am doing fine.

9.3.6 Exercise 6. Indentation

myNumber = 4
if myNumber < 20 and myNumber > 0:
    if myNumber > 0 and myNumber < 15:
        myNumber = myNumber + 3
    else:
        myNumber = myNumber - 3
        print("This is a dead end statement.")
elif myNumber > 20:
    print("This should only be printed if myNumber exceeds 20!")
else:
    myNumber = 17

9.3.7 Exercise 7. Pseudo code conditionals


1.
If not rain
    if Jan has time
        do swimming
    else
        do hiking
else
    do read
    
2.
if age >= 18 and not alcohol abuse
    set participation to True
    
3.
if rain
    set wet to True
    
4.
if eligible
    do briefing
    if condition equals A
        do lead to 001
    else
        do lead to 002
else
    do explain

Number 3 is an example of the infamous Modus Ponens, where a condition a implies condition b. Whenever a is True, b must also be True. Why is it so famous? Two reasons:

  1. In mathematical proofs, a is called the sufficient condition for b, meaning that when a is True, b must be True as well. However, that does not exclude the possibility that b becomes True due to another condition c. For example:

    When it rains the streets are wet

    does not exclude the possibility that the street is wet because it has been washed with water.

  2. In psychology of reasoning it has been shown that people have difficulties with checking the modus ponens. When asked to verify the above example, most people would first check whether the street is wet, although the most relevant question is whether it is raining, indeed.

9.3.8 Exercise 8. Modify Stroop Task

import pygame
import sys
from time import time
import random
from pygame.locals import *
from pygame.compat import unichr_, unicode_

##### VARIABLES #####
# Colors
col_white = (250, 250, 250)
col_black = (0, 0, 0)
col_gray = (220, 220, 220)
col_red = (250, 0, 0)
col_green = (0, 200, 0)
col_blue = (0, 0, 250)
col_yellow = (250,250,0)

NTRIALS = 5

WORDS    = ("red", "green", "blue")

COLORS   = {"red": col_red,
            "green": col_green,
            "blue": col_blue}

KEYS     = {"red": K_b,
            "green": K_n,
            "blue": K_m}


BACKGR_COL = col_gray
SCREEN_SIZE = (700, 500)

pygame.init()
pygame.display.set_mode(SCREEN_SIZE) 
pygame.display.set_caption("Stroop Test")

screen = pygame.display.get_surface()
screen.fill(BACKGR_COL)

font = pygame.font.Font(None, 80)
font_small = pygame.font.Font(None, 40) 


def main():
    """ Start the Stroop task.
    """
    ## Variables
    STATE = "welcome"
    trial_number = 0

    # for gathering the response times
    RT = []

    while True:
        pygame.display.get_surface().fill(BACKGR_COL)        

        # Changing states by user input
        for event in pygame.event.get():
            # welcome screen --> prepare next trial (space bar)
            if STATE == "welcome":
                if event.type == KEYDOWN and event.key == K_SPACE:
                    STATE = "prepare_next_trial"
                    print(STATE)

            # wait for response --> feedback (b, n, m)
            elif STATE == "wait_for_response":
                if event.type == KEYDOWN and event.key in KEYS.values():
                    # remember when the user has reacted
                    time_when_reacted = time()
                    # calculate the response time
                    this_reaction_time = time_when_reacted - time_when_presented
                    RT.append(this_reaction_time)
                    # was the response correct?
                    this_correctness = (event.key == KEYS[this_color])
                    STATE = "feedback"
                    print(STATE)

            if event.type == QUIT:
                STATE = "quit"

        # automatic state transitions
        # prepare next trial --> wait for response (immediatly)
        if STATE == "prepare_next_trial":
            trial_number = trial_number + 1
            # randomly pick word and color
            this_word  = pick_color()
            this_color = pick_color()
            # remember when stimulus was presented
            time_when_presented = time()
            STATE = "wait_for_response"
            print(STATE)

        # show feedback, then advance to next trial or goodbye  (for 1s)
        if STATE == "feedback" and (time() - time_when_reacted) > 1:
            if trial_number < NTRIALS:
                STATE = "prepare_next_trial"
            else:
                STATE = "goodbye"
            print(STATE)

        # Drawing to the screen
        if STATE == "welcome":
            draw_welcome()
            draw_button(SCREEN_SIZE[0]*1/4, 450, "Red: B", col_red)
            draw_button(SCREEN_SIZE[0]*2/4, 450, "Green: N", col_green)
            draw_button(SCREEN_SIZE[0]*3/4, 450, "Blue: M", col_blue)
        
        if STATE == "wait_for_response":
            draw_stimulus(this_color, this_word)
            draw_button(SCREEN_SIZE[0]*1/4, 450, "Red: B", col_red)
            draw_button(SCREEN_SIZE[0]*2/4, 450, "Green: N", col_green)
            draw_button(SCREEN_SIZE[0]*3/4, 450, "Blue: M", col_blue)
        
        if STATE == "feedback":
            draw_feedback(this_correctness, this_reaction_time)
        
        if STATE == "goodbye":
            draw_goodbye()
        
        if STATE == "quit":
            pygame.quit()
            sys.exit()

        pygame.display.update()
        
def pick_color():
    """ Return a random word.
    """
    random_number = random.randint(0,2)
    return WORDS[random_number]

def draw_button(xpos, ypos, label, color):
    text = font_small.render(label, True, color, BACKGR_COL)
    text_rectangle = text.get_rect()
    text_rectangle.center = (xpos, ypos)
    screen.blit(text, text_rectangle)

def draw_welcome():
    text_surface = font.render("STROOP Experiment", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)
    text_surface = font_small.render("Press Spacebar to continue", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,300)
    screen.blit(text_surface, text_rectangle)

def draw_stimulus(color, word):
    text_surface = font.render(word, True, COLORS[color], col_gray)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)

def draw_feedback(correct, reaction_time):
    if correct:
        text_surface = font_small.render("correct", True, col_black, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
        screen.blit(text_surface, text_rectangle)
        text_surface = font_small.render(str(int(reaction_time * 1000)) + "ms", True, col_black, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,200)
        screen.blit(text_surface, text_rectangle)
        if reaction_time > 5:
            text_surface = font_small.render("Come on, you can be faster!", True, col_black, BACKGR_COL)
            text_rectangle = text_surface.get_rect()
            text_rectangle.center = (SCREEN_SIZE[0]/2.0,250)
            screen.blit(text_surface, text_rectangle)
            
    else:
        text_surface = font_small.render("Wrong key!", True, col_red, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
        screen.blit(text_surface, text_rectangle)
        #text_surface = font_small.render("Press Spacebar to continue", True, col_black, BACKGR_COL)


def draw_goodbye():
    text_surface = font_small.render("END OF THE EXPERIMENT", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)
    text_surface = font_small.render("Close the application.", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,200)
    screen.blit(text_surface, text_rectangle)
    
main()

9.3.9 Exercise 9. Simplify nested conditionals

# participant details #
age = 20
gender = "Male"
study = "Psychology"
speaks_Dutch = True
coffee = True
condition = "not eligible for the experiment"

## version 1
### The order of checking for study, coffee and
### language proficiency are interchangable
if age >= 18:
    if study == "Psychology" or study == "Communication Sciences":
        if coffee == True and speaks_Dutch == True:
            if gender == "Female":
                condition = "A"
            else:
                condition = "B"
        else:
            print("Participant is not eligible to take part in the experiment.")
    else:
        print("Participant is not eligible to take part in the experiment.")
else:
    print("Participant is not eligible to take part in the experiment.")
    

## version 2             
if age >= 18 and study == "Psychology" or study == "Communication Sciences" and coffee == True and speaks_Dutch == True:
    if gender == "Female":
        condition = "A"
    else:
        condition = "B"
else:
    print("Participant is not eligible to take part in the experiment.")

9.3.10 Exercise 10. Flow chart conditionals

n = -1
if n > 0:
    n = 2*n
else:
    n += 1
if n > 4*241%17:
    n -= 5
else:
    if n > 10:
        n += 50
    else:
        n = n%2
print(n)

9.4 Chapter 4. Lists

9.4.1 Exercise 1. Indexing

What is the output of the following code snippets?

a = [6, 7]
b = [4, 5]
b.append(a)

print(b)
## [4, 5, [6, 7]]
d = {1: 'a',
    'a': 1}
    
print(d[1])
## a
a = [1]
b = ('a', 2)
a.extend(b)

print(a[1])
## a
a, b = (['a', 'd'], ['b', 'c'])

print(b[0])
## b
a = [1, 2, 3]

print(a[-1])
## 3
a = (1, 2, [3, 4], 5)

print(a[2][1])
## 4

9.4.2 Exercise 2. Debugging

Will the following code snippets throw an error? If anything goes wrong, why does it go wrong?

a, b = 'Sigmund', 'Freud', (1856, 1939)
## Error in py_call_impl(callable, dots$args, dots$keywords): ValueError: too many values to unpack (expected 2)
## 
## Detailed traceback:
##   File "<string>", line 1, in <module>
  • A ValueError is thrown. There are too many values on the right side of the equals sign = to unpack.
a = [1, 2]
b = (3, 4)

a.append(b)
print(a[3])
## Error in py_call_impl(callable, dots$args, dots$keywords): IndexError: list index out of range
## 
## Detailed traceback:
##   File "<string>", line 1, in <module>
  • An IndexError is thrown. After appending b, a has three elements. 3 is not a valid index.
a = ('a', [1, 2])

a[1].append(3)
  • No error is thrown, 3 is appended to [1, 2].
a = {('a', 'b'): 3}

print(a.keys())
## dict_keys([('a', 'b')])
  • No error is thrown, the list of keys contains one element, ('a', 'b').

9.4.3 Exercise 3. Mini programs

What is the output of the following mini programs?

a = {}

print(a.keys())
## dict_keys([])
  • []
a = []
b = ([1, 2], [3, 4], [5, 6])

a.extend(b)
print(a[1])
## [3, 4]
  • [3, 4]
a = ('a', ('b', 'c'))

print('b' in a)
## False
  • False
a = [{'a': 1 }, {'a': 2}]

if 'a' in a[0]:
    print(a[0]['a'])
elif 'a' in a[1]:
    print(a[1]['a'])
  
## 1
  • 1

9.4.4 Exercise 1. Shopping list

['buns', 'cheese', 'milk', 'oatmeal', 'blueberries', 'oranges', 'apples', 'chocolate', ['eggs', 'yoghurt', 'salmon'], ['icing sugar', 'whipping cream', 'lemons', 'flower', 'vanilla sugar', 'eggs', 'baking powder', 'margarine']]

9.4.5 Exercise 2. Dictionnaries

('Erik', 'Erikson', (1902, 1994))
('Theory of Cognitive Development',)
1856
"Frederic"
"Skinner Box"
"positive reinforcement"

9.4.6 Exercise 3. Selecting elements

shoppingList[2]
shoppingList[0][0]
grades["p3"][3]
grades["p5"][1]
grades["p6"][0]
grades["p1"][4][2]
grades["p5"][4][0]
grades["p6"][4][1]

9.4.7 Exercise 4. Adjust a dictionnary data set

#1
dataset['p1'][5] = 6.1
dataset['p7'][5] = 7.4

#2
dataset['p5'][0] = 23
dataset['p5'][1] = "Female"

#3
dataset['p4'][4][2] = True
dataset['p4'][4][3] = True
## or
dataset['p4'][4] = [True,True,True,True,True]

#4
dataset['p2'][3] = "B-Health_Sciences"

#5
dataset['p4'].append("expelled")
## or
dataset['p4'] = dataset['p4'] + ["expelled"]

#final dataset
dataset = {'p1':[21,"Female","Dutch","B-Psychology",[True,False,True,False,False],6.1],
           'p2':[20,"Female","Dutch","B-Health_Sciences",[True,True,True,False,True],8.4],
           'p3':[21,"Female","Dutch","B-Applied_Mathematics",[False,True,True,False,True],7.8],
           'p4':[23,"Male", "German","B-Communication_Science",[True,True,True,True,True],8.8,"expelled"],
           'p5':[23,"Female","Dutch","M-Business_Administration",[False,False,True,True,True],7.6],
           'p6':[19,"Male","Swedish","B-Computer_Science",[True,False,False,True,False],7.5],
           'p7':[19,"Male","German","B-Communication_Science",[True,True,False,True,True],7.4]
           }

9.4.8 Exercise 5. A dictionnary data set

import numpy as np

participants = {'p1':("Male",19,"Dutch","Student"),
                'p2':("Male",47,"Dutch","Pharmacist"),
                'p3':("Male",31,"Italian","PhD Student"),
                'p4':("Female",22,"German","Student"),
                'p5':("Female",46,"Dutch","Florist"),
                'p6':("Male",27,"Dutch","Student"),
                'p7':("Female",22,"Dutch","Police trainee"),
                'p8':("Female",26,"Indian","Architect"),
                'p9':("Male",18,"American","Student"),
                'p10':("Male",20,"Chinese","Student")
               }

""" Calculate the average age """
mean_age = (participants['p1'][1]+participants['p2'][1]+participants['p3'][1]+participants['p4'][1]+participants['p5'][1]+participants['p6'][1]+participants['p7'][1]+participants['p8'][1]+participants['p9'][1]+participants['p10'][1])/float(len(participants))

# A more elegant, manual solution you will learn about in "Chapter 5. Loops"
# would be as follows:
age_sum = 0
for key in participants.keys():
    age_sum += participants[key][1]
loop_mean = age_sum/float(len(participants))

# Using Numpy greatly simplifies calculations, but
# you first need to transform the data to fit your needs.
# You will see, however, that extracting the age variable and saving it
# separately will simplify other statistical operations later on.
age = [participants['p1'][1],
       participants['p2'][1],
       participants['p3'][1],
       participants['p4'][1],
       participants['p5'][1],
       participants['p6'][1],
       participants['p7'][1],
       participants['p8'][1],
       participants['p9'][1],
       participants['p10'][1]]

numpy_mean = np.mean(age)


""" Calculate the standard deviation of the age variable """

std_age = np.std(age)

""" Calculate the minimum and maximum of the age variable """

minimum = np.nanmin(age)
maximum = np.nanmax(age)

9.4.9 Exercise 6. Stroop extension

# -*- coding: utf-8 -*-
import pygame
import sys
from time import time
import random
from pygame.locals import *
from pygame.compat import unichr_, unicode_

##### VARIABLES #####
# Colors
col_white = (250, 250, 250)
col_black = (0, 0, 0)
col_gray = (220, 220, 220)
col_red = (250, 0, 0)
col_green = (0, 200, 0)
col_blue = (0, 0, 250)
col_yellow = (250,250,0)
col_pink = (250,0,127)

NTRIALS = 5

WORDS    = ("red", "green", "blue", "yellow", "pink")

COLORS   = {"red": col_red,
            "green": col_green,
            "blue": col_blue,
            "yellow": col_yellow,
            "pink": col_pink}

KEYS     = {"red": K_b,
            "green": K_n,
            "blue": K_m,
            "yellow":K_v,
            "pink":K_c}


BACKGR_COL = col_gray
SCREEN_SIZE = (700, 500)

pygame.init()
pygame.display.set_mode(SCREEN_SIZE) 
pygame.display.set_caption("Stroop Test")

screen = pygame.display.get_surface()
screen.fill(BACKGR_COL)

font = pygame.font.Font(None, 80)
font_small = pygame.font.Font(None, 40)

p_numbers = range(1,11)

conditions = {"Stroop_3":[1,2,4,8,10],
              "Stroop_5":[3,5,6,7,9]}

def main():
    """ Start the Stroop task.
    """
    ## Variables
    STATE = "welcome"
    trial_number = 0
    # initialize participant number
    p_number = 0

    # for gathering the response times
    RT = []

    while True:
        pygame.display.get_surface().fill(BACKGR_COL)        

        # Changing states by user input
        for event in pygame.event.get():
            # welcome screen --> prepare next trial (space bar)
            if STATE == "welcome":
                if event.type == KEYDOWN and event.key == K_SPACE:
                    STATE = "enter_participant_number"
                    print(STATE)

            # wait for response --> feedback (b, n, m)
            elif STATE == "wait_for_response":
                if event.type == KEYDOWN and event.key in KEYS.values():
                    # remember when the user has reacted
                    time_when_reacted = time()
                    # calculate the response time
                    this_reaction_time = time_when_reacted - time_when_presented
                    RT.append(this_reaction_time)
                    # was the response correct?
                    this_correctness = (event.key == KEYS[this_color])
                    STATE = "feedback"
                    print(STATE)
            
            elif STATE == "enter_participant_number":
                p_number = prompt()
                STATE = "transition_experiment"
                print(STATE + "\nRETURN TO PYGAME WINDOW")
                
            elif STATE == "transition_experiment":
                if event.type == KEYDOWN and event.key == K_SPACE:
                    STATE = "prepare_next_trial"

            if event.type == QUIT:
                STATE = "quit"

        # automatic state transitions
        # prepare next trial --> wait for response (immediatly)
        if STATE == "prepare_next_trial":
            trial_number = trial_number + 1
            # randomly pick word and color
            # depending on condition
            if p_number in conditions["Stroop_3"]:
                this_word  = pick_color()
                this_color = pick_color()
            else:
                this_word = pick_color5()
                this_color = pick_color5()
            # remember when stimulus was presented
            time_when_presented = time()
            STATE = "wait_for_response"
            print(STATE)

        # show feedback, then advance to next trial or goodbye  (for 1s)
        if STATE == "feedback" and (time() - time_when_reacted) > 1:
            if trial_number < NTRIALS:
                STATE = "prepare_next_trial"
            else:
                STATE = "goodbye"
            print(STATE)

        # Drawing to the screen
        if STATE == "welcome":
            draw_welcome()
            draw_button(SCREEN_SIZE[0]*1/6, 450, "Pink: C", col_pink)
            draw_button(SCREEN_SIZE[0]*2/6, 450, "Yellow: V", col_yellow)
            draw_button(SCREEN_SIZE[0]*3/6, 450, "Red: B", col_red)
            draw_button(SCREEN_SIZE[0]*4/6, 450, "Green: N", col_green)
            draw_button(SCREEN_SIZE[0]*5/6, 450, "Blue: M", col_blue)
        
        if STATE == "enter_participant_number":
            draw_enter()
        
        if STATE == "transition_experiment":
            draw_transition()
            if p_number in conditions["Stroop_3"]:
                draw_button(SCREEN_SIZE[0]*1/4, 450, "Red: B", col_red)
                draw_button(SCREEN_SIZE[0]*2/4, 450, "Green: N", col_green)
                draw_button(SCREEN_SIZE[0]*3/4, 450, "Blue: M", col_blue)
            else:
                draw_button(SCREEN_SIZE[0]*1/6, 450, "Pink: C", col_pink)
                draw_button(SCREEN_SIZE[0]*2/6, 450, "Yellow: V", col_yellow)
                draw_button(SCREEN_SIZE[0]*3/6, 450, "Red: B", col_red)
                draw_button(SCREEN_SIZE[0]*4/6, 450, "Green: N", col_green)
                draw_button(SCREEN_SIZE[0]*5/6, 450, "Blue: M", col_blue)
        
        if STATE == "wait_for_response":
            draw_stimulus(this_color, this_word)
            if p_number in conditions["Stroop_3"]:
                draw_button(SCREEN_SIZE[0]*1/4, 450, "Red: B", col_red)
                draw_button(SCREEN_SIZE[0]*2/4, 450, "Green: N", col_green)
                draw_button(SCREEN_SIZE[0]*3/4, 450, "Blue: M", col_blue)
            else:
                draw_button(SCREEN_SIZE[0]*1/6, 450, "Pink: C", col_pink)
                draw_button(SCREEN_SIZE[0]*2/6, 450, "Yellow: V", col_yellow)
                draw_button(SCREEN_SIZE[0]*3/6, 450, "Red: B", col_red)
                draw_button(SCREEN_SIZE[0]*4/6, 450, "Green: N", col_green)
                draw_button(SCREEN_SIZE[0]*5/6, 450, "Blue: M", col_blue)
        
        if STATE == "feedback":
            draw_feedback(this_correctness, this_reaction_time)
        
        if STATE == "goodbye":
            draw_goodbye()
        
        if STATE == "quit":
            pygame.quit()
            sys.exit()

        pygame.display.update()

def prompt():
    p_number = 0
    while p_number == 0:
        p_number = int(raw_input("Please enter participant number here:"))
    if p_number in range(1,len(p_numbers)+1):
        return p_number
    else:
        print("Unknown participant number, valid participant numbers are 1 to 10")
        prompt()
                    
def pick_color():
    """ Return a random word.
    """
    random_number = random.randint(0,2)
    return WORDS[random_number]

def pick_color5():
    """ Return a random word,
    5 color Stroop version
    """
    random_number = random.randint(0,4)
    return WORDS[random_number]

def draw_button(xpos, ypos, label, color):
    text = font_small.render(label, True, color, BACKGR_COL)
    text_rectangle = text.get_rect()
    text_rectangle.center = (xpos, ypos)
    screen.blit(text, text_rectangle)

def draw_welcome():
    text_surface = font.render("STROOP Experiment", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)
    text_surface = font_small.render("Press Spacebar to continue", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,300)
    screen.blit(text_surface, text_rectangle)

def draw_enter():
    text_surface = font_small.render("Please enter participant number in console", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,250)
    screen.blit(text_surface, text_rectangle)

def draw_transition():
    text_surface = font_small.render("Press Spacebar to start the experiment", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,250)
    screen.blit(text_surface, text_rectangle)

def draw_stimulus(color, word):
    text_surface = font.render(word, True, COLORS[color], col_gray)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)

def draw_feedback(correct, reaction_time):
    if correct:
        text_surface = font_small.render("correct", True, col_black, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
        screen.blit(text_surface, text_rectangle)
        text_surface = font_small.render(str(int(reaction_time * 1000)) + "ms", True, col_black, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,200)
        screen.blit(text_surface, text_rectangle)
    else:
        text_surface = font_small.render("Wrong key!", True, col_red, BACKGR_COL)
        text_rectangle = text_surface.get_rect()
        text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
        screen.blit(text_surface, text_rectangle)
        #text_surface = font_small.render("Press Spacebar to continue", True, col_black, BACKGR_COL)


def draw_goodbye():
    text_surface = font_small.render("END OF THE EXPERIMENT", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,150)
    screen.blit(text_surface, text_rectangle)
    text_surface = font_small.render("Close the application.", True, col_black, BACKGR_COL)
    text_rectangle = text_surface.get_rect()
    text_rectangle.center = (SCREEN_SIZE[0]/2.0,200)
    screen.blit(text_surface, text_rectangle)
    
main()

9.5 Chapter 5. Loops

9.5.1 Exercise 1. Following the control flow I

What is the output of the following code snippets?

for i in range(len([1,2,3])):
    print(i)
## 0
## 1
## 2
for i in range(len([])):
    print(i)
a = 0
for i in range(3):
    a += i
    print(a + i)
    
## 0
## 2
## 5
a = 0
b = 30
for i in range(5):
    a += i
    b -= i
    
print(a + b)
## 30
for i in range(1,3):
    print(i)
## 1
## 2
i = 10
while i > 5:
    print(i - 5)
    i -= 2
## 5
## 3
## 1
a = 2
b = (1,2)

while a != 0:
    for i in b:
        print(a + i)
    a -= 1
## 3
## 4
## 2
## 3

9.5.2 Exercise 2. Debugging I

Do the following code snippets throw an error? If they do, what goes wrong? Only one answer is correct.

a = [4,6,8]

for i in len(a):
    print(a[i])

The correct answer is:

  • A TypeError is thrown because the for statement does not include a sequence to iterate over.
myNumber = 43
while True:
    guess = input("Enter a number:")
    if guess > 43:
        print("My number is smaller than {0}".format(guess))
    elif guess < 43:
        print("My number is greater than {0}".format(guess))
    else:
        print("Ding, ding! Correct, my number is {0}".format(myNumber))

The correct answer is:

  • No error is thrown, once the user guesses 43, Ding, ding! Correct, my number is 43 will be printed, but the program does not terminate.
a = [4,6]
b = [0, 1.5]
for i in a:
    for j in range(len(b)):
        print(i * b[j])

The correct answer is:

  • No error is thrown, the output is of the mini program is 0, 6.0, 0, 9.0 because each element in a is multiplied by each element in b.

9.5.3 Exercise 3. Controlling the flow

9.5.4 Exercise 4. Following the control flow II

Disclaimer: It is possible that your Python interpreter returns the keys of dataset in a different order than shown below when you execute dataset.keys() on your system. This has to do with how dictionaries are stored internally in computer memory. Here as well hash functions are utilized for efficiency reasons. As a consequence, the order of the keys in a dictionary is unspecified (which is why you cannot use the index operator to access elements of a dictionary and p1 is not necessarily the first key shown in the list). It also means that when you display the keys of a dictionary as a list (which is what the keys() method does), the order in which the keys occur in the list can differ from system to system. For you this means that you should not worry if your system returns a different order when you execute dataset.keys(). But it is important that you understand why dataset[dataset.keys()[0]] returns the value that is displayed when you execute the code snippet.

['p2', 'p3', 'p1', 'p6', 'p7', 'p4', 'p5', 'p10', 'p8', 'p9']
(20, 'Female', 'Dutch', 'B-Psychology')
(20, 'Female', 'Dutch', 'B-Psychology')
20
5
4
21.8
19.75

9.5.5 Exercise 5. Debugging

data = {'p1':(21,"Female","Condition B",[0.675,0.777,0.778,0.62,0.869]),
        'p2':(20,"Female","Condition A",[0.599,0.674,0.698,0.569,0.7]),
        'p3':(21,"Female","Condition A",[0.655,0.645,0.633,0.788,0.866]),
        'p4':(23,"Male", "Condition A",[0.721,0.701,0.743,0.682,0.654]),
        'p5':(20,"Male","Condition B",[0.721,0.701,0.743,0.682,0.654]),
        'p6':(19,"Male","Condition B",[0.711,0.534,0.637,0.702,0.633]),
        'p7':(19,"Male","Condition B",[0.687,0.657,0.766,0.788,0.621]),
        'p8':(24,"Female","Condition A",[0.666,0.591,0.607,0.704,0.59]),
        'p9':(23,"Female","Condition B",[0.728,0.544,0.671,0.689,0.644]),
        'p10':(18,"Male","Condition A",[0.788,0.599,0.621,0.599,0.623])
        }

fastest = ("initialization",100)
for participant in data:
    RTsum = 0
    for i in range(len(data[participant][3])-1):
        RTsum += data[participant][3][i]
    RTmean = RTsum/len(data[participant][3])
    if RTmean < fastest[1]:
        fastest = (participant,RTmean)
        
slowest = ("initialization",0)
for participant in data:
    RTsum = 0
    for RT in data[participant][3]:
        RTsum += RT
    RTmean = RTsum/len(data[participant][3])
    if RTmean > slowest[1]:
        slowest = (participant,RTmean)
        
all_mean = 0
all_sum = 0
number_of_trials = 0
for participant in data:
    counter = 0
    while counter < len(data[participant][3]):
        all_sum += data[participant][3][counter]
        number_of_trials += 1
        counter += 1
all_mean = all_sum/number_of_trials*len(data)
    
print("fastest:", fastest)
print("slowest:", slowest)
print("all_mean:", all_mean)

9.5.6 Exercise 6. Nested loops

participants = [
    ("p1", ["Condition 1","Location A","withdrew","no audio"]),
    ("p2", ["Condition 1","Location A","no audio","no video"]),
    ("p3", ["Condition 2","Location B"]),
    ("p4", ["Condition 1","Location A","withdrew"]),
    ("p5", ["Condition 2","Location A"]),
    ("p6", ["Condition 2","Location B","withdrew"]),
    ("p7", ["Condition 1","Location A","no video"]),
    ("p8", ["Condition 1","Location B"]),
    ("p9", ["Condition 2","Location B","withdrew"]),
    ("p10",["Condition 1","Location A","withdrew"])]

counter = 0
for (participant,expInfo) in participants:
        for info in expInfo:
            if info == "withdrew":
                counter += 1
        
print("The number of participants who withdrew their participation is", counter)

9.5.7 Exercise 7. Data transformation using loops

participants = [
    ("p1", ["Condition 1","Location A","withdrew","no audio"]),
    ("p2", ["Condition 1","Location A","no audio","no video"]),
    ("p3", ["Condition 2","Location B"]),
    ("p4", ["Condition 1","Location A","withdrew"]),
    ("p5", ["Condition 2","Location A"]),
    ("p6", ["Condition 2","Location B","withdrew"]),
    ("p7", ["Condition 1","Location A","no video"]),
    ("p8", ["Condition 1","Location B"]),
    ("p9", ["Condition 2","Location B","withdrew"]),
    ("p10",["Condition 1","Location A","withdrew"])]

dict_participants = {}
for participant in participants:
    dict_participants[participant[0]] = participant[1]

counterA = 0
counterB = 0
for key in dict_participants:
    if dict_participants[key][1] == "Location A":
        counterA += 1
    else:
        counterB += 1

## or using nested loops

counterA1 = 0
counterB1 = 0
for key in dict_participants:
    for info in dict_participants[key]:
        if info == "Location A":
            counterA1 += 1
        elif info == "Location B":
            counterB1 += 1

print("The number of participants who were tested at location A is", counterA, counterA1)
print("The number of participants who were tested at location B is", counterB, counterB1)

9.5.8 Exercise 8. Calculating a mean

import numpy as np

seq = range(1000)
counter = 0
sum = 0.0

while counter <= 999:
    sum += seq[counter]
    counter += 1

mean = sum/len(seq)

print(mean, np.mean(seq))

9.5.9 Exercise 9. A guessing game

import random
import sys

number = random.randint(0,1000)
guesses = 0

while(True):
    try:
        user_input = input("Please enter a number between 0 and 1000")
    except SyntaxError:
        sys.exit() 
    if user_input == number:
        print("Ding Ding Ding! Correct! The number was", number)
        guesses +=1
        print(guesses, "guesses needed")
        break
    elif user_input > number:
        print("My number is smaller")
        guesses +=1
    elif user_input < number:
        print("My number is larger")
        guesses +=1

sys.exit()

9.6 Chapter 6. Functions

9.6.1 Exercise 1. Following the control flow

"x equals 10"
"y equals 17.5"
"anumber equals 10.0"

9.6.2 Exercise 2. An imperfect list sorting attempt

  • Line 6/7. The insert function does not return the resulting list.
  • Line 20 and 21. The output of the swap function is not assigned to any variable and thereby, the manipulation performed on myList1 is not stored in memory.
  • Line 22. Only two arguments are provided during the function call of insert. The function, however, requires three arguments: an element to be inserted, a position indicating where to insert the element, and a list into which the element is to be inserted.
  • Line 25. The swap function is used incorrectly. First of all, the function only takes three arguments, but five arguments are provided. The person tried to swap several element pairs at once while the function is only suitable for swapping one pair at a time!
  • Line 25. Second, the order of the arguments provided to the swap function is messed up. The function first takes one element to be swapped, then the element with which the first element should be swapped and only then the list which contains the two elements.
  • Line 26. The insert function is as it is defined not suitable for appending elements at the end of a list. This can be solved in one of two ways: either, the function is left as is and instead of using insert, the built-in function append() can be used. Or, and this makes the insertion function more robust, a check is added to the function, appending any element that is supposed to be inserted at a position that exceeds the index range of the list.
def insert(a,position,alist):
    result = copy.deepcopy(alist)
    if position >= len(result):
        return result.append(a)
    else:
        return result[:position] + [a] + result[position:]

9.6.3 Exercise 3. An errorneous sorting algorithm

import copy
import random

def swap(a,b,alist):
    index_a, index_b = alist.index(a), alist.index(b)
    index_a, index_b = index_b, index_a
    result = copy.deepcopy(alist)
    result[index_a], result[index_b] = a,b
    return result

def bubbleSort(alist):
    result = copy.deepcopy(alist)
    for iteration in range(len(result)-1):
        for index in range(len(result)-1,0,-1):
            if result[index] < result[index-1]:
                result = swap(result[index],result[index-1],result)
    return result

myList = range(51)
random.shuffle(myList)
print(myList)
print(bubbleSort(myList))

9.6.4 Exercise 4.

9.6.5 Exercise 5.

9.6.6 Exercise 6. Insertion sort algorithm

import copy
import random

def insertionSort(alist):
    result = copy.deepcopy(alist)
    for index in range(1,len(result)):
        
        # Temporarily assign the element that is to be compared to the
        # (sorted) sublist at the left of the element's position
        value = result[index]
        # Remember the position in the list of the element under investigation
        position = index 
        
        # Stepwise, compare each element left to the designated element (b) and the
        # designated element (value). Whenever b is larger than value, update position
        # by shifting the position of b to the current value of position, thus in fact,
        # one place to the right. Continue until position equals 0 and there are no more elements b
        # left to compare value to.
        while position > 0 and result[position-1] > value:
            result[position] = result[position-1]
            position -= 1
        
        # Insert the value that has been compared to at the right position in the list
        result[position] = value
    return result

myList = range(51)
random.shuffle(myList)

print(insertionSort(myList))