Ramin Hashimzade


Афоризмы про программистов

--
Есть два способа разработки проекта приложения: сделать его настолько простым, чтобы 6ыло очевидно, что в нем нет
недостатков, или сделать его таким сложным, чтобы в нем не было очевидных недостатков.
(с) Ч. Э. Р.Хоар (C. A. P. Hoare)

--
Работая над проблемой, я никогда не думаю о красоте. Я думаю только о решение проблемы. но если полученное решение не красиво, я знаю что оно неверно.
(с) Р. Бакминстер Фуллер (R. Buckminster Fuller)

--
Больше беспокоит то, что программист вполне может выполнить ту же задачу двумя или тремя способами: иногда неосознанно, но довольно часто просто ради изменения или же создание элегантной вариации.
(с) А. Р. Браун и У. А. Сэмпсон

--
Есть лишь два вида языков программирования: те, на которые вечно жалуются, и те, которые никогда не используются.
(с) Бьёрн Страуструп

--
Нет, и не будет такого языка программирования, на котором было бы хоть немного труднее написать плохую программу.
(с) Лауренс Флон

--
Программирование — это гонка между компьютерщиками, которые создают программы, все лучше защищенные от дурака, и природой, которая создает все лучших дураков. Пока что природа выигрывает.
(с) Рич Кук


--
Каждый дурак может написать программу, которую может понять компьютер. Хороший программист пишет программу, которую может понять человек.
(с) Мартин Фаулер

--
Если отладка программы — это устранение ошибок, то программирование следует определить как продуцирование ошибок.
(с) Эдсгер Дийкстра

--
Обучение программированию не может научить быть экспертом, также как и изучение кистей и красок не может превратить кого-либо в художника.
(c) Eric S. Raymond


--
Болтовня ничего не стоит. Покажите мне код.
(с) Linus Torvalds

--
«Пользователь» — слово, используемое компьютерщиками-профессионалами вместо слова «идиот».
(с) Дейв Барри

--
Написание первых 90% программы занимает 90% времени. Оставшиеся 10% также требуют 90% времени, а окончательная шлифовка — еще 90% времени.
(c) Нейл Рубенкинг

--
В теории, теория и практика неразделимы. На практике это не так.
(c) Yoggi Berra

--
Отладка кода вдвое сложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать.
(c) Brian W. Kernighan.

--
Сначала учите науку программирования и всю теорию. Далее выработаете свой программистский стиль. Затем забудьте все и просто программируйте.
(c) George Carrette

--
Многие из вас знакомы с достоинствами программиста. Их всего три, и разумеется это: лень, нетерпеливость и гордыня.
(c) Larry Wall

--
Трудность работы с программистом заключается в том, что вы не можете понять что он делает до тех пор пока не стало слишком поздно.
(c) Seymour Cray

--
Меня два раза спрашивали [члены Парламента]: "Скажите на милость, мистер Бэббидж, что случится, если вы введете в машину неверные цифры? Cможем ли мы получить правильный ответ?" Я не могу себе даже представить какая путаница в голове может привести к подобному вопросу.
(c) Charles Babbage
Если голова сталкивается с книгой и раздается пустой гулкий звук, - всегда ли он принадлежит книге? Ф. Ницше.


--
Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования.
(c) Linus Torvalds


---
Лучше, чтобы в 100 функциях использовалась одна структура данных, чем в 10 функциях - 10 структур.




To Be Continued...


Работа Программиста

Программирование…, Хочу рассказать вам о своей профессии, она очень интересная, хотя кто-то может считать программирование своим хобби. Именно, потому что человек, который программирует(программист) создает то чего не было, то, что будет полезно всем, кто будут использовать плоды труда программиста. Порой даже не зная, кому они обязаны сэкономленными часами жизни... Цель статьи, помочь определиться, тем кто сомневается стоил ли становиться программистом.

Кто такой программист? Я бы не сказал, что это человек, который закончил университеты "вычислительной математики и кибернетики" научился писать простые скрипты и узнал, что такое if/then/else. По моему скромному мнению, это человек, который может четко мыслить, и может четко расставить шаги для достижения той или иной цели, умеет логически рассуждать и аналитически мыслить. Программист должен уметь читать книги. Обратите внимание в предложении я не сказал "для написание исходного кода" а именно цели. Потому что правильно задавать себе цель, это самый важный элемент достижения успеха. Кстати, созидание проекта тоже очень похоже на цель. Программист знает какие ресурсы у него есть, знает с чего начать, что нужно делать и видит конечный итог, а написание исходного кода - это часть всего этого большого проекта.

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

Короткий шаги для написание приложении, я б составил таким:
1) ЧТО НУЖНО ДЕЛАТЬ? (Техническое Задание)
2) ВЫБОР ПЛАТФОРМЫ (под критериями: быстро, четко, эффективно и ПРАВИЛЬНО)
3) TRY (Начать)
4) CATCH/EXCEPT (Отладка)
5) FINALLY (Сдача)

Техническое Задание. Техническое задача, обычно дается от пользователя, то есть, кто будет в дальнейшем использовать эту систему. В многих случаях оно бывает не полноценным, даже не в многих а в 99%. 1% это наверно люди тоже программисты который точно знают что хотят :-).

Какую платформу выбирать? Очень часто новички задают вопросы, на чем лучше начать изучать программирование. Я всегда говорю что надо начинать с ПАСКАЛЯ. Паскаль это такой язык программирования, в котором есть почти все, что может понадобиться. Даже может быть, что Паскаль сначала так же будет казаться сложным языком, главное поставить себя цель , как уже говорил раньше, и попытаться узнать о нем все в основном вникать в суть и понять как он устроен и почему. Многие говорят: учи “JAVA” или “C# курче”, ни в коем случаи не надо слушать таких. Хороший программист должен понять одно, для написание той или иной приложение нужно выбирать правильную платформу! Понятие о старости или вымирание платформы или это круто давай на нем писать, очень не правильно, так как конечному пользователю совсем не интересно и не нужно знать какая платформа какая СУБД, как там написано синтаксис IF/THEN, FOR/DO и т.д.! Хороший программист должен правильно и четко без лишних действии писать программу и конечный результат тест кейсов должен совпадать с бизнес требованием. Вот что требуется от программиста. А выбирать платформу за программистам, если нету никаких требовании! Понять нужно одно: Где я это буду делать быстро, четко, эффективно и ПРАВИЛЬНО!

Различные языки программирования поддерживают различные стили. Отчасти искусство программирования состоит в том, чтобы выбрать язык программирования, наиболее полно подходящий для решения поставленной задачи. Единственный язык, напрямую выполняемый это машинный язык (также называемый машинным кодом и языком машинных команд). Когда то все писали именно в машинном коде, но сейчас практически уже не делается. Вместо этого программисты пишут исходный код на том или ином языке, затем, используя компилятор, транслируют его в один или несколько этапов в машинный код, готовый к исполнению на целевом процессоре, или в промежуточное представление, которое может быть исполнено специальным интерпретатором.

Самая лучшая теория это практика. Нужно иметь хорошую практику во всех направлениях своей работы что б стать лучшим. Поэтому не ленитесь, из себя придумывать задачи и попытаться самому самостоятельно решить эти задачи, на основе которых будете решать другие задачи. Именно разных набор решенных разных задач и будет являться опытом. Даже иногда вам понадобится буквально несколько минут, что б найти тот исходный код, который вы уже решили одной из уже выполненных задач и простым copy/paste решить его в новой.

TRY(Начать разработку). Скажу что самая развлекательная часть, работы. Когда начинаете новый проект, бывает такое ощущение что вы сейчас станете основателем того чего пока нету. С охотой создаете папку для этого проекта, даете имя проекта, создаете Базу, Таблицы, объекты, формы, и т.д. Но не забывайте, что б ДОМ стоял, нужно иметь хороший фундамент. Именно фундамент, строите тогда когда вы начинаете новый проект. Поверти например давать имена на объекты, формы, таблицы , поля и т.д. может казаться очень простым и не важным, но скажу вам что оно не маловажный фактор. В больших проектах не правильное заданное имя к объекту может привлечь за собой много проблем при отладке проекта. По этому всегда постарайтесь построить сильный фундамент.

Хочу отметить не менее важную проблему в разработке клиент-серверных приложении: очень часто новички допускают ошибки при написании приложение которое используют один из широко масштабных СУБД , например как ORACLE, MSSQL Server, SYBASE… и пишут основную бизнес логику на стороне клиентского языка, когда все это можно делать на языке SQL на стороне сервера. Помните, постарайтесь максимально отказаться от клиентской части кода и многое писать на стороне Сервера. Потому что завтра очень легче будет поддерживать и развивать такие системы. И всегда используйте связываемые переменные (Bind Variables). Как сказал один из гуру ORACLE, TOM КАЙТ:

TOM КАЙТ
Если бы мне пришлось писать книгу о том, как создавать не масштабируемые приложения Oracle, первая и единственная ее глава называлась бы "Не используйте связываемые переменные". Это — основная причина проблем, связанных с производительностью, и основная помеха масштабируемости
.

CATCH/EXCEPT (Тестирование и Отладка). Самая нудная часть работы. Потому что будет выходить ошибки и даже может быть много ошибок, если вы новичок. Но не надо расстраиваться, постарайтесь поискать сперва свои проблемы в Интернете, не нашли задайте вопросы в форумах , не стесняйтесь спрашивать у опытных и добейте проблему, поверьте вы просто будете получать удовольствие после решение каждой проблеме. Еще скажу вам по секрету, что может помочь вам в дальнейшем после сдачи проекта, никогда не берите на себя тесты бизнес логике, пусть это делает тот кто вам техническое задание давал. Потому что завтра когда будут проблемы именно с бизнес логикой, тогда вы сможете спокойно сказать что не правильно тестировали. :-)

FINALLY (Сдача). Сдача проекта всегда радует. Особенно когда будете получать деньги :-)

В конце хотел б отметить слова , нашего покойного великого поэта Низами Ганджави:
"Kamil bir palanci olsada insan, yaxsidir yarimciq papaqciliqdan"
что можно переводить как:
"Лучше быть хорошим сапожником, чем никудышном программистом" :-)

Всем Удачи!

С Уважением, Рамин Гашимзаде!


Парсинг строки с разделителями - Delphi

функция который возвращает кол. массива.

function DCOUNT(str, Delimeter: string) : integer;
var
 StrL : TStringList;
 ParseStr : string;
begin
  try
    StrL := TStringList.Create;
    ParseStr:= StringReplace(str, Delimeter, #13, [rfReplaceAll]);
    StrL.Text := ParseStr;
    Result := StrL.Count;
  finally
    StrL.Free;
  end;
end;

Пример :
DCOUNT('test1|test2|test3|test4', '|') = 4


function StrBreak(str, Delimeter: string; fromParts, Cnt : integer) : string;
{
 str : your string
 Delimeter : Delimeter symbol
 fromParts : Initial position
 Cnt : Number of items
}
var
 StrL : TStringList;
 ParseStr : string;
 i : integer;
begin
  Result := '';
  try
    StrL := TStringList.Create;
    ParseStr:= StringReplace(str, Delimeter, #13, [rfReplaceAll]);
    StrL.Text := ParseStr;
    if StrL.Count > 0 then
    begin
      for i := 0 to Cnt-1 do
        if (StrL.Count > i) and (StrL.Count > fromParts) then
            if i>0 then Result := Result + Delimeter + StrL.Strings[fromParts+i]
                    else Result := Result + StrL.Strings[fromParts+i];
    end;
  finally
    StrL.Free;
  end;
end;

Пример :
StrBreak('test1|test2|test3|test4', '|', 0,1) = test1
StrBreak('test1|test2|test3|test4', '|', 0,2) = test1|test2
StrBreak('test1|test2|test3|test4', '|', 1,2) = test2|test3
StrBreak('test1|test2|test3|test4', '|', 3,1) = test4


Создание пользовательского меню - ASP .NET

Как обещал ранее, выкладываю решение по "Создание пользовательского меню" на платформе Visual Studio 2010, языке C#. Структура Базы остается прежним, меняется только таблица BP_USER_MENU поле BP_REPORT_ID, который в свою очередь уже хранит в себе ссылку на страниц.
И так, открываем студию, создаем новый проект и например даем имя проекта Project_UserMenu. Далее добавляем новую страницу, страницу "Входа" и назовем его wfrm_login (учтите что добавление префикса в начале имена объектов, освобождает вас от не чайно использованием зарезервированных слов, в данном случаи префикс "wfrm" означает "web form"), так как эта статья носит тестовый характер, интерфейс входа в приложение будет совсем простым. Добавляем 2 TextBox , 1 Button , 1 Treeview и 1 Custom Validator для отображении ошибок.

Картинка с другого сайта.

<body>
    <form id="form1" runat="server">
    <div>
        <table class="style1">
            <tr>
                <td>
                    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                    

                    <asp:TextBox ID="TextBox2" runat="server" TextMode="Password"></asp:TextBox>
                    

                    <asp:Button ID="Button1" runat="server" Text="Login" onclick="Button1_Click" />
                </td>
            </tr>
            <tr>
                <td>
                    &nbsp;
                    <asp:CustomValidator ID="CustomValidator1" runat="server" 
                        ErrorMessage="CustomValidator"></asp:CustomValidator>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:TreeView ID="cmp_Menu_TreeView" runat="server" ShowLines="true" Style="margin-right: 0px"
                        Font-Bold="True" Font-Size="Medium" ForeColor="Black">
                    </asp:TreeView>
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>


Далее добавляем наши бизнес страницы который будет открываться когда будет выбрано соответствующий нод в меню. Для примера я добавляю 2 страницы с именами wfrm_form1, myfrm_form2 в проект и в таблице BP_USER_MENU в поле BP_REPORT_ID указываем меню который должен открывать эти страницы:

BP_IDBP_PARENT_IDBP_LEVEL_IDBP_MENU_CAPTIONBP_REPORT_ID
10Главное
20Отчеты
611Склад ./wfrm_form1.aspx
711Приход
811Расход
922Бухгалтерия
1022Казначейство
1193Отчет об остатках ./myfrm_form2.aspx
1293Отчет о прибыли
13103Денежные обороты
14103Касса
15103Тестовый отчет



Далее обработка кнопки Button , который в свою очередь будет создавать коннект к Базе данных и вызов метода Populate() на рисование соответствующего меню пользователя. Запрос остается тот же:

SELECT USER_MENU.BP_ID,
       USER_MENU.BP_PARENT_ID,
       USER_MENU.BP_LEVEL_ID,
       USER_MENU.BP_MENU_CAPTION,
       USER_MENU.BP_REPORT_ID
 FROM RAMIN.BP_USER t1  
  
 JOIN RAMIN.BP_USER_GROUP_MENU T
 ON T1.BP_USER_GROUP_ID = T.BP_USER_GROUP_ID
  
 JOIN RAMIN.BP_USER_MENU USER_MENU
 ON USER_MENU.BP_ID = T.BP_MENU_ID

 WHERE (T1.BP_LOGIN = 'ЛОГИН ПОЛЬЗОВАТЕЛЯ ВХОДЯЩЕГО В СИСТЕМУ')
 ORDER BY USER_MENU.BP_LEVEL_ID, USER_MENU.BP_ID



Behind Code странице wfrm_login:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Oracle.DataAccess.Client;

namespace Project_UserMenu
{
    public partial class wfrm_login : System.Web.UI.Page
    {
        string myconn;
        OracleConnection appConn;

        protected void Page_Load(object sender, EventArgs e)
        {
            cmp_Menu_TreeView.Nodes.Clear();
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            myconn = "Data Source=MYDB;User ID=" + TextBox1.Text + ";Password=" + TextBox2.Text;
            try
            {
                appConn = new OracleConnection(myconn);
                appConn.Open();
                Populate();
            }
            catch (Exception ex)
            {
                CustomValidator1.IsValid = false;
                CustomValidator1.Text = ex.Message;
                return;
            }
        }

        // Рисование меню пользователя в виде дерево.
        private void Populate()
        {
            OracleDataAdapter oraAdap = new OracleDataAdapter();
            oraAdap.SelectCommand = new OracleCommand();
            oraAdap.SelectCommand.Connection = appConn;
            oraAdap.SelectCommand.CommandText = Resource1.myQuery;
            oraAdap.SelectCommand.Parameters.Add("login", OracleDbType.Varchar2, 10).Value = TextBox1.Text;
            OracleDataReader oraRead = oraAdap.SelectCommand.ExecuteReader();

            while (oraRead.Read())
            {
                if (System.Convert.ToString(oraRead["BP_PARENT_ID"]) == "")
                {
                    TreeNode tn = new TreeNode();
                    tn.Text = (string)oraRead["BP_MENU_CAPTION"];
                    tn.Value = System.Convert.ToString(oraRead["BP_ID"]);
                    tn.SelectAction = TreeNodeSelectAction.Expand;
                    cmp_Menu_TreeView.Nodes.Add(tn);
                    tn.NavigateUrl = System.Convert.ToString(oraRead["BP_REPORT_ID"]);
                }
                else
                {
                    TreeNode tn = new TreeNode();
                    tn.Text = (string)oraRead["BP_MENU_CAPTION"];
                    tn.Value = System.Convert.ToString(oraRead["BP_ID"]);
                    tn.Target = "_blank";
                    tn.NavigateUrl = System.Convert.ToString(oraRead["BP_REPORT_ID"]);
                    AddChildNode(cmp_Menu_TreeView.Nodes, System.Convert.ToString(oraRead["BP_PARENT_ID"]), tn);
                }
            }
            oraRead.Close();
        }

        // Добавление дочерный нодов ("Как добавить дочерные ноды зная его родителскый нод")
        private void AddChildNode(TreeNodeCollection n, string val, TreeNode tn)
        {
            for (int i = 0; i < n.Count; i++)
            {
                if (n[i].Value == val)
                {
                    n[i].ChildNodes.Add(tn);
                    n[i].SelectAction = TreeNodeSelectAction.Expand;
                    n[i].NavigateUrl = "";
                }
                n[i].Expand();
                AddChildNode(n[i].ChildNodes, val, tn);
                n[i].Collapse();
            }
        }

    }
}


скриншоты теста:
Картинка с другого сайта.
Картинка с другого сайта.

---
Ramin Hashimzade


Создание пользовательского меню - Delphi

Очень часто возникает вопрос, как создать меню пользователя, если для разных пользователей нужны разные меню и разные права. В связи с этим, я решил писать эту статью в свой блог, чтобы хоть чем-то помочь людям, которые задают этот вопрос себе или на форумах.
Как мы знаем, этот вопрос возникает в основном в бизнес проектах и как всем известно, почти 99,99% бизнес проектов используют разные СУБД в качестве хранения информации. Для демонстрации решения, я взял СУБД ORACLE и платформу разработки CodeGear™ Delph 2009 Version 12.0.3420.21218 Copyright 2009 Embarcadero Technologies.
Итак, мы считаем, что базу мы создали, все финансовые таблицы есть и сейчас нужно создать системные таблицы нашего проекта для хранения разграничения меню и прав доступов пользователей. Префикс нашего проекта BusinessProject-BP.
Для пользовательского меню нужны следующие таблицы:

1) BP_USER_MENU
ИМЯ ПОЛЕ ТИП ПОЛЕКомментарий
BP_ID NUMBER уникальный идентификатор таблицы
BP_PARENT_ID NUMBER ссылка на родительский пункт меню в древовидной структуре
BP_LEVEL_ID NUMBER позиция меню в в древовидной структуре
BP_MENU_CAPTION NVARCHAR2(50) Текст меню
BP_REPORT_ID NVARCHAR2(50) уникальный идентификатор библиотеки или формы которую нужно вызывать из пункта в меню. Или строка ссылки если используется веб приложение.

читать дальше...
добавлено: 24 ноя 11 просмотры: 5063, комментарии: 1