суббота, 24 сентября 2011 г.

как сделать чтоб sudo требовал пароль рута.

По умолчанию он требует пароль пользователя.

More...
Сейчас все Френдли Дистры Линукса автоматом ставят первого пользователя в группу sudo. И Когда мы выполняем команды с sudo. Вводим пароль пользователя и команда выполняется с правами администратора. Всю жизнь у меня был 1 пароль у администратора и пользователя.
и я не замечал всё выше-сказаное. Меня только настараживала надпись.

[sudo] password for alex: // а надо:password for root

Но вот поставил Дебиан, которые не добавил меня автоматом в sudo. а я поставил разные пароли админа и юзера. Ну добавить себя не сложно. Но меня не устраивало что при выполнении команд от sudo я должен вводить пароль юзера. Оказалось что это не солжно исправить, всегото немного почитав.

man sudoers

Как там сказано. "rootpw If set, sudo will prompt for the root password instead of the password of the invoking user. This flag is off by default."

тоесть с помощью visudo я прописываю в /etc/sudoers
Defaults rootpw

И всё работает на ура.

PS: Love Linux
Читать дальше......

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

Факториал в 1 строку.

После реализации сложного и интересного проекта наступает Хандра и кризис идей. Так произошло и после эмулятора SkyNet на питоне(скоро появится статья, о том что это, и вылажу исходники, там много интересных и полезных решений). Сначала решил поcносить все свои системы и поставить заново. Просто от скуки. Сначала поставил Win7. Меня взяла ностальгия и я полтора дня рубился в Rome Total War. Когда надоело, стал лениво листать интересные патерны и трюки на питоне. И вот натыкаюсь на фразу "Реализация факториала через лямбда функцию". Хандру как рукой сняло, глаза загорелись. Захотелось самому додуматься.Браузеры закрыл открыл IDLE Питона и понеслась... Таки сделал, в пол третего ночи, довольный собой, пошел спать. В статье хочу привести пример реализации, и немного подробней рассказать почему оно работает.

К середине статьи я приведу функцию.
Сперва немного теории про лямбда функции. В Вики-учебнике худо расписано, но понять можно.
Лямбда функция эта такая функция которая содержит всего 1 строку(выражение), и в отличии от обыкновенной функции, её легко создать прямо походу выполнения программы.
Используется за частую в аргументах к функциям, при передаче параметров. Если обьяснять на примере то например в вашей программе надо часто использовать подобное выражение( с переменными a,b,c)

sin(ln(a/(b+c*(log(c+b+a))))-sqtr(b+1/c)*tg(a div (c+a)))
И переменные a,b,c постоянно разные, вас задалбывает это всё набирать. И вы делаете следующее:

long_func = lambda a,b,c: sin(ln(a/(b+c*(log(c+b+a))))-sqtr(b+1/c)*tg(a div (c+a))
# И потом используете так
try:
   result = long_func(x,y,z)
except:
   result = -1
   print("Arguments Wrong")
А чтоб сделать рекурсию в лямбде надо вызвать её из самой себя где-то так


recurs = lambda : recurs()
Это сделает бесконечную рекурсию. И так с лямбдой разобрались.
Далее в программе: and, or , not.

Начнём с and.
Смысл функции должен быть ясен логически, не зная о том, что такое дискретная математика. Если мы сообщаем ей 2 правды она скажет "Правда" Если хоть один из аргументов будет ложный, она скажет "Лож". Прошу заметить что притон интерпретирует любое численное значение кроме 0, как правду, а 0 интерпретирует как "Лож". Но в этой функции есть пасхальное яйцо. На котором строится решение выше поставленной задачи. Если мы сообщили ей 2 числовых аргумента(не 0), то она вернёт последний(тот который справа). Если дадим хоть 1 ноль, то она возвращает 0. Но это не всё есть ещё 1 пасхальное яйцо. Которое умно называется Сокращенные вычисления. Насколько мне известно, это присуще почти всем языкам программирования.Смысл вот в чём: при длинном выражении использующем логические функции, вычисление прекращается, как-только встречается хоть 1 переменная решающая итог выражения. Таким образом Что-бы дальше не происходило, на результат это не повлияет.
вот небольшой пример показывающий это:


>>> class F():
 def __init__(self,name,RES):
  self.RES = RES
  self.name = name
 def do(self):
  print self.name
  return self.RES

 
>>> for x in range(10):
 exec("F%s = F('F%s',True)"%(x,x))

 
>>> F4.RES = False
>>> F1.do and F2.do() and F3.do() and F4.do() and F5.do() and F6.do() and F7.do() and F8.do() and F9.do()
F2
F3
F4
False
Для тех кто в не совсем понял что творится: Я создал 10 объектов, при выполнении их метода do() они печатают своё имя, и возвращают True. Кроме 4, его я заставил возвращать False. И так давайте посмотрим, что вышло. А вышло то. что как только 4 объект возвратил False,
все and(ы) перестали выполнятся, потому что в этом нету смысла, всё-рфвно общим результатом будет False.

Теперь про or: or возвратит "Правда" если ХОТЬ 1 элемент правдивый, и возвратит "Лож" если Оба ложны. Пасхальные яйца с and(ом) у or анологичны. Кроме:
Если сообщаем 2 не нуля, то она возвращает нам ПЕРВЫЙ( тот что слева) не ноль, даже если скармливаем ей "Правду " и "не ноль" то она возвратит то что слева. Если пичкаем её двумя неправдами ( будь 0 и False, или False и False, или False и 0, или 0 и 0) Она возвратит нам то что справа. Фокус с Сокращёнными вычислениями, анологичен.
Дальше немножко про функцию not. Что бы её не скормили, она возвратит True, или False. Ну вот пример

>>> not False
True
>>> not True
False
>>> not 0
True
>>> not
Ну и последняя капля ,для тех кто не знает как считается факториал с помошью рекурсии.
Вызывается функция с 2 параметрами, 1 (a) - служебный, собственно он будет результатом. 2(i) - то чиcло факториал которого вы собираетесь получать. В своём теле функция умножает служебный параметр(a) на то число факториал которого вы хотите получить. И полученый результат записывает в (a), после этого функция уменьшает (i) на еденицу, и вызывает себя-же, с новым a и новым i. Так продолжается пока i не станет равным 0, к этому времени в a у нас будет факториал i.
вот код:

def fact_def(a,i):
 if i!=0:
  a=a*i
  i-=1
  return fact_def(a,i)
 else:
  return a
Теперь есть всё, чтоб понять наш пример. Если у вас есть спортивный интерес, лучше не смотрите и постарайтесь на основе вышеизложенного написать своё решение. Я узнавал всё о чём я написал сегодня методом научного тыка, проб, предположений и ошибок. У вас же халява, так что вперёд и с песней.

Ну а для тех кто ленив, то вот :

fact_lambda =lambda a,i: not i-1 and a*i or fact_lambda(a*i,i-1)
Если и сейчас вы недопоняли, то читаем дальше.
Ход 1)Поставлю ка я and. При чём так, что по левую сторону будет i-1, а по правую вызов себя-же с i-1 и a*i. (i-1)and(self(a*i,i-1))
Что это даст? (Я для вас поставлю метку Label1, и бо вернусь к этой строке алгоритма )
Label1: Сначала программа считывает левую сторону и смотрит что она равна True( число ведь) потом правую, а в правой вызывается этаже процедура и повторяется Label1. И так пока левая cторона вдруг не станет 0. Когда это случится вся функция возвратит 0.
К примеру я сказал "Факториал от 1,3" и функция построила рекурсивно для себя вот такую картину (3-1)and(2-1)and(1-1). Когда оно дошло до 1-1. То Рекурсия завершилась, потому что выражение равно False, дальше считать нет смысла.
Ход 2) Пусть будет не and а or, только вместо (i-1) будет not(i-1)   Итого, результат аналогичен. Только функция теперь возвращает не 0 а True, потому что not преобразует 0 в True. Дальше, мы знаем, что функция or когда настигнет правдивый результат( это с левой стороны, для этого надо чтоб i-1 ==0) возвратит нам значение с левой стороны. Значит давайте поместим в левую сторону or, end: ((some1)end(some2))or(some3). При чём этот энд должен возвращать факториал на текущем ходу(a*i) при условии что мы дошли до последнего i  (i=1). То-есть он должен быть гдето таким ( not(i-1) ) and( a*i )  .  Когда i станет 1. not(i-1) возвратит правду, и ( not(i-1) ) and( a*i )  тоже возвратит правду, но не просто правду, а вспомним наши пасхальные яйца, правду из правой её руки. А в её правой руке, находится текущее состояние факториала.
Ход 3) Осталось объеденить. Вспомним что мы сделали в Ходе 1, и в начале Хода 2. Да-да мы планировали, Чтоб вместо True которое возвращает not(i-1) возвращалось значение факториала в данный момент. И вот мы сделали это в конце 2 хода. Вместе это выглядит так.

; (   ( not(i-1) )and( a*i )  )or( self(a*i,i-1) ) 

В так как все логические операторы имеют одинаковый и самый низкий приоритет, скобочки можно убрать, выполнятся они будут последовательно, как раз так, как нам надо. Но со скобочками, мне кажется, нагляднее. Хотя на деле, без скобочек красивее. Ну вот. Разжевал буквально до пюрешки. Вам осталось только сглотнуть.  Спасибо тем у кого хватило терпения дочитать эту статью.
Читать дальше......

воскресенье, 14 августа 2011 г.

PyQt Пару слов о потоках.

Графический интерфеейс очень не любит потоки. Ну это естественно, его основная цель - пеерисовываться, медленно последовательно прорисовать каждый пиксель каждой кнопочки, ему далеко до одновременной перерисоки, Он как библиотекарь к которому приходишь за учебниками в 8 класс, и он по очереди приносит тебе каждый учебник. А когда его терзают одноверменно 4 процессора по поводу перерисовки, он ничего не понимает. И поэтому всех кроме первого посылает В (|) И вываливается с ошибкой. Попробуем организовать что-то типо очереди.

Так-Так. Лабръораторная работа номер N, Работа потоков с графическим интерфейсом.
Сначала я думал так:"а что если сделать действительно очередь". Тоетсь сделать класс Lock примерно таким

class Lock():
def __init__(self):
self.locked = False
def begin(self):
while self.locked:
pass
self.locked = True
def end(self)
self.locked = False
## только потом я обнаружил что
## этот велосипед изобрели до меня 
## в threading.Lock()
сделать обьект такого класса, и обличить изменение интерфейса в бегины,энды. Былобы неплохо.
Так програнывает в консоли в критических секциях, или протсо в выполнении какого-то кода. но не с Qt.Ребята создававшие PyQt видимо подумали что я буду небезопасно изменять их графический интерфейс. Ну вот они и запретили потокам его трогать. Так что трогать интерфейс может только главный поток. Ну и что делать спроситте вы? Можно посылать сигналы главному потоку. Вот это мы и попытаемся сделать. И так упрощённая задача. Есть пользователь User который выглядит гдето так.

class User():
def __init__(self,name):
self.name = name
def event(self):
pass
def do_some(self):
print('user.do some')
T = threading.Thread(None,self.event,None)
T.start()
time.sleep(10)
print(self.name)
Это упрощённый вариант,функциональностью не кишит. Но зато каждый пользователь исключительный. Для нас отличается только именем. Мы видем что в функция метода do_some вызывает event(событие , которое мы потом заменим в процессе написания кода) и потом работает ещё 10 секунд.И печатает имя своё.

Формочка наша, это PlanText и pushButton. большего для тестов не надо( я ленив, не люблю писать формы, даже в Дизайнере)

сlass MainForm(QMainWindow):
def __init__(self):
super(MainForm, self).__init__()
uic.loadUi("test.ui", self)

self.connect(self.pushButton,
SIGNAL("clicked()"),
self.pushButton_Click)

self.engine = Engine(self)


self.connect(self.engine,
SIGNAL('send(int)'), self.receiver)

def pushButton_Click(self):
T = threading.Thread(None,self.engine.userlist[0].do_some,None)
T.start()
print('pushButton_Click')
pass
def receiver(self, value):
self.plainTextEdit.appendPlainText(str(value))
Пожалуй вы в замешательстве, тчо такое engine... engine это класс в котором живёт программа. Если немного посмотреть то Графический интерфейс у нас в MainWindow, Данные( обьекты) с которыми мы будем работать это User. Ну а как мы с ними будем работать, это лежит в engine.
Вот он

class Engine(QObject):
 def __init__(self,form):
  QObject.__init__(self)
  self.form = form
  self.userlist = []
  self.userlist.append(User('Alex'))
  self.userlist[0].event = self.event
 def event(self):
  print('Engine.event')
  for x in range(10):
   self.emit(SIGNAL('send(int)'), x)
   time.sleep(0.1)

Я его наследую от QObject почему? потому что он должен порождать сигналы(emit) а это умеет делать только QObject в конце концов мы ведь с Qt работаем. И сссылку на engine мы помещаем в MainWindow, чтоб можно было вызывать его методы в реакциях на кнопки, и enginу мы сообщаем ссылку на форму, чтоб он мог её изменять.Что у нас есть в engine? У нас есть userlist в котором за жизнь программы будет жить только 1 пользователь Alex. И обратите внимание на строку self.userlist[0].event = self.event Таким образом я тому самому event в Userе присваиваю мой собственный переопределённый event, в котором содержится посылка сигнала на изменение интерфейса.

 def do_some(self):
  print('user.do some')
  T = threading.Thread(None,self.event,None)# да,да вот тут и вызовится
  T.start()
  time.sleep(10)
  print(self.name)

Теперь ещё раз прочитите код в MainWindow Видите, по нажатию кнопки вызывается метод do_some единственного нашего пользователя. В нутри метода do_some вызовется переопроеделённое event в отдельном потоке.
И 10 раз выполнится строка self.emit(SIGNAL('send(int)'), x) что это значит? это значит что класс engine генерирует Сигнал 'send(int)', с параметром x. В это самое время основной поток увидит что сигнал сгенерирован вот это строкой

  self.connect(self.engine,
  SIGNAL('send(int)'), self.receiver)

Что у нас тут? мы приконектили сигнал 'send(int)' от self.engine к функции self.receiver.
Это значит тчо если вдруг self.engine скажет 'send(int)' , то вызовется функция self.receiver с параметром x.

А что у нас в receiverе? а там у нас добавление в PlainText переданного параметра.
И ву-аля, это основной потом, при этом наш Юзер в это время спокойно отрабатывает свои 10 секунд, и никому не надо ждать. Но вы не могли не заметить что do some я вызываю в отдельном потоке, почему? Ведь сигнал я уже с потока посылаю. Потому что если я не вызову отдельный поток, то 10  секунд работы прийдётся выполнять основному потоку, а это значит что в это время он не сможет принимать сигналы и изменять граф. интерфейс,  Сигналы будут строится в очередь,  и только когда 10 секунд работы завершится , сигналы приймутся, и PlanText обновится. А когда я запускаю работу Юзера в потоке, то основной поток свободен для наших нужд. Ну вот. Теперь я и вы, можем делать сложные программы с длинными асинхронными вычислениями и связями, и вовремя отображать на экране всё это, без падений программы, потому , что вся работа лежит на новых потоках. Основной поток занимается только по сути обновлением Окна.




PS: Обратите внимание на передаваемый сигнал с параметром, в сигнале я явно указываю ТИП передаваемого параметра. К примеру если вам нужно передать строку , советую использовать QString. Если надо передать параметр своего типа, то этот тип надо специально зарегестрировать до его передачи с помощью qRegisterMetaType()


Читать дальше......

вторник, 28 июня 2011 г.

Writing Django widgets, или "Никаких учебников, только исходники"


Единственный учебник по программированию который я пока-что прочитал от корки до корки  это "Язык программирования Python" хороший учебник. Многое мне дал. Остальные я использовал как справочники, и читал парочку первых страниц с описанием синтаксиса и основных особенностей.Да-да, это плохое качество, но когда времени нет на 1000 страниц теории, а надо сделать что-то ручками, и работающее, то Документация + http://stackoverflow.com/+ Блоги, и в атаку.
Так было и с Django.
И так, Writing Django widgets.
Информации по этой теме мало, документация хреновая.Поделюсь 2-х дневным опытом.
Widget в переводе с забугорного знать как изобразить.
Что мы будем писать? Виджет календарика.
Я погорячился со словом писать. Ну зачем писать то, что уже давно написано, причём сотни раз,умными трудолюбивыми людьми?
Пусть на другом языке, но написано.
Мы просто прикрутим Скриптик к нашей формочке.
Шаг 1
И так у нас есть простенькая формочка

class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField()
    Date = forms.DateField()
Дабы раскрыть архитектуру действия Вижетов, от календарика мы пока удалимся.

class My_widjet(forms.widgets.TextInput):
    def render(self, name, value, attrs=None):
        return """Простите Блог спот и highlight пытаются интерпритировать HTML Теги""" 
Простите, Блог спот и highlight пытаются интерпритировать HTML Теги.
Поэтому буду давать ссылки: Преведущий код. Да покажите мне такой пример 2 дня назад, я бы не заморачивался столько времени. И нервов бы сохранил. Это, только что, был наш с вами первый виджет. Теперь применим его (когда это возможно я всё-же код буду Пастить сюда)

 class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField()
    Date = forms.DateField(widget = My_widjet)

Ну что, загружайте страничку с вашей формочкой, и "О чудо!" Наш виджет сработал Теперь это вовсе не поле для ввода даты, это ссылка на гугл.
Что от сюда надо вынести?
  •  Виджет целиком и полностью заменяет то к чему его применили. Заменяет он это методом render(он вызывается автоматически), точнее не самим методом а тем что он возвращает. 
Шаг 2
Но согласитесь, целый календарик в строку пихать это совсем по быдлокодерски. Поэтому любимый Django позаботился и дал нам класс Media в Виджете, с помощью него можно по человечески работать с таблицами стилей и яваскриптами . Слава богу, включение скриптов и стилей в Media хорошо продокументировано на официальном сайте. Но есть 1 костыль. Если вы прочти документацию, то увидели, что в последствии в виджете self.media(не люблю когда Питонеры попросту играются с регистром, вместо инициализации интуитивно понятных имён)
будут строки подключения файлов скриптов. Но работать эти строки будут уже в браузере. Я уже был в отчайнии, пока не догадался, что нужно сделать чтоб скрипты подключились. И так в медиа у нас лежит что-то типа 

class Media:
  js = ( 
     "/src/js/unicode-letter.js",
  )
а в render мы прописали что то типа

return "%s some code"%self.media
Таким фигом в браузере у нас
<script type="text/javascript" src="/src/js/unicode-letter.js"></script>
А что по Адресу скриптика? А 404 по адресу скриптика.
И отрубите мне копыта если это есть в официальной документации.
И почему там 404, и что делать? Всё просто. Ваш сайт это не html страница, это Джанго проект, и когда вы запрашиваете его о какой-то  ссылке,  он ищет её в файлике urls.py, и вызывает асоциирующуюся с ней функцию, которая в свою очередь возвращает, запросившему её, данные. Вот такой вот каламбур. Теперь когда нам известна суть проблемы мы может её решить.
Надо в наш фаил привязок добывить такую строку

('^src/([\x20-\x7E]*)/?$',views._catalog),

Для тех кому не понятно советую почитать про регулярные выражения, это очень полезно. Я в кратце поясню при вызове чего- начинающегося на src/... вызывается функция views._catalog с 2 аргументами, 1 - request. А второй это всё что после src/ в виде строки.

Далее создадим функцию _catalog в views


def _catalog(request,path):
 path= ""
 try:
  f = open( os.path.join(os.path.dirname(__file__), 'src/').replace('\\','/')+path,'r')
  path = f.read()
 finally:
  f.close()
 return HttpResponse(path)
Да правильно, она считывает фаил по указаному пути( мы ведь уже не в браузере, и файловая система нам доступна)
И ява скрипт будет работать.
 Что от сюда надо вынести?
  • Привязку пути для ваших скриптов к функции которая их возврашает
Шаг 3  Собственно календарик. Я использовал вот этот чудный календарик JSCal2. Для того чтобы он всплывал и по кнопочке и заполнял поле датой и годом, и временем достаточно сделать так.
Тоесть надо подключить css и Js файлы, и выдать пару строк в ответе. Там около 15 файлов css.Можно было разоборатся, что надо, что не надо, и по  подключать это как должно быть, но я устал, поэтому сделал так. Вот Класс Media для виджета календаря.  Как видете, в нём я создал свою переменную my_css, благодоря этому мне не пришлось прописывать в словарик каждый css файлик.
Ну а теперь целиком весь виджет .
Меня не мало бесит, что приходится подставлять в строку (name,name,name,name) но я не придумал пока как это сделать по дугому. Думал сделать функцию типо этой

def N_times(times,what):
    I=0;
    T=tuple()
    while I<=times:
        I=I+1
        T=T+(what,)
    return T
Но это тоже не очень красиво. Придумаю отпишусь. Ну вот. Календарик есть. Ура. Мы разобрались как работают виджеты и сделали кадендарик который можно подключить в 1 строку к любому field-у.
Читать дальше......

Python



from Antigravity import *



Читать дальше......

четверг, 23 июня 2011 г.

Django vs git vs github

Пошел на работу, дали тест. 13 заданий по Джанго. Хоть питон знаю, в Джанго я новичёк. Для контроля версия(это мой первый опыт контроля версий) использовать должен GitHub. Немного поделюсь опытом. С Джанго особых проблем не заимел. Всё пошло как по маслу. Вот в этом самоучителе можно найти всё чтоб начать. И документация на оф сайте хороша.
А вот с github om и Mysql инфу собирал по кусочкам. И так с гит Хабом. Сначала надо установить Git это не сложно, он в синаптике есть. И на офф сайте даже в картинках показано как это сделать. Далее надо зарегестрироватся на GitHub, это тоже просто. Потом получить SHH ключ, элементарно, но с граблями. На оф сайте в картинках рассказано как это сделать. Грабли в том что надо вводить пароль, иначе файлик выходит не такой какой надо.Внимательно смотрите чтоб в начале файла было shh-rsa
А в конце ваше мыло.Потом создать респозиторий Потом в консоли надо привязать вас к вашим данным.

$ git config --global user.name "Firstname Lastname"
$ git config --global user.email "your_email@youremail.com"

Перейти в папку с проэктом и сделать git init.
После нужно добавить все файлы проекта в git: git add -A
Потом создать папку на сервере Гит Хаба  git commit -m 'First commit or any text' 
После добавить место для хранения новой инфы
git remote add NEWPLASE git@github.com:your_email/your_progrct.git
Если хотим добавляем Бранчь git branch NEWBRANCH 
и заливаем на сервер наш проект
push  NEWPLASE NEWBRANCH

Вроде с гитом всё, я хочу спать, поэтому про Mysql и некоторые грабли в Django расскажу потом


Читать дальше......

четверг, 26 мая 2011 г.

Перевод строки

Разбаловались мы программисты высокого уровня замечательным символом \n. Но не так часто знаешь что это за символ и что за собой кроет. Assembler. Все мы знаем что для перевода строки достаточно вывести 10 символ как любимая консолька перескочит вниз, но с файлом такие штучки не пройдут.
 Точнее нет, конечно символ запишется, но мы совсем забыли о том что такое ОП. Оказывается различные ОП, по разному трактуют символы перевода строк, конечно под каждую ОП создан редактор не использующий стандартные библиотеки и способный трактовать всё что хочешь и всё как хочешь, но это не стандартно. В первые с различными трактовками перевода строк я столкнулся на Питоне, когда под Виндой решил чуточку подредактировать скрипт который на писал на Линуксе(Of Top чувствуете разницу ПОД Виндой и НА Линуксе) И обнаружил что открытая блокнотом программа состоит из 1 длиннющей строчки, время от времени с какими-то квадратиками вместо переносов строки. Ну открыл в notepad++ и всё нормально (с тех пор не использую никогда блокнот). Если мы поместим 10 символ в фаил блокнот его отобразит НИКАК. Если мы поместим символ перевода строки в фаил (0Ah) то его блокнот тоже отобразит НИКАК. Чтоб блокнот его хоть кк-то отобразил мы должны поместит символ возврата каретки(0Dh) и потом Символ переноса строки(0Ah). Эта схема будет нормально интерпретироватся во всех редакторах, даже тех кто понимает обыкновенный перевод строки 10 символом, да к стати, вы можете меня наругать и будете правы. Ведь 10 символ это и есть 0Ah в шестнадцатеричной кодировке :) а 0Dh - возврат каретки. И если мы заглянем в учебник нам скажут "переводите так:
сначала 10 потом 13" (хоть порядок не имеет значения). И сетовать мы можем на заботливую консоль, и на свою природную лень.
Читать дальше......

вторник, 24 мая 2011 г.

Макросы это классно

Первое моё знакомство с макросам было случайным. Я обладаю плохим свойством засыпать за чтением учебников. Поэтому учебники я не читаю, и впервые узнал про макросы от преподавателя, который посмотрел что я в сотый раз пишу цикл по 2 переменным и посоветовал мне создать макрос.
Оказалось теперь с помощью
 #define F for(i=0;i<n;i++)
я могу вместо обыкновенного цикла писать просто буковку F. Любопытно также то что Си вполне поддерживает кирилицу в макросах, так что можно по извращатся и набить что-то типа 
#define сделать_10_раз for (i=0; i<10;i++)
Вообще можно весёлый исходник составить.
А теперь макросы в ассемблере, они мне невероятно облегчили жизнь.
Как я задолбался с вечной отладкой и выводом символов порчей регистров, и так далее, но вот ВНЕЗАПНО наткнулся на макрос.
И теперь вместо

push si
push ax
push dx
tabl db '0123456789'
mov si,A
mov ah,2
mov dl,10
int 21h
mov ah,2
mov dl,tabl[si]
int 21h
mov ah,2
mov dl,10
int 21h
pop dx
pop ax
pop si 

Я пишу просто
ToVisual A
где A - то число которое мне надо отобразить.
Классно ещё то что макросам можно сообщать параметры. Да, согласен. Процедуры лучше макросов по занимаемому месту, но по скорости работы макросы выигрывают. Макрос - простая замена текста. Теперь мои программы даже на ассемблере гораздо больше человечны.






















Читать дальше......

суббота, 21 мая 2011 г.

Ночь в музее.

Вчера выступили в музее со спектаклем Щелкунчик, было хорошо: без люфтов, томозов, собрано, слажено, отлично. Отличный танец мой и Алиски. В общем не плохо. Мы не пошли ни на какую культурную программу, было как-то "уставше" от культурных программ. Портит вечер немного разве что небольшой скандал, хотя я до сих пор не понимаю свою вину. Я вышел проводить своих друзей, проводил и вернулся. Да, пожалуй я виновен в том что я не взял телефон и не сказал ни кому куда я направился. Но у меня есть голова на плечах, я знаю что мы закрываем вечер и что надо вот-вот вернутся. Они так-же мои друзья и я люблю их, какими бы они там ни были. Ещё неплохо влетело Косте, сначала за задранные ноги(не поспоришь есть за что) потом уже за что ни-попадя, за то что он оказался рядом с кругом сидящих на полу людей, даже не он его организовал. За то что он перенёс Олю из одного конца зала на руках в другой.  Ну ладно. Бывает так что люди друг друга не понимают. Вероятно что-то на подобии вышло в этой "Ночи в музее".  Всё равно мне понравилось, спасибо всем, в особенности Наталье Георгиевне нашему любимому руководителю.
Читать дальше......

среда, 18 мая 2011 г.

"Неделя убита на ошибки компилятора", "или польлуйтесь проверенным временем ПО"

И вот. Началось всё с обновления, я всё таки согласился на надоедливое окошко " а не хотите ли вы обновить всё и вся?". Я подумал , а почему бы и нет? Ново, лучшее, новые фитчи удобства, клёво всё. Но вот буквально после пары дней я заметил что-то не ладное, мои программы идеальны по определению а работают почему-то не так, я перепроверял алгоритмы много раз они чисты как слеза не целованной девственницы. А работают не правильно и хоть ты убей. Вот уж я пошел по контрольным точкам в каждой строке и проверял состояние переменных каждый раз пока вдруг не обнаружил УДАСНУЮ ВЕСЧЬ!!! Скорее земля сомкнутся с небом чем такое может произойти, наверное в тот момент грохнула ещё какая-то атомная электростанция, может Юпитер обозлился на меня за нерегулярные жертвоприношения, но цикл for вышел за свои рамки! вот такой код, который я использую в среднем по 3-4 раза за час не работает
for i:=0 to 10 do
    for j:=0 to 10 do
       Memo1.Lines.Add(IntToStr(i*j));
Вот так вот ребята. Пришлось переписывать все свои for в whilы.
Ну думаю нет, это адская мука, ну на фиг это Делфю а напишу ка я жизнь на С++.  Фух, там хотя-бы for работает. Писать в наглую по такой же идее скучно, что-бы можно сделать? О! Придумал. А не буду ка я использовать стандартный класс std::Vector.  А научусь ка я самостоятельно работать с динамическими структурами данных на низком уровне.Будет у меня одномерный динамический массив, напишу ка я пересчёт показателей из одномерного в двуменый, пропишу способы доступа как свойства, в общем чтоб научится как положено. Но вот написал смотрю, не работает, мусор из памяти берёт, ну давай рыть что не так. И вуаля. 4 строчки кода.(FA и FB - динамические массивы, A - свойство досупа с пересчётом показателей к FA, B соответственно к FB )

ShowMessage(A[4][1]);//выдал мне -1 как положено
delete []B;
B = new int[50];
ShowMessage(A[4][1]);// и что бы вы думали? выдаёт 16492261(короче мусор)
A  никак не связано с B. Они тупо наезжают друг на друга в памяти.
причём портится только 1 элемент массива A, именно [4][1]. Соль ещё в том что раньше массив B был 4*4 то есть 16. Вот скажите как можно программировать, если не знаешь чему можно доверять а где ошибки компилятора? Как результат неделя убита.
Читать дальше......

пятница, 13 мая 2011 г.

Программирование это механизм.

Помню невероятно радовался когда написал свой первый Хеловорд.
Это был питон( совет всем начинающим начинать с питона ) А ведь до поступления на специальность я даже не знал что такое программирование и с чем его едят. Я поступал на кораблестроительный(океано-техника). Для меня не была принципиальна та специальность, я ещё не определился тогда. Но документы перепутали, и я чудным образом попал на компьютерные технологии. Можно было перевестись, но мне было лень. И вот я понял что надо как-то что-то делать, скачал учебник по питону, скачал питон и начал читать, первые несколько глав конечно были скучными одна теория, всякие пространства имён, типы данных и т.д. Я уже был готов закрыть учебник. Но когда наконец появилась практика и на экранчике появилась консолечька с какой-то  надписью вот тогда я просто прыгал от счастья. дело не в чём то новом, дело в том что своеобразный механизм который я сконструировал РАБОТАЕТ! Позже стали захватывать дух математически красивые идеальные решения интересных задач( круглый поезд, 2 мухи, 2 верёвки).
Алгоритмизацию вполне можно сравнить с каким либо очень сложными механизмом. Ты прописываешь путь движения своих переменных, когда они должны изменятся, куда они должны попасть, что с ними делать, От куда взять и куда положить, это игра по правилам, сложная игра. И после обнаружения что ещё 1 тобою сотворённый механизм работает несравнимо ни с чем. Секс, наркотики,алкоголь, это всё мелочи по сравнению с тем чувством что пара тысяч твоих строк успешно функционируют. Окружающие не понимают твоих радостей, они лишь видят какие-то картинки, символы на экране, что-то делается, помню в воспоминаниях Линуса Торвальдса, когда он создал многозадачность у себя и его программа выделяла процеcорное время для печати букв A и B. И он позвал свою сестру чтоб она это оценила. Но Сестру это почему-то не впечатлило, для неё это были лишь буквы A и B. Люди не знают насколько сложно и  гениально всё функционирует внутри. А мы радуемся.
Читать дальше......

Игрушка "Жизнь"

баловался,вот написал игрушку Жизнь. Интересная штуковина. Правила есть в вики. Интересная статья на хабре. А для тех кто уж заинтересовался то вот целое исследование. Ах, да, вот и сама игрушка. Если хоть кого заинтересует, дайте знать, допишу много чего интересного(сохранение в фаил, пошаговое выполнение, шаг назад, стандартные интересные комбинации и т.д.)
Читать дальше......

среда, 20 апреля 2011 г.

И создал я блог, и увидел что это хорошо.

Блог для программиста, возможность поделится различными наработками с другими программистами. Нельзя же каждый раз изобретать велосипед. Нет, конечно иногда это полезно, но исключительно для веселья и саморазвития.
Я благодарен очень многим блогам в полезной информации, которую я там нашел. Теперь дам возможность другим программистам не наступать на грабли. В блог можно помещать интересные мысли, свои и чужие, которые не помещаются в твитер или контакт. В общем, отделил я свет от тьмы.
Читать дальше......