معرفی شرکت ها


aox-1.1.1


Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر

توضیحات

AdventOfCode Submissions Framework
ویژگی مقدار
سیستم عامل -
نام فایل aox-1.1.1
نام aox
نسخه کتابخانه 1.1.1
نگهدارنده []
ایمیل نگهدارنده []
نویسنده Costas Basdekis
ایمیل نویسنده costas@basdekis.io
آدرس صفحه اصلی https://github.com/costas-basdekis/aox
آدرس اینترنتی https://pypi.org/project/aox/
مجوز MIT License
# aox - Python Advent of Code Submissions helper ![Tests](https://github.com/costas-basdekis/aox/workflows/Tests/badge.svg) [![AOX version](https://pypip.in/v/aox/badge.png)](https://pypi.org/project/aox/) ![AOX downloads](https://pypip.in/d/aox/badge.png) AOX was created with the following ideals: 1. I wanted to be able to run tests for each challenge 2. I didn't want to write the same code to load the input, run the tests, and print the result 3. I wanted all of my challenges to have the same structure The main feature of AOX is auto-creating the boilerplate for each challenge, Currently only Python>=3.7 is supported. [aoc]: https://adventofcode.com/ ## Quick start Install `aox` (Python>=3.7 needed): ```shell script pip install aox ``` Create your settings: ```shell script aox init-settings ``` Edit `.aox/sensitive_user_settings.py` to put your AOC session token ```python # Copy-paste from your browser cookies AOC_SESSION_ID = "..." ``` The following creates the boilerplate, and downloads your input: ```shell script aox add 2020 1 a ``` Edit the file to solve the challenge (your input is automatically passed in), and return the solution inside the `Challenge.solve` body: ```python class Challenge(BaseChallenge): def solve(self, _input, debugger): return your_awesome_calculations(_input) ``` If you want to check it works you can run it: ```shell script aox challenge 2020 1 a run ``` When you're happy with the result, submit it: ```shell script aox challenge 2020 1 a submit --yes ``` It will run your code, take the result, and submit it! If it's successful: hurray! Time to solve part B with: ```shell script aox add 2020 1 b ``` And so on ## Features #### Custom boilerplate If you always want to import certain libraries (eg `itertools`, `functools`, your own `utils` library), you can create a template, so that you don't have to write the same things again and again: ```python #!/usr/bin/env python3 import aox.challenge import my_useful_utils import itertools, functools import re class Challenge(aox.challenge.BaseChallenge): ... ... ``` Check the [boilerplate customisation](#boilerplate-customisation) for more details. #### Testing, running, debugging, interactive challenges I've found that writing small [doctests] makes it much easier to develop solutions for AOC, especially when they become more complicated. AOX automatically picks up all doctests in a challenge and runs them if you run `aox challenge <year> <day> <part> test`. It also prints your solution when you run `aox challenge <year> <day> <part> run`. If you add the `--debug` flag, then you can use the `debugger` parameter to your `Challenge.solve` method, which is useful when you want to print diagnostic stats: ```python class Challenge(BaseChallenge): def solve(self, _input, debugger): # Print something, if debugging is enable, and enough # time has passed from the previous print statement debugger.report_if( "Many many lines of debug information") # By default there is a 5s interval between printing # To change that, use the --debug-interval/-i flag debugger.report_if( "You won't see this") # After enough time, `report_if` will print time.sleep(5) # To print something expensive, first check: if debugger.should_report(): debugger.report( "Some expensive calculation:", expensive_calculation()) # Debug through an iterable for index in range(10): debugger.step() debugger.report_if(f"looking at index {index}") ... # Also helpers to step through an iterable for index in debugger.stepping(range(10)): debugger.report_if(f"looking at index {index}") ... # Or through a while loop value = 0 while debugger.step_if(value < 3): value += 1 debugger.report_if(f"checking value {value}") ... return 6 * 7 ``` To see more information check the [Debugger documentation] `aox challenge <year> <day> <part> run` will print: ``` Solution: 42 (in 0.0s) ``` While `aox challenge <year> <day> <part> run --debug` will print: ``` Many many lines of debug information That you don't want to read every time Solution: 42 (in 0.0s) ``` Some challenges require you to interact with a program you're emulating, eg [2019/15/A] or [2019/25/A], so before you write an automated solution, you might elect to add an interactive mode. Other times, it's useful to be able to interactively explore the problem space. To do that, simply add a `play` method to your challenge, and run `aox challenge <year> <day> <part> play`: ```python class Challenge(BaseChallenge): def play(self): _input = self.input while True: command = click.prompt("Enter u for up, d for down, q to quit") if command == 'u': ... ``` By default, if you don't specify a mode, AOX will first test and then run your solution with `aox challenge <year> <day> <part>`: ```python 4 tests in 1 modules passed in 0.02s Solution: 1234567 (in 0.0s) ``` [doctests]: https://docs.python.org/3/library/doctest.html [2019/15/A]: https://adventofcode.com/2019/day/15 [2019/25/A]: https://adventofcode.com/2019/day/25 [Debugger documentation]: #debugging-your-code #### Debugging your code Sometimes you need to see some details about the process you're running, and that could mean printing some info in the console, especially if you have a very inefficient algorithm. The `Debugger` class, that is passed in as `debugger` in the `Challenge.solve` method, provides some very useful functionality: > `if debugger:` or `if debugger.enabled:` This allows you to only do something if you passed `--debug`/`-d` as an argument > `debugger.step_count`, `debugger.step_count_since_last_report`, `debugger.step_frequency`, and `debugger.step_frequency_since_last_report` You inspect how many steps total/per second have you performed since the start/last time you reported. > `if debugger.should_report(): debugger.report(...)` or > `debugger.report_if(...)` Advance the step count once, and print something to the console, if the debugger is enabled, and enough time has passed since the last reporting (default is `5s`, controlled by the `--debug-interval`/`-i` flag). > `debugger.default_report()` and `debugger.default_report_if()` Similar to the above, but it uses the formatting function from the `DEFAULT_DEBUGGER_REPORT_FORMAT` to include some useful data in the output. If your calculations run through nested function calls, you can also provide additional info, by using `debugger.extra_report_formats`, or using the `debugger.adding_extra_report_format` context manager: ```python def level_1(data, debugger): def report_x(_, message): return f"x: {x}" # Will print: 'start x' debugger.default_report("start x") total = 0 for x in range(10000000): with debugger.adding_extra_report_format(report_x): # Will print: 'x: 0, start y' debugger.default_report("start y") total += level_2(data[x], debugger) def level_2(data, debugger): def report_y(_, message): return f"y: {y}" total = 0 for y in range(10000000): with debugger.adding_extra_report_format(report_y): # Will print: 'x: 0, y: 0, start z' debugger.default_report("start z") total += level_3(data[y], debugger) return total def level_3(data, debugger): total = 0 for z in range(10000000): total += data[z]['a'] * data[z]['b'] # Will print: 'x: 0, y: 0, z: 0' debugger.default_report_if(f"z: {z}") return total ``` > `debugger.duration_since_start` and `debugger.duration_since_last_report`, as > well as `debugger.pretty_duration_*` and `debugger.get_pretty_duration_*()` You can get the duration since the start/last report, which would be the number of seconds since then. Since these are fine precision floats, you would like to use the `pretty_*` property to get a nice `3h5m2s` rendition of time, or the `get_pretty_*` methods to control how many `digits` do of precision do you want to include in the seconds eg `3h5m2s.23`. > `debugger.step()`, `debugger.stepping()`, and `debugger.step_if()` It signifies that you have performed a number of steps (by default 1). There are two helper methods: ```python3 # Step for each item in the passed in iterable for item in debugger.stepping(['a', 'b', 'c']): ... # Step for each truthy value value = 0 while debugger.step_if(value < 3): value += 1 ... ``` #### Reading your stars To keep track how many and which stars you have, you can add your auth credentials (check [Session Cookie](#session-cookie) for details), and use `aox fetch` to refresh the stars cache. Then you can see them either via `aox` or `aox list`: ``` Found 4 years with code and 162 stars: * 2020: 25 days with code and 50 stars * 2019: 25 days with code and 47 stars * 2018: 25 days with code and 34 stars * 2017: 25 days with code and 41 stars ``` Or for a particular year with `aox list 2019`: ``` Found 25 days with code in 2019 with 47 stars: * 25*!, 24**, 23**, 22*x, 21**, 20**, 19**, 18**, 17**, 16*x, 15**, 14**, 13**, 12**, 11**, 10**, 9**, 8**, 7**, 6**, 5**, 4**, 3**, 2**, 1** ``` #### Displaying your swag You might be proud of how many stars you've gotten over the years, or you might want to keep track of which challenges do you still have to solve. In any case, AOX provides the ability to display star & code summaries in your README automatically. The way you can display these are customisable, by creating a new `aox.summaries.BaseSummary` sub-class, and there are two default summaries built-in: **Event summary** Simply add the following lines in your README: ```markdown [//]: # (event-summary-start) [//]: # (event-summary-end) ``` And after every `aox update-readme` you should see something like this: | Total | 2020 | 2019 | 2018 | 2017 | | --- | --- | --- | --- | --- | | 162 :star: | 50 :star: :star: | 47 :star: | 34 :star: :star: | 41 :star: :star: | **Submissions summary** Add the following lines in your README: ```markdown [//]: # (submissions-start) [//]: # (submissions-end) ``` And after every `aox update-readme` you should see something like this: | | 2020 | 2019 | | ---: | :---: | :---: | | | [Code][co-20] & [Challenges][ch-20] | [Code][co-19] & [Challenges][ch-19] | | | 50 :star: :star: | 47 :star: / 2 :x: / 1 :grey_exclamation: | | 1 | [Code][co-20-01] :star: :star: [Challenge][ch-20-01] | [Code][co-19-01] :star: :star: [Challenge][ch-19-01] | | 2 | [Code][co-20-02] :star: :star: [Challenge][ch-20-02] | [Code][co-19-02] :star: :star: [Challenge][ch-19-02] | | ... | ... | ... | | 24 | [Code][co-20-24] :star: :star: [Challenge][ch-20-24] | [Code][co-19-24] :star: :star: [Challenge][ch-19-24] | | 25 | [Code][co-20-25] :star: :star: [Challenge][ch-20-25] | [Code][co-19-25] :star: :grey_exclamation: [Challenge][ch-19-25] | **Your custom summary** Simple override and register your summary class: ```python from aox.summary import BaseSummary, summary_registry @summary_registry.register class MyCustomSummary(BaseSummary): # Don't forget to set your prefix marker_prefix = "my-custom" def generate(self, combined_info): years_with_stars_or_code = [ year for year, year_info in combined_info.year_infos.items() if year_info.has_code or year_info.stars ] return ( "Your custom markdown using stars & code info:\n" f"You have stars or code in {len(years_with_stars_or_code)} years\n" f"In 2020 you had {combined_info.year_infos[2020].stars} :star:\n" ) ``` Don't forget to import your module, which can easily be done in your settings: ```python EXTRA_MODULE_IMPORTS = ['my_custom_summary'] ``` And to add the following lines in your README: ```markdown [//]: # (my-custom-start) [//]: # (my-custom-end) ``` And after every `aox update-readme` you should see something like this: ```markdown Your custom markdown using stars & code info: You have stars or code in 2 years In 2020 you had 50 :star: ``` ### Settings After `aox init-settings`, you'll have an `.aox` folder in your repo: ``` .aox ├──.gitignore ├──sensitive_user_settings.py ├──site_data.json └──user_settings.py ``` You should edit `sensitive_user_settings.py` to put the authentication cookie for your account, to allow AOX access your AOC stats: ```python AOC_SESSION_ID = ( "a-very-long-hex-string" "that-you-can-get-from-your-browser" ) ``` You can find it in the `Application` tab (eg in Chrome), and you should not commit that file in git, as it contains your secrets. `site_data.json` is the cache of the AOC stars, from the last time you did `aox fetch`. If you want all the data that AOX uses you can use `aox dump`. Now, you can customise your experience in `user_settings.py`: #### Session Cookie Simply load it from your not-git-commited file ```python AOC_SESSION_ID = sensitive_user_settings.AOC_SESSION_ID ``` #### Challenges code location Where do your challenges live? The default boilerplate structure is `<repo-root>/year_<year>/day_<day>/part_<part>.py`, so you don't have to change this: ```python CHALLENGES_ROOT = repo_root CHALLENGES_MODULE_NAME_ROOT = None # Top module ``` If you want to use a different folder, eg `<repo-root>/my/challenges/year_<year>/day_<day>/part_<part>.py`, you can do: ```python CHALLENGES_ROOT = repo_root.joinpath('my', 'challenges') CHALLENGES_MODULE_NAME_ROOT = 'my.challenges' # Module prefix ``` #### Boilerplate customisation By default, boilerplate is structure as mentioned above: ```python CHALLENGES_BOILERPLATE = "aox.boilerplate.DefaultBoilerplate" ``` The most common use case is to create a template file with eg custom imports: ```python #!/usr/bin/env python3 import aox.challenge import my_useful_utils import itertools, functools import re class Challenge(aox.challenge.BaseChallenge): ... ... ``` And then change the example part path: ```python from aox.boilerplate import DefaultBoilerplate CHALLENGES_BOILERPLATE = DefaultBoilerplate( example_part_path=repo_root.joinpath('my_custom_example_part.py'), ) ``` Or for more complex customisation, eg if you want a different structure (eg `<repo-root>/<year>_<day>_<part>.py`), you can sub-class `aox.boilerplate.BaseBoilerplate`, which AOX uses to know where to find your code: ```python import aox.boilerplate class MyCustomBoilerplate(aox.boilerplate.DefaultBoilerplate): ... ``` And use it: ```python CHALLENGES_BOILERPLATE = "my_custom_boilerplate.MyCustomBoilerplate" ``` #### Default format To avoid repeating yourself every time you want to print something out, you can define (or use the default) formatter function to add some standard details: ```python def verbose_debugger_format(debugger: 'Debugger', message: str) -> str: return ( f"Step: {debugger.step_count}, {message}, time: " f"{debugger.pretty_duration_since_start}, total steps/s: " f"{debugger.step_frequency}, recent steps/s: " f"{debugger.step_frequency_since_last_report}" ) DEFAULT_DEBUGGER_REPORT_FORMAT = verbose_debugger_format ``` If you want to customise it: ```python def custom_debugger_format(debugger: 'Debugger', message: str) -> str: return ( f"Custom format, delta time is " f"{debugger.pretty_duration_since_last_report} for {message}" ) DEFAULT_DEBUGGER_REPORT_FORMAT = custom_debugger_format ``` #### Site data cache There is no reason to change this, and by default it lives in the `.aox` folder. In case you want it somewhere else (eg your home directory), you can replace this (remembering to use `Path`). ```python # Save this info in my home directory SITE_DATA_PATH = Path.home().joinpath('aoc_site_data.json') ``` #### README location If you want AOX to put a summary of your stars in markdown, you can use this to specify your README path ```python README_PATH = repo_root.joinpath('README.md') ``` #### Custom settings If you want to keep some extra settings, you can add them to `.aox/user_settings.py`, and you can access them via the `settings.module` attribute: ```python MY_CUSTOM_SETTING = "foo" ``` ```python from aox.settings import settings_proxy # Make sure to always use `settings_proxy()` print(settings_proxy().module.MY_CUSTOM_SETTING) ``` ## Contributing: Please see the relevant section in [aox](./aox)


نحوه نصب


نصب پکیج whl aox-1.1.1:

    pip install aox-1.1.1.whl


نصب پکیج tar.gz aox-1.1.1:

    pip install aox-1.1.1.tar.gz