БлогNot. Mathcad: как обработать файл со смешанными числовыми и строковыми данными?

Mathcad: как обработать файл со смешанными числовыми и строковыми данными?

Чтение и обработка матрицы или вектора из текстового файла в Mathcad выглядят довольно просто:

  • Функция READPRN("имя файла") возвращает матрицу, в которой каждая строка определяется записью (строкой) файла. Количество элементов (числовых значений) в каждой строке файла должно быть одинаковым. Используется в виде A:= READPRN("имя файла"), где A - массив;
  • Функция WRITEPRN("имя файла") записывает матрицу в файл данных. Каждая строка матрицы становится записью файла. Используется в виде WRITEPRN("имя файла"):=A, где A - массив;
  • Функция APPENDPRN("имя файла") дописывает матрицу к существующему файлу. Используется в виде APPENDPRN("имя файла"):=A. Существующий файл должен иметь столько же столбцов, что и массив A.

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

В качестве практического примера решим такую задачку:

В файле содержится матрица оценок N студентов по M предметам, N>1, M>0. Прочитать данные и вычислить следующие величины:

  • средний балл по каждому предмету и каждому студенту;
  • общий средний балл группы;
  • количество оценок "2", "3", "4" и "5".

Если исходные данные сохранены в файле data.txt вида

3 4 5
5 4 3
3 3 3
5 5 5
3 2 3

то полный код решения выглядит так:

чтение и запись матрицы в Mathcad
чтение и запись матрицы в Mathcad

Если файл "неправильный", то есть, не содержит одинаковое количество числовых значений в каждой строке, то функция READPRN его не прочитает. Дополнительно мы проверяем, содержатся ли в файле допустимые оценки (то есть, значения 2, 3, 4 или 5) с помощью переменной Check.

Результаты пишутся в файл result.txt текущей папки, вот что там вышло:

 
       3       4       5       4
       5       4       3       4
       3       3       3       3
       5       5       5       5
       3       2       3   2.667
     3.8     3.6     3.8       0

Нижний правый ноль пришлось добавить, чтобы APPENDPRN не отказывалась дописывать в файл вектор-строку со средними баллами по трём предметам.

Чтобы этот код заработал, нужно выполнение 3 условий:

  • документ MathCAD был хотя бы раз сохранен;
  • текстовый файл data.txt был сохранен в той же папке, что и документ MathCAD;
  • в текстовом файле содержатся только числовые значения, причём, их количество в каждой строке файла одинаково (количество пробелов или табуляций между значениями в одной строке не имеет значения).

 Скачать этот пример в архиве .zip с файлом .xmcd Mathcad 15 и файлом данных (17 Кб)

Что в нашем решении оказалось неудобно? Прежде всего то, что студенты из списка отличаются между собой только по номерам. Можно ли сделать так, чтобы Mathcad читал нормальный текстовый файл с текстом и числами, да ещё и позволял иметь разное количество разделителей в строках и разное количество чисел в одной строке?

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

Функция доступна в Mathcad версии 15

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

Подготовим следующие функции:

  • char(s,i) - извлечение из строки s символа с допустимым номером i;
  • isdiv(s) - проверяет, является ли односимвольная строка s разделителем, то есть, пробелом, табуляцией или переводом строки. Возвращает 0 или 1;
  • trimstr(s) - удаляет лишние разделители в начале, конце строки, а также между лексемами. Возвращает строку из лексем, разделённых одним пробелом.

Функции char и isdiv (Mathcad)
Функции char и isdiv (Mathcad)
Функция trimstr (Mathcad)
Функция trimstr (Mathcad)

Значение системной настройки ORIGIN предполагается равным нулю (по умолчанию), опция Тооls - Worksheet options - Calculations - Use ORIGIN to string indexing не установлена, то есть, строки индексируются всегда с нуля независимо от значения ORIGIN, это тоже принято по умолчанию.

Теперь мы готовы написать функцию, которая парсит матрицу из одного столбца, содержащую записи следующего вида (файл test.txt):

Иванов 3 4 5
Петров 4 4 5

функция parse (Mathcad)
функция parse (Mathcad)

Функция предполагает, что первая из оставшихся после обработки trimstr в очередной строке лексема является строкой, попадающей в массив Names, а остальные лексемы - числовые значения, записываемые в матрицу Balls.

Существенно, что эту функцию не должны смущать не-число в данных Balls (в соответствующую позицию матрицы запишется ноль, см. оператор on error) или разное количество чисел в строке (Mathcad автоматически "расширит" матрицу, заполняя свободные столбцы нулями).

Текстовый файл test.txt сохранён в кодировке Юникод (UTF-8), в этом случае мой новенький Mathcad 15 M045 прочитал символы кириллицы без проблем.

Остаётся проверить, что получилось, а дальше использовать массивы Names и Balls по своему усмотрению, например, как в предыдущей задаче.

тест функции parse (Mathcad)
тест функции parse (Mathcad)

 Скачать этот пример в архиве .zip с файлом .xmcd Mathcad 15 и файлом данных (34 Кб)

P.S. Весь наш длинный код следует рассматривать, конечно, как учебный. Реально мы могли бы, настроив чтение функцией READCSV, решить задачу в 3 строчки кода:

READCSV - короткий код для чтения из файла CSV
READCSV - короткий код для чтения из файла CSV

Файл list.txt содержал лишние разделители, будучи таким:

 Иванов  3  4  5
  Петрова  4  4  5

Если файл сохранён из Блокнота, выбрать при сохранении кодировку Юникод или UTF-8, метка BOM Mathcad'у помешать не должна. Также функцию не смутят "недостающие" числа в данных, в нашем случае она заменит их нулями.

24.03.2016, 14:35 [14977 просмотров]


теги: форматы mathcad

К этой статье пока нет комментариев, Ваш будет первым