Как я могу сгенерировать случайные целые числа в диапазоне в Smalltalk?

StackOverflow https://stackoverflow.com/questions/271394

Вопрос

Класс, который я посещаю в настоящее время, требует, чтобы мы выполняли все наше кодирование на smalltalk (это класс проектирования).В одном из наших проектов я хочу кое-что сделать, и мне трудно найти, как это сделать.Похоже, что большинство людей модифицируют свою собственную версию smalltalk, чтобы она делала то, что им нужно.Я не имею права этого делать, так как это вызвало бы ошибку на компьютере моего профессора, если бы у него не было тех же встроенных методов, что и у меня.

Вот что я собираюсь сделать:

Случайные числа.Мне нужно создать случайное число от 1 до 1000.Прямо сейчас я притворяюсь, делая

rand := Random new.
rand := (rand nextValue) * 1000.
rand := rand asInteger.

Это дает мне число от 0 до 1000.Есть ли способ сделать это одной командой?похожий на

Random between: 0 and: 1000

И/Или заявления.Это выбивает меня из колеи.Я перепробовал несколько различных конфигураций

(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...

Поэтому я подделываю это с помощью вложенных операторов ifTrue:

(statement) ifTrue:[
    (statement) ifTrue:[...

Как правильно сделать and / или and Random в smalltalk?

Это было полезно?

Решение

Проблема в том, что

 (expr) and: (expr) ifTrue: aBlock

анализируется как метод and:ifTrue:. Если вы посмотрите на логический класс (и, в частности, на True или False), вы заметите, что ifTrue: это просто обычный метод, и что никакого метода и: ifTrue: существует - однако , добрая и: делает. Чтобы было понятно, что это два сообщения, напишите

((expr) and: (expr)) ifTrue: aBlock

Для более длинных логических комбинаций обратите внимание, что существуют также методы и: и: и и: и: и: реализованы.

Другие советы

(1 to: 1000) atRandom

Если вы используете VisualWorks, а: принимает блок в качестве аргумента, вы должны написать:

(aBoolean and: [anotherBoolean]) ifTrue: [doSomething].

Есть также &, который не принимает блок в качестве аргумента,

aBoolean & anotherBoolean ifTrue:[doSomething].

Разница заключается в том, что: только то, что находится в блоке, вычисляется только в том случае, если первый логический тип true (аналог java), а and: всегда оценивает оба.

Таким образом, Random >> between: and: пригодится, если второе условие является вычислительно дорогостоящим или если оно включает изменения состояния, которые должны происходить только тогда, когда первое условие истинно. (обычно это плохой дизайн).

Что касается Random, то пока вы предоставляете свой пользовательский метод, <=>, а также весь остальной код, он отлично работает на вашем компьютере профессора. Как это сделать конкретно, зависит от формата, в котором вы должны выполнить назначение.

Что касается случайной проблемы: это зависит от того, какую версию ST вы используете. В Squeak 3.9 есть Random>>#nextInt:, который задокументирован как & Quot; Ответить случайному целому числу в интервале [1, anInteger]. & Quot ;. Его реализация гласит

(self next * anInteger) truncated + 1

Итак, у меня есть два комментария:

<Ол>
  • Вы должны научиться пользоваться браузером классов. Это может ответить на (частые) вопросы &, Какие сообщения я могу отправлять объектам класса X & Quot;
  • В ST принято добавлять новые методы в существующие классы. Так что, если вы хотите, чтобы Random имел значения между: и :, просто добавьте его, например, а

    between: low and: high      
       ^(self next * (high-low+1)) truncated + low
    
  • Проще говоря, не зная диалекта Smalltalk, я могу дать только общий ответ. То, как вы задали случайный вопрос, да, это единственный способ сделать это, если вашему профессору нужен общий ответ.

    Что касается вопроса и / или утверждений,

      

    И / или заявления. Этот вышибает из меня живые дневные огни. Я пробовал несколько разных конфигураций

    (statement) and: (statement) ifTrue...
    (statement) and (statement) ifTrue...
    

    Вы хотите попробовать следующее:

    (statement) and: [statement] ifTrue: [ ... ]
    

    обратите внимание на скобки, метод and: принимает блок в качестве аргумента.

    Чтобы создать несколько случайных целых чисел от 1 до 1000
    Сначала создайте серию случайных чисел.Сделайте это только один раз.

    Затем создайте новое случайное число, взяв следующее число из серии.Повторяйте по мере необходимости.

    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"
    

    Логические операции

    aBoolean ответит на and: и or:.Они оба берут блокировать аргументы.

    Вот как они работают.

    and: alternativeBlock
    Если получатель имеет значение true, укажите значение alternativeBlock;в противном случае ответьте false без оценки alternativeBlock.

    or: alternativeBlock
    Если получатель имеет значение false, укажите значение alternativeBlock;в противном случае ответьте true, не оценивая alternativeBlock.

    например ,
    ( 3 > 2 ) or: [ 3 < 4 ] ifTrue: [ ]
    aBoolean and: [ anotherBoolean ] ifFalse: [ ]

    Однако Squeak и Pharo Smalltalks оба будут принимать аргумент в круглых скобках ( )
    Dolphin Smalltalk этого не сделает и строго требует стандартного синтаксиса Smalltalk для блочного аргумента.

    Другие связанные методы:
    & ан И для этого не требуется заключать текст в квадратные скобки (т. е.блокирующий) аргумент
    | ан или для этого не требуется заключать текст в квадратные скобки (т. е.блокирующий) аргумент
    & и | работаю в Amber, Cuis, Gnu, Pharo, Squeak, VisualAge и VisualWorks Smalltalks.

    Squeak Smalltalk также предоставляет:
    and:and: }
    and:and:and: } Они принимают несколько аргументов блока
    and:and:and:and }

    or:or: }
    or:or:or: } Они принимают несколько аргументов блока
    or:or:or:or: }

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top