# 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.affiliation_ranklist() # top 100 affiliations
kt.affiliation_ranklist(affiliation='National University of Singapore') # specific affiliation
kt.affiliation_ranklist(affiliation='nus.edu.sg') # use affiliation 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/74/a4/2210242f50ea3bcd2a96c102c036b294c7286a106c83df4c24f08985c09a/autokattis-2.1.3.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.affiliation_ranklist() # top 100 affiliations\nkt.affiliation_ranklist(affiliation='National University of Singapore') # specific affiliation\nkt.affiliation_ranklist(affiliation='nus.edu.sg') # use affiliation 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.1.3",
"project_urls": {
"Download": "https://pypi.org/project/autokattis/",
"Homepage": "https://github.com/RussellDash332/autokattis"
},
"split_keywords": [
"kattis"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bf8d0cc1645d0d90a9977871c120df10d86a369fd9399a9318b958ec1e1c77af",
"md5": "0edc4dafbdd2a53c184d8b0191ac2832",
"sha256": "6ffc288a9d3d671ed8b0f805958c373cbf8c381714b2026b0195eac2e7e7688c"
},
"downloads": -1,
"filename": "autokattis-2.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0edc4dafbdd2a53c184d8b0191ac2832",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 35105,
"upload_time": "2025-03-07T07:49:46",
"upload_time_iso_8601": "2025-03-07T07:49:46.207594Z",
"url": "https://files.pythonhosted.org/packages/bf/8d/0cc1645d0d90a9977871c120df10d86a369fd9399a9318b958ec1e1c77af/autokattis-2.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "74a42210242f50ea3bcd2a96c102c036b294c7286a106c83df4c24f08985c09a",
"md5": "19313827762d87ec32307179fbb67d11",
"sha256": "d20f2976e9e942256c982715c04ad266fad7af1dfd482f8bdaca08f66e55dc3d"
},
"downloads": -1,
"filename": "autokattis-2.1.3.tar.gz",
"has_sig": false,
"md5_digest": "19313827762d87ec32307179fbb67d11",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 33761,
"upload_time": "2025-03-07T07:49:47",
"upload_time_iso_8601": "2025-03-07T07:49:47.992517Z",
"url": "https://files.pythonhosted.org/packages/74/a4/2210242f50ea3bcd2a96c102c036b294c7286a106c83df4c24f08985c09a/autokattis-2.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-03-07 07:49:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "RussellDash332",
"github_project": "autokattis",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "autokattis"
}