merged gogo into default
This commit is contained in:
commit
6349277217
6
README.md
Normal file
6
README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# mmg.mcquay.me
|
||||||
|
|
||||||
|
## background
|
||||||
|
|
||||||
|
This is a silly little go project that I created to help my child learn his
|
||||||
|
addition/subtraction tables.
|
@ -1,9 +0,0 @@
|
|||||||
=============
|
|
||||||
mmg.mcquay.me
|
|
||||||
=============
|
|
||||||
|
|
||||||
background
|
|
||||||
==========
|
|
||||||
|
|
||||||
This is a silly little django project that I created to help my child learn his
|
|
||||||
addition/subtraction tables.
|
|
123
handlers.go
Normal file
123
handlers.go
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/gorilla/sessions"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type prob struct {
|
||||||
|
Operation string
|
||||||
|
First int
|
||||||
|
Second int
|
||||||
|
Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
type solution struct {
|
||||||
|
Status bool
|
||||||
|
Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
type JsonHandler func(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
|
func (h JsonHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
h(w, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getScore(session *sessions.Session) int {
|
||||||
|
score := session.Values["Score"]
|
||||||
|
var parsed_score int
|
||||||
|
if score == nil {
|
||||||
|
parsed_score = 0
|
||||||
|
} else {
|
||||||
|
parsed_score = score.(int)
|
||||||
|
}
|
||||||
|
return parsed_score
|
||||||
|
}
|
||||||
|
|
||||||
|
func problem(w http.ResponseWriter, req *http.Request) {
|
||||||
|
operation := "+"
|
||||||
|
if r := rand.Intn(2); r == 0 {
|
||||||
|
operation = "-"
|
||||||
|
}
|
||||||
|
|
||||||
|
first := rand.Intn(MAX)
|
||||||
|
var second int
|
||||||
|
if operation == "-" {
|
||||||
|
if first == 0 {
|
||||||
|
second = 0
|
||||||
|
} else {
|
||||||
|
second = rand.Intn(first)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
second = rand.Intn(MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
session, _ := store.Get(req, "Score")
|
||||||
|
score := getScore(session)
|
||||||
|
|
||||||
|
r := prob{operation, first, second, score}
|
||||||
|
|
||||||
|
b, err := json.Marshal(r)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("issue with json marshalling", err)
|
||||||
|
}
|
||||||
|
j := string(b)
|
||||||
|
fmt.Println("problem", j)
|
||||||
|
fmt.Fprintf(w, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
func attempt(w http.ResponseWriter, req *http.Request) {
|
||||||
|
first, err := strconv.Atoi(req.FormValue("first"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cannot parse first", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
operation := req.FormValue("operation")
|
||||||
|
|
||||||
|
second, err := strconv.Atoi(req.FormValue("second"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cannot parse second", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var guess int
|
||||||
|
answer := req.FormValue("answer")
|
||||||
|
if answer == "" {
|
||||||
|
guess = 0
|
||||||
|
} else {
|
||||||
|
guess, err = strconv.Atoi(answer)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cannot parser answer", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result bool
|
||||||
|
if operation == "+" {
|
||||||
|
result = first+second == guess
|
||||||
|
} else if operation == "-" {
|
||||||
|
result = first-second == guess
|
||||||
|
}
|
||||||
|
|
||||||
|
session, _ := store.Get(req, "Score")
|
||||||
|
score := getScore(session)
|
||||||
|
if result {
|
||||||
|
score += 1
|
||||||
|
} else {
|
||||||
|
score -= 1
|
||||||
|
}
|
||||||
|
session.Values["Score"] = score
|
||||||
|
session.Save(req, w)
|
||||||
|
|
||||||
|
b, err := json.Marshal(solution{result, score})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("cannot marshal solution", err)
|
||||||
|
}
|
||||||
|
j := string(b)
|
||||||
|
fmt.Println("attempt", j)
|
||||||
|
fmt.Fprintf(w, j)
|
||||||
|
}
|
30
main.go
Normal file
30
main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"github.com/gorilla/sessions"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const MAX = 12
|
||||||
|
|
||||||
|
var addr = flag.String("addr", ":8000", "address I'll listen on.")
|
||||||
|
var static_files = flag.String("static", "./static", "location of static files")
|
||||||
|
|
||||||
|
var store = sessions.NewCookieStore([]byte(os.Getenv("MMG_SECRET_KEY")))
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
flag.Parse()
|
||||||
|
http.Handle("/",
|
||||||
|
http.FileServer(http.Dir(*static_files)))
|
||||||
|
http.Handle("/api/v0/problem/", JsonHandler(problem))
|
||||||
|
http.Handle("/api/v0/attempt/", JsonHandler(attempt))
|
||||||
|
if err := http.ListenAndServe(*addr, nil); err != nil {
|
||||||
|
log.Fatal("ListenAndServe:", err)
|
||||||
|
}
|
||||||
|
}
|
10
manage.py
10
manage.py
@ -1,10 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mmg.settings")
|
|
||||||
|
|
||||||
from django.core.management import execute_from_command_line
|
|
||||||
|
|
||||||
execute_from_command_line(sys.argv)
|
|
@ -1,88 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
DEBUG = False
|
|
||||||
TEMPLATE_DEBUG = DEBUG
|
|
||||||
|
|
||||||
ADMINS = (
|
|
||||||
('Stephen McQuay', 'stephen@mcquay.me'),
|
|
||||||
)
|
|
||||||
MANAGERS = ADMINS
|
|
||||||
ALLOWED_HOSTS = ['mmg.mcquay.me', 'midna.local']
|
|
||||||
|
|
||||||
TIME_ZONE = 'America/Chicago'
|
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
|
||||||
SITE_ID = 1
|
|
||||||
USE_I18N = True
|
|
||||||
USE_L10N = True
|
|
||||||
USE_TZ = True
|
|
||||||
MEDIA_ROOT = ''
|
|
||||||
MEDIA_URL = ''
|
|
||||||
|
|
||||||
STATIC_ROOT = os.path.expanduser('~/tmp/mmg')
|
|
||||||
STATIC_URL = 'http://tmp.mcquay.me/mmg/'
|
|
||||||
STATICFILES_DIRS = (
|
|
||||||
os.path.expanduser('~/src/mmg/static'),
|
|
||||||
)
|
|
||||||
|
|
||||||
STATICFILES_FINDERS = (
|
|
||||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
|
||||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
|
||||||
)
|
|
||||||
|
|
||||||
SECRET_KEY = os.environ.get('MMG_SECRET_KEY')
|
|
||||||
|
|
||||||
TEMPLATE_LOADERS = (
|
|
||||||
'django.template.loaders.filesystem.Loader',
|
|
||||||
'django.template.loaders.app_directories.Loader',
|
|
||||||
)
|
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
|
||||||
)
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'mmg.urls'
|
|
||||||
|
|
||||||
WSGI_APPLICATION = 'mmg.wsgi.application'
|
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
os.path.expanduser('~/src/mmg/templates'),
|
|
||||||
)
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sessions',
|
|
||||||
'django.contrib.sites',
|
|
||||||
'django.contrib.messages',
|
|
||||||
'django.contrib.staticfiles',
|
|
||||||
)
|
|
||||||
|
|
||||||
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
|
|
||||||
|
|
||||||
LOGGING = {
|
|
||||||
'version': 1,
|
|
||||||
'disable_existing_loggers': False,
|
|
||||||
'filters': {
|
|
||||||
'require_debug_false': {
|
|
||||||
'()': 'django.utils.log.RequireDebugFalse'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'handlers': {
|
|
||||||
'mail_admins': {
|
|
||||||
'level': 'ERROR',
|
|
||||||
'filters': ['require_debug_false'],
|
|
||||||
'class': 'django.utils.log.AdminEmailHandler'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'loggers': {
|
|
||||||
'django.request': {
|
|
||||||
'handlers': ['mail_admins'],
|
|
||||||
'level': 'ERROR',
|
|
||||||
'propagate': True,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
from django.conf.urls import patterns, url
|
|
||||||
|
|
||||||
urlpatterns = patterns(
|
|
||||||
'',
|
|
||||||
url(r'^$', 'mmg.views.home', name='home'),
|
|
||||||
url(r'^api/v0/attempt/$', 'mmg.views.attempt', name='attempt'),
|
|
||||||
url(r'^api/v0/problem/$', 'mmg.views.problem', name='problem'),
|
|
||||||
)
|
|
63
mmg/views.py
63
mmg/views.py
@ -1,63 +0,0 @@
|
|||||||
import json
|
|
||||||
import random
|
|
||||||
|
|
||||||
from django.http import HttpResponse
|
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
MAX = 12
|
|
||||||
|
|
||||||
|
|
||||||
def _generate_problem():
|
|
||||||
operation = random.choice(['+', '-'])
|
|
||||||
first = random.choice(range(MAX))
|
|
||||||
if operation == '-':
|
|
||||||
if first == 0:
|
|
||||||
second = 0
|
|
||||||
else:
|
|
||||||
second = random.choice(range(first))
|
|
||||||
else:
|
|
||||||
second = random.choice(range(MAX))
|
|
||||||
return {
|
|
||||||
'first': first,
|
|
||||||
'operation': operation,
|
|
||||||
'second': second,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_solution(a):
|
|
||||||
f = int(a['first'])
|
|
||||||
o = a['operation']
|
|
||||||
s = int(a['second'])
|
|
||||||
if a['answer'] == '':
|
|
||||||
g = 0
|
|
||||||
else:
|
|
||||||
g = int(a['answer'])
|
|
||||||
r = False
|
|
||||||
if o == '+':
|
|
||||||
r = bool(f + s == g)
|
|
||||||
else:
|
|
||||||
r = bool(f - s == g)
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def home(request):
|
|
||||||
return render(request, 'index.html')
|
|
||||||
|
|
||||||
|
|
||||||
def attempt(request):
|
|
||||||
d = request.POST.dict()
|
|
||||||
r = _validate_solution(d)
|
|
||||||
if r:
|
|
||||||
s = request.session.get('score', 0) + 1
|
|
||||||
else:
|
|
||||||
s = request.session.get('score', 0) - 1
|
|
||||||
request.session['score'] = s
|
|
||||||
return HttpResponse(
|
|
||||||
json.dumps({'status': r, 'score': s}),
|
|
||||||
content_type="application/json")
|
|
||||||
|
|
||||||
|
|
||||||
def problem(request):
|
|
||||||
d = _generate_problem()
|
|
||||||
d['score'] = request.session.get('score', 0)
|
|
||||||
return HttpResponse(json.dumps(d), content_type="application/json")
|
|
32
mmg/wsgi.py
32
mmg/wsgi.py
@ -1,32 +0,0 @@
|
|||||||
"""
|
|
||||||
WSGI config for mmg project.
|
|
||||||
|
|
||||||
This module contains the WSGI application used by Django's development server
|
|
||||||
and any production WSGI deployments. It should expose a module-level variable
|
|
||||||
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
|
|
||||||
this application via the ``WSGI_APPLICATION`` setting.
|
|
||||||
|
|
||||||
Usually you will have the standard Django WSGI application here, but it also
|
|
||||||
might make sense to replace the whole Django WSGI application with a custom one
|
|
||||||
that later delegates to the Django one. For example, you could introduce WSGI
|
|
||||||
middleware here, or combine a Django application with an application of another
|
|
||||||
framework.
|
|
||||||
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
|
|
||||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
|
||||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
|
||||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
|
||||||
# os.environ["DJANGO_SETTINGS_MODULE"] = "mmg.settings"
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mmg.settings")
|
|
||||||
|
|
||||||
# This application object is used by any WSGI server configured to use this
|
|
||||||
# file. This includes Django's development server, if the WSGI_APPLICATION
|
|
||||||
# setting points here.
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
|
||||||
application = get_wsgi_application()
|
|
||||||
|
|
||||||
# Apply WSGI middleware here.
|
|
||||||
# from helloworld.wsgi import HelloWorldApplication
|
|
||||||
# application = HelloWorldApplication(application)
|
|
@ -1,2 +0,0 @@
|
|||||||
Django==1.5.1
|
|
||||||
gunicorn==0.17.2
|
|
@ -1,10 +1,9 @@
|
|||||||
{% load staticfiles %}
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{{ title }}</title>
|
<title>Mardson's Math Game</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="{% static "math.css" %}" rel="stylesheet" media="screen">
|
<link href="/math.css" rel="stylesheet" media="screen">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section id="content">
|
<section id="content">
|
||||||
@ -18,7 +17,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
score: <span id="score"></span>
|
score: <span id="score"></span>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="{% static 'jquery-2.0.0.min.js' %}"></script>
|
<script src="/jquery-2.0.0.min.js"></script>
|
||||||
<script src="{% static "math.js" %}"></script>
|
<script src="/math.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -7,7 +7,7 @@ function update_board(f, o, s, score) {
|
|||||||
|
|
||||||
function new_problem() {
|
function new_problem() {
|
||||||
$.get("/api/v0/problem/", function(d) {
|
$.get("/api/v0/problem/", function(d) {
|
||||||
update_board(d["first"], d["operation"], d["second"], d["score"]);
|
update_board(d["First"], d["Operation"], d["Second"], d["Score"]);
|
||||||
$("#answer").val("");
|
$("#answer").val("");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -20,7 +20,8 @@ function deal_with_answer(e) {
|
|||||||
"answer": $("#answer").val(),
|
"answer": $("#answer").val(),
|
||||||
};
|
};
|
||||||
$.post("/api/v0/attempt/", data, function(d) {
|
$.post("/api/v0/attempt/", data, function(d) {
|
||||||
if(d["status"]) {
|
$("#score").text(d["Score"]);
|
||||||
|
if(d["Status"]) {
|
||||||
$("body").removeClass("wrong");
|
$("body").removeClass("wrong");
|
||||||
new_problem();
|
new_problem();
|
||||||
}
|
}
|
||||||
@ -35,7 +36,7 @@ function deal_with_answer(e) {
|
|||||||
$(function() {
|
$(function() {
|
||||||
new_problem();
|
new_problem();
|
||||||
$("#answer").keypress(function(e) {
|
$("#answer").keypress(function(e) {
|
||||||
if( e.which == 13) {
|
if (e.which == 13 || e.which == 32) {
|
||||||
deal_with_answer(e);
|
deal_with_answer(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user