October 23, 2005
Задачи 1 & 2 - скаларни данни и списъци
За тези, които искат предварително да видят с какви глупости, ужаси или просто задачи ще ви занимавам на упражненията в следващите един-два вторника — хвърлете един поглед на задачите от миналата година: скаларни данни и списъци. В задачите за списъци има малко повече неща от това, за което сме говорили досега на лекции - сборете каквото можете :)
November 19, 2004
Задачи 3: Файлове, директории, функции, references
Това е третият комплект задачи, към лекциите за работа с файлове, функции и references. Някои от тези задачи ще разгледаме на упражнението в понеделник, 22 ноември.
Този път задачите са малко по-практически ориентирани - в тази и следващите серии задачи постеменно ще се доближаваме до създаване на прост архиватор. Ако четете това на главната страница на сайта, изберете "Още от..." по-долу, за да видите самите задачи.
Задача 1: Създаване на директория и "родителите" й
Да се напише функция safe_mkdir($), която приема като параметър път към директория и, ако тя не съществува, я създава, като създава и по-горните директории, ако и те не съществуват. Така, ако имаме празна директория perl, то safe_mkdir("perl/files/slides") ще създаде и perl/files, и perl/files/slides. Функцията трябва да върне истинна стойност, ако директориите са създадени успешно или вече са съществували, и неистина, ако е възникнала някаква грешка в процеса на създаване.
При анализа на подадения път към директория и разделянето му на по-горни директории в тази задача предполагаме, че различните компоненти (директории) от името са разделени с наклонена черта - "/". Ако в пътя има две или повече наклонени черти една след друга, те трябва да бъдат игнорирани (perl/files//slides е еквивалентно на perl/files/slides). Ако пътят завършва с наклонена черта, тя също трябва да бъде игнорирана (perl/files/slides/ е еквивалентно на perl///files/slides).
Задача 2: Изчитане на дърво от файлове и директории в паметта
Да се създадат функции mem_store_dir($ $) и mem_store_file($ $), които обхождат дърво от файлове и директории и запазват информация за него в структура от данни в паметта - хеш с ключове имената на файлове/директории в определена директория. За всеки файл трябва да се запазят първите три реда (или по-малко, ако няма три) в анонимен масив, а за всяка директория - също такъв хеш с ключове имена на файлове и директории, съдържащ информация за нея и за поддиректориите й.
-
mem_store_file SELF, FILEPATH
Прочита първите три реда от файл, пътят към който е зададен във FILEPATH. При успешно изпълнение връща reference към масив, съдържащ прочетените редове. При неуспех записва съобщение за грешка в стойността с ключ 'error' на хеша, reference към който е подаден в SELF, и връща като резултат недефинираната стойност.
Така, ако имаме хеш %self = () и изпълним $file = mem_store_file(\%self, "files/examples/examples.0.html"), то резултатът ще бъде едно от следните:
- ако всичко е наред, $file ще е reference към масив, в който са записани първите до три реда от файла files/examples/examples.0.html;
- ако нещо не е наред, $file няма да бъде дефиниран, а $self{'error'} ще съдържа съобщение за грешка.
-
mem_store_dir SELF, DIRNAME
Изчита съдържанието на директория, пътят към която е зададен в DIRNAME, и връща reference към хеш с ключове имената на файловете и поддиректориите на дадената директория (само тези, които се намират пряко в нея, не в нейните поддиректории):
- за всеки файл, стойността на елемента е reference към масив, съдържат първите до три реда от файла;
- за всяка директория, стойността на елемента е reference към хеш, съдържат информация за съдържанието й в същия формат;
- всеки елемент от директорията, който не е нито файл, нито поддиректория, се игнорира.
Ако изчитането на съдържанието на директорията и нейните поддиректории е било успешно, mem_store_dir() връща reference към гореописания хеш. Ако е възникнала някаква грешка, функцията записва подходящо съобщение в елемента 'error' на хеша, reference към който е подаден в SELF, и връща като резултат недефинираната стойност.
Възможен резултат от успешното изпълнение на $dir = mem_store_dir("files") би могло да бъде:
$dir = { 'examples' => { 'example.0.html' => [ "<html>\n", " <head>\n", " <title>Example 0</title>\n" ], "example.1.html" => [ "<html>\n", "</html>\n" ] }, 'README' => [ "This is the files/ directory.\n", "It contains various files pertaining to the Practical Perl Programming\n", "course - some examples, some slides, and so on.\n" ], "emptydir" => { } };
Задача 3: Запазване на дърво от директории и файлове във файл
Да се създадат функции store_file($ $ $) и store_dir($ $ $), които извеждат на стандартния изход информация за прочетените от mem_store_file() и mem_store_dir() в определен формат. При успешно обхождане на подадените данни функциите връщат истинна стойност, а при неуспешно - връщат недефинираната стойност и поставят подходящо съобщение за грешка в елемента 'error' на хеша, reference към който е подаден като първи параметър.
-
store_file SELF, FILENAME, FILEREF
Обработва масива, създаден от mem_store_file(), reference към който е подаден във FILEREF. Името на файла е подадено във FILENAME. Функцията извежда на стандартния изход информация за името на файла и прочетените от него редове в следния формат:
FILE numlines filename First line Second line Third line END FILE
В изхода numlines се замества с число, показващо колко реда са прочетени от файла, filename се замества с името на файла, след което на отделни редове се записват прочетените от файла редове, като всеки от тях задължително завършва със символ за нов ред. След последния ред се извежда един ред, съдържащ END FILE.
-
store_dir SELF, DIRNAME, DIRREF
Обработва хеша, създаден от mem_store_dir(), reference към който е подаден в DIRREF. В DIRNAME е името на директорията. Функцията извежда на стандартния изход информация за директорията в следния формат:
DIR numentries dirname first entry second entry ... last entry END DIR
В изхода numentries е броят на файлове и поддиректории в тази директория, а dirname е името на директорията. След началния ред се извежда информация за всеки елемент от директорията (всеки елемент от подадения хеш DIRREF) чрез извикване или на store_file(), или на store_dir().
Възможен резултат от извикване на store_dir(\%self, "files", $dir); е:
DIR 3 files DIR 2 examples FILE 3 example.0.html <html> <head> <title>Example 0</title> END FILE FILE 2 example.1.html <html> </html> END FILE END DIR FILE 3 README This is the files/ directory. It contains various files pertaining to the Practical Perl Programming course - some examples, some slides, and so on. END FILE DIR 0 emptydir END DIR END DIR
November 04, 2004
Задачи 2: Списъци, хешове, цикли, условни конструкции
Ето и вторият комплект задачи към лекции 3, 4 и 5 - някои от тях ще разгледаме на упражнението в понеделник. Ако четете това на главната страница на сайта, изберете "Още от..." по-долу, за да видите самите задачи.
Както и при първия комплект, в задачите, където е дадено началото на програмата и там са дефинирани променливи и са им дадени стойности, целта е да допишете програмата така, че тя да работи правилно дори и след като променим тези стойности.
Зад. 1 - Числа
#!/usr/bin/perl @numbers = (1, -4, 2, 8, -5, -7, 25, 12, -103);
Да се довърши горната програма така, че да извежда на един ред, разделени със запетаи числата от масива @numbers, които:
а) са положителни;
б) са отрицателни;
в) не дават остатък 2 при делене на 3;
г) първо положителните в реда, в който са в масива, а след тях - отрицателните в ред, обратен на този, в който са изредени в масива.
Зад. 2 - Напред-назад...
#!/usr/bin/perl @words = qw/mumble frotz bob tenet ant tna rotator elbmum sirius suiris noon ztorf/;
Да се довърши горната програма така, че да извежда на един ред, разделени със запетаи, тези думи от масива @words, които:
а) съвпадат с резултата от обръщането си отзад напред (палиндроми);
б) съвпадат с резултата от обръщането на предходната дума;
в) съвпадат с резултата от обръщането на която и да е от предходните думи.
Зад. 3 - Прости числа
#!/usr/bin/perl
sub read_line()
{
return <>;
}
Дадена е функцията read_line(), която не приема параметри, чете един ред от стандартния вход и връща като резултат прочетения ред в случай на успех (запазвайки символа за нов ред накрая) и недефинираната стойност в случай на неуспех. Да се напише програма, която третира всеки прочетен ред като число и извежда 'Yes', ако то е неотрицателно и просто, а в противен случай не извежда нищо.
Зад. 4 - Оценки
Използвайки функцията read_line() от задача 3, напишете програма, която чете от стандартния вход информация за оценките на студенти и извежда за всеки от тях факултетния му номер, средното аритметично на всичките му оценки с точност до два знака, закръглено надолу, и името на курса, по който студентът е получил най-високата си оценка. Ако има няколко курса с една и съща оценка, да бъде изведено името на първия срещнат във входните данни. Изходните данни трябва да бъдат подредени по нарастващ ред на факултетните номера.
Информацията за студентите ще бъде подадена във вида:
40001 6 Практическо програмиране с Perl 40010 5 Дискретна математика 40003 5 Практическо програмиране с Perl 40001 3 Мрежова сигурност 40003 4 Изкуствен интелект 40002 6 Компютърна графика 40001 6 Програмиране с .NET Framework
Резултатът от програмата трябва да изглежда така:
40001 5.00 Практическо програмиране с Perl 40002 6.00 Компютърна графика 40003 4.50 Практическо програмиране с Perl 40010 5.00 Дискретна математика
October 14, 2004
Задачи 1: Скаларни данни
Това са задачки към лекциите за скаларни данни (лекции 1 и 2). Вижте дали можете да измислите нещо по тях; това ще правим на упражнението в понеделник, 18 октомври. Ако четете това на главната страница на сайта, изберете "Още от...", за да видите пълния текст на задачите.
Обновено: 14 октомври, 20:20 - уточнения по първа и четвърта задачки.
В задачите, където е дадено началото на програмата и там са дефинирани променливи и са им дадени стойности, целта е да допишете програмата така, че тя да работи правилно дори и след като променим тези стойности - решения като безусловно извеждане на 1, 1, 2, 3 за първата задача не се приемат :)
Зад. 1 - Фибоначи
#!/usr/bin/perl -w $n1 = 1; $n2 = 1;
Това е началото на програма на Perl. $n1 и $n2 са първите две числа в редица от типа на тази на Фибоначи - всеки член от третия нататък е сумата от предходните два. Допишете я така, че да изчислява следващите две и да извежда четирите на стандартния изход.
Зад. 2 - Телефонни номера
#!/usr/bin/perl -w $num1='+359888123456'; $num2='+359887192919'; $num3='+359886112233'; $num4='+359889112255';
Четирите низа съдържат телефонни номера в опростения международен формат, без скоби, тирета, интервали и т.н. Допишете програмата така, че да извежда четирите номера в формат "Код: CC Номер: XXX-XXXX", където CC е двуцифреният код на оператора, а XXX-XXXX - седемцифреният номер.
Зад. 3 - Още телефонни номера
Променете програмата от зад. 2 така, че да може един или повече от номерата да са зададени в още по-съкратения формат '0887112233'. Да, това наистина може да бъде направено без използване на условни оператори (if, unless, while и т.н.), по поне два различни начина - един е достатъчен :)
Зад. 4 - Хазарт ;)
Използвайки функцията rand(), напишете програма, която симулира хвърляне на два шестстенни зара и извежда на стандартния изход:
- получените числа;
- сумата им;
- получените числа, повдигнати на втора степен.