# autokattis
Updated Kattis API wrapper as of May 2023 after the major UI/UX change.
## Setup
Simply install it as a Python package.
```sh
$ pip install autokattis
```
## Use Cases
For now, this package supports `OpenKattis` and `NUSKattis`.
### Login
Construct an `OpenKattis` object that takes in the username and the password.
```py
from autokattis import OpenKattis
kt = OpenKattis('username', 'password')
kt = OpenKattis('username') # which will then prompt you for the password
```
where `'username'` is your Kattis username/email and `'password'` is your Kattis account password. **Both should be provided as Python strings.**
Similarly if you want to login to NUS Kattis.
```py
from autokattis import NUSKattis
kt = NUSKattis('username', 'password')
kt = NUSKattis('username')
```
### OpenKattis
> Due to backwards compatibility, you can still use `Kattis` as a shorthand form of `OpenKattis`.
#### Problem-specific
```py
kt.problems() # problems you have solved so far
kt.problems(show_partial=False) # exclude partial submissions
kt.problems(low_detail_mode=False) # include more data for each problem
kt.problems(*[True]*4) # show literally all problems on Open Kattis
kt.plot_problems() # plot the points distribution
kt.plot_problems(filepath='plot.png') # save to a filepath
kt.plot_problems(show_partial=False) # plot fully solved submissions
kt.problem('2048') # fetch info about a problem
kt.problem(['2048', 'abinitio', 'dasort']) # fetch multiple in one
kt.problem({'2048', 'abinitio', 'dasort'}) # tuples or sets also allowed
kt.problem('2048', download_files=True) # download files too
kt.stats() # your best submission for each problem
kt.stats('Java') # all your Java submissions
kt.stats(('Python3', 'Cpp')) # multiple languages
kt.suggest() # what's the next problem for me?
kt.achievements() # do I have any?
kt.problem_authors() # list down all problem authors
kt.problem_sources() # list down all problem sources
```
#### Ranklist
```py
kt.ranklist() # people around you
kt.user_ranklist() # top 100 users in general ladder
kt.challenge_ranklist() # top 100 users in challenge ladder
kt.country_ranklist() # top 100 countries
kt.country_ranklist('Singapore') # specific country
kt.country_ranklist('SGP') # use country code instead
kt.university_ranklist() # top 100 universities
kt.university_ranklist(university='National University of Singapore') # specific university
kt.university_ranklist(university='nus.edu.sg') # use university domain instead
```
### NUSKattis
#### Problem-specific
```py
kt.problems() # problems you have solved so far, only supports low detail mode
kt.problems(show_solved=False) # show literally all problems on NUS Kattis
kt.problem('2048') # fetch info about a problem
kt.problem(['2048', 'abinitio', 'dasort']) # fetch multiple in one
kt.problem({'2048', 'abinitio', 'dasort'}) # tuples or sets also allowed
kt.problem('2048', download_files=True) # download files too
kt.stats() # your best submission for each problem
kt.stats('Java') # all your Java submissions
kt.stats(('Python3', 'Cpp')) # multiple languages
```
#### Course-specific
```py
kt.courses() # current and recently ended courses
kt.offerings('CS3233') # course offerings
kt.assignments('CS3233_S2_AY2223') # offering assignments but course ID not provided
kt.assignments('CS3233_S2_AY2223', 'CS3233') # offering assignments
```
### Convert to DataFrame
As simple as adding `.to_df()`!
```py
kt.problems().to_df()
kt.ranklist().to_df()
```
### Other Scenarios
Some scenarios you can perform when using `autokattis`:
1. Mapping problem ID with its difficulty
```py
okt = OpenKattis(...)
df = okt.problems().to_df()
diff_map = dict(zip(df.id, df.difficulty))
```
1. Find the number of questions on every assignment on an NUS course offering
```py
nkt = NUSKattis(...)
df = nkt.assignments('CS3233_S2_AY2324').to_df()
df['n_problems'] = df['problems'].apply(lambda x: len(x.split(',')))
df[['name', 'n_problems']]
```
1. Find the average difficulty of every assignment on an NUS course offering
```py
diff_map = ... # see scenario 1
nkt = NUSKattis(...)
avg_2dp = lambda x: round(sum(y:=[v for v in x if v != None])/max(len(y), 1), 2)
df = nkt.assignments('CS3233_S2_AY2324').to_df()
df['avg_diff'] = df['problems'].apply(lambda x: avg_2dp(map(diff_map.get, x.split(','))))
df[['name', 'avg_diff']]
```
1. Group top 100 users by country
```py
okt = OpenKattis(...)
okt.user_ranklist().to_df().groupby('country').size()
```
### More Information
The docstrings might be a great help if you want to know more about the JSON return values!
```py
from autokattis import OpenKattis
help(OpenKattis)
```
## Testing
The `test` directory is provided within this repository. You are free to test `autokattis` with these anytime.
```sh
>>> python test/openkattis.py
...
>>> python test/nuskattis.py
...
```
## Useful References
- Old UI Kattis API wrapper: https://github.com/terror/kattis-api
> Most of the work in `autokattis` is heavily inspired and motivated by this repository.
- Kattis official CLI tool: https://github.com/Kattis/kattis-cli
> Since Kattis has provided an official tool to automate submissions, there won't be such feature in `autokattis`.
## Contributing
Feel free to suggest anything or add on some implementation by simply creating a pull request!
Raw data
{
"_id": null,
"home_page": "https://github.com/RussellDash332/autokattis",
"name": "autokattis",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "Kattis",
"author": "Russell Saerang",
"author_email": "russellsaerang@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/7b/6b/edbb447f678e8ca1092e65d1fa2b249adb223949aca026883ba50d79dee0/autokattis-2.0.2.tar.gz",
"platform": null,
"description": "# autokattis\n\nUpdated Kattis API wrapper as of May 2023 after the major UI/UX change.\n\n## Setup\n\nSimply install it as a Python package.\n\n```sh\n$ pip install autokattis\n```\n\n## Use Cases\n\nFor now, this package supports `OpenKattis` and `NUSKattis`.\n\n### Login\n\nConstruct an `OpenKattis` object that takes in the username and the password.\n\n```py\nfrom autokattis import OpenKattis\nkt = OpenKattis('username', 'password')\nkt = OpenKattis('username') # which will then prompt you for the password\n```\n\nwhere `'username'` is your Kattis username/email and `'password'` is your Kattis account password. **Both should be provided as Python strings.**\n\nSimilarly if you want to login to NUS Kattis.\n\n```py\nfrom autokattis import NUSKattis\nkt = NUSKattis('username', 'password')\nkt = NUSKattis('username')\n```\n\n### OpenKattis\n\n> Due to backwards compatibility, you can still use `Kattis` as a shorthand form of `OpenKattis`.\n\n#### Problem-specific\n\n```py\nkt.problems() # problems you have solved so far\nkt.problems(show_partial=False) # exclude partial submissions\nkt.problems(low_detail_mode=False) # include more data for each problem\nkt.problems(*[True]*4) # show literally all problems on Open Kattis\n\nkt.plot_problems() # plot the points distribution\nkt.plot_problems(filepath='plot.png') # save to a filepath\nkt.plot_problems(show_partial=False) # plot fully solved submissions\n\nkt.problem('2048') # fetch info about a problem\nkt.problem(['2048', 'abinitio', 'dasort']) # fetch multiple in one\nkt.problem({'2048', 'abinitio', 'dasort'}) # tuples or sets also allowed\nkt.problem('2048', download_files=True) # download files too\n\nkt.stats() # your best submission for each problem\nkt.stats('Java') # all your Java submissions\nkt.stats(('Python3', 'Cpp')) # multiple languages\n\nkt.suggest() # what's the next problem for me?\nkt.achievements() # do I have any?\nkt.problem_authors() # list down all problem authors\nkt.problem_sources() # list down all problem sources\n```\n\n#### Ranklist\n\n```py\nkt.ranklist() # people around you\n\nkt.user_ranklist() # top 100 users in general ladder\nkt.challenge_ranklist() # top 100 users in challenge ladder\n\nkt.country_ranklist() # top 100 countries\nkt.country_ranklist('Singapore') # specific country\nkt.country_ranklist('SGP') # use country code instead\n\nkt.university_ranklist() # top 100 universities\nkt.university_ranklist(university='National University of Singapore') # specific university\nkt.university_ranklist(university='nus.edu.sg') # use university domain instead\n```\n\n### NUSKattis\n\n#### Problem-specific\n\n```py\nkt.problems() # problems you have solved so far, only supports low detail mode\nkt.problems(show_solved=False) # show literally all problems on NUS Kattis\n\nkt.problem('2048') # fetch info about a problem\nkt.problem(['2048', 'abinitio', 'dasort']) # fetch multiple in one\nkt.problem({'2048', 'abinitio', 'dasort'}) # tuples or sets also allowed\nkt.problem('2048', download_files=True) # download files too\n\nkt.stats() # your best submission for each problem\nkt.stats('Java') # all your Java submissions\nkt.stats(('Python3', 'Cpp')) # multiple languages\n```\n\n#### Course-specific\n\n```py\nkt.courses() # current and recently ended courses\nkt.offerings('CS3233') # course offerings\nkt.assignments('CS3233_S2_AY2223') # offering assignments but course ID not provided\nkt.assignments('CS3233_S2_AY2223', 'CS3233') # offering assignments\n```\n\n### Convert to DataFrame\n\nAs simple as adding `.to_df()`!\n\n```py\nkt.problems().to_df()\nkt.ranklist().to_df()\n```\n\n### Other Scenarios\n\nSome scenarios you can perform when using `autokattis`:\n1. Mapping problem ID with its difficulty\n ```py\n okt = OpenKattis(...)\n df = okt.problems().to_df()\n diff_map = dict(zip(df.id, df.difficulty))\n ```\n1. Find the number of questions on every assignment on an NUS course offering\n ```py\n nkt = NUSKattis(...)\n df = nkt.assignments('CS3233_S2_AY2324').to_df()\n df['n_problems'] = df['problems'].apply(lambda x: len(x.split(',')))\n df[['name', 'n_problems']]\n ```\n1. Find the average difficulty of every assignment on an NUS course offering\n ```py\n diff_map = ... # see scenario 1\n\n nkt = NUSKattis(...)\n avg_2dp = lambda x: round(sum(y:=[v for v in x if v != None])/max(len(y), 1), 2)\n df = nkt.assignments('CS3233_S2_AY2324').to_df()\n df['avg_diff'] = df['problems'].apply(lambda x: avg_2dp(map(diff_map.get, x.split(','))))\n df[['name', 'avg_diff']]\n ```\n1. Group top 100 users by country\n ```py\n okt = OpenKattis(...)\n okt.user_ranklist().to_df().groupby('country').size()\n ```\n\n### More Information\n\nThe docstrings might be a great help if you want to know more about the JSON return values!\n\n```py\nfrom autokattis import OpenKattis\nhelp(OpenKattis)\n```\n\n## Testing\n\nThe `test` directory is provided within this repository. You are free to test `autokattis` with these anytime.\n\n```sh\n>>> python test/openkattis.py\n...\n>>> python test/nuskattis.py\n...\n```\n\n## Useful References\n\n- Old UI Kattis API wrapper: https://github.com/terror/kattis-api\n\n > Most of the work in `autokattis` is heavily inspired and motivated by this repository.\n\n- Kattis official CLI tool: https://github.com/Kattis/kattis-cli\n\n > Since Kattis has provided an official tool to automate submissions, there won't be such feature in `autokattis`.\n\n## Contributing\n\nFeel free to suggest anything or add on some implementation by simply creating a pull request!\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Updated Kattis API wrapper",
"version": "2.0.2",
"project_urls": {
"Download": "https://pypi.org/project/autokattis/",
"Homepage": "https://github.com/RussellDash332/autokattis"
},
"split_keywords": [
"kattis"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0b9af22123595f29c93cdd615fc7903ca0f699bc721231653171d90fb3d25c80",
"md5": "6cb03ba0fabd8dcdda8bf65892c55357",
"sha256": "e660c0df4af526a50346ba0ef085055aa3daa989ebceecde56a98937e046d680"
},
"downloads": -1,
"filename": "autokattis-2.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6cb03ba0fabd8dcdda8bf65892c55357",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 34841,
"upload_time": "2024-11-08T03:00:26",
"upload_time_iso_8601": "2024-11-08T03:00:26.676565Z",
"url": "https://files.pythonhosted.org/packages/0b/9a/f22123595f29c93cdd615fc7903ca0f699bc721231653171d90fb3d25c80/autokattis-2.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7b6bedbb447f678e8ca1092e65d1fa2b249adb223949aca026883ba50d79dee0",
"md5": "8f50e4dc545bb4169a72a3f9fe406404",
"sha256": "a9fe8d94061de77a2985470df8e1c092a4de4121fa78670490408af89a0a9550"
},
"downloads": -1,
"filename": "autokattis-2.0.2.tar.gz",
"has_sig": false,
"md5_digest": "8f50e4dc545bb4169a72a3f9fe406404",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 33702,
"upload_time": "2024-11-08T03:00:28",
"upload_time_iso_8601": "2024-11-08T03:00:28.793347Z",
"url": "https://files.pythonhosted.org/packages/7b/6b/edbb447f678e8ca1092e65d1fa2b249adb223949aca026883ba50d79dee0/autokattis-2.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-08 03:00:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "RussellDash332",
"github_project": "autokattis",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "autokattis"
}