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 виду

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


читання і запис матриці в Mathcad

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

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

Нижній правий нуль довелося додати, щоб APPENDPRN не відмовлялася дописувати в файл вектор-рядок із середніми балами з трьох предметів.

Щоб цей код заробив, необхідним є дотримання 3 умов:
  • документ MathCAD був хоча б раз збережений;
  • текстовий файл data.txt був збережений в тій же папці, що і документ MathCAD;
  • в текстовому файлі містяться тільки числові значення, причому, їх кількість в кожному рядку файлу однаково (кількість прогалин або табуляцій між значеннями в одному рядку не має значення).

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

Для вирішення такого завдання зручно використовувати панель програмування і функцію READCSV. призначену для читання довільних текстових даних. Функція доступна в Mathcad версії 15

Підготуємо наступні функції:
  • char (s, i) - витяг з рядка s символу з допустимим номером i;
  • isdiv (s) - перевіряє, чи є Односимвольна рядок s роздільником, тобто, прогалиною, табуляцією або перекладом рядка. Повертає 0 або 1;
  • trimstr (s) - видаляє зайві роздільники на початку, наприкінці рядка, а також між лексемами. Повертає рядок з лексем, розділених одним пропуском.


Функції char і isdiv (Mathcad)


Функція trimstr (Mathcad)

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

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


функція parse (Mathcad)

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

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

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

Залишається перевірити, що вийшло, а далі використовувати масиви Names і Balls на свій розсуд, наприклад, як в попередній задачі.


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

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

Mathcad як обробити файл зі змішаними числовими і строковими даними

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

Файл list.txt містив зайві роздільники, будучи таким:

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