Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> попытка создать телефонный справочник, perl телефонный справочник 
:(
    Опции темы
tooncheg
Дата 20.5.2013, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Необходимо было изучить perl. Первоначально прочитал Рендала Шварца 5 издание и решил для тренировке создать тел. справочник. Создан файл текстовый БД вида:

Сидоров Самуил Виторганович::5533::113::Бухгалтерия
Петров Лев Игнатьевич::5322::114::Кадров
Иванов Иван Иванович::5322::119::56

Параметры предполагалось заводить через веб форму

Код

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head><title>ФОРМА</title></head>
<body>
<h2>Заполните форму для поиска</h2>
<br>
<form method="get" action="http://site.ru/perl/form_temp.pl">
<pre>
Введите имя: <input type="text" name="name">
Введите фамилию: <input type="text" name="surname">
Введите отчество: <input type="text" name="patronymic">
Введите отдел: <input type="text" name="department">
Введите комнату: <input type="text" name="room">
Введите телефон: <input type="text" name="phone">
<input type=submit value=Поиск>
</form>
<body>
<html>



Задавал вопросы на схожем форуме, но в итоге все пришло к полной неразберихе. Вообщем если начать с чистого листа. Можете ли дать советы как может быть реализован поиск по БД. 
 
PM MAIL   Вверх
arto
Дата 20.5.2013, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



читать и сравнивать.
PM MAIL ICQ   Вверх
tooncheg
Дата 20.5.2013, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Цитата(arto @ 20.5.2013,  16:23)
читать и сравнивать.

В том и дело алгоритм сравнения меня и ввел в тупик.
Вот например:

Код

if (($phone =~ m/@{[param('phone')]}/) && ($room =~ m/@{[param('room')]}/)) {
  say "Фамилия: $name, Телефон: $phone Комната: $room <BR>" ;}
}


это кусок чернового варианта. что тут получается, если равны левые и правая часть, то условие выполнится, а если я в форме ввел только номер телефона, то условие не должно выполняться (на самом деле у меня происходит поиск, по одному параметру из формы, но выводится только первое совпадение из БД).
Именно так как вы предложили я и пытался решить задачу, но алгоритм сравнения оказался не так прост для меня.
PM MAIL   Вверх
arto
Дата 20.5.2013, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



а как надо? если не введен параметр, то как надо поступать?
PM MAIL ICQ   Вверх
vadiml
Дата 20.5.2013, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 27.7.2007

Репутация: 5
Всего: 7



Если задание отсюда https://www.reg.ru/company/jobs/testtask-prog
то там надо написать используя Catalyst, а не просто голый perl.
PM MAIL Jabber   Вверх
tooncheg
Дата 21.5.2013, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Цитата(arto @ 20.5.2013,  17:23)
а как надо? если не введен параметр, то как надо поступать?

Я читал строки так

Код

......
open my $fh, '<', 'phone.txt' or die "Error open phone.txt: $!\n";
while (<$fh>) {
  chomp;
  my ($name,$phone,$room, $otdel) = split /::/, $_;
.....


далее как тут советовали сравнивать. но вот тут как раз то и становится не ясно как это осуществить.

Код

if (($phone =~ m/@{[param('phone')]}/) && ($room =~ m/@{[param('room')]}/))

Операция поиска совпадения по шаблону в левой части - допустим true. Операция поиска совпадения по шаблону в правой части, параметр в форме не был введен - false. Условие же не выполнится. Или я недопонимаю что-то.
Я не знаю как надо поступать. Прочитать строки и сравнить, если это можно реализовать, то как это сделать.

PM MAIL   Вверх
arto
Дата 21.5.2013, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



прочитать поля в хеш (для удобства), затем

map { $_ => exists $hash{$_} && param($_) eq $hash{$_} } param()

получите хеш результатов сравнений существующих параметров (вместо eq можно взять регекс).
далее обрабатываете как вам удобно (предполагается, что param() -- функция из CGI* модулей).

А еще проще -- использовать какой-либо из валидаторов, типа Data::FormValidator
PM MAIL ICQ   Вверх
tooncheg
Дата 24.5.2013, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Цитата(arto @ 21.5.2013,  09:24)
прочитать поля в хеш (для удобства)

 У меня есть пару вопросов по поводу как занести данные в хэш .

я изменил текстовую БД 

1::Сидоров::Самуил::Виторганович::5533::113::Бухгалтерия
2::Петров::Лев::Игнатьевич::5322::114::Кадров
3::Иванов::Иван::Иванович::5322::119::56
 
потом читаю строки так

Код

while (<$fh>) {
  chomp;
  my ($number,$surname,$name,$patronymic,$phone,$room, $otdel) = split /::/, $_;
  %hoh = ($number => {
    'name' => $name,
    'surname' => $surname,
    'patronymic' => $patronymic,
     ........
         },
     
);
}
close $fh;


Но в результате хэш заполняется только последней строкой, т.е. в хэше содержится только последняя строка 3::Иванов::Иван::Иванович::5322::119::56
И вообще правильно ли я Вас понял, как надо прочитать поля в хэш?
PM MAIL   Вверх
alezzz
Дата 24.5.2013, 12:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



Код

use strict;

my %hoh;
while (<DATA>){
    chomp;
    my ($number,$surname,$name,$patronymic,$phone,$room, $otdel) = split /::/, $_;
    $hoh{$number} =  {
        'name' => $name,
        'surname' => $surname,
        'patronymic' => $patronymic
    };
}

use Data::Dumper;
print Dumper %hoh;

__DATA__
1::Сидоров::Самуил::Виторганович::5533::113::Бухгалтерия
2::Петров::Лев::Игнатьевич::5322::114::Кадров
3::Иванов::Иван::Иванович::5322::119::56

PM MAIL   Вверх
tooncheg
Дата 28.5.2013, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Я извиняюсь. Просто потратил кучу времени, а справочник создать не получается даже после совета arto.

Код

#!/usr/bin/perl -w
#use strict;
use utf8::all;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:param/;

 
print "Content-type: text/html; charset=utf-8 \n\n";
open my $fh, '<', 'phone.txt' or die "Error open phone.txt: $!\n";
while (<$fh>) {
  chomp;
  my ($number,$surname,$name,$patronymic,$phone,$room, $otdel) = split /::/, $_;
  $hoh{$number} = {
    'name' => $name,
    'surname' => $surname,
    'patronymic' => $patronymic,
    'phone' => $phone,
    'room' => $room,
    'otdel' => $otdel,
     }
}
%hoh_form = (
    'name' => param ('name'),
    'surname' => param ('surname'),
    'patronymic' => param ('patronymic'),
    'phone' => param ('phone'),
    'room' => param ('room'),
    'otdel' => param ('otdel'),
    );

?????????????????????????????????

close $fh;


Как реализовать сравнение введенного из формы и записанного в ХЭШ, и записанного в ХЭШ из текстового файла. Например, если в форме вводились данные номер телефона и фамилия с кем связан этот телефон, то выводились данные конкретного человека. 
Заранее спасибо.
PM MAIL   Вверх
arto
Дата 28.5.2013, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



map { ( $form{$_} || "" ) eq ( $file{$_} || "" ) } keys %form
PM MAIL ICQ   Вверх
ginnie
Дата 28.5.2013, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



tooncheg, напишите, как Вы представляете поиск, т.е. что вводится в поля и что должно быть выведено в качестве результата поиска (нужны примеры).


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
tooncheg
Дата 28.5.2013, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



Цитата(ginnie @ 28.5.2013,  12:37)
tooncheg, напишите, как Вы представляете поиск, т.е. что вводится в поля и что должно быть выведено в качестве результата поиска (нужны примеры).

Самая простая форма. 6-ть полей куда вносятся данные для поиска Имя,Фамилия,Отчество,Отдел,Комната,Телефон. 

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head><title>ФОРМА</title></head>
<body>
<h2>Заполните форму для поиска</h2>
<br>
<form method="get" action="http://site.ru/perl/form_temp.pl">
<pre>
Введите имя: <input type="text" name="name">
Введите фамилию: <input type="text" name="surname">
Введите отчество: <input type="text" name="patronymic">
Введите отдел: <input type="text" name="department">
Введите комнату: <input type="text" name="room">
Введите телефон: <input type="text" name="phone">
<input type=submit value=Поиск>
</form>
<body>
<html>

Данные передаются в скрипт form_temp.pl , модуль CGI помогает принять значения.
В поля вводятся либо остаются пустыми ИМЯ ФАМИЛИЯ ОТЧЕСТВО ОТДЕЛ КОМНАТА ТЕЛЕФОН. Например ввод ИМЕНИ ТЕЛЕФОНА ОТДЕЛА далее сравнение по текстовой БД и вывод ФАМИЛИИ ИМЕНИ ОТЧЕСТВА ТЕЛЕФОНА...я представляю это типа  выборки по введенным параметрам, но как сделать не знаю. 

PM MAIL   Вверх
ginnie
Дата 28.5.2013, 16:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



tooncheg, вот мой вариант без CGI и для текста в кодировке cp1251:

Код

#!/usr/bin/perl

use strict;
use warnings;

use locale;
use POSIX qw(:locale_h);

setlocale(LC_ALL, "ru_RU.CP1251");

my %directory;
while (<DATA>){
    chomp;
    my ($number,$surname,$name,$patronymic,$phone,$room, $otdel) = split /::/, $_;
    my $person =  {
        name => $name,
        surname => $surname,
        patronymic => $patronymic,
        phone => $phone,
        room => $room,
        otdel => $otdel,
    };
    $directory{number}{$number} = $person;
    while (my ($key, $value) = each %{$person}) {
        next if (!defined $value or $value eq '');
        push(@{$directory{$key}{lc $value}}, $number);
    }
}

my %query = (
#    surname => 'петров',
    phone => '5322',
);

my $round = 0;
my %results;
while (my ($key, $value) = each %query) {
    next if (!defined $value or $value eq '');
    $round++;
    my $numbers = $directory{$key}{lc $value} or next;
    for my $number (@{$numbers}) {
        $results{$number}++;
    }
}

while (my ($number, $counter) = each %results) {
    print join('::', @{$directory{number}{$number}}{qw{surname name patronymic phone room otdel}}), $/ if ($counter == $round);
}


__DATA__
1::Сидоров::Самуил::Виторганович::5533::113::Бухгалтерия
2::Петров::Лев::Игнатьевич::5322::114::Кадров
3::Иванов::Иван::Иванович::5322::119::56


Это сообщение отредактировал(а) ginnie - 28.5.2013, 17:19


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
tooncheg
Дата 30.5.2013, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 20.5.2013

Репутация: нет
Всего: нет



ginnie

Мне не очень понятны несколько строк

Код

$directory{number}{$number} = $person;


$person если его вывести на экран, то это будут ссылки на то где хранится в памяти хэш. Что в реальности происходит тут? Еще не понял для чего нужен  еще {number}.  

Код

push(@{$directory{$key}{lc $value}}, $number);


Что происходит тут?

Прошу отнестись снисходительно, т.к. я только учусь. Заранее спасибо.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0890 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.