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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Календарь произвольных дат, разработка фукции вывода календаря 
:(
    Опции темы
vumnik
Дата 5.6.2006, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



 Здравствуйте. У меня есть интересная, на мой взгляд, задача. Нужно разработать функцию или класс позволяющие вывести произвольный набор дат (в текстовый файлик или на консоль)в строчку, примерно вот так.

          январь             февраль                март      июнь
  Пн       9  16  23  30      6  13  20  27        6  13     5  12
  Вт      10  17  24  31      7  14  21  28       7  14      6  13
  Ср      11  18  25       1   8  15  22        1   8           7  14
  Чт      12  19  26       2   9  16  23        2   9           8  15
  Пт      13  20  27       3  10  17  24       3  10          9  16
  Сб  7  14  21  28       4  11  18  25       4  11        10  17
  Вс   8  15  22  29       5  12  19  26       5  12        11

 Интервал дат задаётся в формате: дд:мм:гггг. Для каждого интервала его начало и конец. Изучаю Перл недавно, на уже успел полюбить, поэтому реализую алгоритм на нём. Возникли проблеммы с определением дня недели по дате, встроенной функции не нашёл (если не прав, поправьте), зато набрёл на этом форуме на реализацию такой на паскале. Переделал под себя, работает.

Код

#определение дня недели по дате
sub DayOfWeek {
    ($d, $m, $y) = @_;

    if ($m < 3) {
        $m += 10;
        $y--;
    }
    else { $m -= 2; }

    $cen = div($y,100);
    $yr = $y % 100;

    $dw = (div((26*$m - 2),10) + $d + $yr + div($yr,4) + div($cen,4) - (2*$cen)) % 7;
    if ($dw < 0)        { $DayOfWeek = $dw + 7; }
    else            { $DayOfWeek = $dw;    }
    #буржуйское начало недели меняем на наше
    if ($DayOfWeek == 0)    { $DayOfWeek = 6;    }
    else            { $DayOfWeek -= 1;    }
    
    return $DayOfWeek;
}


 Не нашёл целочисленного деления (div  в паскале). Если кто встречал, ткните носом, ибо слеп. Вот мой вариант.

Код

#Целочисленное деление
sub div {
    ($a, $b)  = @_;

    $c = $a/$b;
    if ($c =~ /\d+(?=\.)/)    { return $&;}
    else            {return $c; }
}


 Осилил функцию, корректно выводящую календарь на один месяц. 

Код

@dow = ('Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс');
#создание и отрисовка календаря
sub calendar {
    my ($d1,$m1,$y1,$d2,$m2,$y2) = @_;
    
    #календарь будем хранить в матрице    
    #в первом столбце будем хранить название дней недели
    for ($j=0; $j<7;$j++) {
        $mas[$j][0] = $dow[$j];
    }
    
    #заполняем матрицу календаря
    $dow = DayOfWeek($d1,$m1,$y1);
    $j = $dow;
    for ($i=1;$i<7;$i++) {
        while ($j < 7) {
            if ($d1<=$d2) {
                $mas[$j++][$i] = $d1++ ;
            } else {
                $mas[$j++][$i] = "";
            }
        }
        $j = 0;
    }

    #вывод календаря в файл
    #printf FILE "%13s\n", $ear{$m1-1}[0];
    for ($i=0;$i<7;$i++) {
        for ($j=0;$j<7;$j++) {
            printf FILE "%4s", $mas[$i][$j],"\t";
        }
        print FILE "\n";
    }
}


 Оставшиеся нерешёнными вопросы:
    1. Как анализировать и выводить больше одного интервала дат.
    2. Хранить ли сформированный календарь всех интервалов в общей матрице, а затем выводить его, или как-то можно выводить по отдельности в строку (как в образце календаря).

 Если кому интересно, подскажите, сам я запутался. 
PM MAIL   Вверх
korob2001
Дата 5.6.2006, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Сейчас уходить нужно, когда вернусь ещё посмотрю. По поводу целочисленного деления, посмотри такой код (пояснения в коментариях):
Код
#!/usr/bin/perl -w
use strict;

# Объявляем две переменные типа double
my($x,$y) = (10.5,2.2);

# Выводим результат деления
print $x / $y . "\n";


# Переключаемся на целочисленную арифметику
use integer;
# Выводим результаты деления тех же операндов
print $x / $y . "\n";
# Отключаем целочисленную арифметику
no integer;


# Выводим результаты деления тех же операндов
print $x / $y . "\n";
 


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Ivan Kolesnikov
Дата 5.6.2006, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 9.3.2005
Где: г. Новокузнецк

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



Привет.
Цитата

Возникли проблеммы с определением дня недели по дате, встроенной функции не нашёл 

Есть такой модуль Date::Calc, так вот в нем есть функция Day_of_Week($year,$month,$day);
И вообще почитай про этот модуль (набири в командной строке perldoc Date::Calc.

Цитата

Не нашёл целочисленного деления (div  в паскале)

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

Теперь о методе решения, я бы вначале сформировал структуру данных, а затем уже писал функцию как ее выводить, например вот такую

Код

$data = [
  {
    number => 0, #номер месяца
    intervals => [
      {
        first_day_week => 1, #день недели 1-го дня интервала
        first_day => 1, #первый день интервала
        last_day => 20 #последний день интервала
      },
      ...
    ]
  },
  {
    ...
  }
  ...
]

Нужно определиться что делать если середина месяца не попадает в интервал, а края (или часть) попадает. Данная структура, удобна при пропуске интервала, если нужно выводить в таком случае весь месяц, то я бы убрал массив интервалов, заменив просто на элементы месяца.
Данную структуру не слишком сложно сформировать, а потом занялся бы отображением, на мой взгляд так проще smile
Но в принципе можно пойти и твоим методом, тогда формируй отдельные матрицы и напиши процедуру их склеивания smile 
--------------------
PM MAIL ICQ   Вверх
nitr
Дата 5.6.2006, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

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



всегда всем в помощь
CPAN
;) 


--------------------
PM   Вверх
vumnik
Дата 5.6.2006, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



korob2001
Интересный вариант! Не нужно, даже, отдельную функцию создавать.

Ivan Kolesnikov
Спасибо, что натолкнул на мысль. О структуре данных я совсем не подумал.  smile Предложенная тобой структура не совсем удобна. Не учитывает перекрывающиеся интервалы и день недели 1-го дня интервала там не к чему, его можно определять при выводе. Но мысль мне понравилась. 
Думаю сделать так: {'год'}{'месяц'}[день_начала_интервала, д...а+1, д...а+2, ..., день_конца_интервала] просто заполнять, просто выводить и проблемм с перекрывающимися интервалами не будет.
 
PM MAIL   Вверх
Ivan Kolesnikov
Дата 6.6.2006, 03:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 9.3.2005
Где: г. Новокузнецк

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



Привет!
vumnik, я просто привык разделять места обработки данных и отображения smile, и поэтому расчитал день недели заранее, чтобы в функции отображения (перевода в массив строк) уже не задумываться о том какой это день недели, нам уже все сказано, только отображай.

Предложенная тобой структура, мне не совсем понятна: что представляет собой массив, как понял я - это просто дни, которые нужно отобразить, тогда тебе придется для каждого дня вычислять его день недели (что по мне очень не оптимально) или писать дополнительный алгоритм проверки какой был предыдущий день. Мне кажется оперировать готовыми интервалами дней удобнее.

Цитата(vumnik @  6.6.2006,  00:51 Найти цитируемый пост)
Предложенная тобой структура не совсем удобна. Не учитывает перекрывающиеся интервалы

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


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

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


 




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


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

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