The Big Book of Small EK9 Programs
Adapted from Al Sweigart's The Big Book of Small Python Projects: 81 Easy Practice Programs (No Starch Press, 2021; copyright © 2021 Al Sweigart), which he makes freely available under a Creative Commons Attribution-NonCommercial-ShareAlike licence at inventwithpython.com/bigbookpython. Changes were made: each program was ported from Python to EK9 and remodelled in EK9's idioms.
Project 32 — Gullible
This is project 32 of the book, ported to EK9. Its chapter is still being written; until then, this page shows the port itself: a run of it, the whole program, and how it keeps to the original.
A sample run
The player's answers are piped in:
maybe
yes
no
Run it with:
ek9 gullible.ek9 < input.txt
It prints:
Do you want to know how to keep a gullible person busy for hours? Y/N
"maybe" is not a valid yes/no response.
Do you want to know how to keep a gullible person busy for hours? Y/N
Do you want to know how to keep a gullible person busy for hours? Y/N
Thank you. Have a nice day!
The program
#!ek9 defines module bigbook.gullible defines type Answer Yes No defines class //THE input idiom of this book, copied unchanged from lib/LineInput.ek9 (the reasons are //there): read with next(), and every input loop also stops when ended() is true. LineInput stdin as Stdin: Stdin() inputEnded as Boolean: false next() <- rtn as String: stdin.next() if not rtn? inputEnded: true ended() as pure <- rtn as Boolean: Boolean(inputEnded) override operator ? as pure <- rtn as Boolean: true //THE INPUT AND OUTPUT: everything the player sees or types goes through here, worded by Say. Console stdout as Stdout: Stdout() input as LineInput: LineInput() say as Say: Say("en") Console() -> words as Say say: words //Asks until the reply is a yes or a no; unset only if the input ends first. nextAnswer() <- rtn as Answer: Answer() while not rtn? and not input.ended() stdout.println(say.askAnswer()) if entry <- input.next() rtn: answerOf(entry.lowerCase()) if not rtn? stdout.println(say.notYesOrNo(entry)) showGoodbye() stdout.println(say.goodbye()) ended() as pure <- rtn as Boolean: input.ended() //"yes" and "no" are words the player types, so they come from Say. Any other reply is an //unset Answer: the guard in nextAnswer, not a sentinel, says "not a yes or a no". private answerOf() -> reply as String <- rtn as Answer: Answer() if reply == say.yes() or reply == say.y() rtn: Answer.Yes else if reply == say.no() or reply == say.n() rtn: Answer.No override operator ? as pure <- rtn as Boolean: true defines function //THE GAME: the joke's one rule - only "no" stops the question. stopsAsking() as pure -> answer as Answer <- rtn as Boolean: answer == Answer.No defines function //THE language of the words, copied unchanged from lib/Language.ek9: BIGBOOK_LANG when it //is set (fr, zh, ...), otherwise en. language() <- rtn as String: EnvVars().get("BIGBOOK_LANG") ?: "en" //THE WORDS: every word the player sees or types. defines text for "en" Say askAnswer() "Do you want to know how to keep a gullible person busy for hours? Y/N" notYesOrNo() -> reply as String `"${reply}" is not a valid yes/no response.` yes() "yes" y() "y" no() "no" n() "n" goodbye() "Thank you. Have a nice day!" defines program //Gullible (Big Book project 32). Asks whether you want to know how to keep a gullible person //busy for hours, again and again, until you say no. The game decides; the Console asks and //tells, in the player's words. Gullible() //A language with no words of its own is unset: ?: falls back to English. console <- Console(Say(language()) ?: Say("en")) running <- true while running and not console.ended() if answer <- console.nextAnswer() running: not stopsAsking(answer) console.showGoodbye()
About this port
- Faithful to the book: the program is a joke. It asks "Do you want to know how to keep a gullible person busy for hours? Y/N"; answering yes (or y) just asks again, and only no (or n) ends it with "Thank you. Have a nice day!". Any other reply prints
"X" is not a valid yes/no response.(An earlier port printed "Yes, you are gullible!" and stopped, which loses the joke; reconciliation fixed it.)