Dans ce cas, je te propose la version suivante de la boucle principale (dans une approche similaire à celle en Elixir et ce que l'auteur à appeler flow programming).
Ici c'est dans la même veine que le code Rust que tu ne comprenais pas : c'est à base de pipe (on connecte les flux d'entrée et de sortie de fonctions). Il y a deux types de connecteurs de flux sous forme d'opérateurs infixes : |- qui est proche de la commande unix tee (d'où le choix du symbole) et le |> qui fonctionne comme le pipe| du shell.
Si tu comprends cette commande, alors c'est bon :
$ (for i in $(seq 6);do echo; sleep 0.5;done)| ./taptempo | tee log1 | grep bpm | tee log2 | cut -d' ' -f2,3
120 bpm
120 bpm
120 bpm
120 bpm
120 bpm
$ cat log1
Appuyer sur la touche entrée en cadence (q pour quitter).
[Appuyer encore sur la touche entrée pour lancer le calcul du tempo...]
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
Au revoir !
$ cat log2
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
Tempo: 120 bpm
on chaîne les commandes, et on utilise tee pour faire un log de résultats intermédiaires mais sans casser le flux. Comme dans cet exemple OCaml :
letpipelinestr=str|-Printf.printf"la chaîne est: \"%s\"\n"|>String.trim|-Printf.printf"on a retiré les espaces: \"%s\"\n"|>String.length|-Printf.printf"la longueur de la chaîne tronquée est: %i\n"|>succ|>(funx->3*x);;valpipeline:string->int=<fun>
on prend une chaîne, on lui retire les espaces en préfixe et suffixe (String.trim), on calcule la longueur de la chaîne ainsi obtenue (String.length) puis on effectue des calculs sur cette valeur entière, le tout en faisant quelques commandes de log entre temps. Exemple d'usage :
pipeline" hello world ! ";;lachaîneest:" hello world ! "onaretirélesespaces:"hello world !"lalongueurdelachaînetronquéeest:13-:int=42
L'opérateur infixe |- se définit tout simplement ainsi :
(* on applique f à x, puis on retourne x pour pouvoir chaîner *)let(|-)xf=(fx:unit);x;;val(|-):'a->('a->unit)->'a
j'ai juste mis une contrainte de type sur la sortie de f de telle sorte que :
x|-step1|-step2|-step3(* soit bien équivalent à *)step1x;step2x;step3x
Maintenant, si on reprend la partie du code qui correspond au traitement à effectuer lors de l'appui sur la touche enter :
On calcule un nouvelle horodatage et le temps écoulé (en secondes) depuis le dernier appui sur enter; ensuite on enchaîne les traitements sur la file des horodatages :
si le temps écoulé est supérieur au délai de réinitialisation alors on reset, sinon on ne fait rien ;
on ajoute l'horodatage à la file (ce qui met à jour, dans la structure, la valeur du tempo) ;
on affiche le tempo ou le message qui dit d'appuyer une nouvel fois pour lancer le calcul (choix basé sur un type option contenu dans la structure[1]) ;
on repart dans la boucle avec comme paramètres le nouvel horodatage et la file mise à jour.
C'est beau, c'est fin, ça se mange sans faim. :-)
[1]: en arrière plan, le type de la file d'horodatage est
typet={size:int;(* nombre max d'échantillons *)queue:Mtime.tQueue.t;(* FIFO contenant les timestamps *)mutabletempo:floatoption;(* Some tempo ou None *)}
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Lisibilité
Posté par kantien . En réponse au journal Portage de TapTempo en OCaml. Évalué à 6.
Dans ce cas, je te propose la version suivante de la boucle principale (dans une approche similaire à celle en Elixir et ce que l'auteur à appeler flow programming).
Ici c'est dans la même veine que le code Rust que tu ne comprenais pas : c'est à base de pipe (on connecte les flux d'entrée et de sortie de fonctions). Il y a deux types de connecteurs de flux sous forme d'opérateurs infixes :
|-qui est proche de la commande unixtee(d'où le choix du symbole) et le|>qui fonctionne comme le pipe|du shell.Si tu comprends cette commande, alors c'est bon :
on chaîne les commandes, et on utilise
teepour faire un log de résultats intermédiaires mais sans casser le flux. Comme dans cet exemple OCaml :on prend une chaîne, on lui retire les espaces en préfixe et suffixe (
String.trim), on calcule la longueur de la chaîne ainsi obtenue (String.length) puis on effectue des calculs sur cette valeur entière, le tout en faisant quelques commandes de log entre temps. Exemple d'usage :L'opérateur infixe
|-se définit tout simplement ainsi :j'ai juste mis une contrainte de type sur la sortie de
fde telle sorte que :Maintenant, si on reprend la partie du code qui correspond au traitement à effectuer lors de l'appui sur la touche
enter:On calcule un nouvelle horodatage et le temps écoulé (en secondes) depuis le dernier appui sur
enter; ensuite on enchaîne les traitements sur la file des horodatages :optioncontenu dans la structure[1]) ;C'est beau, c'est fin, ça se mange sans faim. :-)
[1]: en arrière plan, le type de la file d'horodatage est
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.