Précédent   Forum des professionnels en informatique > Autres langages > Autres langages > Smalltalk
Smalltalk Forum d'entraide sur la programmation en Smalltalk
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/05/2011, 16h00   #1
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
Par défaut Calcul de moyenne

bonjour,

je cherche à obtenir une moyenne mensuelle sous smalltalk.

Le pas de temps est journalier, et je souhaite obtenir une moyenne sous cette forme :

2000 1 12.0748309618710
2000 2 4.15727314571429
2000 3 20.6630426131935
2000 4 19.1262662252667
2000 5 18.6647294163871
2000 6 18.7016694218667
2000 7 3.9470928703871
2000 8 4.83076521606452
2000 9 3.88788294303333
2000 10 2.12137467729032
2000 11 5.97348665593333
2000 12 4.55005589680645
2001 1 4.29934243735484
2001 2 30.1753449071724
2001 3 17.4209448133548
2001 4 3.74468932326667
2001 5 3.99676139122581
2001 6 6.5915397088
2001 7 4.07887228732258
2001 8 7.13085855070968
2001 9 6.39271218913333
2001 10 9.6324753996129
2001 11 10.4179868901333
2001 12 18.4510738567742


etc...

En fait une variable de mon modèle que l'on appellera X me fourni une valeur à chaque pas de temps :

1 x1
2 x5
3 x..
.....

n xn

En sachant que 1 correspond au 1er janvier 2000.

Et je souhaiterais avoir une variable qui me calcule cette moyenne en parallèle, si cela est possible...

Merci par avance
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/06/2011, 10h44   #2
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
comme ça vite fait, si tu rajoutes une boucle imbriquée dans le premier algo de Maske, ça doit le faire , non ?

si j'ai bien compris, c'est les mêmes données de base...
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 11h49   #3
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
c'est à dire je ne comprends pas ???
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/06/2011, 11h49   #4
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
je veux dire : est-ce que tes données en entrée sont les mêmes que dans ton autre sujet ?

1 23
2 25
3 56
.. ...

et que tu veux faire une moyenne des 31 premières lignes (janv. 2000) pour fabriquer ta première ligne résultat ?

2000 1 12.0748309618710

et une autre ligne à chaque changement de mois ?

si j'ai faux, reprécise bien comment est ton fichier en entrée.
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/06/2011, 14h28   #5
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
oui mon fichier est sous cette forme :

1 x1
2 x2
3 x3
4 x4
.....
n xn

en sachant que x1 correspond au 1er Aout et non au 1er Janvier.
Et le résultat souhaité est bien ce que tu as indiqué dans ton post
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/06/2011, 15h28   #6
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
voilà ce que j'ai réussi à faire :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29


| aReadStream aWriteStream sommeValeurs dateRef ligne newDate quantieme moisRef dateDepart |
"initialisation"
aWriteStream := CfsWriteFileStream open: 'E:\resultat_moyenne.txt'.
aReadStream := CfsReadFileStream open: 'E:\test_moyenne.txt'.
dateDepart:= Date newDay: 1 monthIndex: 8 year: 2000.
dateRef := dateDepart.
moisRef := dateRef monthIndex.
sommeValeurs := 0.
"boucle"
[aReadStream atEnd] whileFalse: [ 
    ligne := aReadStream nextLine subStrings.
    quantieme := (ligne at: 1) asNumber.
    newDate := dateDepart addDays: (quantieme - 1).

    (newDate monthIndex = moisRef) 
	    ifTrue: [ 
		    sommeValeurs := sommeValeurs + (ligne at: 2) asNumber]
	    ifFalse: [ 
		    aWriteStream nextPutAll: dateRef year printString , ' ', dateRef monthIndex printString , ' ' , ((sommeValeurs/dateRef daysInMonth) asFloat) printString ; cr.
		    sommeValeurs := (ligne at: 2) asNumber.
		    dateRef := newDate.
    		moisRef := dateRef monthIndex ]].
"derniere ligne"
aWriteStream nextPutAll: dateRef year printString , ' ', dateRef monthIndex printString , ' ' , ((sommeValeurs/dateRef daysInMonth) asFloat) printString ; cr.
aWriteStream close.
aReadStream close.
avec mon smalltalk (IBM)
il faudra adapter pour ton smalltalk
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 09h43   #7
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
bonjour,

merci pour ta réponse !

Par contre si tu as encore un peu de temps pourrais tu m'expliquer quelques lignes du code :

1)

ligne := aReadStream nextLine subStrings.
quantieme := (ligne at: 1) asNumber.
newDate := dateDepart addDays: (quantieme - 1).

2)

ifFalse: [
aWriteStream nextPutAll: dateRef year printString , ' ', dateRef monthIndex printString , ' ' , ((sommeValeurs/dateRef daysInMonth) asFloat) printString ; cr.
sommeValeurs := (ligne at: 2) asNumber.


(pour cette dernière partie de code, je ne comprends pas l'utilité des ' ', et que veux dire "cr". )

Merci encore
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 10h14   #8
Nouveau Membre du Club
 
Inscription : juin 2007
Messages : 34
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 34
Points : 30
Points : 30
Citation:
Envoyé par youchlure Voir le message
bonjour,

merci pour ta réponse !

Par contre si tu as encore un peu de temps pourrais tu m'expliquer quelques lignes du code :

1)

ligne := aReadStream nextLine subStrings.
quantieme := (ligne at: 1) asNumber.
newDate := dateDepart addDays: (quantieme - 1).

2)

ifFalse: [
aWriteStream nextPutAll: dateRef year printString , ' ', dateRef monthIndex printString , ' ' , ((sommeValeurs/dateRef daysInMonth) asFloat) printString ; cr.
sommeValeurs := (ligne at: 2) asNumber.


(pour cette dernière partie de code, je ne comprends pas l'utilité des ' ', et que veux dire "cr". )

Merci encore
Je réponds à la 2: on met des ' ' pour que ce ne soit pas lu comme du code, mais comme du texte. Donc ' ', ça permet d'insérer un espace entre deux valeurs.

cr est le character "carriage return" => retour à la ligne.

Je pense qu'un petit tour dans les manuels de VisualWorks, comme le BasicLibrairies, vous permettrait de trouver ce type de réponse facilement. La partie sur les streams du même guide vous donnerait des pistes pour mieux comprendre la gestion des I/O.
Mustrum_Ridculle est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/06/2011, 10h59   #9
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
Merci pour les réponses.

ça fait longtemps que je n'avais pas fait de progra

J'ai oublié beaucoup de petits truc, mais c'est vrai que les signes comme ' ' et Cr m'étaient sortis de la tête !!!

Désolé
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 11h14   #10
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
dans l'autre sujet, tu disais être novice en smalltalk.
est-ce toujours le cas ? pas de formation depuis ?
au niveau Objet en général, quelle est ton expérience ?
c'est pour savoir jusqu'à quel niveau d'explication je dois aller
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 11h19   #11
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
En fait je suis toujours novice
Car j'utilise dans mon travail le programme fait par d'autres, ce n'est pas moi qui les mets en place, mais j'apprends petit à petit à lire et à comprendre ceux-ci.

Cela fait environ 4 mois que je manipule la programmation objet, mais vraiment en tant qu'utilisateur d'un programme déjà fonctionnel.
Parfois je dois ajouter des petites variables, rien de plus...


Voila ce que je comprends :


| aReadStream aWriteStream sommeValeurs dateRef ligne newDate quantieme moisRef dateDepart |
Mis en place nouvelles variables

"initialisation"
aWriteStream := CfsWriteFileStream open: 'E:\resultat_moyenne.txt'.
aReadStream := CfsReadFileStream open: 'E:\test_moyenne.txt'.

La par contre je ne vois pas quels fichiers tu veux ouvrir? comme fichier je n'ai que la chronique, la tu me demandes d'ouvrir un fichier de moyenne? C'est ce que je dois calculer...Quelle est la différence entre les 2 fichiers?


dateDepart:= Date newDay: 1 monthIndex: 8 year: 2000.
dateRef := dateDepart.
moisRef := dateRef monthIndex.

"On fixe la date"

sommeValeurs := 0.
"Pourquoi cette ligne????"

Voila pour le reste c'est ce que je t'ai mis dans le post précédent.

merci encore
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 12h18   #12
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
le "read" c'est ton fichier en entrée
le "write" c'est ton fichier en sortie (le résultat des calculs)

en Smalltalk, les variables sont non typées (c'est une des spécificités surpuissantes du langage).
donc tu déclares tes variables au début (entre les barres verticales)
et quand tu en as besoin tu mets n'importe quel objet dedans, c'est magique.
toutefois, quand on met la variable dans une boucle (ici typiquement pour faire des additions), il faut l'initialiser.
c'est pour ça que tu verras souvent des trucs du genre :

moyenne := 0.
chaine := ''.
ou chaine := String new
maColl := OrderedCollection new.

cela initialise des objets que l'on compte enrichir plus tard (dans des boucles).
au passage les "Collection" sont des classes incontournables.

il y en a dans ma "solution".
explications dans le prochain post.
là je vais manger, lol
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 16h42   #13
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
ok, merci pour ces premieres infos
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 17h28   #14
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
complément :

nextLine sert à lire le stream ligne par ligne (excellent !).
tu dois chercher dans tes classes Stream l'équivalent.
j'espère que ça existe, sinon, tu seras obligé de te rabattre sur le code de Maske pour lire
caractère par caractère.

subStrings éclate une chaine en plusieurs chaines, typiquement en se basant sur le caractère <espace> (excellent !)
exemple : 'Rome est une très bonne série télévisée' subStrings

si on évalue ce code, on obtient un tableau (instance de la classe Array) :
#('Rome' 'est' 'une' 'très' 'bonne' 'série' 'télévisée')

dans ton énoncé, on a un tableau avec deux éléments.
ensuite je peux appeler le 1er élément (at: 1) pour avoir le quantième (nb jours écoulés)
et le deuxième pour avoir la valeur.

addDays:
comme son nom l'indique, ça additionne un nb de jours à un date et renvoie la nouvelle date.
c'est magique !
pas besoin de s'occuper des mois de 28 29 30 ou 31 jours, c'est calculé automatiquement.
c'est pour cela que je ne m'occupe que du changement de mois dans mon algo.

nextPutAll:
ajoute une chaine de caractères au stream de sortie.
tu voulais
année<espace>mois<espace>moyenne
c'est ce que j'ai fait
à noter : , est le caratère pour concaténer des chaines
ensuite on insère un saut de ligne dans le stream pour respecter ton format de sortie, et voilà.
milco est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/06/2011, 19h15   #15
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
ok, merci c'est beaucoup plus clair !
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 19h58   #16
Membre éclairé
 
Avatar de maske
 
Homme
Ingénieur développement logiciels
Inscription : mai 2008
Messages : 204
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : mai 2008
Messages : 204
Points : 398
Points : 398
Salut,

pour information, l'interface de la classe Stream dans Visual Works :


On peut avec la méthode upTo: sur un ReadStream lire ligne par ligne un texte séparé par des retours à la lignes :

Code :
aReadStream upTo: Character cr
Si le caractère qui sépare les éléments à lire n'est pas un CR, on peut faire :

Code :
aReadStream upTo: aCharacter
où "aCharacter" est un caractère de la classe Character (donc précédé par $).

Pour ouvrir un stream dans un fichier externe :

Code :
1
2
3
|myFileName myReadStream |
myFileName := "c:\monUrl" asFilename.
myReadStream := myFileName readStream
__________________
[|]
maske est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 12h00   #17
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
Bonjour,

en fait je voulais précisé que je ne récupere pas les données dans un fichier texte, mais directement dans le programme lors d'une simulation.

si vous voulez le programme va chercher le fichier texte précedemment cité :

1 x1
2 x2
n xn

ensuite, le programme calcul une variable V1.
Et aprés je cherche à obtenir les moyennes de V1.
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 15h29   #18
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
alors je verrais bien un dico pour stocker les données à la place du WriteStream. et puis la date de départ pourrait être passé en paramètre à l'appel de la méthode. c'est plus élégant.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

calculMoyenneMensuelleDepuis: dateDepart

    | aReadStream unDico sommeValeurs dateRef ligne newDate quantieme moisRef |
    "initialisation"
        aReadStream := CfsReadFileStream open: 'E:\test_moyenne.txt'.
        unDico := Dictionary new.
        dateRef := dateDepart.
        moisRef := dateRef monthIndex.
        sommeValeurs := 0.
        "boucle"
        [aReadStream atEnd] whileFalse: [ 
            ligne := aReadStream nextLine subStrings.
            quantieme := (ligne at: 1) asNumber.
            newDate := dateDepart addDays: (quantieme - 1).
        
            (newDate monthIndex = moisRef) 
                ifTrue: [ 
                    sommeValeurs := sommeValeurs + (ligne at: 2) asNumber]
                ifFalse: [ 
                    unDico at: (dateRef year printString, ' ', dateRef monthIndex printString) put: ((sommeValeurs/dateRef daysInMonth) asFloat).
                    sommeValeurs := (ligne at: 2) asNumber.
                    dateRef := newDate.
                    moisRef := dateRef monthIndex ]].
        "derniere ligne"
        unDico at: (dateRef year printString, ' ', dateRef monthIndex printString) put: ((sommeValeurs/dateRef daysInMonth) asFloat).
        aReadStream close.
        ^unDico
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 15h47   #19
Futur Membre du Club
 
Homme
Ingénieur développement logiciels
Inscription : août 2010
Messages : 18
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : août 2010
Messages : 18
Points : 16
Points : 16
Dictionary est une fabuleuse classe !
cela permet de ranger des objets à l'aide d'une clé et ainsi de les retrouver facilement.
donc at: <objet-clé> put: <objet-valeur>
tu devines que ça alimente le dictionnaire.

ici j'ai choisi <objet-clé> = la chaine 'année mois' et <objet-valeur> = la moyenne calculée.
rien d'extraordinnaire.

tu regarderas les méthodes de la classe Dictionary.
at:ifAbsent: (pour lire une valeur dont on connait la clé)
keys (renvoie l'ensemble des clés)
values (devine !)
associationsDo: (pour boucler sur l'ensemble d'un dico)

la contrainte est que on doit avoir unicité au niveau des clés.
dans ton cas, ça s'applique donc bien.
milco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 13h53   #20
Invité régulier
 
Inscription : septembre 2009
Messages : 56
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 56
Points : 7
Points : 7
merci beaucoup
youchlure est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h24.


 
 
 
 
Partenaires

Hébergement Web