Skip to content

Commit

Permalink
Simple CLI quizzer; Add project description to README
Browse files Browse the repository at this point in the history
  • Loading branch information
neilramaswamy committed Feb 2, 2020
1 parent 03c31f4 commit 33622b4
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 2 deletions.
129 changes: 129 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# 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/
pip-wheel-metadata/
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/

# 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
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.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/
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# chords
Proof-of-concept for an application that helps you learn the notes in common jazz chords. Because 570 is hard.
# Chords
An application that helps you learn the notes in common jazz chords. Because 570 is hard.

Users will be prompted with a chord, given a chance to vocally dictate the notes, and then they will be told if their dictation was correct. I'm leaning toward vocal dictation (pitch ignorant, however) since speaking is faster than typing, and it more-closely parallels the type of recall needed for Jazz (or, at least, the type of recall that I'd like to have).

Here's a more-concrete idea of what an interaction with this app will look like:

- Front-end displays a chord like "A7#5"
- Front-end pauses for a set amount of time then starts recording audio.
- User dictates the notes that they think are in the chord: "A", "C#", "E#", "G".
- Back-end verifies their answer and sends the result to the front-end, which tells the user how they did.

This will likely turn into a web app whose frontend will be written in Typescript and whose backend will be written in Python. Each "end" will be running its own server. The Python ("verification" server, API) will use GCP's Speech-to-Text to turn audio into a string, which we can more-easily parse.
50 changes: 50 additions & 0 deletions api/checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from musthe import Note, Chord
from typing import List
from random import choice

notes = ["A", "B", "C", "D", "E", "F", "G"]

data = {
"major": "M",
"minor": "m",
"dominant 7": "dom7"
}

def are_notes_equal(n1: Note, n2: Note) -> bool:
"""
Returns whether `n1` and `n2` are the same note, disregarding octave. Checks
note name and accidental values to determine this equality.
"""
letters_equal = n1.letter == n2.letter
accidentals_equal = n1.accidental == n2.accidental

return letters_equal and accidentals_equal

def are_chords_equal(c1: Chord, notes: List[str]) -> bool:
"""
Returns whether two chords have the same notes in the same order, not
considering octave.
"""
chord_notes = c1.notes

if not len(chord_notes) is len(notes):
return False

for i in range(len(chord_notes)):
if not are_notes_equal(chord_notes[i], Note(notes[i])):
return False

return True

def quiz() -> Note:
note = choice(notes)
chord_name, chord_key = choice(list(data.items()))
print(chord_name, chord_key)

inp = input(f"Enter space-separated notes for {note} {chord_name}: ")

target_chord = Chord(Note(note), chord_key)
submission = inp.split(' ')
is_correct = are_chords_equal(target_chord, submission)

print("You were right!") if is_correct else print("You were wrong.")

0 comments on commit 33622b4

Please sign in to comment.