Commit 400b3c2f authored by Christopher League's avatar Christopher League
Browse files

Hex spelling activity

parent 441bf44b
......@@ -99,6 +99,7 @@ mkYesodData
/me ProfileR GET POST
/unit/1/from-base U1FromBaseR
/unit/1/to-base U1ToBaseR
/unit/1/hex-spell U1HexSpellR GET POST
/page/#PageId PageDocR GET
!/page/#AssetId PageAssetR GET
/post/#PostId PostR GET
......@@ -187,7 +188,7 @@ messageAlert (status, body) =
instance Yesod App where
yesodMiddleware =
defaultCsrfSetCookieMiddleware . csrfCheck . defaultYesodMiddleware
csrfCheck . defaultYesodMiddleware
where
csrfCheck handler =
csrfCheckMiddleware
......@@ -199,6 +200,7 @@ instance Yesod App where
getCurrentRoute >>= \case
Nothing -> return False
Just MetaCacheR -> return False
Just U1HexSpellR -> return False
Just r -> isWriteRequest r
authRoute _ = Just (AuthR LoginR)
......
......@@ -120,6 +120,10 @@ unit1 = do
Notes:
<a href=@{PageDocR "notes120-binary.org"}>
Binary numbers
<li .list-group-item>
Practice:
<a href=@{U1HexSpellR}>
Hexadecimal ‘spelling’
|]
getHomeR :: Handler Html
......
......@@ -19,6 +19,8 @@ module App.Quiz1
( Activity (..),
handleU1FromBaseR,
handleU1ToBaseR,
getU1HexSpellR,
postU1HexSpellR,
u1ToBase,
pointsBadge,
dueBadge,
......@@ -46,6 +48,7 @@ import Numeric (readInt, showIntAtBase)
import Test.Tasty
import Test.Tasty.Hedgehog
import Text.Blaze.Html (ToMarkup (..))
import Text.Julius (rawJS)
data Activity
= Activity
......@@ -261,6 +264,12 @@ sub {
top: 1.1ex;
left: 5px;
}
.under-accent {
border-bottom: 2px solid #007bff;
}
.big-text {
font-size: 150%;
}
.base-ten, .foreign-base {
white-space: nowrap;
}
......@@ -293,10 +302,10 @@ $case result
<p>
#{err}
$of _
<div .text-monospace style="font-size:150%">
<div .text-monospace .big-text>
<p>
$forall digit <- bc ^. bcDigits
<span .px-2 .my-3 style="border-bottom: 2px solid #007bff">
<span .px-2 .my-3 .under-accent>
#{digit}
<sub>#{bc ^. bcBase}
=
......@@ -389,7 +398,7 @@ $case result
<p>
#{err}
$of _
<div .text-monospace style="font-size:150%">
<div .text-monospace .big-text>
<p>
<span .my-3>
#{bc ^. bcValue}#
......@@ -489,3 +498,93 @@ $else
<form method=post enctype=#{enctype}>
^{widget}
|]
hexableWords :: [Text]
hexableWords =
Text.split (== ' ') $
"ace aced add added babe bad bead bed bee beef cab cafe dab dad "
<> "dead decaf deed fab face faced fad fade faded faff fed fee feed"
genHexSpell :: Gen Text
genHexSpell = do
w <- Gen.element hexableWords
whenElse (Text.length w < 4) w $ do
k <- Gen.element ['1' .. '9']
coin <- Gen.enumBounded
return $
if coin
then Text.cons k w
else Text.snoc w k
u1HexSpell :: ActivityId
u1HexSpell = "u1hexsp"
lookupHexSpellSession :: Handler Text
lookupHexSpellSession =
lookupSession u1HexSpell >>= \case
Just word -> return word
Nothing -> do
word <- Gen.sample genHexSpell
setSession u1HexSpell word
return word
postU1HexSpellR :: Handler Html
postU1HexSpellR = do
deleteSession u1HexSpell
redirect U1HexSpellR
getU1HexSpellR :: Handler Html
getU1HexSpellR = do
word <- lookupHexSpellSession
binInput <- newIdent
hexOut <- newIdent
finishBlock <- newIdent
defaultLayout $ do
setTitle "Hexadecimal ‘spelling’ challenge"
u1Styles
toWidget
[julius|
function hexSpellUpdate() {
var bs = $(this).val();
var ok = bs.match(/^[01]*$/);
$(this).toggleClass("border-danger", !ok);
if(ok) {
while(bs.length % 4 != 0) {
bs = bs + '0';
}
var hx = bs.length == 0? "" : parseInt(bs,2).toString(16);
var correct = hx == "#{rawJS word}";
$("##{rawJS hexOut}").html(hx).toggleClass("border-success", correct);
if(correct) {
$(this).prop('disabled', true);
$("##{rawJS finishBlock}").toggleClass("d-none", false);
}
}
}
$(function(){
$("##{rawJS binInput}").on('input', hexSpellUpdate);
$("##{rawJS binInput}").trigger('input');
})
|]
[whamlet|
<form .col-12 method=post>
<p>
Because hexadecimal uses the letters A–F as digits, it's possible to
construct binary numbers that spell certain words. Given the goal word
(actually a hexadecimal number), type in the bits (binary digits) that
match the number. Remember that each hexadecimal digit is 4 bits.
<div .mt-2 .text-monospace .big-text>
<p>
Goal:
<span .under-accent>#{word}
<p>
<input ##{binInput} .border type=text autocomplete=off placeholder="Type bits here">
<p>
=
<span ##{hexOut} .border>
<div ##{finishBlock} .d-none>
<p .alert .alert-success>
You did it!
<input .btn .btn-primary type=submit value="Try another problem">
|]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment