SOURCE SUPPRIMÉE À LA DEMANDE DE L'AUTEUR.

WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 - 2 avril 2005 à 12:37
jihelb Messages postés 49 Date d'inscription lundi 27 janvier 2003 Statut Membre Dernière intervention 24 mars 2017 - 5 avril 2005 à 13:04
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/30487-source-supprimee-a-la-demande-de-l-auteur

jihelb Messages postés 49 Date d'inscription lundi 27 janvier 2003 Statut Membre Dernière intervention 24 mars 2017
5 avril 2005 à 13:04
Effectivement Forman, aucun test n'est nécessaire. Jai répondu trop vite sans vérifier (j'étais à mon boulot, pas chez moi). Toutes mes excuses.
Dans ma proposition, je ne m'étais pas attardé sur mon utilisation de RANDOM à la place de RANDOM() croyant que celà allait de soi pour tous. Erreur. Tu as bien fait de préciser.
Décidemment Theos n'aime pas les conseils (pardon "...critiques à 2 balles " ???)
Dommage pour lui, mais ils sont utiles pour nous tous, sinon à quoi sert cette rubrique ?
Bonne Prog à tous.
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
4 avril 2005 à 18:48
En tout cas, je sais pas ou vous avez trouvé cette surcharge mais dans l'aide US de Delphi 7, elle est apparement pas indiquée au chapitre "Random function". Pourtant, je suis certain qu'elle existe depuis les premières version de delphi...

A++
Theos
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
4 avril 2005 à 18:41
Ah ok, désolé, je connaissais pas la fonction surchargée de random...
Bah merde alors, du coups ma fonction ne sert plus à rien...

Je te disais que ta fct allait pas marcher car je pensais que tu parlais de la fonction random que j'utilisais et que tu avais pas réécris toute la fin de mon code pour des raisons de flèmite ;-))

Effectivement maintenant que tu le dis, ca me parrait logique car en c++ j'utilise la fonction random de base (qui d'ailleurs s'appelle rand, je crois) et cette fonction retourne un nombre entre 0 et 1...

Je suis deg que mon code ne servent à rien mais bon ;-))
Pourtant j'avais bien cherché si il y avait pas une fonction qui existait déja et j'avais rien trouvé... j'avais mal cherché... grr..

Bon ben merci à vous pour m'avoir appris l'existence cette putain de surchage....

Je pense que je vais adopter ta fonction Forman (effectivement vu la signature de la surchage, elle doit marcher Nickel) et sera plus rapide que la mienne...

A++
Theos
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
4 avril 2005 à 18:18
Au fait, juste une remarque pour ceux qui ne le savaient pas:

Il existe 2 versions "overload" (C'est à dire 2 fonctions de types différents mais qui portent le mêm nom) de la fonction Random (déclarées je suppose dans l'unité virtuelle System.pas) qui sont respectivement déclarées comme ceci:

function Random(N:Integer):Integer;
function Random:Real;

La première donne un nombre ENTIER compris entre 0 et N-1 (au sens large), et la deuxième un nombre REAL compris strictement entre 0 et 1.

Et une dernière chose Theos, je t'assure que ta fonction initiale et la mienne font la même chose aux approximations près que tu fais en utilisant la première version de Random et moi la 2ème. Si tu veux le vérifier, c'est facile:

fais un programme ainsi:

procedure Test;
var
a:Integer;
begin
for a:=0 to 9 do
if RandomProba(0.3) then
showmessage('True')
else
showmessage('False');
end;

Met un bouton sur la fiche, et dans OnClick, lance la fonction Test.

Lance une fois le programme avec ta fonction, note sur un papier les 10 cas qui vont s'afficher, puis remplace ta fonction par la mienne, refais la même chose, et normallement tu devrais obtenir la même chose, si comme je le pense les 2 versions de la fonction Random sont définies l'une à partir de l'autre par Delphi.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
4 avril 2005 à 18:05
Je persiste et je signe jihelb:

function RandomProba(Proba:real):boolean;
begin
Result:=Random<Proba
end;

fonctionnera dans tous les cas, même si on met une Proba négative. En effet, la fonction random étant toujours positive, elle ne pourra jamais être plus petite qu'un nombre négatif. Donc ma version marche même si Proba est négatif, puisque dans ce cas le résultat est toujours "False".

De plus, Theos, les dépassements de capacités ne devraient pas être un problème dans ma version, toutefois il ne faudra pas dépasser les capacités d'un real, à savoir, comme décrit dans l'aide de Delphi:
5.0 x 10^-324 .. 1.7 x 10^308
en valeur absolue.
Mais bon, là encore, des nombres avec plus de 300 chiffres avant la virgule, ça me parait quand même assez correct comme intervalle de validité... Et si tu regardes bien ma fonction, j'ai utilisé la version sans paramètre de la fonction Random, donc il n'y a pas de problème de "range" ou de dépassement de capacité. Si tu veux vérifier que c'est vrai, compile ton projet en activant l'option "range checking" dans les options du projet, et essaie d'appeler la fonction avec un nombre très grand ou très petit, et tu verras qu'il n'y a pas d'exception déclenchée.

Au fait, ne voyez aucune aggressivité dans mes propos, j'expose simplement mon point de vue sur la façon la plus simple d'implémenter cette fonction!
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
4 avril 2005 à 17:04
jihelb : Je suis d'accord, j'ai reconnu que j'avais utilisé des variables en trop dans MultiEssai alors voila, c'est bon, on va pas psycoter pendant dessus 6 mois :-))
(Lorsque j'ai répondu à WhiteHippo, on pouvait lire :
"effectivement, tu as raison, on peut économiser une variable dans MultiEssaisClick".)

Pour ce qui est du try, je n'ai pas changé d'avis, il ne sert pas à grand chose ici voir même à rien car les paramètres sont traités et les seules exceptions qui penvent arrivés sont des cas extremes qu'il ne sert à rien de traiter dans des applications d'exemples...

Et pour ce qui est de "programmer correctement", tu m'excuseras mais je crois que ton message est une plaisanterie car je ne trouve vraiment pas que

if Proba <= 0 then Result:= false
else if Proba >=1 then Result:= true
else Result:= (Random < Proba)

soit plus lisible que mon code... Je suis même d'un avis contraire mais bon, la lisibilité c'est un avis personnel...
Tu devrais mettre tout sur la même ligne pendant que tu y es ;-) car les "else if" qui se suivent c'est le petit truc qui saute super à l'oeil quand on lit un code...
Non mais sérieux, il suffit que tu soit un peu fatigué, qu'il y ai un beug dans ton ton prog...
Avec ce genre de truc, tu passes facilement 20 minutes de plus à localiser le beug car les if juste derrière les else, ca se voient carrement pas...
Si il y a qu'un if imbirqué, ca va, on peut se permettre de tout mettre sur une ligne mais là, ton "amélioration" :-)), en met 3 qui se suivent les uns dans les autres alors ca va pas...
Enfin, je m'en fou, chacun fait comme il veux... Certains trouvent que 0.0 est plus lisible que 0, d'autres non, d'autres trouvent que c'est la même chose (c'est mon cas) et puis c'est tout...
Ma grand mêre aurait dit "Si tu veux améliorer la lisibilités des codes sources, commence par les tiens ;-)"
Non, je déconne, j'accepte les critiques mais quand elles sont justifiés...
Là vous êtes en train de tomber dans l'abus et de partir completement en vrie.

Pour ce qui est de la simplification de Fortman, ce n'est pas vraiment une simplification car les 2 codes ne font pas les mêmes choses...
Le code de fortman a lui (contrairement au mien) besoin d'un try car si on passe comme probablilité -0.25, il y aura un range négatif dans le random et je sais pas si ca va passer...
Soit il y a une exception, soit la fonction retourne carement n'importe quoi.
De plus, le code de fortman autorise n'importe quel nombre pour parametre alors que le reste de mon code ne fonctionne seulement dans certains cas...
(Exemple simple, avec 9999 pour parametre, je suis certains que certaines variables seront sous dimentionnées et seront en dépassement de capacité).
D'ailleur mon code est prévu pour fonctionner avec des probabilités comprises entre [0 et 1].
proba=0 signifie 0% des cas, proba=1 signifie 100% donc on parlait plus haut de mettre comme probabilité des nombres suppérieurs à 1...
C'est possible mais suppérieur à 100% des cas, ça revient à 100% des cas et voila..

Bref, en conclusion, ne délirez pas trop avec vos critiques à 2 balles ;-))

PS : Je remercie WhiteHippo car sa critique était effectivement intéressante. :-)
J'ai utilisé trop de variables et ca sert rien qu'a bouffer de la mémoire inutilement.

A++
Theos
jihelb Messages postés 49 Date d'inscription lundi 27 janvier 2003 Statut Membre Dernière intervention 24 mars 2017
4 avril 2005 à 16:53
Oui Forman, sauf si Proba est négatif (sait-on jamais ???) donc on gagne encore un test !
Merci.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
4 avril 2005 à 14:46
D'accord, tu as raison, simplifions au maximum:

function RandomProba(Proba:real):boolean;
begin
Result:=Random<Proba
end;

Je crois que ça marche aussi...
<8=D
jihelb Messages postés 49 Date d'inscription lundi 27 janvier 2003 Statut Membre Dernière intervention 24 mars 2017
4 avril 2005 à 14:36
Que de complications inutiles pour une chose si simple !
function RandomProba(Proba:real):boolean;
begin
if Proba <= 0 then Result:= false
else if Proba >=1 then Result:= true
else Result:= (Random < Proba)
end;
De plus il serait bon d'écouter les conseils de ceux qui nous veulent du bien; je suis parfaitement d'accord avec WhiteHippo. Un "progragramme pour débutant" ne doit pas être une excuse pour ne pas réfléchir et programmer correctement, AU CONTRAIRE.
Bonne Prog.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
3 avril 2005 à 17:15
Cool, c'est exactement ça que je cherchais!
Apparemment, c'est le même algo que moi, avec des histogrammes pour les valeurs, mais optimisé avec une méthode arborescente de découpage d'intervalles et des interpolations...
En plus, ça a l'air d'être rapide!

Merci
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
3 avril 2005 à 14:42
Ceci ferait-il ton bonheur ?
http://www.esbconsult.com/amrandom.zip

Cordialement.
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
3 avril 2005 à 14:18
Désolé j'arrive tout juste à comprendre ta question, je suis trop nul en math pour donner une solution à ton problème ;-)

Je rentre juste en fac de math moi ;-)

A++
Theos
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
3 avril 2005 à 12:46
Désolé, je viens un peu foutre ma merde...

Est-ce que quelqu'un a une idée pour le problème suivant:
pour simplifier, on suppose que f est une fonction de [0,1] à valeurs positives, telle que son intégrale sur [0,1] vaut 1 (en fait, f est une densité de probabilité). Quelqu'un connaitrait-il un moyen simple de donner une nouvelle fonction Randomf qui serait une variable aléatoire de loi f? C'est à dire, que la probabilité que a<Randomf<b est égale à l'intégrale de f sur [a,b]? Par exemple, la fonction Random de base de Delphi est la réponse au problème dans le cas où f est constante et vaut 1.

Par exemple, f pourrait être une loi gaussienne...

J'ai une méthode pour faire un calcul approché de f par discrétisation d'histogramme qui est la suivante:

var
DensityValues:array[0..999] of Single;

type
TDensityFunc=function(x:Single):Single;

procedure Initialize(f:TDensityFunc);
var
a,b:Integer;
T:array[-1..999] of Single;
s:Single;
begin
s:=0;
T[-1]:=0;
for a:=0 to 999 do begin
T[a]:=s+f(a/999);
s:=T[a];
end;
s:=1000/s;
for a:=0 to 999 do begin
for b:=Trunc(T[a-1]*s) to Trunc(T[a]*s)-1 do
DensityValues[b]:=a/999;
end;
end;

function Randomf:Single;
begin
Result:=DensityValues[Random(1000)];
end;

On commence à initialiser avec une densité de probabilité f:
Initialize(f);

Ensuite, la fonction Randomf donne des valeurs sur un échantillon de 1000 valeurs différentes dans l'intervalle [0,1]. Le problème, c'est que 1000 valeurs différentes ce n'est pas forcément assez, et que si l'on veut par exemple 1000000000 valeurs différentes possibles, il faut un tableau de Single de cette taille-là, ce qui peut prendre beaucoup de place en mémoire... Quelqu'un aurait-il un moyen de faire ça en utilisant moins (ou carrément pas du tout) de mémoire?
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
3 avril 2005 à 01:17
Non, je suis a 600 km de marseille ;-)

A++
Theos
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
3 avril 2005 à 00:18
Oups j'ai oublié des retours à la ligne devant les ">"
Désolé :oP

Cordialement.
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
3 avril 2005 à 00:16
>* Mouai, effectivement, tu as raison, on peut >économiser une variable dans MultiEssaisClick mais >c'est pas très important... Le seul but de ce prog c'est >la fonction RandomProba :-)

non déjà pas 1 mais 2 (total et bad), et puis si pour un tout petit programme comme celui là, il ya en déjà 2 de trop, imagines ce que ce sera pour un gros projet...
De plus, ce code est destiné aux débutants, faut pas leur donner de mauvaises habitudes

>*Pour ce qui est d'utiliser 0.0 au lieu de 0, je vois >vraiment pas l'intêret... On sait qu'on travaille avec >des reel, il suffit de regarder le type de variable >passée en parametre...

ok, mais comme je l'ai dit précédemment, "juste histoire de clarifier le code"

>Et en plus, une probabilité est généralement comprise >entre 0 et 1 donc c'est obligatoirement un reel...

non, tu peux etre amené à utiliser uniquement des entiers pour représenter une probabilité (calcul en virgule fixe, ou bien en pourcentage par exemple)

>Pour ce qui est des try catch, on peut effectivement en >mettre à toutes les lignes...
>Plus on en met, mieux c'est ;-) mais ce n'était pas ici le >but de ma fonction...
>Quand on traite un sujet précis, mieux vaut faire des >fonctions simples en rapport directe avec ce sujet... >C'est ensuite à celui qui utilise la fonction de gerer la >manière dont il va la lancer....
>J'aurais aussi pu intégrer un chronometre qui compte >la durée de fonctionnement... Et Aussi une gestion >des sockets pour faire du grid computing (calcul >distribué)... Un module qui regarde si si il y a pas de >keyloggers...
>Et après, ca fait une usine à gaz, et on s'y retrouve >plus...

Tu serais pas de Marseilles, toi :P

>Non, je crois qu'il faut pas trop s'écarter du sujet ;-) Il >y a des sources qui expliquent le fonctionnement des >try except et d'autres qui servent à faire des >randoms...
>Effectivement, j'aurais pu mettre un petit try mais je >les garde généralement pour des fonctions ou je ne >peux pas vraiment pas controler l'erreur... (genre du >réseau principalement et des erreurs de sockets)
>Ici l'erreur est partiellement controlée car tu peux >passer n'importe quel paramêtre à RandomProba, elle >ne fera jamais d'exception car elle traite les nombre >négatifs... Le seul cas qui peut générer une exception, >est un cas extreme : Si il y a plus de mémoire ou plus >de ressources systêmes... Et là, si on gère ce cas, on >est bon pour le gêrer à chaque instruction y compris >celle du genre a:=1; C'est tomber dans la parano. Et >d'ailleurs, try except utilise surement un peu de >mémoire donc si il y en a plus, c'est le try lui même qui >va planter...
>Bref, on peut mettre un try, ca coute rien mais on >rencontrera surement jamais d'exception.
>Il faut distinguer les exceptions qui sont créés par des >beugs, de celle qui sont crées par des erreurs >légitimes.
>Pour les premières, le traitement est simple, on doit >se démerder pour qu'elles n'existent pas ;-)) donc pas >besoin de les catcher.

Tout ça, c'est bien beau mais qui te parle d'un try..except ???
Moi je te parle d'un try..finally qui permettra de réactiver le bouton quelle que soit la manière dont la routine s'achèvera. N'oublies pas que là encore tu t'addresses à des débutants. Si quelqu'un utilises ton code et rajoutes un exit en plein milieu de ta procédure, que se passe t-il si tu ne mets pas de try..finally ? Un beau bouton inactif... :)

Cordialement.
cs_Theos Messages postés 26 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 20 décembre 2009
2 avril 2005 à 16:00
* Mouai, effectivement, tu as raison, on peut économiser une variable dans MultiEssaisClick mais c'est pas très important... Le seul but de ce prog c'est la fonction RandomProba :-)

*Pour ce qui est d'utiliser 0.0 au lieu de 0, je vois vraiment pas l'intêret... On sait qu'on travaille avec des reel, il suffit de regarder le type de variable passée en parametre...
Et en plus, une probabilité est généralement comprise entre 0 et 1 donc c'est obligatoirement un reel...

Pour ce qui est des try catch, on peut effectivement en mettre à toutes les lignes...
Plus on en met, mieux c'est ;-) mais ce n'était pas ici le but de ma fonction...
Quand on traite un sujet précis, mieux vaut faire des fonctions simples en rapport directe avec ce sujet... C'est ensuite à celui qui utilise la fonction de gerer la manière dont il va la lancer....
J'aurais aussi pu intégrer un chronometre qui compte la durée de fonctionnement... Et Aussi une gestion des sockets pour faire du grid computing (calcul distribué)... Un module qui regarde si si il y a pas de keyloggers...
Et après, ca fait une usine à gaz, et on s'y retrouve plus...
Non, je crois qu'il faut pas trop s'écarter du sujet ;-) Il y a des sources qui expliquent le fonctionnement des try except et d'autres qui servent à faire des randoms...
Effectivement, j'aurais pu mettre un petit try mais je les garde généralement pour des fonctions ou je ne peux pas vraiment pas controler l'erreur... (genre du réseau principalement et des erreurs de sockets)
Ici l'erreur est partiellement controlée car tu peux passer n'importe quel paramêtre à RandomProba, elle ne fera jamais d'exception car elle traite les nombre négatifs... Le seul cas qui peut générer une exception, est un cas extreme : Si il y a plus de mémoire ou plus de ressources systêmes... Et là, si on gère ce cas, on est bon pour le gêrer à chaque instruction y compris celle du genre a:=1; C'est tomber dans la parano. Et d'ailleurs, try except utilise surement un peu de mémoire donc si il y en a plus, c'est le try lui même qui va planter...
Bref, on peut mettre un try, ca coute rien mais on rencontrera surement jamais d'exception.
Il faut distinguer les exceptions qui sont créés par des beugs, de celle qui sont crées par des erreurs légitimes.
Pour les premières, le traitement est simple, on doit se démerder pour qu'elles n'existent pas ;-)) donc pas besoin de les catcher.

A++
Theos
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
2 avril 2005 à 12:37
Quelques petites remarques en passant :
if (Proba<0) or (Proba=0) then
peut être remplacé par
if (Proba<=0.0) then
idem pour
if (Proba>1) or (Proba=1) then
qui peut être remplacé par
if (Proba<=1.0) then

N.B. 0.0 et 1.0 juste histoire de clarifier le code et pour montrer que tu travailles avec des réels.

Dans MultiEssaisClick
Tu utilises les variables total, ok et bad. Toutes ne sont pas nécessaire. Tu sais que tu fais une boucle de i fois (i=100) donc ton total est égal à i. De plus soit ton résultat est bon soit il est mauvais, donc si tu comptabilises uniquement les bons (ok) les mauvais se deduisent simplement comme etant bad=total-ok ou encore bad=i-ok
Donc en supprimant bad et total, puis en remplaçant total par i tu obtiendras les mêmes résultats.

Un dernier point, tu désactives tes boutons ce qui est une très bonne chose, cependant si une exception intervient dans ton code, le bouton sera définitevement inactif...
Pense à encadre ton code avec un try finally.
bouton.enabled := false ;
try
// .... ton code ici
finally
bouton.enabled := true ;
end ;

Cordialement.
Rejoignez-nous