Массивы строк в nncron

Обсуждение программ nnCron и nnCron LITE

Массивы строк в nncron

Postby Neud » Sun, 07 Mar 2010, 19:37

В моем скрипте мне надо записывать в переменные некоторые строки, выбранные из массива строк случайным образом. Если бы nncron был на Паскале, я бы написал примерно следующее
Code: Select all
const
  beatles:array[0..3]of string=('John','Paul', 'George', 'Ringo');
var
  name:string;

begin
  name:=beatles[random(4)];
end.

Скажите пожалуйста, можно ли подобное сделать на Форте в nncron? Если да, то как?
Спасибо.
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby Dark_Jones » Sun, 07 Mar 2010, 20:10

Первое, что пришло в голову - создать текстовый файл и построчно читать его.
Либо привести все слова к одной длине (в примере - 6 символов) и использовать так:
Code: Select all
: beatles S" John  Paul  GeorgeRingo " ;
......
beatles DROP 2 6 * + 6 \\ извлекаем третий элемент массива (нумерация с нуля)
......
Dark_Jones
 
Posts: 414
Joined: Thu, 09 Nov 2006, 00:43
Location: Russia, S.Peterburg

Re: Массивы строк в nncron

Postby VoidVolker » Sun, 07 Mar 2010, 20:22

Например так:
Code: Select all
\ Создаем строки и выделяем для них память
S" Ringo" S>ZALLOC
S" George" S>ZALLOC
S" Paul" S>ZALLOC
S" John" S>ZALLOC
CREATE str-array , , , ,  0 , \ Сохраняем в массив строки, а в последнюю ячейку ноль как знак окончания массива(опционально)

\ Далее работаем с массивом так:
str-array 4 RANDOM CELLS + @ ASCIIZ>   \ Получить случайную строку из массива
TYPE CR

Или так:
Code: Select all
: A"
  [COMPILE] S"
  SWAP OVER S>ZALLOC , ,
; IMMEDIATE

: NAS@ ( arr n -- a u )
  3 LSHIFT + DUP @ SWAP CELL+ @
;

CREATE str-array A" John" A" Paul" A" George" A" Ringo" 0 ,

str-array 4 RANDOM NAS@
TYPE CR
Last edited by VoidVolker on Mon, 08 Mar 2010, 00:52, edited 1 time in total.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Массивы строк в nncron

Postby Neud » Sun, 07 Mar 2010, 21:08

Спасибо за ответы, есть над чем подумать!
Вообще задачу про битлов я привел для примера - на самом деле массив будет из нескольких сотен строк. Поэтому его, видимо, лучше заполнять из файла. В хелпе я нашел следующий пример:
Code: Select all
#( test_read_by_line
NoActive
\ Построчно (в цикле) считываем файл
\ test.txt в массив list-contents и
\ выводим каждую строчку на экран.
\ Строки в файле не должны быть длиннее 255 символов.
VARIABLE list-file
CREATE list-contents 258 ALLOT
Action:
    S" test.txt" R/O OPEN-FILE-SHARED THROW list-file !
    \ записываем строку во вторую ячейку массива list-content
    BEGIN list-contents 1+ 255 list-file @ READ-LINE THROW WHILE
    \ На стеке осталось число прочитанных символов.
    \ Сохраняем его в первую ячейку массива, чтобы
    \ получить строку со счетчиком
    list-contents C!
    MSG: "%list-contents COUNT%"
    REPEAT
    DROP
    list-file @ CLOSE-FILE DROP
)#

Не подскажете, можно ли исправить этот код, чтобы строки файла (т.е. элементы массива) выдавались на экран не подряд, а в случайном порядке? И бесконечно?
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby Dark_Jones » Sun, 07 Mar 2010, 21:39

Neud wrote:Не подскажете, можно ли исправить этот код, чтобы строки файла (т.е. элементы массива) выдавались на экран не подряд, а в случайном порядке? И бесконечно?

Изучи вот это: http://www.nncron.ru/forums/viewtopic.php?f=23&t=9583. READ-BY-LINE более удобен, чем то, что в хелпе.

Code: Select all
: FILE-NUM-LINE ( a u -- n )
\ возвращает количество строк n в файле a u
0 ROT ROT
READ-BY-LINE
     ROT 1 +
     NIP NIP
;READ-BY-LINE ;

: FILE-READ-LINE-N ( a1 u1 n -- a2 u2 )
\ возвращает n-строку файла a1 u1
\ если n больше количества строк в файле a u, то возвращает последнюю строку
>R 2DUP FILE-NUM-LINE R> MIN 1 MAX
ROT ROT
READ-BY-LINE
     crlf S+
     ROT 1 - DUP
     IF
       NIP NIP -1
     THEN
;?READ-BY-LINE ;

Я использовал старый плагин READ-BY-LINE, так что кое-что придётся изменить. Слова неоптимальны, сделаны "в лоб", но работают. Хотелось бы, конечно, что-нибудь более элегантное...
Dark_Jones
 
Posts: 414
Joined: Thu, 09 Nov 2006, 00:43
Location: Russia, S.Peterburg

Re: Массивы строк в nncron

Postby VoidVolker » Mon, 08 Mar 2010, 01:09

Code: Select all
#( Задача_0053080310
NoActive
  CREATE str-array 10240 ALLOT  \ Массив на 1280 строк
Action:
  str-array
  READ-BY-LINE: "M:\path\file.txt"
    FOUND-LINE SWAP OVER S>ZALLOC SWAP  \ addr a u
    2 PICK 2!
    2 CELLS +
  ;READ-BY-LINE
  str-array - 3 RSHIFT   \ n  \ Число строк
  BEGIN
    DUP RANDOM 3 LSHIFT str-array + 2@   \ n a u
    TYPE CR   \ Печатаем в консоли строку
    1000 PAUSE   \ раз в секунду
  AGAIN
  DROP
)#
Last edited by VoidVolker on Mon, 08 Mar 2010, 12:55, edited 1 time in total.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Массивы строк в nncron

Postby Neud » Mon, 08 Mar 2010, 12:43

Вобщем, по-вашему у меня ничего не получилось - сделал по-другому: написал на Паскале программу, которая случайным образом выбирает из файла строку и помещает ее во второй файл. А в скрипте просто считываю в переменную строку из второго файла.
Все-таки Форт сложноват...
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby VoidVolker » Mon, 08 Mar 2010, 12:51

Neud wrote:по-вашему у меня ничего не получилось

Что именно не получилось? Установить плагин read-by-line.spf? Скопировать задачу в кронтаб? Открыть консоль? Запустить задачу?
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Массивы строк в nncron

Postby Neud » Wed, 10 Mar 2010, 00:14

Текст по ссылке я сохранил в файле read-by-line.spf, добавил его в плагины через Options. После того как написанный вами здесь код я вставляю в кронтаб и сохраняю, nncron пищит и вылетает crontab syntax ERROR.
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby VoidVolker » Wed, 10 Mar 2010, 00:43

После установки плагина надо еще перезапустить ннкрон.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Массивы строк в nncron

Postby Neud » Wed, 10 Mar 2010, 01:04

перезапускал
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby VoidVolker » Wed, 10 Mar 2010, 01:29

Значит что-то неправильно сделано. Плагин рядом с остальными плагинами? В ннкрон.ини присутствует? Крон какой версии? Какая винда? Просто в последних бетах и виндоус каталог с плагинами и ннкрон.ини может браться из каталога профиля пользователя. Для принудительной установки рабочего каталога следует запускать крон с параметром -dir "path".
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Массивы строк в nncron

Postby Neud » Sun, 14 Mar 2010, 02:04

А точно нельзя как-нибудь по-простому взять случайную строку из файла и положить ее в переменную? Типа как на Руби:

arr = IO.readlines('c:\src.txt')
v = arr[rand(arr.size)]
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Re: Массивы строк в nncron

Postby Dark_Jones » Sun, 14 Mar 2010, 12:23

Neud wrote:А точно нельзя как-нибудь по-простому взять случайную строку из файла и положить ее в переменную?


Конечно можно! Только сначала научи крон слову "IO.readlines". Ты (теоретически) можешь обучить крон всем словам своего любимого языка - только зачем тогда крон?

Вставь это в файл ReInstall.bat и положи его в папку с кроном (по умолчанию c:\Program Files\nnCron):
Code: Select all
@echo off
echo Stop nnCron Service...
call "%~dp0stopnncron.bat" %1 %2 %3 %4 %5 %6 %7 %8 %9
start/wait /MIN "nnCron remove service" "%~dp0nncron.exe" -q %1 %2 %3 %4 %5 %6 %7 %8 %9 -remove
sleep 7
echo Remove nnCron Service...
nncron.exe -remove
sleep 5
echo Install nnCron Service...
nncron.exe -dir "C:\Program Files\nnCron\" -install
sleep 5
echo Start nnCron Service...
call "%~dp0startnncron.bat" %1 %2 %3 %4 %5 %6 %7 %8 %9

Файл sleep - придётся скачать из инета: он добавляет паузу в секундах. В принципе можно вместо sleep поставить ДОС'овскую команду pause, но тогда придётся самому нажимать на любую клавишу когда БАТ-ник останавливается.
Запусти - этим самым мы убедимся, что крон будет искать все свои табы/ини/плагины в своей папке (по умолчанию c:\Program Files\nnCron).
Дальше проверяй: *.ini и *.tab должны быть в c:\Program Files\nnCron, а *.spf - в C:\Program Files\nnCron\PLUGINS.
Честно скажу - стандартным меню крона (по иконке) перестал пользоваться на следующий же день. Гораздо удобнее редактировать через notepad файлы *.ini, *.tab, *.spf.
Dark_Jones
 
Posts: 414
Joined: Thu, 09 Nov 2006, 00:43
Location: Russia, S.Peterburg

Re: Массивы строк в nncron

Postby Neud » Sun, 14 Mar 2010, 13:02

После отката с беты на релиз программу VoidVolker я таки смог запустить, прекрасно работает. Единственно - я не понимаю, как ее переделать так, что бы она клала случайную строку в переменную, а не выводила их бесконечном цикле на консоль?

Code: Select all
#( Задача_0053080310
NoActive
  CREATE str-array 10240 ALLOT  \ Массив на 1280 строк
Action:
  str-array
  READ-BY-LINE: "M:\path\file.txt"
    FOUND-LINE SWAP OVER S>ZALLOC SWAP  \ addr a u
    2 PICK 2!
    2 CELLS +
  ;READ-BY-LINE
  str-array - 3 RSHIFT   \ n  \ Число строк
  BEGIN
    DUP RANDOM 3 LSHIFT str-array + 2@   \ n a u
    TYPE CR   \ Печатаем в консоли строку
    1000 PAUSE   \ раз в секунду
  AGAIN
  DROP
)#


То есть, я понимаю, что BEGIN..AGAIN DROP надо убрать, и TYPE CR 1000 PAUSE...
И потом как-то изменить строку

DUP RANDOM 3 LSHIFT str-array + 2@ \ n a u

чтобы в ней было присваивание переменной (например, v) случайного значения массива str-array. Только ввиду незнания Форта я не понимаю, как это написать :(
Neud
 
Posts: 43
Joined: Tue, 18 Oct 2005, 03:59

Next

Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 3 guests