понедельник, 15 апреля 2013 г.

Список имен всех контроллеров в Django

Относительно недавно решил интересную задачу.
Дано: достаточно объемное приложение на Django. Нужно: собрать имена всех контроллеров по файлам urls.py.

Решение:
get_viewname_list.py

суббота, 5 января 2013 г.

Оптимизация производительности Javascript (Предварительное вычисление функций).

Метавычисления и вычисления в computer scince - это как алгебра и арифметика. Если обычная арифметика оперирует конкретными числами, то алгебра - переменными, которые по своей сути являются абстракцией от чисел. Если при обычных вычислениях в процессе выполнения кода исполнитель (интерпретатор кода) оперирует конкретными значениями, то при метавычислениях - абстрактными типами. Есть всего три самых популярных задачи метавычислений: специализация программ, их композиция и инверсия. Все они легко ищутся в сети. Остановимся на специализации, которая заключается в изменении исходного кода программы с учетом входных данных, например из программы которая считает квадратный корень положительного числа можно получить программу, которая будет считать квадратный корень 0 или 4. Код будет меньше и быстрее, но будет считать только для 0 и 4.
Браузерный Javascript - вещь тормознутая и это очевидно. Есть старый прием, когда для "тяжелых" по скорости функций используют кэширование. Прием простой и эффективный, декоратор кэша на js пишется легко и не принужденно. Но, мне почему захотелось пойти дальше и просчитывать результат функции ДО её выполнения. Т.е. при выполнении кода уже у клиента, вместо выполнения функции будет просто возвращаться заранее просчитанный результат из массива. Конечно, такой трюк возможен, только при известных заранее аргументов этой функции, что далеко не всегда, но все же. В итоге мы получаем прирост (увы, не всегда) в скорости при увеличении объема кода.
Написав, опять же на Js, небольшой код, который бы по переданной в виде Plain Text'а кода функции возвращал код вычисленной функции начал все это тестировать. И вот в чем беда: в Js мало того, что плохо с математикой, работой с DOM (все очень медленно), так еще и работа с массивами тоже не ахти.
Ниже логи для моих браузеров (код оптимизированной функции преводить не буду, ибо здоровый он очень):

Source:
function(x1, y1, x2, y2){return 1 + Math.pow(Math.sin((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)),2)}

Chrome:
Time without pre-optimisation: 290

Build Time (template "{}"): 756

Time with pre-optimisation: 161

Build Time (template "[]"): 689

Time with pre-optimisation: 137

Firefox:
Time without pre-optimisation: 262

Build Time (template "{}"): 1122

Time with pre-optimisation: 116

Build Time (template "[]"): 851

Time with pre-optimisation: 80


Opera:
Time without pre-optimisation: 151

Build Time (template "{}"): 1012

Time with pre-optimisation: 71

Build Time (template "[]"): 660

Time with pre-optimisation: 87

Сама ссылочка на тесты: Тык

На днях надо написать UI к этому всему.

суббота, 15 декабря 2012 г.

hobbit - управляй браузером на любимом языке.

Вспомнил тут я про этот блог. Решил что-нибудь написать.
Неделю назад вернулся из Новосибирска (город сам практически не видел, но Академгородок - это просто рай) с hackday. В двух словах: hackday - 48 часовой хакатон. На этом хакатоне мы с командой реализовывали интересную идейку - удобное управление браузером на любом языке программирования. Зачем это вообще надо? Люди - существа ленивые и любят все что можно и даже нельзя автоматизировать, что бы пока они спят\работают\отдыхают скрипт за них делал какую-то работу, которая так или иначе приносила им доход. Т.к. я уже несколько лет занимаюсь автоматизацией, то большинство плюсов и минусов успел испытать на себе. Есть отдельный класс задач автоматизации: автоматизация действий пользователя в браузере: браузерные игры, различные веб-приложения и т.п. Как и для большинства задач автоматизации действий пользователя быстрый старт можно осуществить с AutoIt. Но, возникают траблы, если сайт использует AJAX (не сможешь работать только с сорцами страницы), если нужна фоновая работа с браузером (не мешать пользователю заниматься своими делами). Последнюю подобную задачу я решил тоже с использование autoit, но без всяких там мышко/кнопко-жамканьем и анализом цвета пикселей (ИМХО, но это не кошерные вещи). Суть решения такова: в хроме через адресную строку выполняется Js-код (благо, на сайте был jQuery), который дергает инфу и жамкает кнопочки. Инфа возвращалась через обычный prompt, который скрипт на autoit закрывал. Извращение еще то, но плюсы есть: получение инфы независимо от положения и размера окна браузера. Минусы тоже существенны: нет перехвата событий на странице, вкладка должна быть активна да и вообще комп используется монопольно скриптом. Скрипт работает, код простой, все довольны. Тут мне и пришла идея - использовать расширения (плагины) хрома для работы со страницей. Их минус: есть доступ только к браузеру (например нельзя дернуть емайл и отдать его скрипту, который отправит письмо), писать можно только на Js. Плюсы: просто шикарное API, перехват событий, работа с фоновые вкладками (вообще никак не будем мешать пользователю).
Поэтому и возникла идея hobbit - плагина, который будет проксей между браузером и внешним кодом. Т.о. получаем плюсы плагинов и плюсы внешнего кода в одном флаконе.
Общая архитектура или как взаимодействуют между собой плагин и внешний код. Взаимодействие идет по двум каналам: через localStorage плагина и через WebSocket. Первая способ провалился, т.к. хром грузит содержимое local storage в ОЗУ при запуске и больше ничего не читает из него до следующего запуска. Второй путь: Плагин представляет собой WebSocket клиент, который общается с WebSocket сервером, поднятым на localhost. За 48 часов мы хотели реализовать два сервера: под винду в виде dll и под линь в виде демона. В итоге, завелся только сервер под винду (dll на C#).
В качестве примера за десять минут набрасали на C# виджет для управления плеером Вконтакте. Все работает как надо (хотя от вида кода я плакал кровавыми слезами).
Планы на текущий момент: переписать dll и нарастить функционал.
Сцыль (только сорцы плагина, нет самой длл-ки): hobbit

четверг, 23 февраля 2012 г.

Модификация программ с закрытым исходным кодом.

В общем надо было по учебе сделать видеоролик какой-нибудь. Поэтому было зашпилено вот это:

Тык

понедельник, 2 января 2012 г.

Парсинг Ifolder.ru

Скинули мне недавно файлики через ifolder.ru. Вид ссылки примерно такой: "http://ifolder.ru/12345678" То есть номер файла задается через вот эти самые чиселки. Потыкав наугад пару ссылок, меняя это число, обнаружил, что возможны два случая:

1. Файл удален, т.к. его давно никто не скачивал.

2. Файл лежит на сервере.

Just for fun сделал скрипт на Python, который бегал по ifolder и ссылки писал в файл.

Сорцы

Выдернутые файлы

среда, 3 августа 2011 г.

Стрелки - формулы для координат.

Недавно понадобилось рисовать стрелки в программе (4fun среда для моделирования с преферансом и поэтессами), проблема - зная две точки - начало и конец отрезка, нарисовать стрелку. Решение ниже.

Итак, дано:

Даны точки (x0 ; y0) и (x1 ; y1). Дан угол между отрезками (для удобства вычислений взят 45 градусов). Дана длина мелких отрезков. Нужно найти координаты (x3 ; y3) и (x4 ; y4).

Находим угловой коэффициент прямой, проходящий через точки (x0 ; y0) и (x1 ; y1):

Делаем выкладки, для угловых коэффициентов прямых (x1 ; y1)(x3 ; y3) и (x1 ; y1)(x4 ; y4) :

Обозначим длину отрезка (x1 ; y1)(x3 ; y3) как L. Зная это L и r, можем найти x:



Теперь легко найти y:


Как видно, получили для (x3 ; y3) (x4 ; y4) по две пары точек. Нам нужно взять из них ближайшие к точке (x0 ; y0). Т.е. оценить расстояния:

Или, упростив:

Алгоритм


Берем такие (x3 ; y3) и (x4 ; y4), при которых минимально

и

соответственно.

P.S. Все картинки кликабельны.


понедельник, 16 мая 2011 г.

Удаленное управление

Мда... Давно не писал. В-общем решил запостить небольшую программку, которую использую на работе. Итак, ситуация: есть компов 50, у каждого уникальное имя, все введены в один домен и соответственно находятся в одной подсети. Есть рутинные задачи - почистить мусор на жестких дисков, собрать информация о конфигурации и т.п. Есть батники, которые это делают.

Итак, как это работает.

1. Берем один комп из всех, монтируем общий для всех сетевой диск. В файлике comps.txt вбиваем имена компов, на которых нам нужно выполнить батник.

2. Редактируем батник BAT.BAT, который будет запускаться на каждом компе. Можем в нем вызвать другой.

3. Запускаем на этом компе батник START.BAT

Как это устроенно:

START.BAT

@echo off
psexec @comps.txt -u login -p password -C RUN.EXE
pause

Параметры

@comps.txt - отсюда psexec берет имена компов

-u login - логин пользователя, под которым логинимся.

-p password - его пароль

-с run.exe - копируем run.exe на удаленную машину.

RUN.EXE

Две строчки кода на AutoIt.

RunWait("cmd /c net use X: \\dc01\xchange")

;Монтируем сетевой диск

Run("X:\RBAT\bat.bat")

;Запускаем с сетевого диска батник

Пример BAT.BAT:

rem hostname >> X:\RBAT\IP.txt
rem dir c: /b >> X:\RBAT\IP.txt
rem shutdown /s
X:\test.bat

Думаю все понятно.

Скачать

понедельник, 21 февраля 2011 г.

Конвертер vNote в Txt.

Решил вечерком скинуть заметки с телефона (LG KP-500) на компьютер, зело были нужны. Скинул по Bluetooth, глянул блокнотом, а там все кириллические символы хранятся в UTF-8, да еще и '=' понатыкано как разделителей. Ну UTF-8 зверь не экзотический, поэтому сходив на один полезный немецкий ресурс и выдернув нужные коды кириллицы, написал по-быстрому на AutoIt (работа со строками, передаваемые параметрами мне тут нравится как нигде) простой код, отладил и радовался жизни.

Пользоваться просто:

Для лентяев: перетаскиваем файлик .vnt на иконку программки, жамкаем ok, забираем результат из той же папки, что и .vnt.

Для любителей: в консоле передаем в качестве первого параметра имя .vnt файла, забираем из той же папки, где лежал .vnt.

Ссылка

четверг, 27 января 2011 г.

Класс для печати таблиц (С++)

Нашел вот в своих исходниках занимательный класс для печати таблиц в консоле. Имеются четыре способа отображения таблиц, автоматический перенос строки, если строка не помещается по ширине в строке. Как пользоваться:

Сначала создаем объект класса:
TablePRINT *tp = new TablePRINT(3,0,3,2);
Параметры (по порядку):
1 - количество столбцов
2 - вид (от 0 до 4)
3 - количество пробелов между значением и границей слева
4 - количество пробелов между значением и границей справа

Далее печатаем строки:
tp->TableROW("Allan", "Norton", "40");
После каждой строки, если нужно печатаем разделительную линию:
tp->TableLINE();

И в самом конце печатаем подвал:
tp->TableBOTTOM();

Вот парочка примеров:


В архиве лежит сам исходник класса и пример использования.

воскресенье, 28 ноября 2010 г.

Подобие многопоточности в AutoIt

AutoIt хорош всем, кроме двух вещей (для меня лично): медленность работы и отсутствие многопоточности. С первой проблемой борются оптимизацией кода (полезно все-таки), со второй каждый своими велосипедами. О своем велосипеде мне и хотелось бы рассказать.
В начале был код. Хитрить не буду - код отрубания около 50 машин по сети, с использование программы из пакета pstools (вещь очень удобная и полезная). Вот для этой программы и была написана на AutoIt графическая оболочка, дабы облегчить её использование. В самой оболочке в цикле вызывалась программа psshutdown.exe с именем отключаемой машины в качестве параметра. Все бы хорошо, но следующая машина не выключалась, пока не проработает программа для предыдущей. И вот эти 50 машин выключались добрых полчаса, а то и больше. Вывод был очевиден - нужна было многопоточность. Но в AutoIt`е её нету. Вывод - пишем велосипед, её имитирующий.
Суть:
Весь пакет состоит из двух exe: первый выполняет работу, в зависимости от переданных ему параметров. Второй взвывает первый с нужными параметрами.

Простой пример: вычислить сумму от 1 до (1000000 + I), где I меняется от 1 до 10.

Runer.au3

;Прога, в которой создается "поток"
For $I = 1 To 10
ShellExecute("get.exe", $I)
Next
MsgBox(0, "Finish", "All call completed.")

Get.au3
;Тело "потока"
#NoTrayIcon
$RESULT = 1
For $I = 2 To $CmdLine[1]
$RESULT = $I + $RESULT
Next
MsgBox(0, $CmdLine[1], $RESULT)

Строем .exe для Get.au3 и запускаем Runer.au3

суббота, 18 сентября 2010 г.

Использование AutoIt

Написал статью про использование AutoIt. Программка получилась забавной, по-моему. Строго не судить =)
ACalc.rar

пятница, 17 сентября 2010 г.

ASM или Что делать?

Нашел вот книжицу занятную: "Язык ассемблера: уроки программирования" П.И. Рудакова и К.Г. Финогенова. И призадумался: а нужен ли мне этот самый ассемблер? И что-то повода его изучать подробно не нашел. Текущих знаний для отладки программ вроде хватает. Со всем нуждами до сих пор справлялся на скриптовых и высокоуровневых языках. Драйвера писать не планирую, asm-вставки для критических областей тоже как-то не особо нужны. Отложил книжицу... и опять призадумался: а чем же время занять - пописать статьи про трейнеры, ковырянее игр и т.п. или кодить что-нибудь интересное и не однодневное (пока таких вариантов нет). Жду советов каких-нибудь =).

пятница, 27 августа 2010 г.

Hamachi

Нашел интересную программку. В первую очередь она будет интересна геймерам. Вот например захотели вы с друзьями поиграть в Diablo 2 по сети, а IP у вас динамический, и подключится к вам будет не возможно. Так эта программка создает виртуальную локальную сеть. Т.е. компьютеры на самом деле подключены только к интернету, а обращаться к ним можно как к локальным. Во общем программа для меня полезная. Вот ссылка:
Hamachi2

четверг, 12 августа 2010 г.

О паролях и лени

Человек существо ленивое. Очень. Вот и пришла мне мысля преинтересная - практически везде (ну или почти) человек вводит один и тот же пароль. Т.е. понятно, как этим можно воспользоваться злоумышленникам. Если на один из двух вопросов "Кто виноват? Что делать?" ответ уже дан, то на второй он понятен: не используйте один и тот же пароль. Если у вас взломали ICQ или почту, то получить доступ к другому не составить труда. Лень - это величайшее зло!

понедельник, 2 августа 2010 г.

О кодерах и кодинге

Навеял конец лета... Может эта записка покажется кому-то близкой. Начну сначала. Собрался, я значит написать вторую версию бота, что бы там всяких приятностей было побольше. Начал писать. За месяц реализовал процентов 70. Бросил.. Через 2 месяца за вечер написал ещё 10% процентов. Бросил.. Через недели 3 начал тестить, а-ля альфа-тестирование. Не работает. За неделю написал заплаток. Работает кое-как. Бета-тестирование... Ещё за неделю написал заплатки. Ядро работает, но не всё так красиво как задумывалось в начале. От альфа-версии осталось 80% процентов. Запустил. Работает. НО! GUI нету вообще, управлять можно только меняя исходный код и ручками писать настройки в INI файле. Итого, реализовано 85%. Теперь ещё прикручивать GUI, иначе управлять ботом одной клавишой старта (F9) (причем только старта, стопа нет - только вырубать и запускать заново) и ковырянием настроек - это какой-то ДZен..
Теперь, к чему это я все веду.
1. Кодеры существа ленивые и без надсмотра менеджера ничего толком не сделают
2. Кодеры существа странные. Они в первую очередь задумываются о ядре, а уже потом в самом конце прикручивают интерфейс, чаще всего убогий. Т.е. без менеджера опять же напишут всякую охинею.
3. Кодеры существа самодовольные. Если вы попросите их написать программу, под тип калькулятора, то как ей управлять будет известно только Избранным, таким как сами кодеры (обычно 2-3 человека, тоже кодера)
4. Кодеры существа эгоистичные, очень сложно двум кодерам вести проект: где первый обзовёт переменную "countINDEX", второй гордо напишет "AUI" или что-то в этом роде

Итак, вывод: Процесс написания проекта нифига не зависит от одного кодера. То, что он напишет - процентов 50%, максимум 60% от того, что нужно на самом деле. А если и напишет, то это ещё надо и заказчику спихнуть, при этом никаких: "Э.. А вы зачем сразу две кнопки нажали? У меня это и не предусмотрено!" или "Главное вот на этом процессе чуть-чуть подождать и ничего не нажимать - идет процесс анализ данных. Ну и что, что он идет 20 минут? Зато это самый красивый метод!" и т.п.

пятница, 30 апреля 2010 г.

Оптимизация кода AutoIt

Все кто пишет на AutoIt`е жалуются на медленность кода. Ну я тоже не исключение=) Вот и решил провести маленькое исследование - какая из функций будет работать быстрее - так, которая вызывается из UDF,  описанная в текущем файле или сразу код функции? До начала самого исследования думалось что по скорости они будут расположены так:

1. Сам код функции

2. Описанная в текущем файле

3. Вызываемая из UDF

Итак, для теста было создано два файла:

головной:


#include <TEST.au3>

;Немного подождём - что бы скрипт нормально загрузился и размялся перед боем
$SUM = 0
For $J = 1 To 1000
$SUM += TEST()
Next

;Здесь - для конкретного кода, а не вызывания функции
$time3 = TimerInit()
$SUM = 0
For $J = 1 To 1000
$RET = 0
For $I = 1 To 100
$RET *= $I
Next
$SUM += $RET
Next
$time3 = TimerDiff($time3)
;Здесь будем замерять время для функции вызванной из UDF
$time1 = TimerInit()
$SUM = 0
For $J = 1 To 1000
$SUM += TEST()
Next
$time1 = TimerDiff($time1)
;А здесь - для описанной ниже
$time2 = TimerInit()
$SUM = 0
For $J = 1 To 1000
$SUM += TEST2()
Next
$time2 = TimerDiff($time2)

MsgBox(0,"Результаты", "Из UDF: " & $time1 & Chr(13) & "Внутри: " & $time2 & Chr(13) & "Код: " & $time3)

Func TEST2()
$RET = 0
For $I = 1 To 100
$RET *= $I
Next
Return
EndFunc


TEST.au3 :

Func TEST()
$RET = 0
For $I = 1 To 100
$RET *= $I
Next
Return
EndFunc


Итак, после 10 замеров получили вот такой результат:

1. Сам код функции, а не её вызов

2 и 3 Вызов из UDF и вызов их текущего файла

Причём, влияет порядок следования функций. Например если сначала замерять time1, а потом time2, то time1 будет больше. Если наоборот, т.е. сначала time2, потом time1, то time2 будет больше. 

Итак, резюмирую:

  • На скорость работы скрипта не влияет расположение функции - она может быть описана как в отдельном файле, так и в текущем.
  • Отказ от функций и использование непосредственно кода этой функции даёт существенный прирост скорости.




среда, 28 апреля 2010 г.

Простой навигатор для консоли

Итак, менюшка уже описана, а вот и её применение. Простенький навигатор по диску с помощью меню. Может перемещаться по папкам, запускать любые файлы. Пока всё - это все лишь пример применения меню=)  Но мне вещь показалась полезной при работе в консоле=)

Скачать


суббота, 24 апреля 2010 г.

Меню в BAT

Те кто хоть раз писал на BAT со мной согласятся - всегда чего-нибудь не хватает. Вот мне, например там не хватает менюшки - для более наглядного общения с пользователем. Ведь рядовому пользователю вряд ли понравится читать хелп и смотреть параметры - ему гораздо привычнее нажать пару кнопок и получить результат - например, выбрать нужный пункт меню. Ну и вот, собственно для этого и была написана менюшка на BAT. Итак, как пользоваться:

  call menu.bat "1 string" "2 string" "3 string" "4 string" "5 string" "6 string" "7 string" etc.

После того как пользователь выбрал пункт меню - пакетный файл вернет результат. Обратится к нему можно через переменную errorlevel.

ПРИМЕР

Создадим BAT файл следующего содержания:

  @echo off

  call menu.bat "ADD" "DEL" "EDIT" "HELP" "EXIT"

  echo You Select: %errorlevel%

Результат его работы (копировано с консоли):


1: ADD
2: DEL
3: EDIT
4: HELP
5: EXIT

Select: 6
Error! Retry input
Select: df
Error! Retry input
Select: 4
You Select: 4

Вообщем вот так =) Сделать более красивую менюшку с управлением клавишами стрелок встроенными средствами BAT -  нельзя, т.к.  нельзя считать нажатие клавиши. 

Скачать

воскресенье, 18 апреля 2010 г.

Вводное

Ну что же, попробуем обосноваться здесь. Вот это мы уберём, облако тегов надо будет добавить, здесь почистим.. Если кратко - идёт процесс обживания блога =)

Давно надоевший вопрос - для чего создан блог? Ну надо же куда-то выкладывать все мысли, идеи о тех проектах, которыми я занимаюсь. Ага, а вот и следующий вопрос - а чем же я занимаюсь? Ну первым делом я пытаюсь программировать (ну если не лень как всегда). В основном на C# и AutoIT. Но не брезгую и другими языками. Надеюсь, что в скорое время выложу, точнее напишу статейку про BAT.  Ну и так как основной уклон сейчас у меня на написание второй версии бота для одной MMORPG (только тсссс.... =) ) то и про это что-нибудь тоже попробую написать.