Comment générer des entiers aléatoires dans une plage en Smalltalk?
-
06-07-2019 - |
Question
Une classe que je suis en train de suivre nous oblige actuellement à faire tout notre codage en smalltalk (c'est une classe de conception). Sur l'un de nos projets, je cherche à faire certaines choses et j'ai du mal à trouver comment les faire. Il semble que ce que la plupart des gens font est de modifier leur propre version de smalltalk pour faire ce dont ils ont besoin. Je ne suis pas libre de le faire, car cela provoquerait une erreur sur l'ordinateur de mon prof quand il ne possède pas les mêmes méthodes intégrées que moi.
Voici ce que je cherche à faire:
Nombres aléatoires. Je dois créer un nombre aléatoire compris entre 1 et 1 000. Pour le moment, je le simule en faisant
rand := Random new.
rand := (rand nextValue) * 1000.
rand := rand asInteger.
Cela me donne un nombre compris entre 0 et 1000. Y a-t-il un moyen de faire cela en une seule commande? semblable à
Random between: 0 and: 1000
Et / ou déclarations. Celui-ci me dérange dans la vie quotidienne. J'ai essayé plusieurs configurations différentes de
(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...
Je simule donc des instructions ifTrue imbriquées:
(statement) ifTrue:[
(statement) ifTrue:[...
Quelle est la bonne façon de faire et / ou Random en smalltalk?
La solution
Le problème est que
(expr) and: (expr) ifTrue: aBlock
est analysé comme étant la méthode and:ifTrue:
Si vous examinez la classe Boolean (et en particulier True ou False), vous remarquerez que ifTrue: est simplement une méthode régulière et qu’aucune méthode et: ifTrue: n'existe, cependant. , simple et: fait. Donc, pour préciser que ce sont deux messages, écrivez
((expr) and: (expr)) ifTrue: aBlock
Pour les combinaisons booléennes plus longues, notez qu'il existe aussi des méthodes et: et: et et: et: et: implémenté.
Autres conseils
(1 to: 1000) atRandom
Si vous utilisez VisualWorks, et que: prend un bloc comme argument, vous écrivez:
(aBoolean and: [anotherBoolean]) ifTrue: [doSomething].
Il y a aussi &
, qui ne prend pas un bloc en argument,
aBoolean & anotherBoolean ifTrue:[doSomething].
La différence est et: évalue seulement le contenu du bloc si le premier bool est vrai (semblable à java), alors que and:
évalue toujours les deux.
Ainsi Random >> between: and:
est pratique si la deuxième condition est coûteuse en calcul ou si elle inclut des modifications d'état qui ne devraient se produire que lorsque la première condition est vraie. (c’est généralement une mauvaise conception).
En ce qui concerne Random, tant que vous transmettez votre méthode personnalisée, <=> ainsi que le reste de votre code, elle fonctionne correctement sur l'ordinateur de votre professeur. La manière de le faire dépend du format dans lequel vous êtes censé livrer le travail.
En ce qui concerne le problème aléatoire: cela dépend de la version de ST que vous utilisez. Dans Squeak 3.9, il existe Random>>#nextInt:
, qui est documenté sous la forme & "Répondre à un entier aléatoire dans l'intervalle [1, un Integer]. &"; Sa mise en œuvre se lit
(self next * anInteger) truncated + 1
J'ai donc deux commentaires ici:
- Vous devriez vraiment apprendre à utiliser le navigateur de classe. Cela peut répondre aux questions (fréquentes) & "Quels messages puis-je envoyer aux objets de classe X &";
-
Il est courant, dans ST, d’ajouter de nouvelles méthodes aux classes existantes. Donc, si vous voulez que Random ait entre: et :, ajoutez-le, par exemple. comme
between: low and: high ^(self next * (high-low+1)) truncated + low
Pour le dire simplement, sans connaître le dialecte Smalltalk, je ne peux que donner une réponse générale. Si vous avez dit la question au hasard, oui, c’est la seule façon de le faire si votre professeur a besoin d’une réponse générique.
En ce qui concerne la question et / ou les déclarations,
Et / ou déclarations. Celui-ci me dérange dans la vie quotidienne. J'ai essayé plusieurs configurations différentes de
(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...
Ce que vous voulez essayer, c'est:
(statement) and: [statement] ifTrue: [ ... ]
notez les crochets, la méthode and: prend un bloc en argument.
Pour créer plusieurs nombres entiers aléatoires compris entre 1 et 1 000
Commencez par créer une série de nombres aléatoires. Faites cela une seule fois.
Créez ensuite un nouveau nombre aléatoire en prenant le prochain nombre de la série. Répétez si nécessaire.
aRandomSeries := Random new .
"Seed a new series of random numbers"
aRandomInt := aRandomSeries newInt: 1000 .
"generate a random integer between 0 and 1000"
anotherRandomInt := aRandomSeries newInt: 1000 .
"generate another random integer between 0 and 1000"
Opérations logiques
aBoolean
répondra à and:
et à or:
. Ils prennent tous deux des arguments de bloc .
Voici comment ils fonctionnent.
and: alternativeBlock
Si le destinataire est vrai, répondez à la valeur de alternativeBlock; sinon, répondez false sans évaluer alternativeBlock.
or: alternativeBlock
Si le destinataire est faux, répondez à la valeur de alternativeBlock; sinon, répondez true sans évaluer alternativeBlock.
exemple:
( 3 > 2 ) or: [ 3 < 4 ] ifTrue: [ ]
aBoolean and: [ anotherBoolean ] ifFalse: [ ]
Cependant, Squeak et Pharo Smalltalks accepteront tous deux un argument entre parenthèses ( )
Dolphin Smalltalk ne le fera pas et requiert strictement la syntaxe Smalltalk standard d’un argument de bloc.
Autres méthodes associées:
&
un AND ne nécessitant pas un argument entre crochets (par exemple, un bloc)
|
un OU ne nécessitant pas d'argument entre crochets (par exemple, un bloc)
and:and: }
et and:and:and: }
fonctionnent dans Amber, Cuis, Gnu, Pharo, Squeak, VisualAge et VisualWorks Smalltalks.
Squeak Smalltalk fournit également:
and:and:and:and }
or:or: }
Ils prennent plusieurs arguments de bloc
or:or:or: }
or:or:or:or: }
<=> Ils prennent plusieurs arguments de bloc
<=>