Online Python Runner

Write, run, and test Python code directly in your browser.

Python Editor

Loading Python runtime, one moment.
Loading...

Output

Online Python Runner

Practising Python for interviews in the browser

The runner above executes real Python in your browser, with no installation. This guide is about using it well: exactly what it can and cannot do, the standard library tools interview problems keep asking for, how to read input, how to debug without a debugger, how to talk about complexity, and nine exercises you can paste straight in.

What can you run in this online Python runner, and what are its limits?

It runs real Python in your browser using a build of CPython compiled to WebAssembly, so the language and the standard library behave normally. What it does not have is third party packages, network access, or access to files on your computer. That covers almost every coding interview problem and rules out data science and scripting work.

Because everything executes locally in the page, there is nothing to install and no server running your code. That is what makes it a good scratchpad: you can open it, paste a problem, and have an answer in under a minute. It also means the tab is doing the work, so a program with an infinite loop will freeze the page rather than time out politely.

The runner has three parts. The editor on the left holds your code and remembers it in your browser, so it is still there tomorrow. The input box on the right feeds standard input, which is what makes input() work. The output panel shows everything your program printed, once it has finished running.

The runner at a glance

Cost
Free. No account, no sign up, and no execution quota.
Where it runs
In your browser tab, using CPython compiled to WebAssembly. No code is sent to a server to be executed.
Standard library
Available. collections, heapq, bisect, itertools, functools, math, re, json, and the rest work normally.
Third party packages
Not available here. There is no numpy, pandas, or requests, and no way to install one.
Network access
None. HTTP libraries cannot reach the internet from inside the runner.
Files on your computer
No access. open() writes to an in browser virtual filesystem that is discarded when you reload.
Input
input() reads from the input box on the right, one line per call. Fill it in before you run.
Your code
Saved in this browser under a local storage key, so it survives closing the tab. It is not uploaded.

What runs here, and what does not

It is worth being precise about the boundaries, because a browser based runner is not a smaller version of a local Python install, it is a different environment with a different shape. Knowing which is which saves you from concluding that your code is broken when it is the environment that cannot do the thing.

The language itself is complete. Classes, generators, comprehensions, decorators, context managers, f strings, type hints, exceptions, recursion, and the whole standard library behave the way they do anywhere else. So do collections, heapq, bisect, itertools, functools, math, random, re, json, datetime, and dataclasses. For interview problems, that is effectively everything you need.

Third party packages are not available. There is no numpy, no pandas, and no requests, and there is no way to install one from this page. If a problem needs a package, it is not an interview problem, it is engineering work, and it belongs in a local environment.

There is no network access. Anything that tries to open a socket or make an HTTP request will fail, because the code is running inside the browser's sandbox rather than on a machine with a network stack it can use. This is a security property rather than a bug.

File access is the one that surprises people. open() works, but it writes to an in browser virtual filesystem, not to your disk. You can write a file and read it back in the same run, which is occasionally useful, and it disappears when you reload the page. Your computer's files are not reachable from here at all.

Two execution details worth knowing. Output is collected while your program runs and shown all at once when it finishes, so it does not stream, and a long loop will look like nothing is happening. And execution is synchronous inside the page, so an infinite loop freezes the tab rather than timing out. If that happens, close the tab and reopen the page: your code is saved in the browser and will still be there.

  • Works: the full language and the standard library, including collections, heapq, bisect, and itertools.
  • Does not work: third party packages, and there is no way to install one here.
  • Does not work: network requests of any kind.
  • Partly works: open() writes to an in browser filesystem, not your disk, and it is cleared on reload.
  • Output appears all at once at the end, not as it is printed.
  • An infinite loop freezes the tab. Close it and reopen, your code is saved.

How to practise Python for interviews with this runner

A browser editor makes it easy to practise badly, by starting from a template and stopping once the code works. This is the loop that actually builds the skill an interview tests.

  1. 1

    Wait for the runtime, then clear the editor

    The Python runtime downloads the first time you open the page, and the editor is read only until it is ready. Once it unlocks, delete the sample code. Starting from an empty buffer matters more than it sounds: an interview starts from nothing, and practising from a template quietly removes the hardest part.

    • The runtime is fetched once per session, so the first load is the slow one.
    • Your code is saved in this browser as you type, so you can leave and come back to the same buffer.
  2. 2

    Write the function signature and the examples first

    Before any logic, type the function definition and two or three example inputs with the answers you expect. This is the habit interviewers most want to see and the one candidates most often skip. It forces you to pin down what the function takes and returns, which is where a surprising number of interview failures actually begin.

    • Include the awkward examples: an empty input, a single element, and duplicates.
    • Write the expected answers by hand, before you have written code that could bias you.
  3. 3

    Say the approach out loud before you type the body

    One or two sentences naming the technique and the cost: I will use a hash map to count occurrences, which is linear time and linear space. This is exactly what you would say in an interview, and practising it here is free. If you cannot say it in one sentence, you do not have an approach yet and typing will not produce one.

    • Write it as a comment at the top of the function. In a real interview you say it instead.
    • Name the complexity as you go, not at the end when you have to reverse engineer it.
  4. 4

    Write the brute force version and run it

    Get something correct on the screen before you get something fast. A working solution you can check against your examples is a solid base to optimise from, and in a real interview a correct brute force with ten minutes left is a pass while a half finished optimal solution is not.

    • Run it against every example you wrote in step two, including the awkward ones.
    • Only optimise once it is correct. Optimising a wrong solution is the most common way to run out of time.
  5. 5

    Feed real input through the input box

    If the problem reads from standard input, put the input into the box on the right before you press run. input() reads one line per call, so the number of lines has to match the number of calls. This is the mechanic most people get wrong the first time and it takes one attempt to internalise.

    • First line is usually a count, and the lines after it are the data. Read the count, then loop that many times.
    • Calling input() more times than there are lines raises an EOFError, which tells you your loop count is wrong.
  6. 6

    Print your way to the bug

    There is no step debugger here, so debugging is done with print statements, and doing that well is a real skill. Print the state at the top of each loop iteration with a label, not just a value, so the output panel reads like a trace rather than a column of numbers.

    • Print with labels: print('i', i, 'window', window, 'best', best).
    • If your program raises an exception, the output panel shows the error rather than the prints that came before it. Wrap the risky section in a try block and print inside it if you need both.
    • The output panel shows everything at once when the program finishes, so it does not stream. Keep traces small enough to read.
  7. 7

    Optimise, then state the new complexity

    Now improve it, and say what changed and why: replacing the inner scan with a set takes this from quadratic to linear time, at the cost of linear extra space. That sentence is the answer an interviewer is listening for, and rehearsing it here means you say it fluently when it counts.

    • Keep the brute force version in a comment so you can compare outputs on the same examples.
    • Time and space are separate answers. Give both, and say which one you traded.
  8. 8

    Redo the same problem from an empty editor two days later

    This is the step that produces the improvement. Solving a problem once teaches you that problem. Solving it again from nothing, after you have forgotten the details, teaches you the pattern, and patterns are what transfer to the problem you have not seen.

    • Keep a list of the problems you have solved and the one line technique each one needed.
    • If the second attempt is as slow as the first, you memorised a solution rather than learning a pattern. Go back to the technique.

The standard library patterns interview questions need

Python is a common interview language for one main reason: a handful of standard library tools turn problems that need twenty lines in other languages into three or four. Knowing these fluently is worth more than knowing an extra algorithm, because they come up constantly and using them signals that you write Python rather than translating from another language.

From collections, four things. Counter counts occurrences in one call and gives you most_common for free, which covers frequency problems, anagram problems, and top k by count. defaultdict removes the entire class of bugs where you forget to initialise a key, which is what makes it the right structure for graph adjacency lists. deque gives you appends and pops from both ends in constant time, which is what breadth first search and sliding window problems require, because popping the front of a list is linear. namedtuple gives you a readable lightweight record when a tuple stops being self explanatory.

From heapq, the priority queue. It is a min heap on a plain list: heappush and heappop, plus nlargest and nsmallest for the common top k case. For a max heap, push the negated value, which is the standard idiom and worth practising until it stops feeling like a hack. Heaps are how you answer the k largest, merge k sorted lists, and scheduling families of questions.

From bisect, binary search over a sorted sequence without writing the loop. bisect_left and bisect_right give you the insertion point, and insort keeps a list sorted as you add to it. Most binary search interview questions are really questions about which of left and right you want at the boundary, and using the library forces you to think about that explicitly rather than getting it wrong in your own loop.

From itertools, the combinatorial generators: combinations, permutations, and product for exhaustive search, accumulate for running totals, groupby for runs of equal adjacent elements, and pairwise for consecutive pairs. From functools, lru_cache turns a recursive definition into a memoised one with a single decorator, which is the shortest path from a recurrence to a working dynamic programming solution.

Beyond the modules, the built ins that do real work: enumerate when you need the index and the value, zip to walk two sequences together, sorted with a key function, any and all for predicate checks, and sets for membership tests in constant time. A very large share of interview solutions are a set, a dictionary, and a single loop.

  • collections: Counter for frequencies, defaultdict for adjacency lists, deque for both ended queues, namedtuple for records.
  • heapq: heappush, heappop, nlargest, nsmallest. Negate values for a max heap.
  • bisect: bisect_left, bisect_right, insort. Use it instead of writing the loop yourself.
  • itertools: combinations, permutations, product, accumulate, groupby, pairwise.
  • functools: lru_cache to memoise a recursive solution in one line.
  • Built ins: enumerate, zip, sorted with key, any, all, and sets for constant time membership.

Reading input the way interview problems expect

Standard input trips people up because two different conventions exist and problem statements rarely say which they are using. Some problems hand you arguments to a function. Others expect you to read lines from standard input. The runner supports the second through the input box on the right, and the mechanic is simple once you have seen it: whatever you type there becomes the lines your program reads, one line per call to input().

The classic shape is a count on the first line and the data after it. Read the count with n = int(input()), then loop n times reading a line each iteration. If your loop count does not match the number of lines you provided, you get an EOFError, which is actually a helpful error because it tells you exactly what is wrong.

Two patterns cover nearly everything else. For a line containing several numbers, split it and convert: nums = list(map(int, input().split())). For a grid, read the row count then read that many lines, keeping each one as a string or converting it to a list of characters, depending on whether you need to modify it. Strings are immutable in Python, so anything that mutates the grid needs lists.

Watch out for trailing whitespace and blank lines. Calling strip() on input you are going to compare or parse costs nothing and removes a category of bug that is genuinely hard to see, because a trailing space is invisible in the input box.

Finally, practise both conventions. Interview platforms differ, and arriving at a real interview unsure how to read input is an unforced way to lose five minutes at the start. If a problem gives you a function signature, write the function and call it yourself with hard coded examples. If it reads from input, use the box.

  • input() reads one line per call from the input box. Fill the box before you run.
  • n = int(input()) then loop n times is the standard shape for counted input.
  • list(map(int, input().split())) parses a line of numbers.
  • An EOFError means you called input() more times than you supplied lines.
  • Call strip() on anything you parse or compare, to remove invisible trailing whitespace.

Debugging with prints, properly

There is no step debugger in the browser, so print debugging is the tool, and there is a real difference between doing it well and scattering bare prints until something makes sense. Done well, it is fast enough that experienced engineers use it by choice.

Label everything. print(i) gives you a column of numbers with no context, while print('i', i, 'window', window, 'best', best) gives you a trace you can read like a table. Print at the top of each loop iteration rather than in several places, so the output has one line per iteration and the shape of the run is visible.

Print the shape of your data before you print its contents. A one line print of len(nums), type(nums[0]), and nums[:5] resolves a surprising share of bugs on its own, because most wrong answers come from the data being a different shape than you assumed rather than from the algorithm being wrong.

One specific thing about this runner: if your program raises an exception, the output panel shows the error instead of the prints that ran before it. That is worth knowing because it can look as though your prints never executed. If you need to see both, wrap the risky section in a try block and print inside the except branch, or comment out the line that raises while you inspect the state.

For recursion, print with indentation proportional to depth. Passing a depth parameter and printing ' ' * depth before your message turns an unreadable flat log into a visible call tree, which makes off by one errors in base cases obvious in seconds.

And when the bug will not surrender, shrink the input. Almost every bug that is invisible on a hundred element input is obvious on a three element one, and reducing the input is nearly always faster than reading the code again.

  • Label every print, and print once per loop iteration rather than in several places.
  • Print the shape first: length, type, and the first few elements.
  • An exception replaces the output panel contents, so use a try block if you need the prints too.
  • Indent recursive prints by depth to get a readable call tree.
  • Shrink the input before you reread the code.

Complexity, in the terms interviewers actually use

You will be asked for the time and space complexity of every solution you write, and the answer is expected in a specific vocabulary. It is a short vocabulary and it is worth being fluent rather than approximately right, because hesitating here reads as uncertainty about your own solution.

The ladder, from best to worst for a growing input: constant, logarithmic, linear, linear times logarithmic, quadratic, and exponential. In practice, constant means you did a fixed amount of work regardless of input size. Logarithmic means you halved the problem each step, which is binary search and balanced tree operations. Linear means you looked at each element a constant number of times. Linear times logarithmic is what sorting costs, and it is the cost of a heap based solution over all elements. Quadratic is a nested loop over the same input, and exponential is unpruned exhaustive search.

Two habits make this easy. First, state it as you write rather than reconstructing it afterwards, because the reason for each cost is fresh while you are writing the line that causes it. Second, always give both time and space, and say what the space is holding: linear extra space for the hash map, or constant extra space beyond the output.

The Python specific costs worth memorising, because they are where interview candidates go wrong: membership in a list is linear while membership in a set or dict is constant, appending to a list is amortised constant but inserting or popping at the front is linear, which is exactly why deque exists. Slicing a list copies it, so slicing inside a loop turns a linear algorithm quadratic without anything looking wrong. String concatenation in a loop is the same trap, and joining a list at the end is the fix.

Finally, know the difference between the complexity of your algorithm and the complexity of your implementation. They are frequently different, and the difference is almost always one of the Python costs above hiding inside an innocent looking line.

  • The ladder: constant, logarithmic, linear, linear times logarithmic, quadratic, exponential.
  • Give time and space separately, and say what the space is holding.
  • Membership is linear in a list and constant in a set or dict.
  • Popping the front of a list is linear. Use deque.
  • Slicing copies, and string concatenation in a loop is quadratic. Build a list and join it.

Exercises you can paste in right now

Each of these runs as written in the editor above. Work through them in order: they move from confirming the runner works to the standard library patterns that interview problems keep asking for. The hint under each one is the follow up question an interviewer would ask.

  1. 1

    Warm up: does the runner work

    Paste this, put the word python on the first line of the input box, and press run. It confirms the runtime is loaded and that you understand how the input box feeds input().

    word = input().strip()
    print("reversed:", word[::-1])
    print("letters:", len(word))
    print("unique:", len(set(word)))

    Next: If you get an EOFError, the input box is empty. input() needs a line to read.

  2. 2

    Counting with Counter

    Frequency counting appears in anagram checks, top k problems, and duplicate detection. Counter does it in one call, and most_common gives you the ranking for free.

    from collections import Counter
    
    text = "the quick brown fox jumps over the lazy dog the end"
    counts = Counter(text.split())
    print(counts.most_common(3))
    print("words seen once:", [w for w, c in counts.items() if c == 1])

    Next: Now do it without Counter, using a plain dict. Then say which is linear and why they both are.

  3. 3

    Two sum in one pass

    The canonical example of trading space for time. The nested loop version is quadratic. Remembering what you have already seen makes it linear, and this trick generalises to a large family of problems.

    def two_sum(nums, target):
        seen = {}
        for i, n in enumerate(nums):
            if target - n in seen:
                return (seen[target - n], i)
            seen[n] = i
        return None
    
    print(two_sum([2, 7, 11, 15], 9))
    print(two_sum([3, 2, 4], 6))
    print(two_sum([1, 2], 100))

    Next: State the complexity out loud: linear time, linear space. Then handle duplicates in the input.

  4. 4

    Sliding window maximum sum

    Windows are one of the highest frequency interview patterns. Recomputing the sum for each window is quadratic. Adding the new element and subtracting the old one keeps it linear.

    def max_window_sum(nums, k):
        if k > len(nums):
            return None
        window = sum(nums[:k])
        best = window
        for i in range(k, len(nums)):
            window += nums[i] - nums[i - k]
            best = max(best, window)
        return best
    
    print(max_window_sum([2, 1, 5, 1, 3, 2], 3))
    print(max_window_sum([1], 1))
    print(max_window_sum([1, 2], 5))

    Next: Add a print inside the loop showing i, window, and best. That trace is the whole algorithm.

  5. 5

    Breadth first search with deque

    Graph traversal with defaultdict for the adjacency list and deque for the queue. Using a list as a queue and popping from the front makes this quadratic, which is the mistake deque exists to prevent.

    from collections import defaultdict, deque
    
    edges = [("a", "b"), ("a", "c"), ("b", "d"), ("c", "d"), ("d", "e")]
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)
    
    def shortest_path_length(start, goal):
        queue = deque([(start, 0)])
        seen = {start}
        while queue:
            node, dist = queue.popleft()
            if node == goal:
                return dist
            for nxt in graph[node]:
                if nxt not in seen:
                    seen.add(nxt)
                    queue.append((nxt, dist + 1))
        return -1
    
    print(shortest_path_length("a", "e"))
    print(shortest_path_length("a", "a"))

    Next: Mark nodes as seen when you enqueue them, not when you dequeue them, or you will visit some twice.

  6. 6

    Top k with a heap

    Sorting everything to take k elements costs linear times logarithmic in the whole input. A heap of size k costs the input size times the logarithm of k, which matters when k is small and the input is large.

    import heapq
    
    nums = [5, 1, 9, 3, 14, 7, 11, 2]
    
    def top_k(values, k):
        heap = []
        for v in values:
            heapq.heappush(heap, v)
            if len(heap) > k:
                heapq.heappop(heap)
        return sorted(heap, reverse=True)
    
    print(top_k(nums, 3))
    print(heapq.nlargest(3, nums))

    Next: heapq is a min heap, which is why keeping the k largest means popping the smallest. Now write the k smallest version.

  7. 7

    Binary search boundaries with bisect

    Most binary search questions are really about which boundary you want. bisect_left and bisect_right make that choice explicit instead of leaving it to an off by one in your own loop.

    import bisect
    
    sorted_nums = [1, 2, 2, 2, 5, 8, 13]
    print("first index of 2:", bisect.bisect_left(sorted_nums, 2))
    print("index after last 2:", bisect.bisect_right(sorted_nums, 2))
    print("count of 2s:", bisect.bisect_right(sorted_nums, 2) - bisect.bisect_left(sorted_nums, 2))
    print("insert position for 6:", bisect.bisect_left(sorted_nums, 6))

    Next: Now write bisect_left yourself with a while loop. Getting the boundary right is the whole exercise.

  8. 8

    Memoised recursion with lru_cache

    The shortest route from a recurrence to a working dynamic programming solution. Write the naive recursion, add one decorator, and the exponential version becomes linear.

    from functools import lru_cache
    
    @lru_cache(maxsize=None)
    def ways_to_climb(n):
        if n < 0:
            return 0
        if n == 0:
            return 1
        return ways_to_climb(n - 1) + ways_to_climb(n - 2)
    
    for i in range(1, 11):
        print(i, ways_to_climb(i))
    print("n=60:", ways_to_climb(60))

    Next: Remove the decorator and try n=35. The pause is the difference between exponential and linear.

  9. 9

    Counted input from the input box

    The standard competitive and interview platform input shape: a count, then that many lines. Put 4 on the first line of the input box and four numbers on the lines after it.

    n = int(input())
    nums = [int(input()) for _ in range(n)]
    print("count:", n)
    print("sum:", sum(nums))
    print("max:", max(nums))
    print("sorted:", sorted(nums))

    Next: If you get an EOFError, your count and the number of lines disagree. That error is a feature.

Browser runner or a local Python install

Neither one is better in general. They are good at different jobs, and knowing the boundary is what stops you wasting an afternoon on something the browser cannot do.

What you want to doThis browser runnerA local Python install
Solve a coding interview problemIdeal. One file, no dependencies, no setupWorks, but the setup is friction you do not need
Check a piece of language behaviourIdeal. Faster than opening anything elseFine, if a shell is already open
Use numpy, pandas, or requestsNot possible. No packages can be installedThe right choice
Read a data file from your diskNot possible. The filesystem is in browser onlyThe right choice
Step through code with breakpointsNot available. Debug with labelled printsThe right choice
Run tests, linting, and version controlNot availableThe right choice
Long running or heavy computationPoor. It freezes the tab while it runsThe right choice

When to move to a local environment

A browser runner is the right tool for a specific job: short programs, interview problems, quick checks of language behaviour, and teaching. It is the wrong tool for several others, and recognising the boundary saves time.

Move to a local install as soon as you need a package. Anything involving numerical work, data analysis, HTTP requests, a web framework, or a database needs libraries this runner cannot install, and fighting that is wasted effort rather than a challenge to solve.

Move locally when you need real files. Reading a large data file from your disk, writing output you want to keep, or working across multiple modules in a project are all things the in browser filesystem is not for.

Move locally when you need proper tooling. A step debugger with breakpoints, a test runner, a linter and formatter wired into your editor, and version control are what make longer work sustainable, and none of them exist here. If a program is more than about a hundred lines, you are past the point where a single buffer is helping you.

And move locally when performance matters. WebAssembly is fast but it is not a native install, and anything long running is better on your own machine where it can use full resources and where you can leave it going without holding a browser tab open.

The workflow that works well is to use both. Sketch here, because it is quicker than opening anything. Once the sketch turns into something you want to keep, move it into a real project with tests and version control. For interview preparation specifically, you may never need to leave, since almost every coding interview problem fits comfortably in a single file with no dependencies, which is exactly what this page runs best.

  • Any third party package means going local.
  • Real files on your disk, or a project with several modules, means going local.
  • A step debugger, a test runner, a linter, or version control means going local.
  • Long running or performance sensitive work means going local.
  • Interview practice does not. One file, no dependencies, is exactly what this runs.

Online Python runner questions

Is the online Python runner free?

Yes. There is no account, no sign up, and no limit on how many times you run your code.

Everything on the page works immediately once the Python runtime has finished loading, which happens the first time you open it.

Where does my code run, and is it sent to a server?

It runs inside your browser tab, using a build of CPython compiled to WebAssembly. Your code is not sent anywhere to be executed.

The editor also keeps your code in your browser's local storage so it is still there when you come back. That copy stays on your machine.

Can I install packages like numpy, pandas, or requests?

No. Only the Python standard library that ships with the runtime is available, and there is no way to install a third party package from this page.

The standard library is enough for essentially every coding interview problem, since collections, heapq, bisect, itertools, functools, math, re, and json are all present. For anything that needs a package, use a local Python install.

Does input() work?

Yes. input() reads from the input box on the right, one line per call, so fill the box in before you press run.

If you call input() more times than there are lines in the box, you get an EOFError. That is usually a sign that your loop count does not match the input you provided.

Can I read and write files?

open() works, but it reads and writes an in browser virtual filesystem rather than your computer's disk. You can write a file and read it back within the same run.

Anything you write there is discarded when you reload the page, and files on your own machine are not reachable from the runner at all.

Can my code make network requests?

No. The runner has no network access, so anything that opens a socket or makes an HTTP request will fail.

That is a property of running inside the browser's sandbox rather than a limitation we added, and it is the reason the runner is safe to use with no account.

Why does the output only appear when the program finishes?

Output is collected while your program runs and shown all at once at the end, so it does not stream. A long loop will look as though nothing is happening until it completes.

Keep debug traces small enough to read for this reason, and print once per loop iteration rather than in several places.

My program printed things and then crashed, but I only see the error. Why?

When your code raises an exception, the output panel shows the error rather than the output that was produced before it. It can look as though your prints never ran.

If you need both, wrap the risky section in a try block and print inside the except branch, or comment out the line that raises while you inspect the state.

The page froze. What happened?

Almost certainly an infinite loop. Execution is synchronous inside the page, so a loop that never ends locks up the tab rather than timing out.

Close the tab and reopen the page. Your code is saved in the browser, so you will get it back, and then add a print inside the loop to see where it is not terminating.

Is this good enough for coding interview practice?

Yes, and for that specific purpose it is arguably better than a local setup, because there is no friction between deciding to practise and starting. Almost every coding interview problem is one file with no dependencies, which is exactly what this runs.

The one thing to be deliberate about is starting from an empty editor rather than a template, because starting from nothing is the part a real interview tests.

Which Python modules should I know for interviews?

collections for Counter, defaultdict, and deque. heapq for priority queues and top k. bisect for binary search boundaries. itertools for combinations, permutations, product, and groupby. functools for lru_cache.

Alongside those, the built ins that do the most work: enumerate, zip, sorted with a key function, any, all, and sets for constant time membership tests.

When should I switch to a local Python install?

As soon as you need a third party package, real files on your disk, a project with several modules, a step debugger, a test runner, or version control.

Also switch for anything long running or performance sensitive. WebAssembly is fast, but your own machine is faster and does not need a browser tab left open.

Does it work on a phone or tablet?

It runs in any modern browser, and there is a run button positioned for smaller screens.

Writing more than a few lines of code on a phone keyboard is uncomfortable, so for real practice use the largest screen you have.

Related products, tools, and guides on HireCade

A runner makes you quick at writing code. These are the pages that make you good at the interview around it.

Learn Python properly

Practise the interview, not just the code

  • AI interview practice

    Twenty minute spoken practice interviews with written feedback, because interviews test talking as well as coding.

  • Mock interviews with experts

    Sixty minute sessions with engineers and hiring managers, with feedback and a recording.

  • Interview questions library

    Questions by role and company, so you can pick problems that match the loop you are facing.

  • Free online whiteboard

    A blank canvas for sketching a data structure before you code it, and for design rounds.

  • Community

    Ask what the coding round at your target company actually looks like.

The rest of the job search

  • Resume builder

    Free builder with a live preview and PDF export, plus a guide to structure and bullet points.

  • For job seekers

    The whole path in order: learn, practise, build a resume, apply, interview, and negotiate.

  • Engineering levels

    How titles map to levels across companies, which tells you how hard a coding round will push.

  • Salary data

    Compensation ranges by role and company, for the conversation after the interviews.

  • Blog

    Longer articles on interviews, hiring, and engineering careers.

  • Resources

    Guides and reference material collected by topic.