Я использую сценарий gnuplot, который выдает ошибку при выполнении последней строки сценария. Я не вижу никаких проблем в этой строке. Ошибка: ')' ожидается. Если a переместить массив строк M_x_N[numRecord] перед строкой
статистика N с использованием (M_x_N[int($0+1)] = N[int($0+1)]*M[int($0+1)]) name "M_x_N" nooutput
ошибки нет. Что не так?
Я использую терминал QT, патч gnuplot 5.4 уровня 8. ОС — Windows 10.
Сценарий:
reset session
set encoding utf8
set datafile separator comma
cd 'C:\Users\smallz4'
corpusFile = "lz4_silicia_corpus.txt_4096.csv"
stats corpusFile nooutput
numRecord = STATS_records
chunkSize = numRecord-15.0
bias = 2048.0
array M[numRecord]
array N[numRecord]
array M_x_N[numRecord]
stats corpusFile using (M[int($0+1)] = $1) name "M" nooutput
stats corpusFile using (N[int($0+1)] = $2) name "N" nooutput
stats N using (M_x_N[int($0+1)] = N[int($0+1)]*M[int($0+1)]) name "M_x_N" nooutput
Какой сценарий вы на самом деле выполнили? Прежде чем присваивать значения массиву, вам необходимо указать размер массива. Итак, конечно, array M_x_N[numRecord]
должно быть перед stats N using (M_x_N[int($0+1] = ...
. Может я что-то неправильно понял?
Хорошо, я долго пытался понять, что происходит. По причине, которую я пока не понимаю, кажется, что имя вашего окончательного массива вызывает ошибку.
help variables
говорит:
Допустимые имена такие же, как и в большинстве языков программирования: они должны начинаются с буквы, но последующие символы могут быть буквами, цифрами, или "_".
Итак, M_x_N
должно быть допустимым именем переменной или массива. По крайней мере, я еще не нашел утверждения, в котором говорилось бы, что _
не разрешено для имен массивов.
С помощью следующего минимального и полного примера я могу воспроизвести вашу ошибку. И теперь, мне кажется, я понимаю, что вы имеете в виду.
Видимо, важна последовательность определений массива и команд stats
.
Скрипт: (этот скрипт завершится ошибкой из-за вашей ошибки)
### strange behaviour with setting arrays and using stats
reset session
$Data <<EOD
1 10
2 20
3 30
4 40
EOD
stats $Data u (c=$0+1) nooutput # get the number of rows into c
array M[c]
array M_x_N[c]
stats $Data u (M[int($0+1)] = $1) name "M" nooutput
stats $Data u (M_x_N[int($0+1)] = $2) name "M_x_N" nooutput
### end of script
Однако, если вы измените последовательность на следующую, это сработает.
array M[c]
stats $Data u (M[int($0+1)] = $1) name "M" nooutput
array M_x_N[c]
stats $Data u (M_x_N[int($0+1)] = $2) name "M_x_N" nooutput
Другая версия с исходной последовательностью, т.е. сначала все определения массива, а затем все команды stats
, будет работать как положено, если вы измените имя массива M_x_N
на MxN
.
array M[c]
array MxN[c]
stats $Data u (M[int($0+1)] = $1) name "M" nooutput
stats $Data u (MxN[int($0+1)] = $2) name "MxN" nooutput
Итак, я пришел к выводу, что подчеркивание в M_x_N
каким-то образом портит команду stats
. Я бы посчитал это ошибкой или, может быть, кто-то другой может объяснить.
Я сообщу об ошибке и посмотрю, что скажут разработчики. Я буду держать тему в курсе. - Извините за борьбу с примером.
@GuyB, не волнуйся, я рад узнавать и понимать что-то новое ;-) Хорошо, ты добавишь это на sourceforge.net/p/gnuplot/bugs или мне следует?
Пожалуйста, сделайте это. В конце концов, вы привели пример.
Это странно. Я понимаю, что происходит, но у меня нет простого решения или обходного пути, кроме как использовать другую схему имен для ваших переменных.
Проблема в том, что когда gnuplot видит команду
`stats $Data u (<anything>) name "M"`
он знает, что команда stats создаст группу переменных с именем M_*
, в данном случае
М_записи = 4
М_инвалид = 0
М_заголовки = 0
М_пустой = 0
М_блоков = 1
M_внедиапазона = 0
М_столбцы = 2
М_среднее = 2,5
и так далее. Готовясь к этому, он удаляет все существующие переменные, соответствующие шаблону M_*
. К сожалению, это включает в себя ранее объявленный массив M_x_N
.
Если я правильно помню, основанием для удаления потенциально конфликтующих переменных было то, что сбой команды stats
считается нефатальной ошибкой. Некоторые сценарии использовали наличие одной из этих переменных, чтобы проверить, была ли предыдущая команда stats
успешной или нет. Идея заключалась в том, что stats
удалит их при входе, а затем создаст (или, возможно, создаст заново) после успешного выполнения. Таким образом, если STATS_records
(или в данном случае M_records
) не существовало или было неопределенным после выполнения команды stats
, то команда, должно быть, завершилась неудачно. Более того, если сценарий слепо использует одну из этих переменных для построения графика или дальнейших вычислений, то удаление при сбое предотвращает создание неправильного графика или расчета с использованием оставшихся значений от более ранней успешной команды stats
в другом источнике данных.
Кто-то может жаловаться, что удаление всех переменных, соответствующих шаблону имени, является излишним; почему программа не ограничивается удалением только заведомо длинного списка имен переменных, которые она создаст? Справедливо. Но даже в этом случае вы столкнетесь с той же проблемой, если вместо создания массива с именем M_x_N
вы создадите массив с именем M_sumxy
или любое из более чем 30 других имен, которые команда stats
может перезаписать.
Спасибо за подробное объяснение. В этом есть смысл. Ошибка должна быть открыта для дальнейшего обсуждения с разработчиками. И, пожалуйста, задокументируйте это ограничение. По крайней мере, существует обходной путь, и мы знаем, в каком контексте это произойдет.
Пожалуйста, всегда предоставляйте минимальный воспроизводимый пример включая минимум данных для копирования, вставки и тестирования. Если это не очевидная опечатка или неправильный синтаксис и если у нас нет ваших данных и структуры каталогов, воспроизведение вашего сообщения об ошибке может занять много времени.