diff --git a/mathpractice/__init__.py b/mathpractice/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathpractice/__main__.py b/mathpractice/__main__.py
new file mode 100644
index 0000000..32e41c4
--- /dev/null
+++ b/mathpractice/__main__.py
@@ -0,0 +1,53 @@
+import argparse
+import json
+import os
+import random
+import sys
+
+sys.path.insert(
+ 0,
+ os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+)
+
+from mathpractice.sheet import Sheet
+from mathpractice.html_formatter import HTMLFormatter
+from mathpractice.json_formatter import JSONFormatter
+
+
+def main(sysargs=sys.argv[:]):
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument('-L', '--lowest-factor', type=int, default=0)
+ parser.add_argument('-H', '--highest-factor', type=int, default=15)
+ parser.add_argument('-t', '--total', type=int, default=100)
+ parser.add_argument('-s', '--seed', type=float, default=random.random())
+ parser.add_argument(
+ '-f', '--format',
+ type=str, choices=('html', 'json'), default='html'
+ )
+ args = parser.parse_args(sysargs[1:])
+
+ sheet = Sheet.generate(
+ args.lowest_factor,
+ args.highest_factor,
+ total=args.total,
+ seed=args.seed
+ )
+
+ if args.format == 'html':
+ sys.stdout.write(
+ HTMLFormatter().format(sheet)
+ )
+ elif args.format == 'json':
+ sys.stdout.write(
+ JSONFormatter().format(sheet)
+ )
+ else:
+ raise ArgumentError('unknown format {}'.format(args.format))
+ sys.stdout.write('\n')
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/mathpractice/html_formatter.py b/mathpractice/html_formatter.py
new file mode 100644
index 0000000..f8ea6aa
--- /dev/null
+++ b/mathpractice/html_formatter.py
@@ -0,0 +1,73 @@
+import textwrap
+
+
+class HTMLFormatter(object):
+ STYLE = textwrap.dedent("""\
+ body {
+ color: black;
+ font-size: 18px;
+ font-family: Arial, sans-serif;
+ }
+
+ .ex {
+ display: inline;
+ text-align: right;
+ padding: 3px;
+ margin: 24px;
+ float: left;
+ }
+
+ .op {
+ padding-right: 18px;
+ }
+
+ .eq {
+ min-width: 48px;
+ border-bottom: 1px solid black;
+ }
+ """)
+
+ def __init__(self, style=''):
+ self.style = style if style != '' else self.STYLE
+
+ def format(self, sheet):
+ gen = [self._format_header(sheet.seed)]
+
+ for (f0, f1), answer in sheet.entries:
+ gen.append(self._format_entry(f0, f1, answer))
+
+ gen.append(self._format_footer())
+ return '\n'.join(gen)
+
+ def _format_header(self, seed):
+ return '\n'.join([
+ '',
+ '',
+ '
',
+ 'MATHS',
+ ''.format(seed),
+ '',
+ '',
+ ''
+ ])
+
+ def _format_entry(self, f0, f1, answer):
+ return '\n'.join([
+ '',
+ '
',
+ '{}'.format(f0),
+ '
',
+ '
',
+ 'x',
+ '{}'.format(f1),
+ '
',
+ '
',
+ '{}'.format(answer),
+ '
',
+ '
'
+ ])
+
+ def _format_footer(self):
+ return ''
diff --git a/mathpractice/json_formatter.py b/mathpractice/json_formatter.py
new file mode 100644
index 0000000..098476e
--- /dev/null
+++ b/mathpractice/json_formatter.py
@@ -0,0 +1,12 @@
+import json
+
+
+class JSONFormatter(object):
+ def format(self, sheet):
+ return json.dumps(
+ {
+ 'seed': sheet.seed,
+ 'entries': sheet.entries
+ },
+ indent=4
+ )
diff --git a/mathpractice/mksheet.py b/mathpractice/mksheet.py
deleted file mode 100644
index 91e2937..0000000
--- a/mathpractice/mksheet.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import os
-import random
-import sys
-
-
-def main(sysargs=sys.argv[:]):
- lowest_factor = 0
- highest_factor = 15
- total = 100
-
- if '-h' in sysargs or '--help' in sysargs:
- return _help(sysargs=sysargs)
-
- if len(sysargs) > 1:
- lowest_factor = int(sysargs[1])
- if len(sysargs) > 2:
- highest_factor = int(sysargs[2])
- if len(sysargs) > 3:
- total = int(sysargs[3])
-
- _mksheet(lowest_factor, highest_factor, total=total)
- return 0
-
-
-def _mksheet(lowest_factor, highest_factor, out=sys.stdout, total=100):
- gen = [_format_header()]
-
- for f0, f1 in _generate_matrix(lowest_factor, highest_factor, total=total):
- gen.append(_format_pair(f0, f1))
-
- gen.append(_format_footer())
- out.write('\n'.join(gen))
- out.write('\n')
-
-
-def _generate_matrix(lowest_factor, highest_factor, total=100):
- gen = []
- for f0 in range(lowest_factor, highest_factor):
- for f1 in range(lowest_factor, highest_factor):
- gen.append((f0, f1))
- random.shuffle(gen)
- return gen
-
-
-def _format_header():
- return '\n'.join([
- '',
- '',
- '',
- 'MATHS',
- '',
- '',
- ''
- ])
-
-
-def _format_css():
- style_css = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- 'style.css'
- )
- with open(style_css) as out:
- return out.read()
-
-
-def _format_pair(f0, f1):
- return '\n'.join([
- '',
- '
',
- '{}'.format(f0),
- '
',
- '
',
- 'x',
- '{}'.format(f1),
- '
',
- '
',
- '',
- '
',
- '
'
- ])
-
-
-def _format_footer():
- return ''
-
-
-def _help(sysargs=sys.argv[:], out=sys.stdout):
- from textwrap import dedent
- out.write(dedent("""\
- Usage: {} [lowest-factor] [highest-factor]
-
- Generate some math practice HTML.
- """.format(sysargs[0])))
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/mathpractice/sheet.py b/mathpractice/sheet.py
new file mode 100644
index 0000000..4b6cc22
--- /dev/null
+++ b/mathpractice/sheet.py
@@ -0,0 +1,16 @@
+import random
+
+class Sheet(object):
+ def __init__(self, seed=None, entries=()):
+ self.seed = seed
+ self.entries = entries
+
+ @classmethod
+ def generate(cls, lowest_factor, highest_factor, total=100, seed=None):
+ entries = []
+ for f0 in range(lowest_factor, highest_factor):
+ for f1 in range(lowest_factor, highest_factor):
+ entries.append(((f0, f1), f0 * f1))
+ random.seed(seed)
+ random.shuffle(entries)
+ return cls(seed=seed, entries=entries)