Блог C2ArchitectorЖурнал

Журнал

5 июля 2008

Дописал псевдокод парсера калькулятора и распечатки иерархии. Завтра отшлифую его а послезавтра реализую в коде и будет ясно работает или нет. А сегодня буду читать статьи про соединение питона и С и архитектуру.

В калькуляторе это моё первое применение псевдокода. Есть ошибки. Я пишу его слишком детально, как будто на С только на русском языке, потэому выгода от него небольшая. Рутину надо выражать логичесими концепциями, при этом обращать внимание на сложные моменты, устанавливать их и находить решение.

Например рутиной оказалось всё кроме того как реализовывать увеличение уровня иерархии. Создавать при этом пустышку или цеплять ребёнка прямо к другой сущности. Пока остановился на специальной сущности типа выражение (или составное число).

Также сложности с манипуляцией указателями следующий дочерний, надо не только их правильно расставить, но и иметь предыдущий элемент.

Скобки превращаются в лишние пустышки и их надо удалить.

Также есть похожие функции обработки операций сложения и умножения. Я их сделал как одну функцию, но сначала думал что они разные. Умножение выделяет иерархию, сложение нет. Получилось что ради быстроты написания пожертвовал эффективностью, сложение тоже выделяет иерархию.

Также похожи функции и унарные функции. Стоит подумать о том, чтобы и их объединить.

Может удастся ещё что-нибудь объединить.

Ссылка

4 июля 2008

wglChooseVisual()
Type: Function
Category: Games
License: GNU Library Public License
Language: C

Description:
A function which mimics glXChooseVisual behavior and implements a wrapper around the obscure windows PIXELFORMATDESCRIPTOR. This function should provide a more convinient way to quickly setup a window device context for OpenGL rendering.

https://developer.berlios.de/snippet/detail.php?type=snippet&id=22

Ссылка

2 июля 2008

Книжка старая, в формате doc с ошибками, не интересно.

Проектирую калькулятор. Создал для этого тему Проектирование калькулятора.

Ссылка

2 июля 2008

Даю себе установку работать над проектом хотя бы час в день.

Начну с калькулятора, так как колорайзером буду заниматься после прочтения книжки про регулярки.

Кода на 368 строчек, часть не рабочая. Какая архитектура.

CALC_main
    CALC_parse
    CALC_calc
    CALC_present
   
CALC_parse парсит на вычислительные иерархии.
CALC_calc считает иерархии снизу вверх
CALC_present простая функция, форматирующая результат, например отбрасывая нули.

Я уверен в идее парсить на иерархии.

Сделал высокоуровневые функции рекурсивного парсенья подвыражений и добавления их в иерархии. Проблемы с низкоуровневой организацией парсенья и считания. Попробую разбить модуль на файлы, так как уже запутываюсь куче функций.

Разбил на несколько модулей и прокомметировал некоторые функции, плохо что не сделал этого раньше. Теперь стало чуть понятней. Есть например модуль calc_parse. У него есть 2 высокоуровневые функции. CALC_parse создаёт корень и вызывает CALC_parse_subexpressions. Она циклом выдёргивает следующее подвыражение которое может быть составным, добавляет его в иерархию и рекурсивно парсит его подвыражения. Проблема в функции которая собственно должна просто выдернуть выражение. Она у меня получилась рекурсивной, хотя теперь понял что не должна. Рекурсия в CALC_parse_subexpressions, а CALC_parse_expression парсит только одно подвыражение. Причём оно должно быть максимально большого уровня. Например скобки самого большого уровня. Эта функция должна принимать строчку выражения, выдёргивать из него подвыражение и возвращать структуру для добавления в иерархию. Например если есть (1*2+3)+(4*5+6), то сначала она вытащит (1*2+3), потом 1*2, потом 1, *, 2. Для этого надо упорядочить операции по приоритету:
()
*/
+-
Какой приоритет функции? Она содержит скобки и может содержать подвыражения. То есть она как скобки, но выше или ниже их? Наверно такая же. Это типа обычные скобки, но над которыми проводится ещё операция, поэтому
() func()
*/
+-
Добавлю сразу и константы, а также собственно числа:
() func()
*/
+-
const и value
Есть ещё унарные операторы +-, которые могут быть перед скобками, функцией, константой, числом, + или -, но не */. То есть перед тем что может быть числом или перед самими собой. Я рассматривал унарные операторы как функцию, которая обозначается как оператор и не имеет скобок. Отличается от оператора тем, что перед ней нет того что может быть числом. Рассматривать все +- как одинарные операторы я отказываюсь, не нравится так потому что не похоже на то как я воспринимаю. Итак подведём резме унарным операторам: приоритет функции, нет скобок, ожидают число, перед ними не число.
(число)    func(число)    +-сколько_угодно_раз затем число
число*число    число/число
число+число    число-число
const    value

Какой может быть псевокод функции?

функция поиск и парсенье выражения
    взять выражения по приоритетам
    для каждого выражения начиная с высшего приоритета
        попробовать на совпадение выражение
        если совпало то
            парсить это выражение
            вернуть структуру с этим выражением
        конец если
    конец для каждого выражения
    вернуть 0 что означает что выражений больше нет
конец функции
   
Как пробовать выражение на совпадение и как его парсить? Этим я займусь завтра.

Ссылка | Комментарии [1]

2 июля 2008

Прочитал главу 29 "Интерграция".
Прочитал главу 30 "Инструменты программирования".
Прочитал главу 31 "Форматирование и стиль".
Прочитал главу 32 "Самодокументирующийся код".
Прочитал главу 33 "Личность".
Прочитал главу 34 "Основы мастерства".

Резюмировать не могу. Разве что, интеграцию делать итеративно, инструментами пользоваться или даже самому сделать, стиль главное чтоб был, код писать чтоб и без комментариев понятен был. А кстати он не поддерживает комментирования каждой строчки, рекомендует прототипирование и потом оставлять это как комментарии блоков. Я каждую строчку всё равно буду комментировать, но прототипироание надо тоже применять. Программист должен признавать свои ошибки, ограниченность своего ума, быть чесным, любознательным, должен читать.

Сейчас буду читать или мифический человеко месяц или про регулярки. Постоянно думаю о коларайзере и калькуляторе. Там есть проблемы которые я не знаю как решить. Решил хотябы формализовать их и указать возможное решение и имеющийся прогресс, чтобы поднять мотивацию, но не хочется пока лезть в код.

Ссылка

30 июня 2008

Потом решил что сам я уже прогрессировать не могу, так просто не могу найти книжки про программирование web, где бы было что-то новое. А новые области типа дизайна я изучать не хотел. Я решил что нужна команда специалистов, где бы я мог бы быть кодером, тут бы опытные товарищи подсказали с тем о чём в книжках не пишут, а другие делали свои части, типа дизайна. Решил попробовать устроиться на работу. Но меня не взяли. Не было портфеля, не учился в вузе, кроме того вёл себя не уверенно, что делать не рекомендую. Если ведёшь себя неуверенно, то работодатель думает, что это ты не уверен так как ничего не знаешь или просто не любит таких. А я был в депрессии из-за предыдущих неудач и сложности жизни. Да и хотел посмотреть как будут вести себя работодатели с волнующимися, просто не хотел перед ними раскрываться. (На самом деле я даже слишком самоуверенный.) Попытаются успокоить, выяснить способности? Щас. Я из-за своей неуверенности после того как сказал что нет портфеля и не учусь сразу был списан в утиль. Думаю, если бы вёл себя уверенно, то мог бы заинтересовать даже без портфеля. Это ж всего лишь людишки, управляемые эмоциями. А я то думал, что будут оценивать объективно и попытаются помочь. В следущий раз приду уже с портфелем. Буду изображать из себя позитивиста, будто бы я уверен в себе, и делать вид что мне очень хочется у них работать и что я готов сделать для этого всё. Отказываться ли выполнять дурацкие тесты ещё не знаю, может стоит выполнить но предупредить что я не считаю, что они оценивают мой уровень поэтому к ним не готовился. Работодатели наверно просто привыкли что всякое быдло просто выгрызает себе эту нещасную работу и ожидают ото всех новичков такого поведения и если видит не такого, то отбрасывает на всякий случай. Видать никакого кадрового голода нет. Если бы был, с кадрами так бы не обращались. Действительно, программирование это ж своего рода элитарная отрасль с большой зарплатой, так что многие туда ломятся и получить место сложно.

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

Но сколько это по сравнению с теми, кто отучился на 2 курсе? Возмём например Найтмареза, спасибо ему за его публичность. Он как я понял уже получил диплом, не знаю, это 4 или 5 курс. Он уже работает, даже женат, с чем его и поздравляю, и у него есть комплекс физических программ. Последнее что он показывал, и что было дипломной работой, это модель движения электронов в поле. Уровень графики там простой. Просто вывод нетекстурированных плоскостей и точек или шариков. Формулы расчёта движения электронов. Это как мне кажется не сложнее формулы движения мяча в football-o-saurus. То есть сказать, что он ускакал от меня на недостижимое расстояние нельзя.

С другой стороны, я как-то наталкивался на интересные и глубокие темы обсуждаемые в вузе типа тут http://ttp.unicyb.kiev.ua/?action=language¶ms=ru (украинский язык).
3 курс
Розробка інструментальних засобів ілюстративної графіки для інтерактивних навчальних курсів
Реалізація підсистеми редагування HTML-сторінок
Реалізація підсистеми контрольованого доступу до табличних БД
Розробка файлового менеджера та під системи спеціалізованої обробки текстів
Система управління WEB – сайтами
e-commerce системи
Портальні системи
Технології пошуку інформації в Internet
Тут ничего особо глубокого нет, но зато показывается что они на 3 курсе учат практические вещи, те же CMS-ки. Про глубокое тоже как-то видел, сейчас найти не могу. Там было системное программирование, алгоритмы, операционные системы, чё-то такое.

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

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

Преимущества, это наверно то, что я трачу на обучение то же или большее время, но меньшими усилиями. Также может я его более эффективно трачу, так как учу то что мне интересно. Выбираю темы, выбираю когда читать когда кодить. Могу тратить 2 часа на еду, 2 часа на спорт, 10 часов на сон, и около 8 часов в день на обучение, особенно когда не пишу такие длинные посты, сегодня исключение. При этом я никуда не спешу и есть время размышлять над жизнью. Когда смотрю на других людей, то чуствую, что они озабочены городской суетой и уверен что многого они не достигнут.

Этот душевный пост разросся на таку длину, что я уже забыл зачем я его писал и какой должен быть вывод. Я хотел проанализировать своё положение и переспективы. Выяснил, что отказ от вуза было не однозначным решением, у самообразования тоже есть проблемы и пока нельзя сказать оно лучше или хуже. Если посмотреть предварительные итоги, то если бы учился в вузе, то я уже работал бы. Но я выбирал этот путь ради больших результатов, так что это не показатель. Так всегда бывает, что большой результат приходит позже. Подождём ещё.

А поводом к этому посту стало моё очередное на этот раз виртуальное общение с работодателями. Откликнулся на объявление где предлагали обучение талантливым джуниорам (опять выискивают себе только лучших, вот гады!), мне сказали пройти у них тест. Я сказал, что не пройду его так как он дураццкий. Они тогда предложили выполнить тестовое задание. Я согдасился но сдуру ляпнул можно ли мне его делать публично на форуме. Похоже что их эта фраза оттолкнула. Или не понравилось что я всё спрашиваю или не понравилась идея делать задание публично. Хотя что тут такого, понятно, что новичёк всё равно спрашивает на форуме. И они не ответили, что меня обидело и натолкнуло на эту длинную рефлексию. С работой мне не везёт настолько, что работодатели от меня уже отворачиваются даже по почте.

Ссылка | Комментарии [13]

30 июня 2008

Не буду пытаться устраиваться на работу раньше чем через год и до того как сделаю хоть 1 большой проект, так как всё равно не возьмут ублюдки. Я понял что у нас неразвитая экономика и жлобьё в фирмах хочет получить максимум, эксплуатировать рабочих как можно сильнее, поэтому предъявляет к кандидатам большие требования. Например у джуниоров php требуют опыт работы и знание html, css. Это что они ещё и дизайн будут делать? Если даже новички должны обладать опытом, то где им его приобретать? Кроме того в тестах спрашивают чепуху, типа точного знания функций, которые можно быстро посмотреть в справке. Короче совсем оборзели.

Кроме того ко мне у них особенное отношение. Чувак, который не учится в вузе и не имеет портфеля, выглядит просто как идиот, который не смог туда поступить, научился выводить "hello world", подумал, что гений и пошёл на работу устраиваться. Хотя, слышал, что студентов 2-3 курсов берут, и не думаю что они программируют лучше меня (хотя это надо доказать наконец проектом).

Так что если перед вами стоит вопрос поступать ли в вуз, то ответ, поступайте конечно, хотябы ради того, чтобы легче было устроиться на работу, так как сам факт присутствия в вузе и невылет оттуда причисляют вас к определённой элите в глазах работодателя. Типа вы смогли это осилить, значит стоящий, кроме того они надеются на математическию и прочую теоретическую базу.

Насколько я понял, для поступления в вуз в Украине надо окончить 11 классов, причём можно  иметь 1 по всем предметам, пасспорт, справку о здоровье, сдать тест по математике, примеры которого можно найти. Все эти процедуры надо выполнить даже если вы хотите учиться за деньги. А я то думал, что если платишь бабки, то тесты сдавать не надо и бюрократической хрени будет поменьше. Обидно, что даже за деньги поступить сложно, я имею в виду не способности, а формальности, при этом вузы забиты иностранцами! То есть государсто в наших вузах учит иностранцев, так как деньги зарабатывает, при этом затруднена возможность обучения собственным гражданам.

Кому-то поступить в вуз было легко, мне тоже было бы легко, если бы я не поумнел. Раньше я был уверен, что буду учиться в вузе. Так как был уверен, что заслуживаю и что это единственный путь. Но потом, когда прошла пора когда учился за оценки и похвалы, и когда задумался какая польза от того, что я учил в школе, то я пришёл к выводу, что после 3 класса я в школе учился зря. В школе преподают много лишнего. 90% тех кто учился плохо и говорили что им это не надо, говорили правду, им действительно это не надо, так как это куча специализированных знаний, которые никогда не пригодятся, а не они так говорили просто по тому что тупые и не могли учится. А я просто доверился бытующему мнению что учится хорошо у учился, интуитивно не ощущая, что это не то что мне нужно, так как думал, что для счастливого будущего нужно хорошее образование и не знал, что если я буду например программистом игр, мне нужна будет только математика (притом не вся, квадратные уравнения например не нужны), физика Ньютона, английский, но не всё остальное.

Я не кончил 11 классов, у меня нет пасспорта, справки о здоровье и я не собираюсь сдавать тесты, хотя с математикой у меня нормально (хуже чем у тех кто учился в спец школах, я им завидую). При этом я не считаю себя кретином, который даже не может получить пасспорт. Я пытался, но когда меня стали гонять по кабинетам несколько дней, то решил не тратить на это своё время, потому что я не хочу чтобы меня нагибали и обращались со мной как с быдлом. Я надеюсь, что когда-то придёт момент и мне дадут пасспорт, пригласят в любой вуз без формальностей и работодатели будут охотиться за мной. Или если такого момента не наступит, то жизнь меня так согнёт, что я побегу за паспортом и прочим, или всё равно никуда не побегу.

Почему я выбрал не учиться в вузе? Потому что я подумал, что там царит такой же дибилизм как и в школе. Я думал, что там будут учить куче лишней хрени, типа литературы, что там вообще не учат программированию, что уровень низок из-за ориентировки на дебилов, что придётся тратить много времени на транспорт, ожидание. Не хотел испортить себе здоровье этим бешенным графиком и плохим питанием. Кроме того в школе учителя говорили, что начиная со старшых классов школы должно быть самообразование. Кроме того пример Билла Гейтса. Я не хотел идти путём большинства, так как большинство рабы и ни к чему хорошему не приходят. Я расчитывал, что сам смогу стать хорошим программистом, что так мой уровень будет выше чем у большинства.

Что я имею. Я потратил несколько лет. Пара это 10-11 классы, пара - 1-2 курсы в вузуе. Может даже 3-4 курс. Не охота считать точно. Какую эволюцию я прошёл:

Сначала бейсик, делфи, потом С++. Потом идея сделать мегаигру, попытка собрать команду, бурное обсуждение, над которым ухохатывался весь форум, облом.  Изучение directX (пытался даже скелетку делать, но не осилил Адамса), winapi,  изучение Ламота, openGL (только затектурированый кубик).

Потом ударился в сеть: php, MySQL, html, CSS, javascript, useability. Тут я больше приблизился к результату. В отличие от игры мне удавалось создавать кое-какие сайты, но это было дерьмо, так как там был плохой дизайн, юзабилити, архитектура и полезность. Я наивно думал, что раз php интерпретируемый язык и у него низкий порог вхождения, то сайты делать будет легко, так как я ж изучал трёхмерную графику... Но оказалось что сделать хороший сайт не легче чем игру, не смотря на то что программировать на php действительно чуть легче.

Пробовал заниматься фрилансингом, за деньги меня никто не заказывал, было 2 бесплатных проекта. Один сайт фотографу. Тут я в первый раз столкнулся с явлением, когда клиент не знает что он хочет. Он заказал мне сайт на php и сказал типа делай сайт фотографу. Потом ему не понравился дизайн и он сказал что хочет модерн. Потом показал дизайн на флеше. Я переделал, но всё равно ему не понравилось. Причины провала были такие:
1. Баги с кодировкой и кешированием. На хостинге была другая кодировка, но хоть я и выставил utf8 ведзе, всё равно глючило. Кроме того клиент жаловался что картинки или не обновляются или каждый раз перезагружаются. Тут сказался мой непроффесионализм. Потом только я выяснил, что лучше не выпендриваться и картинки грузить с диска, а не динамически, а кодировку списал на дураццкий бесплатный хостинг.
2. Низкое юзабилити форматирования сообщений. Клиенту было сложно писать теги. И ему хотелось большей гибкости форматирования при большей простоте (наверно как в ворде). Тут сказалась неопытность в работе с клиентами. Фичалист надо уточнять сначала. Да и плохо я продумал форматирование. Для меня это было второстепенным (типа ну что такое вывод, как нибудь выведем, главное, чтоб работало), а для пользователя это главное. Это был на самом деле самый сложный модуль и я ему уделил недостаточно внимания.
3. Плохой дизайн. Я понял что хороший дизайн никогда не сделаю, так как не умею критически оценивать свой дизайн. То что нраится мне, не нравится другим.
4. Плохая архитектура и отсутствие планирования. Я просто представил сколько мне займёт это времени закодить, и могу ли я это закодить, но не думал о том, чтобы понять лучше задачу, сделать требования, сделать хорошую архитектуру, предугадать сложности, оценить сроки, попытаться удовлетворить клиента.
Хоть проект был и дерьмо, но я вынес из него много пользы. Я не могу сделать полностью сайт, так как это работа разных специалистов, я даже не могу выполнить всё программирование, так как не могу организовать архитектуру и исправить баги. Кроме того я не могу работать с клиентами и вырабатывать требования, тем более если их не может сформулировать сам клиент.

Ещё был один проект с англичанином. Он взял меня кодить магазин. Обещал гонорар сотни баксов, каждый день изливал на меня похвалы типа "Great work!". Но потом не заплатил. Насколько я понял, ему нужен был не сайт, так как он у него уже собственно был, он сказал что надо преписать, а некоторые модули, которые залазят на другой похожий сайт и достают оттуда информацию, а сайт это типа прикрытие, чтобы втереться в доверие. Когда я сделал несколько больших форм ввода данных, корзину, один модуль обработки данных другого сайта, то потребовал часть денег. Он стал выдумывать что не может перечислить, что он всеми силами пытается, но у него не получается, просил продолжать работу. Я отказался, пока не увижу хоть каких-то денег, тогда он меня послал... Тоже полезный опыт, что тебя могут и кинуть. В этом проекте дизайном я не занимался, только программил, причём точные задания, выслушивал комплименты, обещания денег. Было очень приятно, я думал, что фриланс это для меня. Но когда не заплатли, понял, что это не исключение, а что я только такого рода проекты и могу найти. Успешным фрилансером может быть только профессионал. Никаких путей типа чтобы фрилансерская фирма взяла на обучение или аутсорсинг кодера такого нет. Ни клиенты ни фирмы с непрофессионалами не связываются.

После этого облома с сайтами, но не сразу, я понял, что язык не главное, не главное и знание api, а главное можешь ли ты добиваться результата, а также что создание успешного софта включает в себя не только коденье. Оно занимает где-то четверть, на мой взгляд. Важная роль у цели проекта, требований, юзабилити, дизайна, архитектуры, тестирования, коммерции.

Ссылка | Комментарии [6]

27 июня 2008

Это совет не мой, конечно же.

Прочитал главу 23 "Отладка".
Прочитал главу 24 "Рефакторинг".
Прочитал главу 25 "Стратегии оптимизции кода".
Прочитал главу 26 "Методики оптимизации кода".
Прочитал главу 27 "Как размер программы влияет на конструирование".
Прочитал главу 28 "Управление конструированием".

Внимание качеству надо уделять с начала, чтобы к отладке прибегать как можно реже. При отладке не делать случайных исправлний, а вникнуть в проблему, а ещё лучше в программу и запастить выносливостью, если ничего не получается, то прибегнуть к грубой силе, даже переписать код.

Рефакторинг делать минимальными шагами и тестировать изменения.

Повышать производительность лучше изменением требований, архитектуры, железа, а не кодированием.

Привёл пример оптимизации, где он сокращает время с 45 минут до 20 секунд. Это он такой крутой оптимизатор, или изначально пишет такой топорный код?

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

Сравнивает с помощью == double-ы в жабе при демонстрации кеширования квадратного корня. Хотя сам же писал что дроби надо сравнивать особо.

Кстати поделюсь полезным советом про оптимизацию загрузки windows с помощью настройки сервисов :) Я сначала думал, что ненужные сервисы стоит вырубать и написал программу которая делает это чтоб вызывать её перед тем как буду играть. Или даже пробовал не грузить их при запуске, но так не все программы работают. Потом мне сказали что сервисы не занимают процессор а память выгружается в своп. Тогда я сделал все сервисы automatic, но как и при почти всех выключенных сервисах, винда грузится долго. Наверно когда automatic, долго проводит проверку каждого сервиса грузить его или нет и в конечном случае грузит только некоторые или может быть даже грузит и выгружает, а когда сервисы manual то или не может без них работать быстро или долго вычисляет что грузить. Только некоторые надо сделать automatic, а другие manual. Сначала я все сервисы сделал manual, винда загрузила некоторые, сделал их automatic. В следующий раз винда загрузила ещё несколько manual. Сделал и их automatic. И так несколько раз. Вот к какому результату я пришёл, автоматические сервисы (в комментариях есть неуверенность, так как я пишу по памяти, давно это было):
Event Log (кажется можно отключить и его без вреда для скорости загрузки),
Fast User Switching Compatibility (это по моему помогает быстрее загружаться),
Machine Debug Manager (нужен для студии, она сама его не грузит),
Network Connections (для сети),
Network Location Awareness (NLA),
NVIDIA Display Driver Service,
Plug and Play,
Remote Access Connection Manager,
Remote Procedure Call (RPC),
SSDP Discovery Service,
Telephony (кажется грузится если загружен Network Connections),
Terminal Services,
Themes (темы),
Windows Audio (плеер сам его не грузит),
Windows Time (для обновления времени по интернету).
Outlook при запуске грузит пару сервисов Cryptographic Services и Protected Storage. Если хотите чтобы он быстрее грузился, то сделайте и их automatic, но тогда винда грузится дольше.

В больших проектах ошибок на 1000 строк кода больше, количество строк на человека в год меньше чем в маленьких.

Стоимось программного продукта (программа для других) примерно в 3 раза больше чем программы (программа для себя). Теперь понятно, почему когда мне моя программа нравится, другие её просто уничтожают в критике и навешивают новых требований - они оценивают её как программный продукт. Так что чтоб мои программы нравились другим, надо работать над ними в 3 раза больше. Добавление подсветки типов и переменных к колорайзеру это примерно 100% первоначальной работы. Посмотрим, в чём же состоят ещё 100%. Кстати если бы я сначала выяснил все требования, то не делел бы 50% лишней работы, которую придётся выкинуть при создании второй версии программы.

Из ссылок заинтересовал Carnegie Dale. Это про отношения между людьми. Brooks Frederick "mythical man month" истоии об ошибках и как надо было сделать.

У меня ещё есть Гради Буч "Объектно-ориентированный анализ и проектирование с примерами приложений на С++". Посмотрим как надо проектировать в ООП. У Страуструпа тоже про это есть, но я когда его читал, вообще не понимал, что такое проектирование и не очень-то мне это далось. От этого может и проблемы с ООП-архитектурой. Может придётся и проектирование по Страуструпу перечитать. Также думаю почитать его книжку про дизайн и эволюцию плюсов.

Подогрелся интерес к тому чтобы не смотря на то что я работаю сам, хранить свой код в CVS, причём желательно на сервере, чтобы другие могли смотреть и для большей надёжности. Но помню в прошлый раз когда хотел, то не мог найти подходящего хостинга (бесплатного разумеется:), также не охота вспоминать как работать с CVS хотя там всего несколько комманд. Популярный SVN меня не привлекает, так как не видел подходящего клиента под винду. Слышал что на гугле есть SVN хостинг. Если это единственный хороший хостинг для кода, то может придётся смириться с SVN. Не понимаю, чем она так хороша, что все просто взяли и выкинули CVS. Есть ещё sourceforge, но сайт тяжеловат.

В книжке было про измерения. Натолкнуло на мысль сделать программу измерений. Например количества строчек кода. Причём с датами, чтобы можно было анализировать скорость роста проекта. Там ещё есть десятки параметров.

Задумался над своим стилем кодирования. Там есть 2 спорных момента.
1. Каким регистром буков объявлять дефайны-константы в С. У меня щас или все большие или каждое слово с большой буквы. Аргументы в пользу второго: а зачем так выделять нещасную константу, что аж всеми большими буквами её писать, достаточно отличить её от переменной большими буквами только в начале слова, кроме того это отличается от стиля в виндовс что предотвращает конфликт имён.
2. Как обозначать модули функций. Раньше у меня была идея в названии функции обозначать большими буквами иерархию модулей к которым она принадлежит. И не использовать в этой функции вызовы с большим уровнем иерархии. Но получалось, что если я пишу низкоуровневый модуль работы со строками например, то функция в нём может иметь большую иерархию модулей. Например:

int STRING_BUFFER_clear(StringBuffer* str)
{
}

int STRING_BUFFER_DELETE(StringBuffer*& str)
{
    STRING_BUFFER_clear(str);
}

int STRING_BUFFER_RESIZE(StringBuffer* str, int max_size)
{
    STRING_BUFFER_clear(str);
}

int STRING_BUFFER_APPEND_SAFE(StringBuffer* str, const char* a)
{
    STRING_BUFFER_RESIZE(str, max_size);
}

int STRING_BUFFER_APPEND_SAFE_INT(StringBuffer* str, int ival)
{
    STRING_BUFFER_APPEND_SAFE(str, buf);

}

То есть если функция STRING_BUFFER_DELETE вызывает STRING_BUFFER_clear то значит она на 1 уровень выше и должна отображать этот уровень в своём названии. А если есть функция STRING_BUFFER_APPEND которая вызывает STRING_BUFFER_RESIZE то она должна содержать слов большими буквами на уровень больше и надо добавить слово SAFE чтобы это отобразить. Может это кажется глупым, но это упорядочивает программу. Проблема только в том, что получаются сильно длинные названия и что высокоуровневая функция STRING_BUFFER_APPEND_SAFE_INT является для использующего её модуля лишь первым уровнем и функция которая её использует может быть лишь первым уровнем. А STRING_BUFFER_APPEND_SAFE_INT требует чтобы она была 6 уровня. Это логично, так как раз функция вызывает функцию которая делает много, то эта функция делает ещё больше и её название должно об этом говорить, но противоречит абстракции. Поэтому есть 2 варианта. Или убрать это требование, что я и сделал и оставил только название модуля STRBUF большими буквами. Или другой вариант, который наведывается ко мне. Это сделать функцию-обёртку STRBUF_append_int, чтобы эта функция была 1 уровня для пользовательской функции. Даже может быть strbuf_append_int чтобы она была 0 уровня, так как её может использовать функция 1 уровня в иерархии программы. Но не для каждого модуля это годится. Какой-то модуль предусматривает своё использование на нижнем уровне, какой-то на более высоком. Но как определить на каком именно? Кроме того нижний регистр модуля 0 уровня не подчёркивает модуль, а я уже привык, чтобы модули были подчёркнутыми. Кроме того всё относительно. Любой модуль может быть нулевым для другого. Поэтому пока и остановился на том чтобы просто подчёркивать название модуля и всё. Но как вспомню функцию WINDOW_create_textbox, так начинаю размышлять, а не лучше ли написать более модульно WINDOW_textbox_create или WINDOW_TEXTBOX_create.

Ссылка

25 июня 2008

Прочитал главу 20 "Качество ПО".
Прочитал главу 21 "Совместное конструирование".
Прочитал главу 22 "Тестирование, выполняемое разработчиками".
Страница 547.
Главы 20 и 21 для меня были не важны, так как парное программирование мне не светит, а про качество ПО там было в общем то же что по всей книге. Глава о тестировании более полезная, но я её не осилил. Решил разве что, что хорошо попробовать спроектировать тесты вместе с проектом программы и сделать тесты до тестируемого кода.

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

// creating console!
AllocConsole();
freopen("CON", "wt", stdout);
freopen("CON", "wt", stderr);
freopen("CON", "rt", stdin);

В работе с ошибками есть ещё уровни. Для разработки орать обо всём, для клиента только о критичном. Но до клиентов мне ещё далеко, так что обойдусь и без уровней. Хотя хотелось бы, но сейчас это неоправданная сложность.

Ссылка

25 июня 2008

Прочитал главу 17 "Нестандартные управляющие структуры".
Прочитал главу 18 "Табличные методы".
Прочитал главу 19 "Общие вопросы управления".

Вот как я придумал использовать goto. Какие выгоды: код очищения в одном месте, часть кода обработки ошибки в
одном месте, один возврат из функции.

#include <stdio.h>
#include <string.h>
#include <windows.h>

int ERROR_report(const char* title, const char* msg)
{
    char buffer[1024];
    //MessageBox(0, msg, title, 0);
    sprintf(buffer, "%s %s", title, msg);
    puts(buffer);
    return 1;
}

int LOG_add(const char* msg)
{
    puts(msg);
    return 1;
}

int read_data(void* buffer, int buffer_size, const char* file_name)
{
    char err_msg[1024];
    FILE* file = 0;
    int result = 0;

    LOG_add("read_data()");

    LOG_add("Checking buffer pointer");
    if(!buffer) {
        sprintf(err_msg, "Wrong buffer pointer");
        goto Error_Processing;
    }

    LOG_add("Checking file name pointer");
    if(!file_name) {
        sprintf(err_msg, "Wrong file_name pointer");
        goto Error_Processing;
    }

    LOG_add("Trying to open file");
    file = fopen(file_name, "r");
    if(!file) {
        sprintf(err_msg, "Can not open file %s", file_name);
        goto Error_Processing;
    }

    LOG_add("Trying to read file");
    if(!fread(buffer, buffer_size, buffer_size, file)) {
        sprintf(err_msg, "Can not read file %s", file_name);
        goto Error_Processing;
    }

    LOG_add("Completed task");
    result = 1;
    goto Clean_up;

Error_Processing:
    ERROR_report("read_data()", err_msg);

Clean_up:
    LOG_add("Cleaning up");
    if(file) {
        LOG_add("Closing file");
        fclose(file);
    }

    return result;
}

int main()
{
    int ch;
    char buffer[1014];
    int buffer_size = 1024;
    const char* file_name = "bla.txt";

    read_data(buffer, buffer_size, file_name);

    ch = getchar();
    return 1;
}

Кстати задумал рефракторинг модуля ошибок. Заменю ERROR_show_winapi на более общую ERROR_report. Она будет писать в файл, консоль или выдавать окно в зависимости от настроек типа ERROR_set_report_type(ERROR_REPORT_TYPE_CONSOLE); Проверил, можно делать окна из консольного приложения. Наверно можно и консоль из оконного. Но это будет уже не задача модуля ошибок.

Прочтённое сегодня даёт ответ на вчерашний вопрос про множественные возвраты. Макконнел их рекомендует для улучшения читабельности. Буду примнять их если не нужно освобождение ресурсов. А единственный выход можно сделать не только вложенными условиями, но и goto.

Удивили возможности таблиц. Я думал что их можно применять только для кеширования, а оказывается ими можно заменить логику или наследование. А меня как раз интересовал вопрос нормально ли это, когда в игре для логики персонажа используется куча условий. Надо будет подумать над тем чтобы применить там таблицу.

Ссылка | Комментарии [1]

24 июня 2008

Прочитал главу 11 про имена переменных.
Прочитал главу 12 "Основные типы данных".
Прочитал главу 13 про структуры, указатели и глобальные данные.
Прочитал главу 14 "Организация последовательнго кода"
Прочитал главу 15 "Условные операторы"
Прочитал главу 16 "Циклы"
Страница 405

Эти главы оказались лёгкими, нового мало, так как затрагивают вопрос кодирования, в чём я более опытен чем в проектировании и уже своими граблями пришёл к многим выводам из книжки. Но некоторые новые моменты всё же есть:

1. Оказывается некоторые именитые в компъютерной науке люди предлагают запретить массивы и использоать вместо них множества, стеки, очереди. И что эксперимент доказал что проект с таким правилом эффективней.

2.

// Макрос для определения длинны массива
#define ARRAY_length(x) sizeof(x) / sizeof(x[0])

Советует использовать этот макрос прямо в цикле. Не понятно сможет ли компилятор заменить это на константу и работает ли это с динамическими массивами.

3. Интересный совет размещать главнее основные пути алгоритма. Например в условном операторе первым условием должен быть успех:

if(status == success) {
    // algorithm
} else {
    // error
}

А я люблю сначала проверять ошибки, чтобы сразу возвратиться из функции и не делать вложенных условий. Я такую методику увидел в первый раз у Страуструпа и она меня приятно удивила. Структурное программирование, которое я так люблю, советует только 1 выход из функции то есть коррелирует с этой рекомендацией. Это заставляет меня задуматься над тем чтобы попробовать закрыть глаза на вложенность ради чистоты структуры функции. При этом я называю функции достаточно длинными именами и не хочу выходить за пределы 80 символов строчки в ширину, требование в Unix. Думаю что если вложенность будет больше 3 то буду разбивать на подфункции. Может сделаю исключение для тривиальных проверок типа проверка входного указателя.

Ссылка | Комментарии [2]

23 июня 2008

Прочитал главу 9 про псевдокод. Прочитал главу 10 "Общие принципы использования переменных".

Прошёл тест на знание типов. Надо поставить балл за каждый известный термин и половину если не уверен в значении. Вот мои результаты.

1  abstract data type
2  array
3  bitmap
4  boolean variable
5  B-tree
6  character variable
7  container class
8  double precision
0  elongated stream
9  enumerated type
10 floating point
11 heap
12 index
13 integer
14 linked list
15 named constant
16 literal
17 local variable
18 lookup table
19 member data
20 pointer
21 private
0  retroactive synapse
0  referential intergity
22 stack
23 string
0  structured variable
24 tree
25 typedef
26 union
0  value chain
27 variant

20-24 Вы эксперт в программировании. Вероятно на вашей полке стоят книги указанные ниже.
Cormen Introduction to algorithms
Sedgewick Algorithms in C++
25 - 29 Вы знаете о типах данных больше чем я. Может напишете собственную книгу.
Если больше то вы мошеннник.

Оказалось что я типо гений. Наверно я просто неправильно понял смысл выраженния "известный термин". Это наверно если собаку на нём съел, используешь его всячески каждый день, типа int. А вот что такое бинарное дерево я знаю, но не реализовывал его никогда. Может тогда пол балла надо было ставить? Пройду ещё раз. Хотя int я тоже не знаю как реализовать (в смысле что это последовательность битов знаю и про двоичную арифметику знаю, но никогда ж int не реализовывал, значит чесней сказать что не знаю), но не говорить же что я не знаю что такое int.

1  abstract data type
2  array
3  bitmap
4  boolean variable
0  B-tree
5  character variable
6  container class
7  double precision
0  elongated stream
8  enumerated type
9  floating point
0  heap
10 index
11 integer
0  linked list
12 named constant
13 literal
14 local variable
15 lookup table
16 member data
17 pointer
18 private
0  retroactive synapse
0  referential intergity
0  stack
20 string
0  structured variable
0  tree
21 typedef
22 union
0  value chain
23 variant

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

Ссылка

23 июня 2008

Теперь код часов выглядит так:

// Clock

#include <window/window.h>
#include <window/sys_vars.c>
#include <window/textbox.h>
#include <window/font.h>
#include <datetime/date.h>

// font handle
HFONT hfont = 0;

// clock update timer ID
#define Clock_Timer_ID 1
// clock update interval 1 second
#define Clock_Update_Interval 1000
// clock font height
#define Clock_Font_Height 30
// text offset from window
#define Off 2
// text color
#define Clock_Text_Color RGB(0, 0, 0)
// background color
#define Clock_Back_Color RGB(255, 255, 255)

int SYSTEM_widen_window(HDC hdc, int len)
{
    // Widens window to fit text

    // text width
    int text_w;
    // window client width
    int client_w;

    // getting text width
    text_w = FONT_calc_width_singleline(hdc, g_buffer, len);
    // getting window client width
    client_w = WINDOW_get_client_w(hMainWnd);

    // checking if we need to widen window to fit text
    if(text_w <= client_w)
        return 1;

    // resizeing window to fit text
    WINDOW_set_client_w(hMainWnd, text_w + Off*2);
    return 1;
}

int SYSTEM_show_date()
{
    // Draws date time to window

    // date time string length length
    int len;
    // device context
    HDC hdc;
    // paint struct
    PAINTSTRUCT ps;
    // client rect
    RECT client_r;

    // getting date time string
    DATE_get_now_ru(g_buffer);
    // getting date time string length
    len = (int)strlen(g_buffer);

    // invalidating client rectangle
    InvalidateRect(hMainWnd, 0 /*whole client rect*/, 1 /*erase*/);
    // getting device context
    hdc = BeginPaint(hMainWnd, &ps);
    // selecting font
    SelectObject(hdc, hfont);
    // selecting background color
    SetBkColor(hdc, Clock_Back_Color);
    // selecting text color
    SetTextColor(hdc, Clock_Text_Color);
    // widening window
    SYSTEM_widen_window(hdc, len);
    // getting client rectangle
    GetClientRect(hMainWnd, &client_r);
    // drawing date time
    DrawText(hdc, g_buffer, len, &client_r, DT_SINGLELINE);
    // freeing device context
    EndPaint(hMainWnd, &ps);
    return 1;
}

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    // Main window callback

    // switching message
    switch(msg) {

        // paint message
        case WM_PAINT:
            // drawing date
            SYSTEM_show_date();
            return 0;

        // close message
        case WM_CLOSE:
            // terminating program
            PostQuitMessage(0);
            return 0;

        // timer message
        case WM_TIMER:
            // if this is clock timer (always true since we have just 1 timer)
            if(wParam == Clock_Timer_ID) {
                // drawing date
                SYSTEM_show_date();
            }
            return 0;

    }
    // default message handling
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrInst, char* cmd, int cmdc)
{
    // Main function

    // window class name
    const char * class_name = "MainWindow";
    // window title
    const char * title = "Часы";
    // error code
    const int err = 1;
    // window width
    int w;
    // background brush
    HBRUSH hBack;
    // window style
    DWORD style;

    // saving input parameters
    SYSVARS_save(hInst, hPrInst, cmd, cmdc);

    // creating brush for background
    hBack = CreateSolidBrush(Clock_Back_Color);
    // registering window class
    if(!WINDOW_register_common(class_name, hBack, WndProc, hInst))
        return err;
    // setting small window height
    w = Clock_Font_Height;
    // setting window style
    style = WS_OVERLAPPEDWINDOW ^ WS_SIZEBOX ^ WS_MAXIMIZEBOX;
    // creating window
    hMainWnd = WINDOW_create(class_name, title, CW_USEDEFAULT,
        CW_USEDEFAULT, w + Off*2, Clock_Font_Height + Off,
         style, 0, hInst);
    if(!hMainWnd)
        return err;
    // creating font
    hfont = FONT_create_common("Georgia", Clock_Font_Height);
    // creating timer
    SetTimer(hMainWnd, Clock_Timer_ID, Clock_Update_Interval, 0);
    // drawing date to widen window
    SYSTEM_show_date();
    // showing window
    if(!WINDOW_show_norm(hMainWnd))
        return err;

    // main loop
    WINDOW_main_loop();

    // deleting timer
    KillTimer(hMainWnd, Clock_Timer_ID);
    // deleting font
    FONT_delete(&hfont);
    // deleting window
    if(!WINDOW_delete(&hMainWnd))
        return err;
    // unregistering window class
    if(!WINDOW_unregister(class_name, hInst))
        return err;
    // not deletnig window brush
    return 0;
}

Также прокомментировал свои либы и нашёл там баг стиля. Есть функции типа WINDOW_create_textbox, а мне вроде хотелось TEXTBOX_create, так как и так понятно что это модуль window. Та и название для модуля window не совсем подходящее. Лучше бы WINGUI, или просто GUI. Что я думал, когда называл модуль window? Наверно мне не нравилась аббревиатура GUI и я решил назвать таким словом, которое бы обозначало что это  и GUI и для windows и не было аббревиатурой... Похоже что так и оставлю. Название модуля должно вобоще-то присутствовать.

Ссылка

23 июня 2008

На rsdn в теме про качество open source кода дискуссия зашла про coroutines. Это когда есть функция со switch и мы её вызываем рекурсивно с новыми параметрами. И для coroutines в C можно сделать макрос. Было мнение что это плохой так как непонятный код, и что лучше реализовать это без yield. Была задача про бор, который двигается по курсу большим количеством шагов вверх, вниз, влево, вправо и что это реализуется с помощью этих корутин и можно ли без них. Вот написал программку.

#ifndef BORE_H
#define BORE_H

// Bore module. It provides bore movement without coroutines.

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

// Point struct
typedef struct Point2D_T {
    int x;
    int y;
} Point2D, *Point2D_Ptr;

// Target struct
typedef struct Bore_Target_T {
    // End point coord. We use it to calc new course to it
    Point2D coord;
    // If target has just chagned
    int b_new;
} Bore_Target, *Bore_Target_Ptr;

// Course Line struct
typedef struct Bore_Course_Line_T {
    // Direction to move. Can be 'L', 'R', 'D', 'U'
    char dir;
    // Number of steps
    int count;
} Bore_Course_Line, *Bore_Course_Line_Ptr;

// Course struct
typedef struct Bore_Course_T {
    // array with direct lines
    Bore_Course_Line_Ptr lines;
    // lines array size
    int lines_count;
    // lines array index
    int line_i;
    // Start point. Used to calc new course from it.
    Point2D coord;
} Bore_Course, *Bore_Course_Ptr;

Bore_Target_Ptr BORE_create_target()
{
    // Creates Target struct

    // allocating memory for Target struct
    return malloc(sizeof(Bore_Target));
}

int BORE_delete_target(Bore_Target_Ptr* target_pp)
{
    // Deletes Target struct

    // if we have correct adress of pointer
    if(!target_pp)
        return 0;
    // if pointer is valid
    if(!*target_pp)
        return 0;
    // freeing struct memory
    free(*target_pp);
    // invalidating pointer
    *target_pp = 0;
    return 1;
}

Bore_Course_Ptr BORE_create_course()
{
    // Creates Course struct

    // course pointer
    Bore_Course_Ptr course_p;

    // allocating memory for Course struct
    course_p = malloc(sizeof(Bore_Course));
    // invalidating lines pointer
    course_p->lines = 0;
    return course_p;
}

int BORE_delete_course(Bore_Course_Ptr* course_pp)
{
    // Deletes Course struct

    // if we have correct pointer adress
    if(!course_pp)
        return 0;
    // if we have valid pointer
    if(!*course_pp)
        return 0;
    // freeing lines memory
    free((*course_pp)->lines);
    // freeing struct memory
    free(*course_pp);
    // invalidating pointer
    *course_pp = 0;
    return 1;
}

int BORE_get_new_target(Bore_Target_Ptr target_p)
{
    // Gets new target to move. Target is the nearset resource. For now we
    // set just b_new, because we do not use coord in making course.
    target_p->b_new = 1;
    return 1;
}

int BORE_calc_new_course(Bore_Course_Ptr course_p, Bore_Target_Ptr target_p)
{
    //Calcs course to target consisting from number of direct lines.

    // number of lines in new course
    int lines_count = 4;
    // freeing old lines
    free(course_p->lines);
    // allocating memory for new lines
    course_p->lines = calloc(lines_count, sizeof(Bore_Course_Line));
    // saving lines size
    course_p->lines_count = lines_count;
    // pointing to first line
    course_p->line_i = 0;

    // Setting first line 10 steps right
    course_p->lines[0].dir = 'R';
    course_p->lines[0].count = 10;
    // Setting second line 10 steps down
    course_p->lines[1].dir = 'D';
    course_p->lines[1].count = 10;
    // Setting third line 20 steps right
    course_p->lines[2].dir = 'R';
    course_p->lines[2].count = 20;
    // Setting fourth line 5 steps down
    course_p->lines[3].dir = 'D';
    course_p->lines[3].count = 5;
    // Setting fifth line 30 steps left
    //course_p->lines[4].dir = 'L';
    //course_p->lines[4].count = 30;

    // saving where we will be
    course_p->coord = target_p->coord;
    return 1;
}

char BORE_get_next_step_dir(char* dir, Bore_Course_Ptr course_p)
{
    // Gets direction of next step according to course.

    // current line
    Bore_Course_Line_Ptr line_p;

    // checking if we have no more lines
    if(course_p->line_i == course_p->lines_count)
        // course is finished
        return 0;
    // getting current line
    line_p = &course_p->lines[course_p->line_i];
    // assuming line is not empty

    // saving direction
    *dir = line_p->dir;
    // updating made steps
    --line_p->count;
    // checking if we finished line
    if(!line_p->count)
        // going to next line
        ++course_p->line_i;
    // continue course
    return 1;
}

int BORE_make_step(Point2D_Ptr coord, char dir)
{
    // Makes step to some direction. And prints it.

    // buffer for line to print when moving down
    char buffer[256];
    // pointer to fill buffer
    char* buffer_p = buffer;
    // counter
    int i;
    // switching direction
    switch(dir) {
        // right
        case 'R':
            // increasing x coord
            ++coord->x;
            // printing step
            printf("*");
            // we are done
            return 1;
        // left
        case 'L':
            // decreasing x coord
            --coord->x;
            // I do not know how to print left
            return 0;
        // down
        case 'D':
            // increasing y coord
            ++coord->y;
            // adding new line for printing
            *buffer_p++ = '\n';
            // filling line with left offset
            for(i = 1; i < coord->x; ++i) {
                *buffer_p++ = ' ';
            }
            // adding step sign
            *buffer_p++ = '*';
            // finishing buffer
            *buffer_p++ = '\0';
            // printing step
            printf(buffer);
            return 1;
        // up
        case 'U':
            // decreasing y coord
            --coord->y;
            // I do not know how to draw up
            return 1;
    }
    return 0;
}

int BORE_work(Point2D_Ptr coord)
{
    // Drills resources. And prints it.

    // buffer to print line
    char buffer[256];
    // pointer to fill buffer
    char* buffer_p = buffer;
    // counter
    int i;
    // going on new line
    *buffer_p++ = '\n';
    // making offset
    for(i = 1; i < coord->x; ++i) {
        *buffer_p++ = ' ';
    }
    // adding drill sign
    *buffer_p++ = '#';
    // finishing buffer
    *buffer_p++ = '\0';
    // printing work
    printf(buffer);
    // making pause to work
    Sleep(2000);
    return 1;
}

#endif

// Bore program. Tests bore movement.

#include "bore.h"

// work state
#define STATE_WORK 1

int main()
{
    // target object
    Bore_Target_Ptr target_p;
    // course object
    Bore_Course_Ptr course_p;
    // direction
    char dir;
    // position
    Point2D coord;
    // program state
    int state;

    // creating target object
    target_p = BORE_create_target();
    // creating course object
    course_p = BORE_create_course();
    // setting position
    coord.x = 0;
    coord.y = 0;
    // setting work state
    state = STATE_WORK;
    // while we are working move and work
    while (state == STATE_WORK) {
        // getting next target
        BORE_get_new_target(target_p);
        // calcing course from target
        BORE_calc_new_course(course_p, target_p);
        // while we have next step
        // getting direction for each step from course
        while(BORE_get_next_step_dir(&dir, course_p)) {
            // making step
            BORE_make_step(&coord, dir);
        }
        // working
        BORE_work(&coord);
        // breaking just after first iteration
        break;
    }
    // pause to view results 1 minute
    Sleep(60*1000);
    // deleting course object
    BORE_delete_course(&course_p);
    // deleting target object
    BORE_delete_target(&target_p);
    return 1;
}

Ссылка

23 июня 2008

Итак, я описал, за счёт чего я планирую добиться большего успеха чем раньше в своих проектах. Теперь перейдём к конкретике. Какие проекты.

1. Доделаю колорайзер. Я не хочу больше бросать ни одного проекта. Блог не считается так, как я решил его вообще не писать. А вот колорайзер я писать начал и должен его доделать. Чтобы приучить себя выносливости, приобрести опыт создания полного цикла программы и чтобы было что показывать.

2. Калькулятор. Тут была тема про калькуляторы. И мне зохотелось тоже сделать. Опыт создания законченной небольшой программы. Я его тоже уже начал писать, но натолкнулся на проблемы. Про калькулятор поговорю в отдельном сообщении.

3. Потом надо будет сделать программу учёта времени работы за разными программами. Тоже небольшая но возможно полезная программа.

4. Ещё мне не хватает опыта с CMS. И у меня есть трудности с их изучением. Во-первых, там отвратительный код. Пишете open source, значит сделайте маленькие функции с понятными названиями, прокомментируйте каждую строчку кода, это ж будут читать тыщи людей! Но нет, парочка комментариев на весь файл, большие функции, непонятно как работающие. Я не согласен с принципом чёрного ящика, так как это ограничивает возможности. То есть, если выучить систему как чёрный ящик, то единственное что ты сможешь, это прилепить модуль, типа календарика. Мне же хочется полностью контролировать систему, понять каждую её строчку кода, чего видимо не хотят сами разработчики системы. Короче я решил изучить и переписать drupal (выбрал его так как там много маленьких функций). Кстати расчитываю и на прирост производительности, например за счёт того что уберу поддержку разных баз данных. И вообще за счёт улучшения архитектуры :) Хотя раз я её не понял, это не значит что она плохая. Надо будет написать ещё какой-нибудь сайтец, чтобы потестить новую систему.

5. "Стратегический футбол". И наконец, игра. Я решил сделать футбик на C, OpenGl. Его особенности в искусственном интеллекте. Он там должен быть самой сильной частью. Физика будет средней, графика плохой, так как я не умею моделировать. Управляя, игрок будет советовать футболистом куда им перемещаться, кому давать пас, а они сами будут решать как это делать. Например футболист реализует пас не напрямую, а через промежуточный пас, как он считает лучше, игрок управляет только стратегией. Кроме того хотелось бы добавить возможность создания позиции по картинке из видео реального матча, чтобы можно было проанализировать как компъютер бы её реализовал. Я позиционирую программу и как и игру и ещё чтобы с её помощью можно было даже тренировать футболистов командной игре, а также применять для анализа матчей по телевизору :)

Значит начнём с колорайзера.

При написании его я понял что плохо знаю регулярки. И решил прочитать внимательно книгу о них, авторства Jeffrey E. F. Friedl. Кроме того я читаю книгу "Совершеный код". Так что или дочитаю эти книги перед дописыванием колорайзера, или если при чтении захочется покодить то буду это делать итеративно. Процесс буду документировать в блоге.

Вот кстати первый комментарий про регулярки. [^a] означает не "нет символа a", а "какой-то символ, кроме а". То есть требует наличие символа, так что не путать эту конструкцию с negative lookbehind (?<!a) . Ещё я раньше преувеличивал со слешеньем символов. Читая книгу, я впитываю хороший вкус слешить только то что надо и вообще точно понимать что делает регулярка.

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

Ссылка

Архив 

Предыдущие записи | Следующие записи