Я написал сценарий, который позволяет мне вручную импортировать в Matlab данные, записанные во время тестов.Можно ли избежать `eval()`? (Назначить имя переменной во время выполнения)
Каждый тестовый прогон сохраняет около 2600 переменных в файлах .csv
, каждый из которых имеет две строки заголовка, два столбца данных и ;
является разделителем.
Имена файлов происходят из внутреннего C-структуры, используемой программой мониторинга и, таким образом, такого рода: foo.bar.another.foo.bar.local_varname#VALUE.csv
, и я хочу использовать это, чтобы заново создать структуры в Matlab для того, чтобы сохранить только то, что в test_name.mat
файле ,
Много раз local_varname
имеет длину более 63 символов, поэтому у меня есть некоторые правила подстановки, чтобы сократить имена без сокращения Matlab имен (и поэтому избегайте конфликтов имен).
Это код
clear all
clc
% Main names
path_self = pwd;
backslash_indices = strfind(path_self,'\');
test_name = path_self(backslash_indices(end)+1:end); % the directory name gives me the test_name
% Preallocation
filenames = cell(1,2600);
addresses = cell(1,2600);
i=0;
% Full list
MyFiles = dir(path_self);
% Discard subdirectories and non interesting files
for k=1:length(MyFiles)
if ~MyFiles(k).isdir,
if ~isempty(strfind(MyFiles(k).name,'#VALUE.csv'))
i=i+1;
% Too many files
if i > length(filenames)
filenames = [filenames cell(1,100)];
addresses = [addresses cell(1,100)];
end
% Naming Substitution Rules
%%% INSERT HERE BUNCH OF RULES
% Addresses and names
filenames{i} = strrep(filename,'#VALUE.csv','');
addresses{i} = fullfile(path_self, MyFiles(k).name);
end
end
end
filenames = filenames(1:i);
addresses = addresses(1:i);
% Check that no conflicts are created
if length(filenames) ~= length(unique(filenames))
error('filenames not unique')
end
% Housekeeping #1
clear MyFiles backslash_indices i k path_self
% Import data
for j=1:length(filenames)
% Read data
Data = importdata(addresses{j}, ';', 2);
% Assign data
eval([filenames{j}, '.time = Data.data(:,1)./1000000;']); % Converted in seconds
eval([filenames{j}, '.values = Data.data(:,2);']);
% Let's avoid data corruption
clear Data
end
% Housekeeping #2
clear filenames addresses j
% Save data struct
save(test_name, '-regexp', '^((?!name).)*$')
Теперь мой вопрос При исследовании информации и помочь написать код выше я часто люди хмуро на использовании eval()
: почему это так? В приведенной выше ситуации я могу избежать этого?
Благодаря
EDIT Как было предложено @wakjah, я испытал containers.Map()
подход. К сожалению, это не подходит для наших нужд, так как в этот момент необходим список ключей, и доступ к данным не совсем дружественный (помните, что у меня есть ~ 2600 переменных, что означает, по крайней мере, то же количество ключей)
Что касается то, что задал @Dennis Jaheruddin, структура данных применима и не создает каких-либо конфликтов даже с этими длинными именами (при условии, что каждое имя * между двумя последовательными .
имеет длину менее 63 символов)
* мои извинения за неиспользование лучшего технического термина
К сожалению, это решение создает проблему другого типа: предел 63 символов наложен на полные 'filenames {j}' (в некоторых случаях это до 180 символов), а с 'eval()' мне нужно заботиться только о 'local_varname'. Кроме того, он возвращает ошибку, если 'filenames {j}' содержит '.' (всегда для меня случай) – Federico
Как этого избежать с помощью' eval'? Я просто попробовал - MATLAB выдает предупреждение, выполняете ли вы это с помощью 'eval' или нет, когда ваше имя поля длиннее 63 символов. Возможно, я вас не понимаю ... Во всяком случае, если вам действительно нужны имена полей, которые вы долгое время рассматривали с помощью ['container.Map'] (http://www.mathworks.co.uk/help/matlab/map- containers.html)? – wakjah
Пример: 'имена файлов {1} = ABCDE.ABC0.ABCDE.ABC_AA_AA_AAA_00.BBB_BBB_00_BBB_CCCC_ABCDE_ABCDEFGHIJKLMNO_AAAA0.A_ABCDE_CCC_DDDD_EEEEE_AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD00_DDDD0' (153 символа длина) С' Eval() ', если сжать последнюю часть (теперь 71 обугленной длиной) до менее чем 63 chars, у меня нет проблем, с вами код 1) У меня есть ошибка для '.'s и 2), он жалуется, что' filenames {1} 'слишком длинный – Federico