first
This commit is contained in:
140
.gitignore
vendored
Normal file
140
.gitignore
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
.idea/
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
12
Pipfile
Normal file
12
Pipfile
Normal file
@@ -0,0 +1,12 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
pytest = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
100
Pipfile.lock
generated
Normal file
100
Pipfile.lock
generated
Normal file
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "828b8ad012f4c8773e6e61e3ac2be0ffcd7540fd7ed175a8355676c8e31c4d3d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
|
||||
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
|
||||
],
|
||||
"version": "==19.3.0"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:0505dd08068cfec00f53a74a0ad927676d7757da81b7436a6eefe4c7cf75c545",
|
||||
"sha256:15ec6c0fd909e893e3a08b3a7c76ecb149122fb14b7efe1199ddd4c7c57ea958"
|
||||
],
|
||||
"markers": "python_version < '3.8'",
|
||||
"version": "==1.6.1"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be",
|
||||
"sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"
|
||||
],
|
||||
"version": "==8.3.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8",
|
||||
"sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"
|
||||
],
|
||||
"version": "==20.4"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
|
||||
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
|
||||
],
|
||||
"version": "==0.13.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa",
|
||||
"sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"
|
||||
],
|
||||
"version": "==1.8.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
|
||||
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
|
||||
],
|
||||
"version": "==2.4.7"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1",
|
||||
"sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.4.3"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
||||
],
|
||||
"version": "==1.15.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f",
|
||||
"sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f"
|
||||
],
|
||||
"version": "==0.2.4"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
|
||||
"sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
|
||||
],
|
||||
"version": "==3.1.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Binary Math Exercises
|
||||
|
||||
## Description
|
||||
|
||||
A command line application and Python library for generating binary numbers for a human to decode, as well as generating the integers they represent, to check the human's work.
|
||||
|
||||
## Installation on MacOS or Linux
|
||||
1) `git clone https://github.com/Averbach-Transcription/email_quote`
|
||||
2) `ln -s <repo_fullpath>/app/get_quote /usr/local/bin/`
|
||||
|
||||
## Usage
|
||||
```make_binary_problems <number_of_bits: integer> <number_of_problems: integer>```
|
||||
|
||||
## TODO
|
||||
- use click to make it a proper CLI, now that there will be multiple options
|
||||
- make it produce printable sheets, probably as PDFs
|
||||
- add nice spacing for easy reading
|
||||
- options
|
||||
- create_pdf
|
||||
- number of columns [auto]
|
||||
- font
|
||||
- include column labels
|
||||
|
||||
### Other Projects That Could Depend On This
|
||||
- do the problems online/on computer
|
||||
- a website to serve these up and let people use them for free
|
||||
- a web API that serves it, so people can do that programmatically
|
||||
0
app/__init__.py
Normal file
0
app/__init__.py
Normal file
3
app/check.py
Normal file
3
app/check.py
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
def check(binary_string):
|
||||
return int(binary_string, 2)
|
||||
1
app/config.py
Normal file
1
app/config.py
Normal file
@@ -0,0 +1 @@
|
||||
BEGIN_ANSWERS_TOKEN = "*BEGIN ANSWERS*"
|
||||
15
app/generate.py
Normal file
15
app/generate.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import random
|
||||
|
||||
from app.check import check
|
||||
|
||||
|
||||
def generate(bits=8):
|
||||
return "".join([random.choice("10") for i in range(bits)])
|
||||
|
||||
|
||||
def generate_problems(bits, num_problems):
|
||||
return [generate(bits) for i in range(num_problems)]
|
||||
|
||||
|
||||
def generate_answers(problems):
|
||||
return [check(problem) for problem in problems]
|
||||
27
app/main.py
Executable file
27
app/main.py
Executable file
@@ -0,0 +1,27 @@
|
||||
import sys
|
||||
|
||||
from app.generate import generate_answers, generate_problems
|
||||
from config import BEGIN_ANSWERS_TOKEN
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(
|
||||
"please supply the number of bits and the number of exercises you'd like, "
|
||||
"space-separated, like so:\n\n $ binary 8 100\n"
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
bits = int(sys.argv[1])
|
||||
num_problems = int(sys.argv[2])
|
||||
|
||||
problems = generate_problems(bits, num_problems)
|
||||
answers = generate_answers(problems)
|
||||
|
||||
problems_string = "\n\n".join(problems)
|
||||
answers_string = "\n\n".join(
|
||||
[f"{problem} | {answer} " for problem, answer in zip(problems, answers)]
|
||||
)
|
||||
|
||||
sys.stdout.write(BEGIN_ANSWERS_TOKEN.join((problems_string, answers_string)))
|
||||
return problems_string, answers_string
|
||||
29
app/test/test_generate.py
Normal file
29
app/test/test_generate.py
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
from app.generate import generate, generate_problems
|
||||
from app.check import check
|
||||
|
||||
|
||||
def test_generate():
|
||||
first_problem = generate(bits=5)
|
||||
assert len(first_problem) == 5
|
||||
assert all(char in ('1', '0') for char in first_problem)
|
||||
assert '1' in first_problem
|
||||
assert '0' in first_problem
|
||||
|
||||
|
||||
def test_generate_problems():
|
||||
problems = generate_problems(bits=5, num_problems=100)
|
||||
first_problem = problems[0]
|
||||
assert len(problems) == 100
|
||||
assert len(first_problem) == 5
|
||||
assert all(char in ('1', '0') for char in first_problem)
|
||||
assert '1' in first_problem
|
||||
assert '0' in first_problem
|
||||
|
||||
|
||||
def test_check():
|
||||
assert check('110') == 6
|
||||
assert check('000') == 0
|
||||
assert check('001') == 1
|
||||
assert check('011') == 3
|
||||
assert check('010') == 2
|
||||
26
setup.py
Normal file
26
setup.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setup(
|
||||
name="binary_math_exercises",
|
||||
author="Zev Averbach",
|
||||
author_email="zev@averba.ch",
|
||||
version="0.1",
|
||||
description=(
|
||||
"A command line application and Python library for generating binary numbers for "
|
||||
"a human to decode, as well as generating the integers they represent, to check "
|
||||
"the human's work."
|
||||
),
|
||||
long_description=long_description,
|
||||
packages=find_packages(),
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
python_requires=">=3.5",
|
||||
entry_points={"console_scripts": ["binary=app.main:main"]},
|
||||
)
|
||||
Reference in New Issue
Block a user