Хеш-массивы в Perl

Модератор: Модераторы разделов

Аватара пользователя
greengroon
Сообщения: 119
ОС: Ubuntu 9.04, FreeBSD 7.2

Хеш-массивы в Perl

Сообщение greengroon »

Привет всем я начинающий чайник)
Решил изучать перл. Прочитал небольшой параграф про типы данных и переменных с упражнением в конце. Звучит так:

Предположим, что есть группа слушателей курса по языку Perl, состоящая из 10 человек. В середине курса слушатели сдают промежуточный экзамен, а в конце — выпускную работу. За экзамен и за выпускную работу выставляется оценка по пятибалльной системе. По окончании курса каждый слушатель получает удостоверение, в котором указано, естественно, его имя, а также оценки за экзамен и выпускную работу. Разработайте базу данных слушателей курса, которую можно использовать для автоматизации подготовки удостоверений об успешном окончании курса. (Указание: воспользуйтесь хеш-массивами.)

Сделал такой скрипт

Код: Выделить всё

1 #! /usr/bin/perl -w
      2
      3 %names=(001, "Иванов", 002, "Петров", 003, "Сидоров");
      4 %exam=(001, "ivanovmark", 002, "petrovmark", 003, "sidorovmark");
      5 %finalwork=(001, "ivanovmark", 002, "petrovmark", 003, "sidorovmark");
      6 $ivanov=001;
      7 print $names{$ivanov};
      8

Подозреваю что это неправильно). Тем более что при выполнении выдает ошибки

Код: Выделить всё

Name "main::finalwork" used only once: possible typo at /home/evgeny/script.pl line 5.
Name "main::exam" used only once: possible typo at /home/evgeny/script.pl line 4.

Укажите на ошибку пожалуйста
Какая GNUсная, GNUсная жизнь...
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Хеш-массивы в Perl

Сообщение pcodr »

greengroon писал(а):
03.05.2009 06:57
Подозреваю что это неправильно). Тем более что при выполнении выдает ошибки

Код: Выделить всё

Name "main::finalwork" used only once: possible typo at /home/evgeny/script.pl line 5.
Name "main::exam" used only once: possible typo at /home/evgeny/script.pl line 4.

Укажите на ошибку пожалуйста


Это не ошибки, а предупреждения (warning). Вывелись они потому что переменные %finalwork и %exam вы использовали всего лишь 1 раз в своей программе, о чем и предупреждает вас perl, подозревая что данная ситуация могла возникнуть из-за того что вы описались в имени переменной, что иногда и случается по невнимательности. Также эти предупреждения вывелись, потому, что вы сами попросили perl выдавать их использовав ключ -w при запуске. Достаточно заменить !#/usr/bin/perl -w на !#/usr/bin/perl и предупреждения исчезнут.

Используя более продвинутую технику базу можно описать так:

Код: Выделить всё

%db =    (
        names     => ['Иванов', 'Петров', 'Сидоров'],
        exam      => [3, 5, 2],
        finalwork => [4, 3, 5]
         );


for (0..$#{$db{names}})
{
    print    "Имя:              $db{names}[$_]\n",
             "Экзамен:          $db{exam}[$_]\n",
             "Финальная работа: $db{finalwork}[$_]\n\n";
}
remote system type is unix
Спасибо сказали:
Аватара пользователя
greengroon
Сообщения: 119
ОС: Ubuntu 9.04, FreeBSD 7.2

Re: Хеш-массивы в Perl

Сообщение greengroon »

Спасибо. Поскольку про оператор цикла я еще не читал, то вначале хочу спросить про переменную... ))
Правильно ли я понимаю, что для переменной db вы создали три массива с соответствующими индексами names exam и finalwork?
Объясните пожалуйста назначение квадратных скобок. Насколько я понимаю элементы массива заключаются в круглые скобки.
Если ошибки нет то почему мой скрипт не хочет печатать Иванова с его оценками за экзамен и за конечную работу?
Какая GNUсная, GNUсная жизнь...
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Хеш-массивы в Perl

Сообщение pcodr »

Правильно ли я понимаю, что для переменной db вы создали три массива с соответствующими индексами names exam и finalwork?

Да, в данном случаи переменную %db можно назвать хешем массивов. Хотя names, exam и finalwork не являются индексами массивов, это индексы хеша %db.
Объясните пожалуйста назначение квадратных скобок. Насколько я понимаю элементы массива заключаются в круглые скобки.

Квадратные скобки создают анонимный массив, т.е. такой массив который не ссылается ни на одну переменную. Напротив, именованный массив создается с помощью круглых скобок, т.е так: @a = (1, 2, 3)

Если ошибки нет то почему мой скрипт не хочет печатать Иванова с его оценками за экзамен и за конечную работу?

Ваш скрипт должен напечатать "Иванов", что он успешно и делает, возможно вы не заметили этот вывод т.к. не поставили перенос строки в конце и он слился со строкой приглашения командной оболочки.
remote system type is unix
Спасибо сказали:
Аватара пользователя
greengroon
Сообщения: 119
ОС: Ubuntu 9.04, FreeBSD 7.2

Re: Хеш-массивы в Perl

Сообщение greengroon »

Да действительно не заметил, что иванов слился со строкой. Если учесть, что кроме азов про скаляр, массив и хэш я пока ничего не читал, нормальная ли у меня запись получилась? :)
И еще такой вопрос...
Может строка с номером 6 в моем случае лишняя? И проще вывести Иванова на печать просто

Код: Выделить всё

print $names{001};

?
Какая GNUсная, GNUсная жизнь...
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Хеш-массивы в Perl

Сообщение pcodr »

Если учесть, что кроме азов про скаляр, массив и хэш я пока ничего не читал, нормальная ли у меня запись получилась?


Да нормальная. Как гласит девиз Perl: There's More Than One Way To Do It.

Может строка с номером 6 в моем случае лишняя? И проще вывести Иванова на печать просто

Да, лишняя
remote system type is unix
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Хеш-массивы в Perl

Сообщение diesel »

pcodr писал(а):
03.05.2009 07:48
Используя более продвинутую технику базу можно описать так:

Смотря как это использовать в конечном счете, конечно, но

Код: Выделить всё

'иванов' => ( 3,4)


или

Код: Выделить всё

'иванов' => ( exam => 3, finalmark => 4)


IMHO смотрится логичней.

Код: Выделить всё

      3 %names=(001, "Иванов", 002, "Петров", 003, "Сидоров");
      4 %exam=(001, "ivanovmark", 002, "petrovmark", 003, "sidorovmark");
      5 %finalwork=(001, "ivanovmark", 002, "petrovmark", 003, "sidorovmark");


если Вы храните id в хэше, то остальные два хэша вполне могут быть массивами. Первый же хэш, скорее всего должен строится наоборот, то есть не ID => человек, а человек=>ID. Поскольку искать вы будете там человека, и если отчет составлять, то тоже скорее всего сортировать по именам людей будете.
Спасибо сказали: