Comments 45
Осталось это оформить в виде консольной программы и пользоваться :)
Тоже часто на php делаю повседневные задачи. Вот всегда знал, что программирование мне пригодится.
Тоже часто на php делаю повседневные задачи. Вот всегда знал, что программирование мне пригодится.
РНР довольно удобен в повседневных задачах, в свое время делал дизасм для x86, nes, редактор прошивок для своего телефона, 3d… если надо, потом уже релизил проги на С++, а вот для изучения каких либо файлов, для меня РНР самое то, оч удобно
По-моему Python для прототипирования и мелких скриптов «для себя» более удобен.
Как минимум тем, что не надо окружать код <?php ?> :)
И, да, программу на python можно вызывать как $ ./code, а вот программу на php нужно вызывать как $ php ./code, потому что sh ищет #! в первых символах первой строки, а искать после <? он не догадывается. Маленькое различие, но глаза мозолит.
input = bytearray(open('test.bup', 'rb').read()) start = end = fileno = 0 while True: start = input.find(bytearray([0x4d, 0x54, ...]), start) if start == -1: break end = input.find(bytearray([0xff, 0x2f]), end) open('mid%i.mid' % fno, 'wb').write(bytearray([0x4d, 0x54, ...]) + input[start:end]) fno += 1
Copy Source | Copy HTML
- # Выносим и именуем константы, чтобы в программе не было "магических чисел"
- START_MARK = "\0x4d\0x54..."
- END_MARK = "\0xff\0x2f...."
- FILE_FINALIZE = "\0x4d\0x54\0x68\0x64..."
-
- # Читаем данные, инициализируем счетчик
- input = open('test.bup', 'rb').read()
- fileno = 0
-
- # Пока в input есть нужный нам маркер...
- while START_MARK in input:
- # Определяем границы песни
- start = input.find(START_MARK)
- end = input.find(END_MARK)
-
- # Записываем в файл
- open('mid%i.mid' % fileno, 'wb').write(input[start:end]+FILE_FINALIZE)
-
- # Сдвигаем input на конец записанной песни...
- input = input[end:]
- fileno += 1
По сравнению с исходным PHP файлом, пример на Python:
1) 11 строчек вместо 25 — почти в 2.5 раза лаконичней
2) Нет никаких «забытых разработчиками функций» — в PHP же такая ситуация очень типична и встречается постоянно, если вы отходите в сторону от прямого назначения языка — т.е. от Web-фич.
3) Визуально код чище благодаря отсутствию громадного количества служебных символов, служебной пунктуации и прочего мусора, который облегчает жизнь транслятору, но зумусоривает мозг программисту.
Я не претендую на объективность и не претендую на истинность, а высказываю лишь свое субъективное мнение, с которым вы можете быть согласны, а можете быть не согласны. Я не хочу никого переубеждать, лишь хочу обратить внимание на то, что, на мой взгляд, существуют более простые решения для подобного рода задач.
Чем вообще могут отличаться два разных языка программирования: набором предоставляемых функций, господствующей парадигмой и синтаксисом. Правильно?
Набор функций PHP и Python различен в пользу второго, но в данном примере нас это не сильно волнует, т.к. оба набора достаточны для реализации. Будем считать, что применительно к данной задаче, функционал языка эквивалентен (хотя опять же, в общем случае, это далеко не так).
Что касается синтаксиса, то по моему личному мнению синтаксис Python более чист – нет замусоривающих взгляд конструкций и излишней пунктуации. Вообще здесь, конечно, вы правы – надо рассматривать случай, когда оба куска написаны хорошо. Я буду рад, если вы представите хорошо написанный вариант указанного кода и мы сравним полученное.
Что касается семантики и господствующей парадигмы – в PHP это, в основном, структурное программирование. Да, классы там есть, а в 5.3 и старше – они сделаны на достаточно высоком уровне чтобы ими можно было комфортно и беспроблемно пользоваться. Но стандартная библиотека по-прежнему структурно-ориентирована. Массивы, строки – все это простые типы данных, а не объектов. Для манипуляций с ними нужны внешние, относительно объекта, функции, принимающие ссылку на данные в качестве своего аргумента.
Например strpos(ссылка_на_строку, ссылка_на_подстроку) vs строка.find(подстрока) – казалось бы «какая разница»? ИМХО разница есть и она значительна. Разница в том, что, например, функции по работе со строками предоставляют множество модулей – ядро, mbstring, iconv. С массивами точно так же существует 4 различных сортировки, которые реализованы независимо друг от друга и обладают своими плюсами и минусами. Каждый раз чтобы произвести какую-то операцию, нам нужно осуществить подбор нужной функции, и вспомнить ее особенности. А особенности могут быть весьма нетривиальны: в одном модуле функции принимают данные в первом параметре, в другом – в последнем. Где-то тип возвращаемых данных зависит от передаваемых в функцию флагов. Т.е. в стандартной библиотеке творится достаточно приличный разброд.
Та же функция pack – чтобы найти ее в мануале – нужно достаточно потрудиться, и, видимо, автор ее не нашел потому, что он увидел функцию hexdec и ему в голову не пришло, что аналогичная hexdec-у функция может быть реализована через pack. Да, те, кто по-опытней вспомнят аналогичную фичу C++ и найдут ее там, но вопрос в том, сколько времени они потратят на прототипирование при этом?
ИМХО в Python данная проблема решена лучше, т.к. там, в отличие от PHP, существуют очень четкие Code Conventions, которые обязаны соблюдаться всеми разработчиками. Без их соблюдения код не принимают, даже если он чист, отлажен и идеально быстр. Благодаря этому достигается полное единообразие всей стандартной библиотеки и большого количества сторонних модулей, которые придерживаются этого правила, что существенно сокращает время на обучение новым модулям и разработку.
Фактически это дает возможность программисту не думать о модулях, а думать об алгоритме. А не этого ли мы ждем от хорошего ЯП, господа? :-)
Чем вообще могут отличаться два разных языка программирования: набором предоставляемых функций, господствующей парадигмой и синтаксисом. Правильно?
Набор функций PHP и Python различен в пользу второго, но в данном примере нас это не сильно волнует, т.к. оба набора достаточны для реализации. Будем считать, что применительно к данной задаче, функционал языка эквивалентен (хотя опять же, в общем случае, это далеко не так).
Что касается синтаксиса, то по моему личному мнению синтаксис Python более чист – нет замусоривающих взгляд конструкций и излишней пунктуации. Вообще здесь, конечно, вы правы – надо рассматривать случай, когда оба куска написаны хорошо. Я буду рад, если вы представите хорошо написанный вариант указанного кода и мы сравним полученное.
Что касается семантики и господствующей парадигмы – в PHP это, в основном, структурное программирование. Да, классы там есть, а в 5.3 и старше – они сделаны на достаточно высоком уровне чтобы ими можно было комфортно и беспроблемно пользоваться. Но стандартная библиотека по-прежнему структурно-ориентирована. Массивы, строки – все это простые типы данных, а не объектов. Для манипуляций с ними нужны внешние, относительно объекта, функции, принимающие ссылку на данные в качестве своего аргумента.
Например strpos(ссылка_на_строку, ссылка_на_подстроку) vs строка.find(подстрока) – казалось бы «какая разница»? ИМХО разница есть и она значительна. Разница в том, что, например, функции по работе со строками предоставляют множество модулей – ядро, mbstring, iconv. С массивами точно так же существует 4 различных сортировки, которые реализованы независимо друг от друга и обладают своими плюсами и минусами. Каждый раз чтобы произвести какую-то операцию, нам нужно осуществить подбор нужной функции, и вспомнить ее особенности. А особенности могут быть весьма нетривиальны: в одном модуле функции принимают данные в первом параметре, в другом – в последнем. Где-то тип возвращаемых данных зависит от передаваемых в функцию флагов. Т.е. в стандартной библиотеке творится достаточно приличный разброд.
Та же функция pack – чтобы найти ее в мануале – нужно достаточно потрудиться, и, видимо, автор ее не нашел потому, что он увидел функцию hexdec и ему в голову не пришло, что аналогичная hexdec-у функция может быть реализована через pack. Да, те, кто по-опытней вспомнят аналогичную фичу C++ и найдут ее там, но вопрос в том, сколько времени они потратят на прототипирование при этом?
ИМХО в Python данная проблема решена лучше, т.к. там, в отличие от PHP, существуют очень четкие Code Conventions, которые обязаны соблюдаться всеми разработчиками. Без их соблюдения код не принимают, даже если он чист, отлажен и идеально быстр. Благодаря этому достигается полное единообразие всей стандартной библиотеки и большого количества сторонних модулей, которые придерживаются этого правила, что существенно сокращает время на обучение новым модулям и разработку.
Фактически это дает возможность программисту не думать о модулях, а думать об алгоритме. А не этого ли мы ждем от хорошего ЯП, господа? :-)
> Кто о чем, а alexey_uzhva о питоне.
Ну мы же про него начали:) Не я начал, я лишь поддерживаю разговор;)
Функции типа [:], in, List Comprehensions — это из разряда того, что единожды учится при изучении нового языка. Такие фичи есть в любом языке — что те же доллары перед переменной, что === и тому подобные конструкции.
Конечно, идеально чтобы их было бы по-меньше, но одно дело изучить какой-то небольшой объем вначале и дальше работать свободно, другое дело — когда процесс обучения нужен постоянно. Из ряда языков, на которых мне приходится работать — C#, Java, Python, PHP, C++ (Qt) — в PHP эта проблема выражена ярче всего (в C тоже много такого, но там Qt спасает). Т.е. в процессе работы на PHP надо постоянно следить за порядком параметров, искать функции с далеко не очевидными названиями и следить даже за их написанием, т.к. часть из них написана без "_" в имени, а часть с ним.
> Я замечу, ни в pyqt4 ни в opencv эта проблема не решена и решается она как б-г на душу положит.
Да, тут вы правы. Но тут скорей проблема в том, что и Qt и Python написаны по четким Code Conventions и написаны хорошо и качественно. Но эти конвенции, увы, не сходятся. И потому местами получается ядреный микс, от которого может потянуть на тошноту. Для этого приходится перетягивать GUI в отдельный модуль или пакет.
С другой стороны неизвестно что было бы лучше — оставить чистый код, но заставить людей изучать Qt дважды (с оригинальным написание и без), либо попустится чистотой. Для такой большой библиотеки, возможно, их решение оптимально т.к. позволяет использовать те тысячи готовых в сети примеров на C++ практически без портирования. А вот более мелкие библиотеки надо было бы писать в «питонячьем» синтаксисе.
Ну мы же про него начали:) Не я начал, я лишь поддерживаю разговор;)
Функции типа [:], in, List Comprehensions — это из разряда того, что единожды учится при изучении нового языка. Такие фичи есть в любом языке — что те же доллары перед переменной, что === и тому подобные конструкции.
Конечно, идеально чтобы их было бы по-меньше, но одно дело изучить какой-то небольшой объем вначале и дальше работать свободно, другое дело — когда процесс обучения нужен постоянно. Из ряда языков, на которых мне приходится работать — C#, Java, Python, PHP, C++ (Qt) — в PHP эта проблема выражена ярче всего (в C тоже много такого, но там Qt спасает). Т.е. в процессе работы на PHP надо постоянно следить за порядком параметров, искать функции с далеко не очевидными названиями и следить даже за их написанием, т.к. часть из них написана без "_" в имени, а часть с ним.
> Я замечу, ни в pyqt4 ни в opencv эта проблема не решена и решается она как б-г на душу положит.
Да, тут вы правы. Но тут скорей проблема в том, что и Qt и Python написаны по четким Code Conventions и написаны хорошо и качественно. Но эти конвенции, увы, не сходятся. И потому местами получается ядреный микс, от которого может потянуть на тошноту. Для этого приходится перетягивать GUI в отдельный модуль или пакет.
С другой стороны неизвестно что было бы лучше — оставить чистый код, но заставить людей изучать Qt дважды (с оригинальным написание и без), либо попустится чистотой. Для такой большой библиотеки, возможно, их решение оптимально т.к. позволяет использовать те тысячи готовых в сети примеров на C++ практически без портирования. А вот более мелкие библиотеки надо было бы писать в «питонячьем» синтаксисе.
Ничего личного, чисто субъективное ощущение =) Синтаксис более компактный, куча фишек вроде генераторов и проч., биндинги к Qt и gtk (это к прототипированию) и наконец на нем просто приятно писать =)
Удобен, как правило, тот язык, который лучше знаешь, даже если понимаешь, что тот, которого не знаешь или знаешь плохо для этой задачи объективно лучше :)
Изучаю питон сейчас «для себя», но когда встаёт реальная задача, например, перекодировать пару тысяч файлов «вчера», то мне в разы, а может и на порядки, быстрее её решить на php, поскольку после составления алгоритма останется только «тупое кодирования» с редким подглядыванием функций в мануале (помню что есть такая, но не помню как называется), а на питоне буду лезть в доки после каждого слова (не настолько, конечно, но всё же), а потом пару часов отлавливать какой-нить баг, скажем, из-за того, что в срез [0:5] не входит 6-й символ.
Собственно трудность изучения новых языков «за свой счёт» (а не работодателя :) ) заключается в том, что пока язык не знаешь (прежде всего библиотеки и типовые приёмы; синтаксис в императивных языках, как правило, изучить трудности не представляет), реальные задачи будешь решать очень долго — то будешь тратить время на поиски несуществующей функции/метода, то изобретатать велосипед, реализованный в стандартной библиотеке (о сторонних библиотеках/фреймворках и оптимизации кода вообще не заикаюсь даже). Чтобы решать реальные задачи (с реальными дедлайнами) быстро, нужен опыт, которого на учебных задачах не получишь — замкнутый круг :( Думаю лучший способ — в свободное время переписывать на «новый» язык, проекты уже реализованные на «старом», но, блин, до чего это скучно — чаще всего переписываешь код чуть ли не строка в строку, макрос, кажется, лучше бы справился.
P.S. Упс, что-то пива перепил, многабукв вышло
Изучаю питон сейчас «для себя», но когда встаёт реальная задача, например, перекодировать пару тысяч файлов «вчера», то мне в разы, а может и на порядки, быстрее её решить на php, поскольку после составления алгоритма останется только «тупое кодирования» с редким подглядыванием функций в мануале (помню что есть такая, но не помню как называется), а на питоне буду лезть в доки после каждого слова (не настолько, конечно, но всё же), а потом пару часов отлавливать какой-нить баг, скажем, из-за того, что в срез [0:5] не входит 6-й символ.
Собственно трудность изучения новых языков «за свой счёт» (а не работодателя :) ) заключается в том, что пока язык не знаешь (прежде всего библиотеки и типовые приёмы; синтаксис в императивных языках, как правило, изучить трудности не представляет), реальные задачи будешь решать очень долго — то будешь тратить время на поиски несуществующей функции/метода, то изобретатать велосипед, реализованный в стандартной библиотеке (о сторонних библиотеках/фреймворках и оптимизации кода вообще не заикаюсь даже). Чтобы решать реальные задачи (с реальными дедлайнами) быстро, нужен опыт, которого на учебных задачах не получишь — замкнутый круг :( Думаю лучший способ — в свободное время переписывать на «новый» язык, проекты уже реализованные на «старом», но, блин, до чего это скучно — чаще всего переписываешь код чуть ли не строка в строку, макрос, кажется, лучше бы справился.
P.S. Упс, что-то пива перепил, многабукв вышло
Но разве появившаяся возможнасть написать «боевой» скриптец не отличный способ выучить язык? ;)
Грубо говоря, задание даётся на определённое количества часов/дней, рассчитанного на средний, как минимум, уровень владения, языком (каким, работодателю часто не важно, если он не «спонсирует» изучение нового языка) и просто не успеешь сделать к дедлайну (со всеми вытекающими), если язык только начал изучать и практики нет. Так что остаётся в свободное время переписывать уже готовое на новый язык чисто для получения практики кодирования на нём. Как вариант — сделать с нуля свой проект, типа стартапа (если есть идеи), но скорее всего этот проект уйдёт в «корзину», максимум для портфолио оставить можно будет (главное чтоб не стыдно было код показывать :) ), т. к. с плохой идей всё равно уйдёт в треш, хоть на каком языке пиши, а с хорошей пока напишешь на малознакомом языке, то нишу уже, скорее всего, займут.
Как тут сказали, что лучше знаешь на том и удобней, питон я только недавно начал изучать, и соглашусь довольно гибок, даже при том же чтении из файла.
Перенесите в PHP, кармы хватает
А не долго преобразовывать весь файл в хекс а потом уже искать?
Ну хотя миди файлы маленькие конечно…
Ну хотя миди файлы маленькие конечно…
а кто мешает искать не в хексе, а в бинарнике?
как-то так
$header = base_convert(4d54726b, 16, 2);
strpos($file_content, $header);
Note: This function is binary-safe.© http://php.net/manual/en/function.strpos.php
как-то так
$header = base_convert(4d54726b, 16, 2);
strpos($file_content, $header);
Опять же можно в потоке искать а не грузить весь файл в память. Но midi маленькие, да, так что ниче страшного
Кто-то еще кодит на пхп? Казалось, что все давно перешли на лисп
Извращенство… Снимаю шляпу =)
Мне кажется, что вообще привязывать полноценные языки к какой-то конкретной области неправильно. Я тоже использую perl как для веба, так и для повседневных задач: от обработки данных до сканирования сети на предмет SNMP-агентов, например. Всё ведь зависит от привычек и предпочтений.
вот из-за таких строк как 2-8 я и стал зоофилом — питонопоклонником :)
Зачем вы в hex и обратно гоняете?? Я бы еще мог понять, если бы Вы хранили как байты и искали вхождеия в массив…
Да, а почему file_get_contents не используем, что бы кода побольше написать?
Да, а почему file_get_contents не используем, что бы кода побольше написать?
Сделайте сайт как сервис, позволяющий на входной бэкап-файл получить на выходе midi-файлы. Думаю, ямаховцы будут вам благодарны :)
Изврат:(
hex2bin — PHP-программисты такие велосипедисты. А функция unpack не?
А вот вопрос в тему: есть некоторые ФТП сервера.
Каким образом я могу прочитать с помощью PHP заголовки этих файлов (необходимо для поиска подобных).
Каким образом я могу прочитать с помощью PHP заголовки этих файлов (необходимо для поиска подобных).
PHP 5.4.0 alpha — 1 Added hex2bin() function.
Sign up to leave a comment.
О midi-файлах и о PHP, как инструменте повседневного программирования на живом примере