Martin Döring, September 18th of 2021
I wanted to learn a new language, but I did not find a satisfying solution for that. Anki drove me crazy in it's complexity and handling. So today I wrote my own intentionally minimalistic 80 lines flash cards script in bash. I named it »lern« which is German for »learn«, as you may have assumed. ;-)
For now it is a very simple learning algorithm. The code could be enhanced to save the progress in an extra file. Also for now there is no way to learn a subset, say just 30 records from 300. Best for now would be to structure you flash card files in a way, that every file is just about 30 records long.
usage: lern [-r] filename.csv
The script works like this:
The running script looks like this:
#################### English : animal Italiano: animale #################### q or x to quit ok? y/N:
The file format for the vocabulary is simple: The CSV file has two columns with words or phrases to learn. Column »A« is the question asked and column »B« is the answer. Although, you can change this with the -r option and learn the other way round.
The first line of the file contains the languages to learn in column »A« and »B«. The csv file needs to be saved with embracing double quotes for every cell. The whole file looks like this, as an example:
"English";"Italiano" "animal";"animale" "jacket";"giacca" "decision";"decisione"
#!/bin/bash # Copyright 2021 Martin Döring # This Code is MIT licensed: # https://opensource.org/licenses/mit-license.php # Check argument count typeset -i reverse=0 if [[ $# -eq 1 ]]; then file=$1 elif [[ $# -eq 2 && "$1" == "-r" ]]; then reverse=1 file=$2 else echo "usage: lern [-r] filename.csv" exit 1 fi # read in all records to learn from csv file IFS="\"" typeset -i n=0 typeset -a fronts typeset -a backs typeset -ai unknown while read d1 front d2 back d3 do if [[ $reverse -eq 1 ]]; then fronts[n]="$back" backs[n]="$front" else fronts[n]="$front" backs[n]="$back" fi unknown[n]=3 n=n+1 done < $file unset IFS # find the length of the longest column header of the two typeset -i headlen=${#fronts[0]} if [[ ${#backs[0]} > $headlen ]]; then headlen=${#backs[0]} fi # learn all the vocabulary, have each at least 3 times known typeset -i count=${#fronts[@]} typeset -i todo while :; do todo=0 for ((n=1;n<$count;n++)); do if [[ ${unknown[n]} > 0 ]]; then clear echo "####################" printf "%-${headlen}s: " "${fronts[0]}" echo "${fronts[n]}" printf "%-${headlen}s: " "${backs[0]}" read -s ok echo "${backs[n]}" echo "####################" echo echo "q or x to quit" read -n 1 -p "ok? y/N: " ok if [[ "$ok" == "q" || "$ok" == "x" ]]; then echo "See you next time ..." exit 0 elif [[ "$ok" == "y" ]]; then unknown[n]=${unknown[n]}-1 fi if [[ ${unknown[n]} > 0 ]]; then todo=1 fi fi done if [[ $todo == 0 ]]; then clear echo "Congratulation, you are done for today!" break fi done
If you have any suggestions, how to make the script even smaller or faster, just write me:
——