In this exercise we are going to get some hands on practice using higher order functions. We are going to have a form simulating a ticket booking UI. The user can enter the number of tickets to book and submit the form to book the tickets.
Problem Statement
There are three pieces of code that we will deal with in this exercise:
- A
Form
object that accepts the number of tickets to book from the user - A
book_tickets
function that simulates a call to the backend with the number of tickets to book. The number of tickets to book will come from theForm
class - A
get_token
function that creates an authentication token which needs to be passed tobook_tickets
in order to make the backend call
We need to integrate these three bits of code together. Writing that integration is the goal of this exercise.
The Form class
This class accepts a submit handler. When the user submits the form, the UI will call submit
which in turn will execute the submit handler with the number of tickets booked by the user.
class Form:
def __init__(self):
self.handler = lambda x: None
def on_submit(self, handler):
self.handler = handler
def submit(self, num_tickets):
self.handler(num_tickets)
get_token
This function just returns a token. The token should be passed as the first parameter of book_tickets
def get_token():
return "A123"
book_tickets
This function takes the token (from get_token
above) and the number of tickets to book (from the form). If the token is valid, it simulates a call to the backend (it just prints a message to indicate this).
def book_tickets(token, num_tickets):
if token != "A123":
print("Invalid token")
return
print(f"Booked {num_tickets} tickets")
What we need to do
- Part 1: Implement the
main
function, which takes theform
as input. Pass in an appropriate function toform.on_submit
such that when the form is submitted, it callsbook_tickets
with the right parameters. We cannot modify any of the existing code forform
,get_token
orbook_tickets
. We can only changemain
- Part 2: Write the code in such a way that if the user double-clicks the
Book Tickets
button, it still makes only a single call to the backend
Code
def main(form): # write code here to connect the form, # get_token and book_tickets form.on_submit(???)
Output
Solution Hints
Feel free to expand any of the hints below to guide you while implementing this exercise.
Guided Hint 1
You need to configure a handler function to the form by calling on_submit
such that book_tickets
is executed when the form is submitted
Guided Hint 2
form.submit
will call the handler function with a single parameter (num_tickets
) but book_tickets
requires two parameters
Guided Hint 3
Maybe we can partially apply the first parameter to book_tickets
before setting it as the event handler. When form.submit
is called it will pass in the second parameter and book_tickets
will get executed
Solution Part 1
Use form.on_submit(partial(book_tickets, get_token()))
inside the main
function. (Don't forget to do from functools import partial
on top). Then proceed to part 2 – even if the book tickets button is clicked multiple times it should still call the backend once
Guided Hint 4
Click the button multiple times. Notice that it calls the backed multiple times. How can we make book_tickets
get executed only once?
Guided Hint 5
Remember we wrote a higher order function once
in the article on impure functions? Maybe we can use that?
Solution Part 2
Copy and paste the implementation of the once
function from the impure functions article. Then change on_submit
to wrap the function with once
before setting it as the handler: form.on_submit(once(partial(book_tickets, get_token())))
Did you like this article?
If you liked this article, consider subscribing to this site. Subscribing is free.
Why subscribe? Here are three reasons:
- You will get every new article as an email in your inbox, so you never miss an article
- You will be able to comment on all the posts, ask questions, etc
- Once in a while, I will be posting conference talk slides, longer form articles (such as this one), and other content as subscriber-only