Linguado
Language learning program for the terminal.
In 2017 I was really interested in learning two different languages: german and ruby. For german, I was using mainly Assimil’s German with Ease books, Anki flashcards and a lot of duolingo. As for ruby I was making little projects like a Tetris clone.
During this period my main laptop broke down and I was left with a really underpowered HP Stream netbook. I really like the little guy since it was pretty cheap, lightweight and had decent battery life but it really didn’t perform all that well on javascript-heavy pages like duolingo was.
Since I wanted to learn more ruby and needed a less resource-intensive way to do duolingo-style lessons I started working on a terminal-based duolingo clone called linguado. It emulated the key parts of the learning method duolingo had on its website: It had lessons that prompted users to transcribe, complete, choose between options or translate sentences both written or spoken (using text-to-speech software) all from the comfort of the command line.
I was also interested in Domain Specific Languages at the time and, harnessing ruby’s flexibility, I decided to create a sort of DSL for the lessons: They are just ruby code like the rest of the app, inheritting from a base Lesson class:
class BasicsI < Lesson
def initialize
super course: 'German', language: 'de-DE', name: 'Basics I'
ask_to write: 'hallo'
ask_to choose: '? katze', answer: 'die', wrong: ['das', 'der']
ask_to translate: 'ich bin fröhlich', answers: ['I am happy', 'I am cheerful']
ask_to select: 'hallo', answers: ['hi', 'hello'], wrong: ['goodbye']
end
end
Same thing happens with courses: They all inherit from the Course class with the topic method allowing you to specify lesson progression and dependencies:
class GermanCourse < Course
def initialize
topic 'Basics I', lesson: BasicsI.new
topic 'Greetings', lesson: Greetings.new, depends_upon: 'Basics I'
topic 'Basics II', lesson: BasicsII.new, depends_upon: 'Greetings'
topic 'Phrases', lesson: Phrases.new, depends_upon: 'Greetings'
end
end
To give some leeway for accidental typos, the lesson creator can also specify word policies allowing a certain levenshtein distance between words. Finer tuning of this can also be achieved with conditions and exceptions to allow ‘ ein’, for instance, to have a typo like ‘eni’ but not be written like ‘eine’ or ‘einen’.
Answers, errors and lessons completed are stored in a local sqlite database to generate stats for the user, adjust learning and allow progression between lessons.