Bonjour à tous,
Suite aux portages de TapTempo en divers langages (Rust, Ada, Javascript, Perl (5.10), Python (2.7), bash), je me suis chargé de traduire cet outil en PERL6 parce que c'est quand même plus mignon à regarder.
J'ai essayé de respecter l'esprit de TapTempo à la lettre, en répliquant les fonctionnalités & options présentées dans le journal de mfz. De ce fait, j'ai adopté la même approche KISS tout en poussant le bouchon un peu plus loin puisque le script ne comporte aucune dépendance, même pas pour gérer le terminal. Il devrait donc fonctionner directement quelque soit la plateforme, pour peu qu'elle dispose d'un moteur PERL6.
Voici les quelques différences qui existent entre le TapTempo original et ce portage en PERL6 :
- Ce portage n'est pas internationalisé (la flemme me poursuit)
- Pour quitter le script, il faut appuyer sur q et entrée (ce n'était pas clairement spécifié dans le journal de mfz)
- Le code-source n'est hébergé qu'ici même
- Le code-source du script est en Unicode
Pour résumer, vous pouvez faire un simple copier/coller du code source ci-dessous dans un fichier texte (encodé en Unicode sinon ça ne marchera pas) pour le tester directement.
Les langues de la famille PERL ont souvent mauvaise réputation auprès des informaticiens, d'aucuns prétendent que ce sont des langues obscures, illisibles voir oubliées de tous, j'espère que la limpidité et la compacité du code source de ce script vous prouvera le contraire en moins de temps qu'il ne faut pour le lire.
Quoi qu'il en soit, vous retrouverez dans ce script quelques fonctionnalités intéressantes de PERL6, n'hésitez-pas à partir à la découverte des innombrables possibilités de cette fantastique langue de programmation, personnellement j'en suis resté bouche bée quand j'ai parcouru la documentation.
sub MAIN (
Int :$precision? = 0,
Int :$reset-time? = 5,
Int :$sample-size? = 5,
Bool :h(:$help)? = False,
Bool :v(:$version)? = False
)
{
say "Tap Tempo version 0.0 - Glaeken, licence GPL-3.0+" if $version;
say q| -h, --help affiche ce message d'aide
-p, --precision changer le nombre de décimale du tempo à afficher
la valeur par défaut est 0 décimales, le max est 5 décimales
-r, --reset-time changer le temps en seconde de remise à zéro du calcul
la valeur par défaut est 5 secondes
-s, --sample-size changer le nombre d'échantillons nécessaires au calcul du tempo
la valeur par défaut est 5 échantillons
-v, --version afficher la version | if $help;
exit if $version;
exit if $help;
exit if $precision < 0;
exit if $precision > 5;
exit if $sample-size < 2;
exit if $reset-time < 0;
my Int $Itérateur = 1;
my @Dates;
my $Rythme = prompt "Appuyer sur la touche entrée en cadence (q pour quitter).";
exit if $Rythme eq 'q';
@Dates.push: DateTime.new(now);
say "[Appuyer encore sur la touche entrée pour lancer le calcul du tempo...]";
while True {
$Rythme=prompt;
my $Maintenant = DateTime.new(now);
exit if $Rythme eq 'q';
if $Maintenant - @Dates[$Itérateur-1] > $reset-time {
while @Dates.elems {@Dates.shift}
@Dates.push: $Maintenant;
$Itérateur=1;
} else {
if $Itérateur < $sample-size {
$Itérateur++;
@Dates.push: $Maintenant;
} else {
@Dates.shift;
@Dates.push: $Maintenant;
}
if @Dates[ @Dates.elems - 1 ] == @Dates[ 0 ] {
say "Tempo : ∞";
} else {
$Rythme = @Dates.elems/(@Dates[@Dates.elems-1]-@Dates[0])* 60;
if $precision == 0 {
say "Tempo : " ~ sprintf "%u bpm", $Rythme;
} else {
say "Tempo : " ~ sprintf '%.' ~ $precision ~ 'f', $Rythme;
}
}
}
}
}
Petit détail, je n'ai pas pu m'empêcher de tester le cas pour lequel la durée entre deux frappes de la touche entrée était nulle, auquel cas le script vous répondra que le Tempo est infini.
N'hésitez-pas à tester et à envoyer vos remarques ou commentaires constructifs, il s'agit de mon premier journal sur LinuxFr.
# À quand le brainfuck
Posté par martoni (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 24 août 2019 à 18:09.
J'attends avec impatience le portage de TapTempo en brainfuck et en whitespace ;)
J'ai plus qu'une balle
[^] # Re: À quand le brainfuck
Posté par Mali (site web personnel) . Évalué à 2.
Et moi celui en Lua
[^] # Re: À quand le brainfuck
Posté par Siltaär (site web personnel) . Évalué à 2.
Du Haskel aussi se serait sympa.
Et du Forth ?
La liberté ne s'use, que si on ne s'en sert pas.
[^] # Re: À quand le brainfuck
Posté par freem . Évalué à 3.
Ou quelqu'un qui soumette un portage à l'IOCCC.
[^] # Re: À quand le brainfuck
Posté par martoni (site web personnel, Mastodon) . Évalué à 1.
Vœux exaucé ;)
J'ai plus qu'une balle
# L'infini
Posté par mzf (site web personnel) . Évalué à 3.
Merci pour ce portage qui tente de reproduire l'original au plus près !
Je vois que tu as géré le cas où les deux dates sont similaires en affichant "Tempo : ∞". Bonne idée, même si c'est peu probable d'arriver il faut que je le rajoute :-)
Petite question : les lignes "exit if $precision < 0;" font que le programme sort si les valeurs sont hors bornes ? Si on est pointilleux c'est une différence avec l'original :-)
Pour le non-perliste que je suis, je pense être arrivé à comprendre à peu près ta version. Ton objectif de démontrer que le langage PERL peut être lisible me semble atteint !
[^] # Re: L'infini
Posté par freem . Évalué à 3.
Je vois peu de cas pendant lesquels ça peut arriver, mais par exemple comment se comporte la fonction pour récupérer l'heure si un changement d'heure à lieu pile au mauvais moment?
Pour moi, ce qu'il a fait, c'est le genre de choses qui rendent un programme robuste.
En plus, ça fait gagner des points au .
[^] # Re: L'infini
Posté par Glaeken (site web personnel) . Évalué à 4.
Effectivement, il y a peu de chances pour que ça arrive mais ça coûte rien d'y penser : je ne sais pas sur quel simulateur ce script tournera.
Si un changement soudain de temporalité survient (par exemple si l'utilisateur change la date sur le système sous-jacent), je ne vois pas bien ce que ça change : s'il va dans le futur brusquement, il obtiendra probablement rien car le script se ré-initialise après 5 secondes d'inactivité ; s'il va dans le passé subitement, il obtiendra un bpm négatif et ça correspondra bien à la réalité perçue du point de vue du script : il fait ce qu'on lui a demandé même si c'est le Docteur Who qui appuie sur la touche entrée.
Le seul problème réel est dans le cas d'une durée nulle : une durée nulle ça n'existe pas, c'est seulement une absence de durée : ça n'aurait pas les propriétés qu'on peut légitimement attendre d'une durée.
[^] # Re: L'infini
Posté par ckyl . Évalué à 5.
Si tu peux bien sur inventer le besoin et la spécification que tu veux, je pense que la majorité des personnes saines d'esprit comprendrons l’énoncé du problème en
CLOCK_MONOTIC
et non enCLOCK_REALTIME
. Ta vision me semble pour le moins farfelue.[^] # Re: L'infini
Posté par Glaeken (site web personnel) . Évalué à 0.
Je suis un être humain et je fonctionne en realtime depuis qu'on m'a booté : TapTempo Perl6 s'adresse à des êtres humains, il est écrit par un humain et il réponds à des humains capable de comprendre l'infini, pas de le calculer.
[^] # Re: L'infini
Posté par kantien . Évalué à 2.
Difference between CLOCK_REALTIME and CLOCK_MONOTONIC? ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: L'infini
Posté par claudex . Évalué à 7.
Je ne connais aucun humain qui fonctionne en realtime mais tous ceux que je connaisse fonctionne en monotonic. Une preuve, c'est que les changements d'heure ou de fuseau horaire posent problème.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: L'infini
Posté par ckyl . Évalué à 5. Dernière modification le 01 mars 2018 à 17:58.
Si tu veux rendre un programme robuste, enfin surtout correct, tu utilises une horloge monotone pour mesurer un écart de temps. Ce que la version C++ faisait correctement et qui s'est perdu ici :)
Le ∞ c'est juste utile si tu dépasses la résolution.
[^] # Re: L'infini
Posté par mzf (site web personnel) . Évalué à 1.
Dans la version originale, si on considère la méthode
TapTempo::computeBPM
seule, rien ne garantit que les argumentscurrentTime
etlastTime
ne sont pas similaires. Dans les faits l'appelant ne pourra pas le faire, mais la vérification est la bienvenue pour éviter des erreurs dans le futur si le code évolue.[^] # Re: L'infini
Posté par Glaeken (site web personnel) . Évalué à 3.
Bonjour et merci à toi car ta démarche m'a inspiré, je trouve que ce que tu as fait avec Taptempo est très chouette.
Les exits servent à éviter que mon script plante comme un gros tas au cas où l'utilisateur lui demanderait de faire des choses déraisonnables, comme par exemple demander un nombre négatif de chiffres après la virgule ou bien calculer une durée à partir d'un seul échantillon : dans un premier je type fortement les données que l'utilisateur essaye de transmettre au programme, ensuite je lis le cahier des charges et je réduis la voilure au maximum.
De manière générale, je ne programme jamais mais quand je le fais, je fais tout pour que le programme refuse de fonctionner le plus souvent possible. C'est pour la même raison que je teste si du temps s'est écoulé entre deux dates avant de faire une division par la durée entre ces deux dates, ça évite de faire un division par zéro et ça donne la bonne réponse à la place.
# Perl 6, pas PERL 6
Posté par Sylvain Colinet (site web personnel) . Évalué à 1.
Y a pas vraiment de séparation entre perl, Perl et PERL comme en Perl 5. (l'interpreteur, le langage et l'acronyme) :)
Tu peux aussi te priver de l'utilisation du type Date. now est un Instant et des différences d'Instant te donne un type Duration. C'est suffisant pour obtenir ce que tu veux.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.