NetLogo: чтение данных из входных файлов с переменным количеством строк - PullRequest
4 голосов
/ 11 февраля 2010

Я проводил симуляции теории игр в NetLogo, и теперь у меня есть много файлов данных, содержащих кросс-табулированные данные - в каждом столбце хранится значение своей переменной, и есть c. 1000 строк, содержащих данные. Я пытаюсь написать программу, которая будет принимать эти файлы и вычислять среднее значение для каждого столбца.

У меня есть программа, которая работает до тех пор, пока в каждом файле есть постоянное количество строк данных. Программа использует цикл команд чтения файла для вычисления промежуточных итогов, которые затем делятся на количество строк, прочитанных после прочтения всех строк.

Однако мои файлы реальных данных имеют переменное количество строк. Я пытался изменить свой код, используя файл в конце? заставить его выйти из цикла выполнения итогов после последней строки, но я не смог найти никакого способа использовать его, который работает - я просто получаю сообщение об ошибке, сообщающее, что файл заканчивается.

Пожалуйста, кто-нибудь может предложить способ борьбы с этим? Я вставил рабочий код ниже.

-

globals [target-file-name  
current-tally-file  
lines-read  
coops-fixed-run cheats-fixed-run either-fixed-run coop-freq-min-run  
coop-freq-max-run coop-freq-mean-run ticks-run  
num-lines  
]  

to setup  
set target-file-name user-input "Type a name for the target file"  
file-open target-file-name  
file-print("TallyFile Reps pFixCoop pFixCheat pFixEither MeanMinCoop MeanMaxCoop MeanMeanCoop")  
file-close  
set num-lines read-from-string user-input "How many lines in the file to be processed?" 
end 

to go  
set current-tally-file user-file  
file-open current-tally-file  
set lines-read 0  

while [lines-read < num-lines][  
let in1 file-read set coops-fixed-run (coops-fixed-run + in1)  
let in2 file-read set cheats-fixed-run (cheats-fixed-run + in2)  
let in3 file-read set either-fixed-run (either-fixed-run + in3)  
let in4 file-read set coop-freq-min-run (coop-freq-min-run + in4)  
let in5 file-read set coop-freq-max-run (coop-freq-max-run + in5)  
let in6 file-read set coop-freq-mean-run (coop-freq-mean-run + in6)  
let in7 file-read set ticks-run (ticks-run + in7)    
set lines-read (lines-read + 1)   
]  

stop-and-clear  
end  


to stop-and-clear  

let pfixcoop (coops-fixed-run / lines-read)  
let pfixcheat (cheats-fixed-run / lines-read)  
let pfixeither (either-fixed-run / lines-read)  
let mean-of-mins (coop-freq-min-run / lines-read)  
let mean-of-maxs (coop-freq-max-run / lines-read)  
let mean-of-means (coop-freq-mean-run / lines-read)  
let mean-of-ticks (ticks-run / lines-read)  

file-open target-file-name  
file-print (word current-tally-file " " lines-read " " pfixcoop " " pfixcheat "
" pfixeither " " mean-of-mins " " mean-of-maxs " " mean-of-means " "
mean-of-ticks)  
file-close  


set coops-fixed-run 0  
set cheats-fixed-run 0  
set either-fixed-run 0  
set coop-freq-min-run 0  
set coop-freq-max-run 0  
set coop-freq-mean-run 0  
set ticks-run 0  
set lines-read 0  

stop  

end  

1 Ответ

4 голосов
/ 11 февраля 2010

Метод чтения всех строк из файла выглядит следующим образом:

to read-file [filename]
  file-open filename
  while [not file-at-end?][
    ;read one line
    let in1 file-read
    let in2 file-read
    ;and so one, at the end you will probably want to put these into some global variable
    set global-in1 fput in1 global-in1
  ]
  file-close filename
end

Предполагается, что все строки имеют в точности имя элемента данных, и вы знаете, что это за число. В противном случае просто используйте file-read-line вместо file-read

...