Skip to content
/ plr Public

Python LeetCode runner to fetch problems and test solutions.

License

Notifications You must be signed in to change notification settings

dashmage/plr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

plr(python-leetcode-runner) is a tool to fetch LeetCode problems (using the problem title slug) and then to test your solutions.

A lot of code logic has been lifted from the wonderful leetcode-runner project.

  • fetcher.py: To execute the GraphQL query on the public API and get the problem details.
  • models.py: Pydantic models for the problem data obtained.
  • generator.py: To generate the template for the python solution file that's created.

Some of my improvements include,

  • A new test subcommand instead of calling the class method in the solution file.
  • Supports testing with multiple solutions for a problem.
  • Specify your own custom methods for more complex testing scenarios required for certain problems.
  • Shorter name 😉

Installation

pipx makes it super easy to get started with using plr in an isolated environment.

pipx install git+https://github.com/dashmage/plr.git

You might need to add ~/.local/bin to your PATH in case calling plr doesn't work.

echo "export PATH=$PATH:~/.local/bin" >> ~/.bashrc
source ~/.bashrc

Otherwise, you can also install the package with pip (preferably in a virtual environment).

python3 -m venv venv
source venv/bin/activate
pip install git+https://github.com/dashmage/plr.git#egg=plr

Usage

From the LeetCode problem URL, obtain the title slug name. For the two sum problem, that would be two-sum.

Now run,

$ plr pull two-sum

1-two-sum.py has been created! Happy solving

This fetches the problem description and python starter code and adds into the newly created 1-two-sum.py python file. 1 is the problem ID for the two sum problem.

After coding up a solution and adding it to the Solution class, run the plr test command to validate it against the example test cases.

$ plr test two-sum

This will test the Solution class method(s) with the examples automatically parsed from the problem description in the docstring.

Multiple Solutions

You can even provide multiple solution methods in the Solution class and each of them would be validated with the example test cases.

=== twoSum_1 ===

[ OK ]
nums = [2,7,11,15], target = 9
Expected: [0, 1]
Actual  : [0, 1]
------------------------------
[ OK ]
nums = [3,2,4], target = 6
Expected: [1, 2]
Actual  : [1, 2]
------------------------------
[ OK ]
nums = [3,3], target = 6
Expected: [0, 1]
Actual  : [0, 1]
------------------------------

Passed: 3/3

=== twoSum_2 ===

[ FAILED ]
nums = [2,7,11,15], target = 9
Expected: [0, 1]
Actual  : [1, 2, 3]
------------------------------
[ FAILED ]
nums = [3,2,4], target = 6
Expected: [1, 2]
Actual  : [1, 2, 3]
------------------------------
[ FAILED ]
nums = [3,3], target = 6
Expected: [0, 1]
Actual  : [1, 2, 3]
------------------------------

Passed: 0/3

Extra Test Cases

Extra test cases can easily be added by appending a new "Example" in the problem description. This additional test will be picked up by the test validator.

Example 5:
Input: nums = [1,2,3], k = 2
Output: [1,2]

Advanced Usage

Certain problems require more steps to be performed either while evaluating and returning the actual results from the solution method or while validating whether the results are as expected.

For these situations, you can optionally define two methods outside the Solution class, namely evaluate and validate.

Evaluate Method

The evaluate method comes in handy when you need to alter the results returned by the solution method. This can happen when the expected results also check the value of the input array which changes in-place.

For example, in Problem #26, duplicates are to be removed from a sorted array. For testing solutions to this problem, we need to evaluate the number of unique elements and return that along with the input array as a tuple.

Here is what a sample input and output look like,

Input: nums = [1,1,2]
Output: 2, nums = [1,2,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

We can then define our evaluate method accordingly.

def evaluate(method, kwargs):
    result = method(**kwargs)
    return result, kwargs["nums"][:result]

Validate Method

The validate method can be defined when you need to explicitly specify how to compare the actual and expected test case results. By default, this is checked simply by running actual == expected. But in some problems, say, where the order of elements in the expected array can be ignored, you cannot directly compare their values.

For example, in Problem #347, we're expected to return the top k frequent elements as a list in any order. So Counters can be used to ignore the sort order but still preserve duplicates during the comparison between the lists.

Here is what a sample input and output look like,

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

We can then define our validate method accordingly.

def validate(actual, expected):
    from collections import Counter
    return Counter(actual) == Counter(expected)

Take a look at the solved LeetCode problems provided in the repo some of which utilize these methods for testing.

Development

Ensure you have poetry installed. Clone the repo, change into the created directory, run poetry shell and you're good to go.

Tests can be executed with poetry run pytest -v

About

Python LeetCode runner to fetch problems and test solutions.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published