It appears you want 10 unique random jokes. Instead of recursion, I'd use a loop (to iterate until you have 10 jokes) and a set (to keep track of duplicate ids):
import requests
def get_joke(
url="https://official-joke-api.appspot.com/jokes/programming/random"
):
response = requests.get(url)
response.raise_for_status()
return response.json()[0]
def get_unique_random_jokes(n):
ids_used = set()
jokes = []
while len(jokes) < n:
joke = get_joke()
if joke["id"] not in ids_used:
ids_used.add(joke["id"])
jokes.append(joke)
return jokes
if __name__ == "__main__":
jokes = get_unique_random_jokes(n=10)
for joke in jokes:
print(f'Setup: {joke["setup"]}\nPunchline: {joke["punchline"]}\n')
If you do use recursion, you'll need to return the response of the recursive call, e.g. return getJoke(idList)
A couple other remarks:
I'd cache the result of response.json()[0]
in a variable to reduce parsing and make the code prettier.
idList
is mutated by the getJoke
function, so state management is shared between client and the function. This is hard to reason about. Functions should be self-contained and stateless if possible.
Recursion can blow the stack, is confusing (the bug here is testament to this) and a poor fit for "try again" semantics. Stick to recursion for stuff like tree processing and divide & conquer algorithms.
Although it's a rather premature optimization, keep in mind that in
is linear on lists and constant time on sets. Sets are generally the best way to check for membership.
For requests
, response.raise_for_status()
raises a better error to the caller than .json()
would. For a not found request, you'd get
requests.exceptions.HTTPError: 404 Client Error: Not Found for url:
https://official-joke-api.appspot.com/jokes/programming/asdasd
instead of the irrelevant
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Follow PEP-8's recommendations of snake_case
instead of camelCase
and spacing around operators, foo=bar
=> foo = bar
.
When making multiple requests to the same domain, use requests.Session
to speed things up (exercise for the reader).