| http://lukeplant.me.uk/blog.php?id=1107301645
Позабавило :) Примерно подводит черту под моими отношениями с С++ после знакомства с Питоном. Может бросить хаскель пока не поздно? :)
P.S. Ощущаю всё больший этический и эстетический протест против лживых и подлых нападок на stateful-системы. Что такое алгебраические типы данных? Исходя из того, что я понял, с практической точки зрения это и есть механизм автоматического обеспечения внутренней целостности и непротиворечивости системы с состоянием. Могу предположить, что теория может быть развита далее, до автоматического обеспечения непротиворечивости и целости сложных изменяемых объектно-оринетированных систем, а собственно высокоуровневые «методы» будут прикручиваться уже сверху на полученный костяк. Технологически, часть этого уже реализована в Хаскеле. Причем, подозреваю, большая часть. Идеология объединения данных и мехнизмов их обработки, суть ООП - великое достижение, и принципиальная подверженность получающихся сложных систем ошибкам, как мне кажется, вовсе не вина подхода и уж точно не аргумент в пользу функционального стиля («битый небитого везёт», выезжать на спине других - нехорошо), а всего лишь индикатор несовершенства теоретический и технологической базы.
Всё-таки многие системы для человеческой мысли гораздо удобнее представлять в виде асинхронных сущностей с состоянием и методами, чем в виде деревьев вызова чистых функций. Именно это и стало причиной появления и формулировки данной проблемы. Будь нам функциональная парадигма ближе, этой проблемы бы даже не появилось. | comments: 30 комментариев or Оставить комментарий  |
| оказался проще, чем мы думали:
import threading
import wx.lib.newevent
MakeEvent01, wx.EVENT01 = wx.lib.newevent.NewEvent()
class widget1(wx.SomeWidget):
def async_report(self, s):
event = MakeEvent01()
event.text = s
wx.PostEvent(self, event)
def __init__(self, parent, **kwargs):
wx.SomeWidget.__init__(self, parent, wx.ID_ANY, **kwargs)
def AssignJob(self,do_stuff):
do_stuff_frozen = functools.partial(do_stuff, async_report)
self.t = threading.Thread(target=do_stuff_frozen)
self.Bind(wx.EVENT01, self.Event01Handler)
self.t.start()
def Event01Handler(self, evt)
self.Display(evt.text)
Этому добру кормим любую функцию вида DoSomeLongAndHeavyStuff(log) и радуемся жизни. Интересно, можно ли ещё проще. | comments: 5 комментариев or Оставить комментарий  |
| Черезвычайно интересно. Оказывается, существуют средства, позволяющие допилить работу с SQL в питоне до немного похожей парадигмы. Из имен я нашел Dejavu, Geniusql и SqlSoup (SQLAlchemy). Причем два последних предоставляют синтаксис, по ясности не уступающий интегрированному в язык псевдо-sql, причем оба умеют превращать вызовы методов и лямбды во вполне неиллюзорные sql-запросы (т.е. это обертки для, а не эмуляторы sql). Единственная ключевая продажная точка у LINQ (кроме, конечно же, нашего любимого идола Синтаксического Сахарозного Диабета) — он представляет из себя универсальную унифицированную архитектуру преобразования запросов в AST предметной области, к которой легким движением руки навинчиваются нужные реализации для чего угодно. Теоретически, можно создать нечто подобное для питона на базе существующих элементных деревьев, супов и прочего добра для XML, но работы там непочатый край. И вопрос синтаксической сахарозы вовсе не так пренебрежим, как кажется: не всех радует вручную передавать лямбды генераторным выражениям (Geniusql), кто-то просто вернется к старым добрым функциям (SqlSoup), и не будет никакой единой инфраструктуры.
Вообще, чувствую, в конце времен придут к идее добавить в питон явную статическую типизацию. Этот момент будет началом сингулярности.
P.S. Хм. Судя по вот этой дискуссии, я не точно не превый, кто догадался расширить питон (лол), но по однострочному ответу на неё (о содержимом можно догадаться, не кликая на ссылку), ожидать чего-либо интересного от питона в этой конкретной области не приходится. Кстати, я потрясен: я думал, Питон реализует первоклассные объекты кода (полностью согласен насчет Лиспа с тем оратором :). Использовать чёрную магию и грязные хаки типа разборки байткода для решения в сущности примитивной задачи - это подозрительно похоже на знак старения языка и сообщества вокруг него.
P.S. Лол батарейка в рабочем компе садится, записи оказываются отправленными в прошлое =) | comments: 2 комментария or Оставить комментарий  |
| если я передаю метод класса куда-то далеко, то self для него фиксируется неявно и доступен, хотя при вызове ни слева, ни в аргументах этого объекта нет. Тогда, спрашивается, зачем было вообще с явной передачей this огород городить... | comments: 2 комментария or Оставить комментарий  |
| Проблема в разделении. С одной тсороны, суровое и серъёзное отношение питона к типу информации в строках более чем оправдано. Мы хотим быть уверены, что наши алгоритмы обрабатывают строки корректно, и что в каждый конкретный момент времени тсрока гарантирует осмысленность своего содержимого и возможность его интерпретации. С другой, вывод в консоль, исторически используемый для дебага, а в гуевых программах - исключительно для сбрасывания дебаг-мусора. И требования к этому практически нулевые, более того, что это за дебаг, если он наоборот вызывает баги? Но разделить их с точки зрения грамматики-то уже невозможно. Кто поределит, является ли данный вызов str() фрагментом гениального алгоритма или участвует в очередном print "%s" ? Технологически, это можно было бы сделать, оставив особый грамматический статус print как инструкции и вызывая в пределах её действия прощающую версию str(). Звучит как ересь, однако, до сих пор скользкие религиозные вопросы не мешали питону быть фактически эталоном прагматизма. В случае с print же, как мне лично кажется, идеологический маразм перевесил разумные соображения. Каков смысл делать print функцией? Четкой мотивации ни от Гвидо, ни от кого-либо ещё лично я не видел. Унификация ради унификаци? О какой унификации может идти речь, если эта консоль работает по-своему (по-своему криво) на каждой из платформ? Или что, кто-то и вправду использует перенаправление вывода print? смешно же. | comments: Оставить комментарий  |
| я уже потерял счет ПО на питоне, умирающему со словами print "launch successful! %s" %path Убил бы. Улучшит ли эту ситуацию депрекация print в пользу print()? Вряд ли. Сама идея типизированного вывода порочна. А консольный ио развратил людей, они слишком привыкли швырять в stdout что ни попадя :(
Posted via mobilebloger | comments: 2 комментария or Оставить комментарий  |
| | Интересно, насколько недырява абстракция генераторов? Приемлемо ли использовать генераторы в 2.5 как процедуры с сохранением состояния в общем случае - допустим, может ли метод гуевого класса использовать yield? | comments: 7 комментариев or Оставить комментарий  |
| Все мы помним, какая хорошая это идея — архитектура Model-View и её вариации, и какое дикое количество геморроя она вызывает на практике. Связано это с тем, что она никак принципиально не решает проблему переплетения кода модели и кода представления, не убирает этот беспорядок, а всего лишь дает возможность в нем ориентироваться. На гордое звание решения могут претендовать лишь инструменты, избавляющие нас от хаоса. Об разделении business-кода и интерфейсов много говорили, и иногда по делу, но в итоге все сводилось к вписыванию кода в обработчики событий и бесчиаленные вызовы TextCtrl1.GetText(). Просто вместо хардкода последовательности инициализации интерфейсов хранились в отдельных файлах и представлялись в виде xml — этакий психологичеcкий трюк, чтоб относиться к ним, как данным. И если для компилируемых языков это было критично, то для, скажем, Питона уже никакой разницы между трансляцией xml-файла в интерфейсный код и собственно подгрузкой и непосредственным исполнением файла с уже имеющимся интерфейсным кодом в принципе не существует.
Эти жалкие полумеры меня не могли радовать. Идеальная система, как я её себе воображал, выглядела примерно так: берется алгоритм, где все инструкции вида print(x) или Label.SetText(x) убираются, а вместо них в начале ставятся, «watch(x) as Label»; а всякие словоблудия типа TextCtrl.GetText(s) заменяются на «reflect(s) as TextCtrl». Странные термины были выбраны специально, чтобы подчеркнуть декларативность стиля, вневременность и внеконтекстность связей: мы, Человек, должны только высказать, что хотим отображать переменную или знать значение текстбокса, а остальное - проблемы роботов.
Оказалось, что похожая штука существует: http://avc.inrim.it/ Именно (почти) об этом я мечтал. Это, товарищи, потрясающе. Эта штука автоматически связывает извлекаемые из ресурсов гуи и переменные в коде. Но мало того, по сути дела это ещё и мета-тулкит. Можно писать код, абсолютно агностичный не только к платформе, не только к конкретному тулкиту, — но и к гую как таковому в принципе.
От моей конепции AVC отличается тем, явно что использует xml и редакторы гуя. Это разумное решение - опираться на уже имеющиеся инструменты. А взамен на это она вообще избавляет нас от необходимости явно декларировать, что мы хотим отображать или знать - достаточно просто дать контролам имена соответсвующих переменных. Теоретически, на базе этого легко можно построить предложенную мной систему, которая будет ещё проще и примитивнее, но зато позволит быстро и в два слова писать истинно декларативный гуй от руки. А для случаев посложнее по-прежнему грузить интерфейсные файлы или читать конфигурацию раскладки шуевых элементов из строки с подобием вики-таблицы. Ну это все теоретически, на практике-то у меня кишка тонка такое кодить.
Картинка.
Рабочий код идентичен для любого из пяти тулкитов. Последовательности инициализации и внешний вид, как и следовало ожидать, немного отличаются - и даже этого бойлерплейта можно было избежать, добавив дополнительные обертки и конфигураторы отдельно для каждого тулкита, а также упростить обработку сложных типов (выводить голые словари и списки без требуемого специального форматирования).
P.S. Ещё один похожий концепт был в экспериментальном интерфейсно-остроумном тулките Shoes для Руби, но для написания стандартного интерфейс он не подходил, да и не ставил перед собой такую задачу. | comments: 3 комментария or Оставить комментарий  |
| Пардон, интроспекция. На этом мы заканчиваем любимое нытьё о том, что нам якобы не дают нормально поковырять в живых объектах.
from wx.lib.mixins.inspection import InspectableApp app = InspectableApp(False) frame = TestFrame() frame.Show(True)
import wx.py shell = wx.py.shell.ShellFrame(frame, locals={'wx':wx, 'frame':frame}) shell.Show() app.MainLoop()
Ха! Кому после этого нужны дебаггеры? Вместе с нашим окном запускается PyCrust. Разобраться бы, как заставить wx выводить ошибки в стандартный поток вместо кретинического гуевого окошка, вызывающего exit() и исчезающего раньше, чем успеваешь прочитать трейсбэк. | comments: Оставить комментарий  |
| С помощью функциональных декораторов добавить «эфемерные» (кстати, как они правильно называются?) локальные переменные функции в её же func_dict (т.е. сделать их собственно локальными) невозможно, т.к. декоратор определяется и вызывается раньше, чем определение декорируемой функции (duh), и поэтому до его вызова декорируемая функция определена и вызвана быть никак не может, а соответственно не может и иметь locals(). Лол, и чем я думал... Придется, наверное, рано или поздно разобраться в метапрограммировании на пейтоне основательнее, но от этих мета-танцев голова идет кругом.
А хотя... inspect.getsource()? :O XD | comments: 2 комментария or Оставить комментарий  |
| Наконец-то, наконец-то! Настоящий код инсайт: автодополнение находит импорты, анализирует их и выдает адекватную структуру классов. Из плюшек: нормальный дисплей-контрол, отображает шрифт очень качественно (аналогичный Комоду). Из встроенных цветовых схем дефолтная по традиции оказалась унылой «Серобуромалиновой», но Guepardo и Dessert терпимы. Дикое количество лексеров, и, соотв. синтаксической подсветки, и возможность её нормально настроить. Подсветка и автодополнение в шелле. Очень отзывчивый и почти неуродливый интерфейс. Если убрать тулбар, то можно даже забыть, что оно GTK. Ололо, я дал маху. Это ж официальный редактор платформы wxWidgets, входящий в дистрибутив :) Но зачем они сделали такой уродливый тулбар?.. Табы закрываются по средней кнопке мыши (приятно видеть, что эта парадигма стала повсеместно распространенной ^^) Из минусов: Суровые глюки, влоть до внезапно стирания файла при обновлении. Без бэкапа или контроля версий работать нельзя. :( UPD: Молодец разраб, глюк оперативно выпилил. Там просто опечатка была =)
Пытался перенести настройки цветовой схемы из комода в едитру (да, все уже поняли, что я больной на голову, но все же) - и не понял, как они в Комоде в конфиг-файле цвет записывают. Скажем, R:153 G:0 B:0 будет записано как «153», но вот R:0 G:153 B:0 — это уже внезапно «39168». Что это? | comments: 3 комментария or Оставить комментарий  |
| | Оказывается, существует некий стек обработчиков. То есть функция Bind() не просто назначает обработчики событиям, а добавляет их в этот самый стек обработки события. Для управления этим тоже можно пользоваться функцией event.Skip(), хотя основное её предназначение, как говорит хелп - вызов обработчиков из родительских классов. Если убрать её из обработчика, то событие не будет передано дальше, ни по иерархии, ни по стеку. | comments: Оставить комментарий  |
| Можно ли в питоне как-нибудь просто надстроить автоматическое отображение локальных переменных пространства функции в переменные-члены класса ? Чтобы, скажем, каждый объявленный в конструкторе x автоматически получал и self.x = x? Идея простая, но я не очень соображаю, как (и можно ли вообще) это сделать. Надо знать куда больше о внутрнностях. | comments: 2 комментария or Оставить комментарий  |
| Все у них хорошо, но вот фанатичное использование британского английского меня просто бесит. Какой такой wx.Сolour?! P.S. Я очень люблю британский английский. Но пожалуйста, в хуожественной литературе. А не в моих API. | comments: 21 комментарий or Оставить комментарий  |
| Маялся я маялся с передачей параметров. На задачах требующих выполнения абсолютно никак не связанных между собой (ни логически, ни структурно) вещей примерно одновременно, как-то мозги отказывают. Технология-то есть, пожалуйста: обширное использование механизма исключений, ООП, треды, разделение интерфейса от кода и вынос его в xml с подгрузкой (надо, кстати, наконец научиться) — все это как раз и пытается решить нашу проблему. А вот мозгам думать трудно. Я до сих пор не определился, что лучше - передавать окно как параметр делающей работу функции или вписывать вызов функции в метод окона. Второе является современным подходом, оно комфортнее, но противно пахнет. Первое зачастую уж слишком сурово и аскетично. Дошел до того, и затосковал по подобию метаданных к функциям.
Потом до меня дошло, что все давно придумано за нас, что и классы, функции на самом деле и состоят из этих самых метаданных чуть более чем полностью, и дикое количество моих проблем решается фривольным раскидыванием по коду довески атрибутов к тем самым функциям и оконным классам. Зачем имитировать фп и каррировать функцию, приплясывая с functools.partial, если можно просто в нужном месте привесить ей дополнительный член? :) Зачем передавать конструктору какие-то там вспомогательные параметры, если можно их просто присвоить их готовому объекту? Это питон, детка. Я так растрогался.
P.S. хотя как я понимаю, это затрудняет выпендреж с DSL. Если нет возможности разделить создание x.A и установку property x.A, то проще использовать старые добрые функции. | comments: Оставить комментарий  |
| Хорошая IDE, однако её представление о том, как должен выглядеть красивый рендер шрифта, застряло где-то в девяностых, и меня категорически не устраивает. Также, очень сложно подстроить под себя цветовую схему, я так и не смог до конца сымитировать комодскую «medium». Подсветка синтаксически корректных лексем (т.е. легитимных идентификаторов) отсутствует. Да-да, текст по-умлочанию на правой картинке - черный, зеленые слова - это уже подсветка. Понимаю, фича не самоочевидная, и с первого взгляда кажется просто остроумной финтифлюшкой, но когда привыкаешь, её тоже начинает очень не хватать. Именно такие мелкие финтифлюшки, в изобилии разбросанные по идеологии Комода (и Питона!), в итоге помогают освобождать мысли от всякого мусора. Можно сказать, именно финтифлюшками меня Комод и купил (в вопросе инструментария у меня принципиальная позиция: ехать надо, но и без шашечек нельзя). Также я не заметил никакого драматического улучшения работы автодополнения. Справедливости ради нужно сказать, что пробовал я не последнюю версию, а 6.5 (она оказывается у меня уже стояла). Пытался скачать и поставить последнюю, но от меня все время что-то хотели, и я так и не понял, что именно. ( дофига картинок и трёпли ) | comments: Оставить комментарий  |
| каждый битый плюсами гражданин знает, что без перегрузки конструкторов нам не жить. ну вот настала и моя очередь: я уткнулся в то, что ни в одном доке или туториале перегрузка как она понимается в С++ просто не упоминается. Ну логично, да — питону ведь плевать на типы ваших аргументов, хотим - можем хоть весь исполняемый код вместе с интерпретатором в качестве аргумента сунуть. Но что делать, если мы хотим создавать объект нашего класса из разных источников? поискал-поискал, нашел варианты с статик классметодами, банальной проверкой типа, и кучей шаманства. Совершенно ненамеренно я стал вчитываться в шаманство, и меня осенило: а ведь всё это просто... не нужно. Если наши источники разнородны, то и семантика объектов разнородна. Тогда и их интерфейсы разнородны, и мы имеем два законно разных класса =) Что в питоне, с его минимумом писанины, да ещё и в комоде, с его автодополнением скобочек и всех слов по табу, сделать ничуть не напряжнее, чем один. Гвидо опять оказался умнее :) Я сразу увидел свет, и всё расплывалось и превращалось в атомы, и затем в байт-код, и даже небо, даже аллах и посмотрел на свой код, и понял, что отравленный ядовитыми флюидами ООП мозг пытался сунуть в один класс совершенно не относящиеся друг к другу сущности... | comments: 6 комментариев or Оставить комментарий  |
| Современные технологии меня трогают до слез. ВНЕЗАПНО, кликнув на маахонький подозрительно знакомый значок во вкладке скрипта в IDE «Комодо», обнаруживаю что мне предлагают сделать Hg-коммит! Интеграци~я *_* Алсо RxToolkit в комоде прекрасен. Лучший дебаггер регэкспов из всех, что я видел (2 шт.). До этого я работал в Kodos (тоже родной, на питоне), функционал тот же, но комод удобнее, красивее и шустрее. Как и во всём остальном что касается комода — «удобнее и красивее» не удивило. Но вот «шустрее» стало приятным сюрпризом :)
Открыл для себя синтаксис флагов (?...). Shiawase ~^_^~. Наконец-то я могу внедрить опции исполнения в регэксп, а не помнить сам, что их надо передать движку. Алсо to whom it may concern, я е..ался с re.UNICODE добрых часа три только чтобы выяснить, что включать его нельзя. Все прониклись? Включать re.UNICODE, обрабатывая файлы в utf-8, НЕЛЬЗЯ. Иначе ничего не будет работать. Самое смешное, что и Кодос, и RxToolkit вообще никак не реагируют на этот флаг (иначе я бы выяснил эту муть куда раньше, да). А стоит перепастить код в скрипт - и ни..уя не работает. Швайссе!
P.S. Буду делать свой первый pull/merge, пожелайте мне удачи :) | comments: Оставить комментарий  |
| Система конечно-элементного анализа SIMULIA Abaqus - это относительно новое детище старой доброй Dassault Systems, более всего известной массам своей системой быдломоделлинга SolidWorks (илита же знает про Катюшу и с такими мелочами не заморачивается). Как всегда, получилось нечто монструозное: если в KATIA можно было построить самолёт от фюзеляжа до унитаза, то в SIMULIA получившийся туалет самолет можно прогнать через все известные человечеству виды нагрузок и посмотреть, что получится. Как можно догадаться, архитектура такой всеобъемлющей универсальной системы вполне соответствует благим намерениям. Даже с учётом того, что работает всё это на расовом питоне, — не то чтобы API была плоха, просто всё это такой дикой сложности, что никак не хочет с наскока вмещаться в одну отдельно взятую несчастную голову.
А ещё какая-то мразь повписывала в API рандомно методы с большой буквы! Красота! :) Ну и конечно же, как всегда, бесконечные foo.setFuckingValue() и foo.getFuckingValue() вместо человеческих свойств. Это, пожалуй, самая распространённая паршивость прикладных API - нежелание разработчиков использовать доступный высокий уровень по максимуму. Предполагается, мы должны запоминать все эти наборы идиотских функций, которые все равно никогда не понадобятся 99% сторонних пользователей. Объектная, бл..ть, ориентированность. Если раньше просто писали "DoShitEx()", то теперь приходится ещё ломать голову, в каком же объекте или классе она спрятана! Но это ещё цветочки. Гораздо хуже то, что построено всё это на каком-то унылом тулките, — разумеется, межплатформенном! — который выглядит как дерьмо незаконнорожденное дитя windows 95 и Office XP. Это чудо не может адекватно и надёжно отображать ничего, кроме ascii. Казалось бы, кто мешал взять wx или qt?.. Ненависть. | comments: 13 комментариев or Оставить комментарий  |
| Мои проблемы были вызваны некорректным и немного наивным пониманием некоторых деталей. В частности, интерпретация строковых литералов. Простые строковые литералы даже при чтении из юникодного (utf-8-sig) файла будут интерпретированы вовсе не в utf-8! Они дают объекты типа str, зарепренные, если я не ошибаюсь, в подобии utf-16 (upd: в ascii-представление шестнадцатиричной записи кода, причём именно в utf-8). В отличие от юникодных (u"") строковых литералов, которые дают объекты типа unicode, закодированные четырехзначным номером UCS.
Сколько раз говорил себе "не связывайся со строковыми литералами", и в очередной раз оказался прав же! :)
Вот так стало всё гораздо понятнее: # -*- coding: utf-8 -*- sl1 = "абвгд abcdef №" sl2 = u"абвгд abcdef №" s1 = unicode(sl1, "utf-8").encode("windows-1251") s2 = sl2.encode("windows-1251")
f = open("lol.txt","wb") f.write(s1 + " " + repr(sl1) + "\n") f.write(s2 + " " + repr(sl2) + "\n")
получаем: абвгд abcdef № '\xd0\xb0\xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4 abcdef \xe2\x84\x96' абвгд abcdef № u'\u0430\u0431\u0432\u0433\u0434 abcdef \u2116'
~^_^~ | comments: 7 комментариев or Оставить комментарий  |
| | Как перекодировать одно в другое, или записать файл в чём-то кроме ANSI? Я без понятия. То есть конечно есть unicode(), "".decode() и "".encode(), но как я их ни тыкал веточкой, получается либо ничего, либо ошибка. Что-то я делаю не так... | comments: 2 комментария or Оставить комментарий  |
| Я таки люблю питон. У него, конечно, есть свои шероховатости, но, например, меня самого поражает, с какой скоростью и лёгкостью нужные действия пишутся именно так, как они думаются. Причём иногда приходится мысленным усилием отстраиваться от паскльно-сишного образа мыслей, чтобы потом, почти не задумываясь, практически буквально перекладывать мысли сразу в код, именно нужное и делающий. Кто-то скажет, ничего особенного. Но меня это не устает удивлять. Оказывается, программирование могло быть совсем-совсем другим ^__^
В данном скрипте мы побеждаем сотрудников патентного отдела, принесших две тысячи результатов в виде сохранённых страничек в mht и htm как они были выданы поисковиком. Что характерно, наибольшее количество времени было потрачено на отладку рабочих регэкспов. К сожалению, я совсем забыл про встроенный в Комодо отладчик регэкспов, иначе сэкономил бы добрый час (я пока ещё не очень хорошо ориентируюсь в модификаторах, квалификаторах и прочей лабуде). ( ... ) | comments: Оставить комментарий  |
| Ура. Теперь код готов к труду и обороне. Будучи запущенным внутри какой-нибудь РК, он получает номер максимальной ревизии, закоммитченной в этой РК и вставляет его в открытый документ в компасе. К сожалению, довести скрипт до реально полезного состояния мне мешает абсолютно изуверская API компаса. Всё, что касается отрисовки и создания геометрии, там очень просто и в общем straightforward. Но получить параметры документа или перебрать уже существующие в чертеже элементы - ой мама!.. В идеале скрипт должен перебирать все открытые документы (или сам их открывать) и проставлять номер редакции не в нуле чертежа, а в конкретном месте под основной надписью. Но для этого нужно уметь использовать эти дрянные итераторные апи и схемы получения параметров (знать формат листа), что, как мне кажется, нереально -_-
Впервые передо мной забрезжил свет потенциальной осмысленности регэкспов: http://docs.python.org/dev/howto/regex.html понятно и доходчиво объясняет их функцию в роли трафарета, — использование групп для выделения конкретных участков текста. Все объяснения регэкспов, встречавшиеся мне до сих пор, видимо, содержали объяснение групп сильно далече после того места, на котором я их дропал читать по причине беспросветного уныния. Кому в прикладухе нужно матчить какие-то строчки текста? Его, как правило, нужно парсить! Вот с этого и должно начинатсья объяснение регэкспов. Или хотя бы упоминать такую возможность.
( ... ) | comments: 13 комментариев or Оставить комментарий  |
| Пока что для TortoiseSVN. Потом перепишу для svn или, если перейду, hg или git. с ними будет даже проще. Интересно, заставлю ли я себя когда-либо изучить регулярные выражения... Период тупизны у меня прошёл (видимо, это связано с увеличением длины дня), и скрипт я написал за такое время, за которое и положено писать примитивные скрипты на питоне. Не считая часа, ушедшего на то, чтобы разобраться, как исопльзовать трубы. Заметим, правда, что в шелле подобная "задача" вообще записывается в одну строчку ^^;
( ... ) | comments: 13 комментариев or Оставить комментарий  |
| | Но великодушно разрешил также Mercurial, написанную на расовом Питоне. Пробуем. Гит будем пробовать, когда появится TortoiseGit :) | comments: Оставить комментарий  |
| | Кстати, неоднократно замечал, что прикладное программирование на питоне не позволяет слишком вольно жонглировать моими любмыми анонимными экземплярами. Сам по себе язык относится к ним прохладно: хочешь — пиши, твоё дело. Не поощряет (это идёт вразрез с 4-й заповедью, «Flat is better than nested»), но и не запрещает. Для простых объектов типа Color(r,g,b) использовать анонимные экземпляры, как правило, можно без проблем. Но вот попыток написать, например, self.SetColAttr(0, gridlib.GridCellAttr().SetReadOnly() ) вместо грамматически идентичного бойлерплейта attr = gridlib.GridCellAttr(); attr.SetReadOnly(); self.SetColAttr(0, attr) вам не простят. Это наблюдение относится не только к WxWidgets, за то же самое можно получить по ушам и в Qt. Видимо, за высокую степень абстракции мы платим большой большой сложностью низлежащих реализаций (swig - г..но!!), а автоматическая сборка мусора подсчётом ссылок не всегда прощает акробатику в стиле С++? | comments: 5 комментариев or Оставить комментарий  |
| | чёрт, чёрт, чёрт!! ну неужели ничего нельзя сделать с ненавистью половины питонского ПО к путям типа "C:\Documents and Settings\Администратор" (он же известен как "Àäìèíèñòðàòîð" )?!.. Причём вылазит же, зараза, Unicode Decode Error в самых неожиданных местах. Скажем, main.py - работает, а вот main.exe - уже нет. Какая-то фигня вызывает какую-то фигню, которая делает что-то не то. Ну не могу я писать в требованиях "запускайте с диска C:\", не могу, лучше убейте меня. 2009 на дворе. | comments: 5 комментариев or Оставить комментарий  |
| Надо бы в идеале добавить функциональность простановки номеров по имеющейся окружности (с автоматическим определение диаметра), но пока что я не разобрался в итераторных апи, а других спосоов выяснить свойства подсвеченного объекта я не знаю. ( Read more... ) | comments: 4 комментария or Оставить комментарий  |
| |