Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 4 [Все]   Вниз
  Печать  
Автор Тема: Типичные ошибки при написании программ.  (Прочитано 38481 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ezus
Опытный

il
Offline Offline

« : 23-01-2010 22:26 » 

Напрашивается очевидный ответ - О бабах или о пиве Улыбаюсь
Но я все-таки попробую, как было предложено, показать на примерах из "пАмАгите!!!" конкретные рекомендации, о которых шла речь в  "Почему программисты допускают ошибки?".

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

Это мне напоминает обучение игре в шахматы: дали ходы, объяснили правила,  показали что-такое мат. И вперед, думай.
А о чем думать? И вот сидишь ты перед доской с фигурами в начальной позиции и тупа смотришь на нее - что делать? - до мата как до Луны, а ходить-то как-то надо.
Во всяком случае так было со мной.  И только много позже, когда я прочитал книжку Немцовича, посвященную середине игры, я понял что-такое шахматы и полюбил их.

Так и в обучении программированию: вот тебе язык, вот тебе среда, вот тебе примеры - Вперед!! - а чтобы написать программу - Думай!! Здесь была моя ладья...
А вот о чем "Думай" не говорят.

Итак.
Из языковой модели: Есть три вопроса, на которые надо ответить: ЗАЧЕМ, ЧТО и КАК.

ЗАЧЕМ - это уровень постановки задачи, очень важный и интересный, но сейчас не о нем речь. На него худо-бедно отвечают.

КАК - это уровень кода, это результат работы, без ответа на него нет программы. Если ты знаешь язык, библиотеки, среду, то проблем с КАК возникнуть не должно. Хотя, конечно, в  "пАмАгите!!!" есть много вопросов и этого уровня. Но речь тоже не о нем.

Теперь ЧТО. Это промежуточный вопрос.
Может показаться, что он необязательный, очевидный: можно сразу приступить к коду. И его просто пропускают. Таких примеров в "пАмАгите!!!" много.
И вот о нем я и хотел бы поговорить.

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

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

К сожалению, жись заставляет прерваться Жаль


Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 24-01-2010 00:15 » 

Давайте уточним:

1. Кому думать? Руководителю проекта, аналитику, архитектору, кодерам, тестерам, ...? Разные роли в команде подразумевают разные функции. А разные функции должны требовать разных направлений мышления.

2. На каком этапе думать? Формулирование задач и границ проекта, сбор требований, разработка архитектуры, ...? Разные задачи, значит, орять же, думы разные.

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

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #2 : 24-01-2010 07:34 » 

Давайте уточним:

1. Кому думать? Руководителю проекта, аналитику, архитектору, кодерам, тестерам, ...? Разные роли в команде подразумевают разные функции. А разные функции должны требовать разных направлений мышления.
Всем думать, но в данном случае я имел ввиду программиста над небольшой задачкой.

Цитата
2. На каком этапе думать? Формулирование задач и границ проекта, сбор требований, разработка архитектуры, ...? Разные задачи, значит, орять же, думы разные.
На всех этапах думать, но в данном случае я имею ввиду ответ на вопрос "ЧТО делать?".

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

Над упражнениями в 10 строк тоже надо думать, потом это поможет при работе над большими проектами. Если не научишься думать на этом этапе, потом будет сложнее (это мягко сказано).

Я просто хочу привести ряд примеров "о чем думать" на простеньких задачках.
Я ни Дейкстра, ни академик какой-нибуть, я даже не защитил кондидатскую - я простой программист, поэтому от меня трудно ждать великих откровений - это мой личные опыт и мои рассуждения.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #3 : 24-01-2010 10:02 » 

И так - есть строка символов, содержащая слова, разделенные произвольным числом символов. Надо получить другую строку, в которой слова разделены только одним символом.

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

Сначала несколько замечаний.


Замечание 1.
Я буду использовать для иллюстрации структур простенькую нотацию Джексона, представленную в приложении. Мне кажется она не требует комментариев.

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

Замечание 3.
Учитывая замечание 2, структуру исходного объекта можно использовать для построения структуры нашей программы.
Это предположение использеутся в декомпозиционной модели для построения цепочки следующих соображений.

Имеем структуру объекта в виде дерева,  например:
  • завод
  • изделия
  • детали
  • цеха
Завод выпускает изделия - изделие состоит из деталей - детали производятся в цехах.
Это структура исходного объекта.

Каждый компонент нашего дерева описывается некоторыми данными, например:
  • название завода
  • название изделия, план выпуска
  • код детали, применяемость
  • код цеха, затраты на изготовление данной детали
Получаем структуру данных.

В рамках нашей задачи эти данные обрабатываются некоторыми функциями:
  • расчитать затраты на план выпуска завода
  • расчитать затраты на план выпуска данного изделия
  • посчитать объем производства и затраты на план
  • посчитать затраты цеха на изготовление данной детали на план

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

Причем подчеркиваю - объективно, вне зависимости от желаний отдельного программиста.

Данная структура соответствует работе планового отдела.

Если мы будем говорить о оперативно-календарном планировании, то теже компаненты собираются в другой последовательности:
  • завод
  • цеха
  • детали
  • изделия
Завод состоит из цехов - цеха производят детали - детали используются в изделиях, которые надо выпустить в соответствии с планом.
И опять мы автоматически получаем нужную структуру программы.
  • Обработка завода - содержит цикл по обработке цехов
  • Обработка цеха - содержит цикл по обработке деталей
  • Обработка детали - содержит цикл по обработке изделий
  • Обработка изделия

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

Ну, а теперь наша задачка.

* Jacson.jpg (14.47 Кб - загружено 696 раз.)
« Последнее редактирование: 24-01-2010 11:26 от Sel » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 24-01-2010 10:39 » 

Цитата: ezus
я имею ввиду ответ на вопрос "ЧТО делать?"
По-моему, Николай Гаврилович Чернышевский будет ворочаться в гробу ещё о-очень долго Улыбаюсь

Цитата: ezus
И так - есть строка символов, содержащая слова, разделенные произвольным числом символов. Надо получить другую строку, в которой слова разделены только одним символом.

Простенькая задачка
По-моему, постановка неполна. Должны быть: либо чётко определены слова, либо разделительные символы, либо и то и другое. Без этого задача нерешаема, с первым и вторым решаема на любых данных, с третьим возможно распознание синтаксически некорректной последовательности.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-01-2010 11:06 » 

ezus, мой комментарий к замечанию 3.

Императивный стиль программирования во главу угла ставит обработку информации (операции), собственно информация в этом случае подлежит обработке. Исходя из таких представлений в первую очередь ставится задача или множество задач, под которые формируются структуры данных. Говорят "код управляет данными".

Такое отношение к данным было обусловлено тем, что данные для решения задач вводились в машину, результаты выводились из неё, а хранились данные в лучшем случае на внешних носителях, в худшем - в бумажных регистрах (того же планово-экономического отдела). Коротко говоря, машина нужна была лишь для того, что "посчитать" и ни для чего другого.

В нынешние времена данные хранятся в машине (или сети машин) почти полностью, используются для решения разных задач, поэтому во главу угла ставится сама информация и её структура, а постановка и решаемость задач подчинены этой структуре. Говорят "данные управляют кодом". Этот ортогональный взгляд на вещи приводит нас к декларативному стилю программирования.

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

Смена образа мышления разработчиков ПО хорошо просматривается в истории развития АСУ.

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #6 : 24-01-2010 11:23 » 

Цитата: ezus
я имею ввиду ответ на вопрос "ЧТО делать?"
По-моему, Николай Гаврилович Чернышевский будет ворочаться в гробу ещё о-очень долго Улыбаюсь
А что делать, если вопрос "Что делать?" никуда не пропал?

Цитата
По-моему, постановка неполна. Должны быть: либо чётко определены слова, либо разделительные символы, либо и то и другое.
Согласен и уточняю: слово - это последовательность не пробельных символов, а пропуск - это, соответственно, последовательность пробелов.
Записан
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 24-01-2010 11:24 » 

последовательность пробелов, или разделителей?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
ezus
Опытный

il
Offline Offline

« Ответ #8 : 24-01-2010 11:25 » 

ezus, мой комментарий к замечанию 3.
Разрешите прокомментировать Ваш комментарий после того, как я закончу с примером?
Вы правы, но у меня есть что сказать пару слов.

последовательность пробелов, или разделителей?
пусть для простоты - пробелов
« Последнее редактирование: 24-01-2010 11:27 от Sel » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 24-01-2010 12:08 » 

Имеем структуру объекта в виде дерева,  например:
  • завод
  • изделия
  • детали
  • цеха
Завод выпускает изделия - изделие состоит из деталей - детали производятся в цехах.
Это структура исходного объекта.

Не вполне понятно. На данном заводе действительно каждый цех выпускает только одну деталь? Если нет, то в данном случае структура никак не может быть представлена деревом.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 24-01-2010 12:43 » 

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

Однако дело не в этом, а в том, что ответ на вопрос "что делать?" очень сильно зависит от ответа на вопрос "как думать?", т.е. методология (в широком смысле) первична. Пример с заводом уже демонстрирует применение определённой методологии, способа мышления, причём как-то без обсуждения и без оговорок о выборе именно такого способа из прочих имеющихся. Собственно, мой комментарий и был реакцией на "умолчание" в этом вопросе. Фразы "давайте будем думать в императивном стиле" для меня достаточно, чтобы я успокоился Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #11 : 24-01-2010 12:51 » 

Имеем структуру объекта в виде дерева,  например:
  • завод
  • изделия
  • детали
  • цеха
Завод выпускает изделия - изделие состоит из деталей - детали производятся в цехах.
Это структура исходного объекта.

Не вполне понятно. На данном заводе действительно каждый цех выпускает только одну деталь? Если нет, то в данном случае структура никак не может быть представлена деревом.
Не понял, что не понятно. Хотя у меня есть подозрение, но ...

В рамках данной структуры:
завод выпускает изделиЯ
изделиЕ состоит из деталЕЙ
деталЬ обрабатывается в ряде цехОВ.

Что не понятно?
Реально цех может обрабатывать много деталей, а одна деталь может быть использована в разных изделиях, но в рамках данной постановки это не важно.

Если Вы хотите увидеть все детали одного цеха рядом, то это уже другой объект со своей структурой. Я привел такой пример для оперативно-календарного планирования. Там как раз важно знать какие детали выпускает цех и в каком количесте, поэтому структура:

завод состоит из цехов
цех выпускает детали
деталь используется в изделиях.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #12 : 24-01-2010 12:57 » 

Фразы "давайте будем думать в императивном стиле" для меня достаточно, чтобы я успокоился Улыбаюсь
"Давайте будем думать в императивном стиле".

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

Dale, структура данных здесь сетевая, а иерархии "вытягиваются" из сети лишь под конкретную задачу путём наложения удобного иерархического порядка на сеть.
Да нет еще никаких данных. Они могут быть и иерархические, и сетевые, и реляционные, и линейные в виде флат-файлов. Вот ПОТОМ, стыкуя структуру объекта задачи с существующей вне задачи структурой данных, выявляются коллизии структур, которые и приходится решать специальным образом.
« Последнее редактирование: 24-01-2010 13:07 от Sel » Записан
ezus
Опытный

il
Offline Offline

« Ответ #13 : 24-01-2010 13:41 » 

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

Текстовый символ нам надо переписать.
Срединный пробел пропустить.
Особенный пробел тоже переписать.

Все понятно и естественно.
Программа должна содержать один цикл и 2 условных оператора.

Псевдо-код:
Цикл по символам до конца строки.
   Если текущий символ - текстовый
       переписать.
   иначе
        если текущий символ - особенный
              переписать.
        иначе пропустить.
конец цикла.

Кстати, эту задачку я давал в качестве теста на своих лекциях, и у меня было более 400 вариантов решения этой задачи. Так вот более 75% решений изходили из данной структуры или ей подобной. Главное отличие было в выборе определения специального символа: первый, последний, через признаки, через индексы, сравнением с предыдущим символом или последующим. И именно это место было главным источником ошибок.

Мои комментарии. Я не люблю оператор IF, т.к. в рамках мой модели он трудно воспринемаем нашими мозгами.

Поэтому попробуем его избежать.

* v1.jpg (18.85 Кб - загружено 672 раз.)
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 24-01-2010 14:03 » 

ezus, уточнение про типы пробела: первый/последний относительно строки или слова?

Цикл засчитывать за iF + GOTO или нет?
« Последнее редактирование: 24-01-2010 14:14 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #15 : 24-01-2010 15:35 » 

ezus, уточнение про типы пробела: первый/последний относительно строки или слова?
Слова.
Цитата
Цикл засчитывать за iF + GOTO или нет?
Я предполагаю структурный язык, но в данном случае это просто псевдо-код, структурный,
в котором цикл - это цикл, а не iF + GOTO.

Теперь вариант второй.

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

Псевдо-код:

Цикл по участкам до конца строки.

    Если текущий участок - это слово

         Цикл по символам до конца слова или строки.
             переписать.
         Конец цикла

    Иначе
         записать пробел.

         Цикл по пробелам до конца слова или строки.
             пропустить.
         Конец цикла

    конец если.
конец цикла.

Что-то не понятно?
Все просто. Но все-таки один IF есть.

* v2.jpg (19.73 Кб - загружено 647 раз.)
« Последнее редактирование: 24-01-2010 16:38 от Sel » Записан
ezus
Опытный

il
Offline Offline

« Ответ #16 : 24-01-2010 16:05 » 

И наконец, третий вариант.
В нем мы используем дополнительную информацию о том, что наши участки чередуются.
Это факт в структуре объекта отражается в том, что верхний участок состоит сначала из слова, а потом из пропуска. И теперь нам не требуется условный оператор. Только циклы.

Псевдо-код:
Цикл по участкам до конца строки.

    Цикл по текстовым символам до конца слова или строки.
             переписать.
    Конец цикла
 
    Записать пробел.

    Цикл по пробелам до конца слова или строки.
             пропустить.
    Конец цикла

конец цикла.

Вопросы?
Мне кажется, что проще и понятней быть уже не может.

Этими примерами я хотел показать, о чем я думаю при работе над программой.
Я ищу подходящий объект и такую его структуру, на которые наиболее точно накладывается исходная задача, которые позволяют как можно глубже и подробней провести ОБЪЕКТИВНУЮ декомпозицию алгоритма.
Естественно, это не единственный предмет обдумывания, просто я хотел показать, что не все в сфере разработки алгоритма это интуиция и искуство, даже основанные на опыте.

* v3.jpg (21.36 Кб - загружено 515 раз.)
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 24-01-2010 16:47 » 

Если я не потерял нить по ходу рассуждений, поначалу шла речь об устранении "лишних" (более одного подряд) разделителей между словами.

Третий вариант, насколько могу судить, принудительно дописывает пробел после последнего слова, даже если в исходных данных его там не было.

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 24-01-2010 17:55 » 

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

Все эти "особые пробелы", "слова", "участки" и прочие структурные элемент появляются в рассуждении, как кролик из шляпы фокусника. Однако на исходных данных (цепочке символов), вообще говоря,  в подавляющем большинстве случаев их  нужно распознавать из-за нерегулярной структуры обрабатываемого потока. Любое распознание ведёт к управляющей таблице переходов (массив меток для GOTO, case/switch/select конструкции или цепочке if ... then ... else if ...), определяющей принятие решений.

Да и циклы воспринимать как нечто "безусловное" довольно странно.

Признаться, не улавливаю прагматику избавления от IF ради добавления WHILE.

P.S. Крепнет ощущение разговора под крепкое пиво Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #19 : 24-01-2010 18:32 » 

Строго говоря, решена не совсем та задача, которая ставилась изначально. По условию можно было удалять, но не дописывать отсебятину.
Согласен, но эта неточность была уплачена ради иллюстрации идеи.
Хотя Ваше замечание, само по себе ценно, как пример некачественного анализа исходного текста задачи. Хороший пример.
« Последнее редактирование: 24-01-2010 18:34 от ezus » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #20 : 24-01-2010 18:47 » 

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

К сожалению, тут ситуация похуже, чем простая невнимательность.

Дело в том, что если запретить писать этот злополучный лишний пробел после последнего слова, то выплывет тот самый условный оператор, с которым боролись. Вы стремились продемонстрировать линейный поток управления без ветвлений (если закрыть глаза на циклы, конечно). Теперь же нам придется анализировать, является ли слово последним, и если нет, то припысывать после него разделитель. Вроде мелочь, а вся затея рушится.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #21 : 24-01-2010 18:48 » 

Любое распознание ведёт к управляющей таблице переходов (массив меток для GOTO, case/switch/select конструкции или цепочке if ... then ... else if ...), определяющей принятие решений.
Оказывается не всегда:
если входной поток рассматривать не как произвольный поток произвольных символов, а привлекать дополнительную информацию об исходном объекте.

Цитата
Да и циклы воспринимать как нечто "безусловное" довольно странно.

Признаться, не улавливаю прагматику избавления от IF ради добавления WHILE.
Никто не говорил о безусловности циклов, я отмечал только, что это не оператор IF.
А "прагматика избавления от IF ради добавления WHILE" исходит из моего пунктика об одномерности нашего мышления, и как отмечал еще Дейкстра оператор IF не совсем удобен для нашего восприятия, в то время как WHILE привлекает аппарат вложенности, который по своей сути намного ближе к линейности.
Но т.к. главный мой тезис об одномерности был отвергнут, то и мои варианты, возможно, неактуальны.

Цитата
P.S. Крепнет ощущение разговора под крепкое пиво Улыбаюсь
100%.
Много в нашем деле без пива не прет. Улыбаюсь

К сожалению, тут ситуация похуже, чем простая невнимательность.

Дело в том, что если запретить писать этот злополучный лишний пробел после последнего слова, то выплывет тот самый условный оператор, с которым боролись. Вы стремились продемонстрировать линейный поток управления без ветвлений (если закрыть глаза на циклы, конечно). Теперь же нам придется анализировать, является ли слово последним, и если нет, то припысывать после него разделитель. Вроде мелочь, а вся затея рушится.
Это говорит лишь только о том, что надо подыскать другую структуру для нашего объекта.

А вообще-то я приводил эти варианты не в целях отказа от оператора IF, а как иллюстрация связи структуры исходного объекта и структуры нашей программы. Очевидно, опять не получилось донести свою главную идею. Сам виноват.
« Последнее редактирование: 24-01-2010 19:00 от Sel » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 24-01-2010 19:05 » 

Очевидно, опять не получилось донести свою главную идею. Сам виноват.

Давайте лучше попробуем двигаться вперед небольшими шагами. А то на нас сразу наваливается куча деталей, в которых по ходу дела к тому же обнаруживаются изъяны. За этим нагромождением теряется основная идея.

Вот сейчас какой тезис Вы намереваетесь выдвинуть? О том, что правильная структуризация данных приводит к более ясному и изящному коду? Или я ошибаюсь?
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #23 : 24-01-2010 19:54 » 

Вот сейчас какой тезис Вы намереваетесь выдвинуть? О том, что правильная структуризация данных приводит к более ясному и изящному коду? Или я ошибаюсь?
Я делаю еще один шаг по лестнице абстракции: рассматриваю не данные, а сам исходный объект. Дело в том, что структура объекта задачи далеко не всегда совпадает со структурой этого объекта, со структурой алгоритма. Например: исходные данные сортированы по одним ключам, а нам нужен доступ к ним по другим ключам. Т.е. использование в качестве основы структуры данных может привести к построению структуры программы, не соответствующее целям исходной задачи.
Поэтому я в таких случаях отдаю предпочтение не данным, а самому объекту задачи. Конфликт этих структур теперь можно решить осмысленно и управляемо существенно раньше. а не ждать, когда эти конфликты возникнут в процессе разработки детального алгоритма, или еще хуже на этапе кодирования, и их придется решать срочным применением различных триков..
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 24-01-2010 20:06 » 

Вот тут всё про if и while, и про то, что while натуральнее, чем if. А как насчёт старого доброго сопоставления с образцом? Ведь ветвление в каком-нибудь Prolog или более современных декларативных языках часто реализуется именно по этому принципу. Регулярные выражения - это ещё один подход при реализации того же принципа. Или пока разбирается только императивный подход, и я забегаю вперёд?
Записан
ezus
Опытный

il
Offline Offline

« Ответ #25 : 24-01-2010 20:48 » 

Вот тут всё про if и while, и про то, что while натуральнее, чем if. А как насчёт старого доброго сопоставления с образцом? Ведь ветвление в каком-нибудь Prolog или более современных декларативных языках часто реализуется именно по этому принципу. Регулярные выражения - это ещё один подход при реализации того же принципа.
Если само разветвление прячется внутрь, и о нем не надо думать, то это то самое и я за.
Цитата
Или пока разбирается только императивный подход, и я забегаю вперёд?
К сожалению - да - "императивный подход". Я как раз и надеялся, в частности,  пополнить свою коллекцию размышлениями о природе декларативного подхода, его соответствие или противоречие человеческому мышлению и рекомендациями по борьбе с этими противоречиями. Дело в том, что когда я размышлял над своей коллекцией, декларативный подход еще не стал актуальным.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 24-01-2010 20:57 » 

Цитата: Вад
Или пока разбирается только императивный подход, и я забегаю вперёд?
Так вот я с этого и начал - непонятно, по каким правилам действуем (если они вообще есть). Вроде как императивный, и если автор не любит ветвлений, то рекурсивную функцию я даже предложить побоялся Улыбаюсь Меня только циклы смущают.

Цитата: ezus
Оказывается не всегда:
если входной поток рассматривать не как произвольный поток произвольных символов, а привлекать дополнительную информацию об исходном объекте.
Категорически не согласен. Если есть априорно известная информация об объекте, то нет акта распознавания; если же есть акт распознавания, то нет априорно известной информации об объекте. Вся суть процесса вычисления сводится к уменьшению неопределённости, к "прояснению" результата.

Цитата: ezus
А "прагматика избавления от IF ради добавления WHILE" исходит из моего пунктика об одномерности нашего мышления, и как отмечал еще Дейкстра оператор IF не совсем удобен для нашего восприятия, в то время как WHILE привлекает аппарат вложенности, который по своей сути намного ближе к линейности.
Но т.к. главный мой тезис об одномерности был отвергнут, то и мои варианты, возможно, неактуальны.
Не понимаю, чем "вложенность" тела цикла отличается от "вложенности" условия. Всегда можно написать условие без ветви "иначе", и всегда можно написать цикл WHILE, работающий как IF...THEN.

Я не то что отвергаю тезис об "одномерности", я его пытаюсь понять, но у меня "не срастается", когда выясняется, что цикл одномерен, а условие - нет.

Цитата: ezus
Я делаю еще один шаг по лестнице абстракции: рассматриваю не данные, а сам исходный объект. Дело в том, что структура объекта задачи далеко не всегда совпадает со структурой этого объекта, со структурой алгоритма. Например: исходные данные сортированы по одним ключам, а нам нужен доступ к ним по другим ключам. Т.е. использование в качестве основы структуры данных может привести к построению структуры программы, не соответствующее целям исходной задачи.
Поэтому я в таких случаях отдаю предпочтение не данным, а самому объекту задачи. Конфликт этих структур теперь можно решить осмысленно и управляемо существенно раньше. а не ждать, когда эти конфликты возникнут в процессе разработки детального алгоритма, или еще хуже на этапе кодирования, и их придется решать срочным применением различных триков..
Хочу полюбопытствовать, что такое "сам объект"? Понимаю, что вопрос философский, но куда ж без неё родимой?! Улыбаюсь Тут вспоминается бессмертное творение Хорхе Луиса Борхеса "Аналитический язык Джона Уилкинса":
Цитата
Декарт в письме [9] , датированном еще ноябрем 1629 года, писал, что с помощью десятичной цифровой системы мы можем в один день научиться называть все количества вплоть до бесконечности и записывать их на новом языке, языке цифр [10] ; он также предложил создать аналогичный всеобщий язык, который бы организовал и охватил все человеческие мысли. В 1664 году Джон Уилкинс взялся за это дело.

Он разделил все в мире на сорок категорий, или «родов», которые затем делились на «дифференции», а те в свою очередь на «виды». Для каждого рода назначался слог из двух букв, для каждой дифференции – согласная, для каждого вида – гласная. Например: de означает стихию; deb – первую из стихий, огонь; deba – часть стихии, огня, отдельное пламя. В аналогичном языке Летелье (1850) а означает животное; ab – млекопитающее; abo – плотоядное; aboj – из семейства кошачьих; aboje – кошку; abi – травоядное; abiv – из семейства лошадиных и т. д. В языке Бонифасио Сотоса Очандо [11] (1845) imaba – здание; imaka – сераль; imafe – приют; imafo – больница; imarri – пол; imego – хижина; imaru – вилла; imedo – столб; imede – дорожный столб; imela – потолок; imogo – окно; bire – переплетчик; birer – переплетать. (Последним списком я обязан книге вышедшей в Буэнос-Айресе в 1886 году: «Курс универсального языка» д-ра Педро Маты.)

Слова аналитического языка Джона Уилкинса – это не неуклюжие произвольные обозначения; каждая из их букв имеет свой смысл, как-то было с буквами Священного Писания для каббалистов. Маутнер замечает, что дети могли бы изучать этот язык, не подозревая, что он искусственный, и лишь потом, после школы, узнавали бы, что это также универсальный ключ и тайная энциклопедия.

Ознакомившись с методом Уилкинса, придется еще рассмотреть проблему, которую невозможно или весьма трудно обойти: насколько удачна система из сорока делений, составляющая основу его языка. Взглянем на восьмую категорию – категорию камней. Уилкинс их подразделяет на обыкновенные (кремень, гравий, графит), среднедрагоценные (мрамор, амбра, коралл), драгоценные (жемчуг, опал), прозрачные (аметист, сапфир) и нерастворяющиеся (каменный уголь, голубая глина и мышьяк). Как и восьмая, почти столь же сумбурна девятая категория. Она сообщает нам, что металлы бывают несовершенные (киноварь, ртуть), искусственные (бронза, латунь), отделяющиеся (опилки, ржавчина) и естественные (золото, олово, медь). Красота фигурирует в шестнадцатой категории – это живородящая, продолговатая рыба. Эти двусмысленные, приблизительные и неудачные определения напоминают классификацию, которую доктор Франц Кун приписывает одной китайской энциклопедии [12] под названием «Небесная империя благодетельных знаний». На ее древних страницах написано, что животные делятся на а) принадлежащих Императору, б) набальзамированных, в) прирученных, г) сосунков, д) сирен, е) сказочных, ж) отдельных собак, з) включенных в эту классификацию, и) бегающих как сумасшедшие, к) бесчисленных, л) нарисованных тончайшей кистью из верблюжьей щерсти, м) прочих, н) разбивших цветочную вазу, о) похожих издали на мух. В Брюссельском библиографическом институте также царит хаос; мир там разделен на 1000 отделов из которых 262-й содержит относящееся к папе, 282-й – относящееся к Римской католической церкви, 263-й – к празднику Тела Господня, 268-й – к воскресным школам, 298-й – к мормонству, 294-й – к брахманизму, буддизму, синтоизму и даосизму. Не чураются там и смешанных отделов, например 179-й: «Жестокое обращение с животными. Защита животных. Дуэль и самоубийство с точки зрения морали. Пороки и различные недостатки. Добродетели и различные достоинства».
Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #27 : 25-01-2010 13:00 » 

Вроде как императивный, и если автор не любит ветвлений, то рекурсивную функцию я даже предложить побоялся Улыбаюсь
И правильно побоялись. Правда, любовь к этому не имеет ни какого отношения. Рекурсия в  императивном смысле принципиально противопаказана человеческим мозгам.
Цитата
Меня только циклы смущают.
Хорошо, попробую объяснить по-другому.
Представим: я анализирую код на его корректность. Рассмотрим линейный участок текста, в том смысле, что это тело некоторой функции или часть тела. Таким образом мы можем встретить последовательные участки операторов, условные операторы, циклы и вызовы простых и рекурсивных функций. GOTO я не рассматриваю из-за его старости, а исключения из-за их молодости по отношению к моей коллекции.
Мне кажется естественным анализировать код от начала к концу. При этом уверенность в правильности всего кода гарантируется правильностью любого участка кода от начала до текущей точки анализа. Продвигаясь таким образом от начала к концу и убеждаясь в правильности в каждой текущей точке я могу быть уверен в конечной оценке правильности.
Будем двигаться пооператорно. Если код до данного оператора правильный и данный оператор правельный, то и весь текущий участок правельный.
( Небольшое отступление, так удается не всегда, например, в начале модуля надо выполнить что-то, что потребуется только в конце и не из ничего другого это что-то не следует. Но это не существенно для того, что я хочу сказать).

1. Если текущая точка находится после простого последовательного оператора, то анализ правильности требует принять во внимание только этот оператор. Ничего параллельно анализировать не надо.

2. Если это условный оператор, то за один шаг от точки входа до точки выхода (текущей точки) я "одновременно" должен проанализировать 2 (или более) ветки-блока. Я так не могу, поэтому я работу выполняю дважды - прохожу этот путь сначала по одной ветке, потом по другой.

3. С циклом проще, он тоже состоит из 2 частей: условие и тело, но их можно анализировать последовательно и во многом независимо.

4. К рекурсиии.
Правильность работы функции фиксируется в операторе return. Если в простой функции, дойдя до return ты можешь быть уверен в результате, то при рекурсии
В отличии от обычной функции, анализ рекурсивное функции требует одновременно держать в голове не одну фотографию кода, а несколько, для каждого ветвления в теле функции.
Если это что-то типа расчет факториала, то больших проблем не возникает. А если вариантов рекурсии много, с разными параметрами и переменными состояний. А если это не прямая рекурсия, а косвенная? Тогда приходится держать в голове не просто предыдущий оператор, не просто тело данной функции, а еще целый веер промежуточных модулей.

Может быть кто-то и не видит большого различия между 1. и 4., но для меня это проблема. Это не значит, что я ее не могу решить, но умственные затраты существенно различны. А я "не люблю думать" там, где можно не думать.

Еще один вопрос. Если честно, неужели освоение рекурсии в Вашем программистском детстве прошло у Вас также легко как и того же оператора IF? Если "да", то действительно мои размышления должны вызывать у Вас удивление, и, вряд ли актуальны для Вас.

Цитата: Dimka
Я не то что отвергаю тезис об "одномерности", я его пытаюсь понять, но у меня "не срастается", когда выясняется, что цикл одномерен, а условие - нет.
С точки зрения того, что я только что написал, цикл намного более "одномерен", чем условный оператор.

Цитата: Dimka
Хочу полюбопытствовать, что такое "сам объект"?
Например: Объект - это представление завода с точки зрения планового-отдела, модель завода. Не база данных в отделе АСУ, не море документов в самом плановом отделе, а модель в головах людей.
Это почти реальный объект. С т.зр. планового отдела завод - это не цеха, это не люди - завод - это изделия.
С т.зр, отдела кадров это люди( или точнее цеха\люди), с т.зр. отдела снабжения - это материал \ поставщик.
И с т.зр. самой модели\объекта в общем-то все-равно какие поля и в каких записях есть в фактуре и в каком порядке они там располагаются.
Это будет волновать на следующем шаге, когда функциям данной модели\объекта потребуется информация. Сама по себе информация ценности не имеет - только в приложении к конкретной функции.
« Последнее редактирование: 25-01-2010 13:01 от ezus » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 25-01-2010 14:25 » 

Цитата: ezus
1. Если текущая точка находится после простого последовательного оператора, то анализ правильности требует принять во внимание только этот оператор. Ничего параллельно анализировать не надо.

2. Если это условный оператор, то за один шаг от точки входа до точки выхода (текущей точки) я "одновременно" должен проанализировать 2 (или более) ветки-блока. Я так не могу, поэтому я работу выполняю дважды - прохожу этот путь сначала по одной ветке, потом по другой.

3. С циклом проще, он тоже состоит из 2 частей: условие и тело, но их можно анализировать последовательно и во многом независимо.
Во-первых, вторую ветвь условия всегда можно убрать - вынести в отдельное условие. Во-вторых, и тело цикла и тело условия вносят какие-то изменения в текущее состояние вычислительного процесса (значения локальных переменных). В-третьих, и цикл и ветвь условия могут как выполниться, так и не выполниться. Исходя из этого я не вижу между ними абсолютно никакой разницы с точки зрения заявленной вами "одномерности".

Фиксацию множества допустимых состояний до и после любой операции можно осуществлять с помощью пред- и постусловий. Собственно, с их помощью и осуществляется проверка. В современных условиях (опуская язык Eiffel, где эти вещи встроены в синтаксис языка и обрабатываются компилятором) проверка корректности обычно прописывается в виде assert-конструкции или макроса. Истинности грамотно составленного утверждения или условия в любой точке кода достаточно для подтверждения корректности, повторный анализ цепочки операторов в таком случае является лишним. Работы Дейкстры как раз посвящены именно такому методу управления кодом, при котором можно значительно сократить тестирование.

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

Цитата: ezus
4. К рекурсиии.
Правильность работы функции фиксируется в операторе return. Если в простой функции, дойдя до return ты можешь быть уверен в результате, то при рекурсии
В отличии от обычной функции, анализ рекурсивное функции требует одновременно держать в голове не одну фотографию кода, а несколько, для каждого ветвления в теле функции.
Если это что-то типа расчет факториала, то больших проблем не возникает. А если вариантов рекурсии много, с разными параметрами и переменными состояний. А если это не прямая рекурсия, а косвенная? Тогда приходится держать в голове не просто предыдущий оператор, не просто тело данной функции, а еще целый веер промежуточных модулей.
Для анализа циклов и рекурсий наряду с пред- и постусловиями используют инварианты и рекурентные соотношения. Они статичны сами по себе, но "вмещают" в себе всё разнообразие динамики реального вычислительного процесса. В наибольшей степени такой подход практикуется в функциональном и логическом программировании.

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

Цитата: ezus
Еще один вопрос. Если честно, неужели освоение рекурсии в Вашем программистском детстве прошло у Вас также легко как и того же оператора IF? Если "да", то действительно мои размышления должны вызывать у Вас удивление, и, вряд ли актуальны для Вас.
Отчётливо не помню, как я осваивал рекурсию. Но один тот факт, что я не помню никаких связанных с этим мучений, говорит, что этот этап прошёл достаточно легко. К 10-му классу я её точно использовал наряду с ООП (хотя и ограниченно). Сожалею лишь, что не приобрёл хорошего навыка в использовании динамического программирования - не встретилось хороших учителей.

Цитата: ezus
Например: Объект - это представление завода с точки зрения планового-отдела, модель завода. Не база данных в отделе АСУ, не море документов в самом плановом отделе, а модель в головах людей.
Это почти реальный объект. С т.зр. планового отдела завод - это не цеха, это не люди - завод - это изделия.
С т.зр, отдела кадров это люди( или точнее цеха\люди), с т.зр. отдела снабжения - это материал \ поставщик.
И с т.зр. самой модели\объекта в общем-то все-равно какие поля и в каких записях есть в фактуре и в каком порядке они там располагаются.
Это будет волновать на следующем шаге, когда функциям данной модели\объекта потребуется информация. Сама по себе информация ценности не имеет - только в приложении к конкретной функции.
Согласен. Но проблема в том, что прежняя психология, восприятие машины, как одного лишь вычислителя, в нынешних условиях мешает строить полезные системы. С таким восприятием под каждую задачу нужно сформировать удобную структуру данных, посчитать результат, и благополучно выбросить сформированную структуру данных, как негодную для использования где бы то ни было ещё. Возникают накладные расходы на переформатирование данных, возникают ошибки из-за несогласованности исходных данных и подготовленной для обработки копии. Почему бы от этого не избавиться? Что мешает, кроме привычки определённого восприятия?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #29 : 25-01-2010 17:42 » 

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

И все-таки последний вопрос:
Вы действительно используете формальные методы доказательства корректности Ваших программ на Си, Яве или даже Паскале? Или без анализа своего кода уверенны в его правильности? Если "да", то значит Ваша отладка действительно заключается только в проверке синтаксиса?
Если и здесь "да", то я восхищаюсь Вами. Никакой иронии - абсолютно искренне. Вы, пожалуй, первый такой программист, с которым мне  приходилось общаться.

При любом ответе - Спасибо за Ваши комментарии.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #30 : 25-01-2010 18:55 » 

Мне опять не удалось донести свои оценки и результаты своих размышлений.
Вижу 2 возможные причины
1. Моя косноязычность
2. Мои проблемы и размышления действительно не стоят выеденного яйца, а тем более затраченного на это времени.

Я бы отдал приоритет третьей причине.

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

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

Конкретные предложения? Тут я полностью солидарен с Полиграфом Полиграфовичем:

Цитата
-  Да что  тут  предлагать?.. А  то  пишут,  пишут...  Конгресс,  немцы какие-то... Голова пухнет. Взять все, да и поделить...

Давайте делить, чтобы голова не пухла.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 25-01-2010 19:13 » 

Цитата: ezus
Вы действительно используете формальные методы доказательства корректности Ваших программ на Си, Яве или даже Паскале? Или без анализа своего кода уверенны в его правильности?
1) Иногда, но крайне редко. 2) Процесс написания и проверки обычно совпадают. Тем не менее, иногда возникают ситуации, когда нужно перечитать ранее написанный код, чтобы "освежить память". Поэтому я отвечу: когда как. Есть ряд случаев (например, использование сторонних малознакомых библиотек), когда я сильно сомневаюсь в правильности того, что пишу - тогда надо попробовать в работе (по сути тестирование). В своём собственном коде обычно уверен в гораздо большей степени. Но от невнимательности никто не застрахован - я ж не машина.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #32 : 26-01-2010 08:40 » 

Dale
Абсолютно верно, извинением мне может быть только желание впихнуть необъятное в маленькую коробочку.
Отбросим теоретизированию и умствование на общие темы.

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

Эти приемы могут быть примитивны, и у опытных программистов уже перешли на уровень подсознательного автоматизма, тем интересней будет их от туда выудить и вербализовать.
Если это вообще кому-либо надо.

Приведу примеры.
1. Есть цикл и индекс по массиву.
С индексем связаны 3 операции:
  • присвоение начального значение - "0" или "-1"(для Си)
  • инкремент - в начале тела или в конце
  • использоание индекса по выходу из цикла - "i" или "i-1"
Умственные затраты и ошибки будут существенно меньше, если сначала задать себе вопрос:
"На ЧТО указывает индекс перед входом в тело цикла?"

На первый свободный элемент, первый необработанный
или
Последний занятый, последний обработанный.

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

Если индекс указывает на первый пустой, то ответы: 0, в конце, i-1.
Если на последний обработанный, то: -1, в начале, i.

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

2. Есть несколько вложенных объектов: объект А содержит множество объектов В, В содержит ряд объектов С, а С - D.
Есть также составная фунциональность типа суммирования, состоящая из 3 частей: обнуление счетчика, прибавление очередной дельты, вывод результата.

Размещению этих частей в теле программы поможет ответ на вопрос:
"Сколько раз мне надо выполнить эту часть?" с ответом типа "столько же сколько раз будет встречатся соответствующий объект".

3. Приемы анализа типа "упрощение" и "конкретизации".

И тому подобное.


Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #33 : 26-01-2010 10:00 » 

Приведу примеры.
1. Есть цикл и индекс по массиву.
С индексем связаны 3 операции:
  • присвоение начального значение - "0" или "-1"(для Си)
  • инкремент - в начале тела или в конце
  • использоание индекса по выходу из цикла - "i" или "i-1"
Умственные затраты и ошибки будут существенно меньше, если сначала задать себе вопрос:
"На ЧТО указывает индекс перед входом в тело цикла?"

На первый свободный элемент, первый необработанный
или
Последний занятый, последний обработанный.

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

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

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

Если должны быть обработаны все элементы, есть прекрасная возможность избежать этой ошибки в принципе - заменить такой массив коллекцией. В современных языках программирования имеется богатый выбор реализации таких коллекций и идиомы работы с ними через итераторы. А в том же C# имеется оператор foreach, который гарантированно перебирает все элементы коллекции без явного участия индексов. Возможно, этот подход применим не в 100% случаев, но там, где он уместен, им стоит воспользоваться.

Таким образом, вместо первоначального вопроса "На ЧТО указывает индекс перед входом в тело цикла?" имеет смысл задаться вопросом: а действительно ли индекс необходим для решения данной задачи, или это лишь вспомогательное средство, навязанное нам конкретным отображением сущностей решаемой задачи на низкоуровневую архитектуру вычислительной системы?

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

P.S. Именно поэтому я и призывал перейти к рассмотрению конкретных типичных классов ошибок, а не некоей абстрактной "сферической ошибки в вакууме", с которой и бороться-то непонятно как. Хорошо, что это наконец было услышано.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #34 : 26-01-2010 10:15 » 

2. Есть несколько вложенных объектов: объект А содержит множество объектов В, В содержит ряд объектов С, а С - D.
Есть также составная фунциональность типа суммирования, состоящая из 3 частей: обнуление счетчика, прибавление очередной дельты, вывод результата.

С этого места ясность пропала. "Конгресс, немцы какие-то..."

Понял, что есть несколько типов объектов, которые находятся в отношениях агрегации. Что такое "составная фунциональность типа суммирования", я не рискнул даже делать предположения. Также осталось неясным, что именно считает счетчик (количество вложенных объектов, общую сумму некоего атрибута всех вложенных объектов, что-то еще?), а также как определяется "очередная дельта": в привычном смысле, как разность каких-то величин (тогда каких именно?), или как-то иначе? По-моему, пункт нуждается в более четкой переформулировке.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #35 : 26-01-2010 11:29 » 

Таким образом, вместо первоначального вопроса "На ЧТО указывает индекс перед входом в тело цикла?" имеет смысл задаться вопросом: а действительно ли индекс необходим для решения данной задачи, или это лишь вспомогательное средство, навязанное нам конкретным отображением сущностей решаемой задачи на низкоуровневую архитектуру вычислительной системы?
Почему "вместо"? Это 2 равноправных вопроса.

Сначала Ваш.
А потом, если ответ на него "Да, индехс необходим, т.к. подходящих стандартных средст не нашлось", то возникает мой.

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

Суть вопроса от этого не меняется.

Цитата
P.S. Именно поэтому я и призывал перейти к рассмотрению конкретных типичных классов ошибок, а не некоей абстрактной "сферической ошибки в вакууме", с которой и бороться-то непонятно как.
Частные примеры, конечно, полезны. Но на их основе редко произрастают большие идеи. Для этого все-таки надо иногда подниматься до уровня [абстрактной "сферической ошибки в вакууме"/i]
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #36 : 26-01-2010 11:47 » 

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

Суть вопроса от этого не меняется.

Указатель - тоже низкоуровневое средство (фактически адрес ячейки памяти), и по части притягивания ошибок не уступает индексу.

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

А что касается больших идей, вырастающих из частностей, то одну из них мы сами подробно обсудили - проблема оператора GOTO. При поверхностном подходе это такой же оператор, как и любой другой. Сторонник обобщения сказал бы: а что это вы привязались к одному несчастному оператору? Давайте тогда уж все искореним. И быб бы неправ.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #37 : 26-01-2010 11:57 » 

Почему "вместо"? Это 2 равноправных вопроса.

Сначала Ваш.
А потом, если ответ на него "Да, индехс необходим, т.к. подходящих стандартных средст не нашлось", то возникает мой.

По-моему, нелогично получается.

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #38 : 26-01-2010 12:44 » 

По-моему, нелогично получается.

Равноправные вопросы можно было бы задавать в любом порядке, не меняя сути. А если второй вопрос может возникнуть лишь в случае положительного ответа на первый, вряд ли их можно считать равноправными.
Ну, хорошо.
Если это так важно для понимания проблемы, то Ваш вопрос важнее. Улыбаюсь
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #39 : 26-01-2010 13:01 » 

Кстати, легко ли подобрать пример, когда использование в цикле массива действительно предпочтительнее коллекции с итераторами? Я навскидку затрудняюсь привести.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #40 : 26-01-2010 13:12 » 

Кстати, легко ли подобрать пример, когда использование в цикле массива действительно предпочтительнее коллекции с итераторами? Я навскидку затрудняюсь привести.
Например, буфер в виде массива с прямым методом доступа по индексу: код цеха, номер месяца или код символа при работе с текстами. В этом случае вспомогательные функции типа загрузки и выгрузки буфера, специальный поиск по буферу будут требовать классического цикла.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #41 : 26-01-2010 14:01 » 

Например, буфер в виде массива с прямым методом доступа по индексу: код цеха, номер месяца или код символа при работе с текстами. В этом случае вспомогательные функции типа загрузки и выгрузки буфера, специальный поиск по буферу будут требовать классического цикла.

Контейнеры вроде класса vector из STL для C++ или List из .NET Framework предоставляют произвольный доступ к своим элементам по индексам и в то же время поддерживают работу с итераторами, то есть позволяют обойтись без полного перебора по индексу в цикле типа for. Мне кажется, это неудачный пример.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #42 : 26-01-2010 14:36 » 

Давайте сравним записи переборных циклов (типа FOR) на разных языках программирования и попытаемся понять семантику:
Код: (Text)
FOR I=1 TO N STEP 1
NEXT I
В одной конструкции задание начального значения, размер инкремента. Смысл конечного значения N неочевиден, если между начальным и конечным значением не умещается целое число шагов.
Код: (C++)
for(int i=0; i<N; ++i) {}
По сути дела удобная модификация цикла WHILE: задаётся произвольное количество начальных значений, произвольное условие выполнения цикла, произвольное изменение значений переменных.
Код: (Text)
1 to: N do: [ :n | ]
Неочевидная семантика на уровне объектов, хотя очевидная на уровне чтения кода человеком. У числа определяется метод перебора до следующего числа с выполнением на каждом шаге параметризированного блока кода.
Код: (Ruby)
N.times {}
Буквально переводится "N раз". Очевидно, но не всегда удобно, поскольку внутри блока кода нет счётчика итераций.
Код: (Ruby)
(1..N).each { | i | }
Определяется новая сущность - region как интервал на упорядоченном конечном множестве (целых чисел, символов и т.п.). Для каждого элемента множества выполняется параметризированный блок.

По-моему, последний вариант - самое точное выражение для цикла FOR, которое ближе всего по смыслу к вышеупомянутому "безопасному" циклу типа FOR EACH. В конструкциях старых языков так или иначе "торчат уши" цикла WHILE, особенно в C, где цикл FOR - не более, чем "синтаксический сахар".
« Последнее редактирование: 26-01-2010 14:39 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #43 : 09-02-2010 11:04 » 

Хочу возразить вот на этот пример:
Код: (Ruby)
N.times {}
Буквально переводится "N раз". Очевидно, но не всегда удобно, поскольку внутри блока кода нет счётчика итераций.

Счетчик итераций есть:
Код: (Ruby)
3.times { |i| puts i }
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #44 : 09-02-2010 23:39 » 

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #45 : 10-02-2010 05:39 » 

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

перебор же элементов с шагом 1, практически всегда можно реализовать используя range, а не индекс
в другой теме мы уже затрагивали этот вопрос
собственно большинство (если не все) алгоритмов stl так и делают
мне проще в коде Улыбаюсь
Код: (C++)
for(T::iterator it = begin; it != end; ++it)
{
.....................
}
что такое begin и end не важно, важно, что они:
1. указывают на интересующие нас данные
2. их можно сравнить не > или < (это не всегда возможно), а именно == или !=
3. позволяют переходить к следующему элементу

Кстати, легко ли подобрать пример, когда использование в цикле массива действительно предпочтительнее коллекции с итераторами? Я навскидку затрудняюсь привести.
Например, буфер в виде массива с прямым методом доступа по индексу: код цеха, номер месяца или код символа при работе с текстами. В этом случае вспомогательные функции типа загрузки и выгрузки буфера, специальный поиск по буферу будут требовать классического цикла.

это заблуждение из заблуждений, совершенно спокойно можно итерироваться без индекса, при загрузке выгрузке и т.д. и т.п.
одни из частых задач, когда нужен индекс, а точнее произвольный доступ к элементу (это разные вещи)
1. быстрая сортировка
2. быстрый поиск в отсортированном массиве или коллекции (не говорим про ассоциативные контейнеры)
слово "быстро" тут ключевое, т.к. для решения этих задач не обязательно иметь произвольный доступ, если нам не важна скорость или объёмы данных ничтожны

ps: ezus, у меня складывается ощущение, что Вы очень давно не программировали
Записан

Странно всё это....
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #46 : 10-02-2010 07:30 » 

baldr, ну тогда хорошо. Правда, range удобнее в том смысле, что правая и левая границы задаются произвольно, да ещё ко всему прочему могут быть не только целыми числами, но и символами, и даже строками.
Ruby хорош тем, что можно самому определить любую подобную конструкцию и дальше просто передавать ей блок. Например, задать цикл от случайного числа до другого случайного числа с шагом, случайно изменяющимся каждую итерацию Улыбаюсь)
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #47 : 10-02-2010 07:38 » 

Можно я свои пять копеек вставлю?

Код: (Perl)
for ($i = M; $i <= N; $i++) { }

for $i (M..N) { }

for (M..N) { }

map { } (M..N);
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #48 : 10-02-2010 12:03 » 

совсем не легко (посмотри на свою последнюю фразу Улыбаюсь ), у меня был лишь один прецедент (или два Улыбаюсь ), когда я вынужден был отказаться от концепции работы с итераторами (указателями) и запоминать индекс...

Я к этой мысли и пытался подвести автора темы, но без особого успеха.

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

Задача: Необходимо выполнить сходные действия над совокупностью неких сущностей.

Решение: Объединить сущности в массив, затем в цикле типа пересчета (for) перебрать все элементы массива по индексам и выполнит над каждым элементом требуемые действия.

Типичные ошибки: неправильное задание диапазона индекса (например, в массиве из N элементов индексы перебираются от 1 до N, в то время как фактически в языке C индексы должны принимать значения от 0 до N-1); кроме того, в языках, где вместо явной верхней границы цикла применяется условие продолжения, возможна ошибка при записи этого условия (например, i<=N вместо i<N).

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

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

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

ezus, если Вы еще не утратили интерес к собственной теме, предлагаю проанализировать еще какой-нибудь класс типичных ошибок. Например, что-то вроде  обращения по указателю null, или другой, на Ваш выбор.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #49 : 11-02-2010 06:07 » 

тему переименовываем в "типичные ошибки"?
Записан

Странно всё это....
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #50 : 11-02-2010 06:22 » 

Да, так явно уместнее было бы. Нынешнее название уж больно философское и как-то ни к чему не обязывает.

Заодно хорошо бы переместить ее в более подходящий раздел. Идея поместить ее по соседству с обсуждением сортов пива и опросом по поводу диет, по-моему, была не самой блестящей.

Впрочем, тему не я придумал, так что хорошо бы выслушать мнение автора.
« Последнее редактирование: 11-02-2010 06:26 от Dale » Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #51 : 18-02-2010 15:01 » 

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

ps: ezus, у меня складывается ощущение, что Вы очень давно не программировали
Это не совсем так.
После смены 10 лет назад своего места жительства и соответственно статуса, мне пришлось вернуться к классическому программированию. Сначала 4 года на ABAP/4, потом 4 года на Java, и вот последние 2 года, после почти 20 летнего перерыва опять окунулся в С\С++.
Причем в систему, которую разрабатывали до этого тоже почти 20 лет, а это MS VS C++ 6.0 + MFC. Причем о смене платформы или даже библиотек не может быть и речи. Жаль Система насчитывает более 15 тысяч исходных файлов ( 850 мегабайт ), причем некоторые  файлы размером до 20 тысяч строчек. Многие модули были написаны просто на С. Причем основная масса текста была написана программистами-пользователями, а не программистами-профессианалами (по моей классификации, которую я приводил ранее). А это накладывает неизгладимый отпечаток  на стиль. Да что ты говоришь?.. Кроме того, проповедуется в общем-то неплохой принцип: не трожь то, что дышит. Но он развит далее: "все изменения и дополнения делай в уже принятом стиле" - и хрен с того, что стилю 20 лет?

Поэтому, я думаю, понятно, почему в моих рассуждениях нет этих  foreach, итераторов и коллекций. Кроме того, я приводил пример НЕ того как ПИСАТЬ, а пример того как ДУМАТЬ.

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

Я задумывал нечто другое - не "Типичные ошибки при написании программ", а "Типичные ошибки при размышлении над программой". Но может быть в новой ипостаси она принесет больше пользы.

ezus, если Вы еще не утратили интерес к собственной теме, предлагаю проанализировать еще какой-нибудь класс типичных ошибок. Например, что-то вроде  обращения по указателю null, или другой, на Ваш выбор.
Вы предложили, на мой взгляд, очень хороший анализ, и было бы не плохо развить этот успех.
Действительно новая тема это кое-что другое. Мой интерес к ней не пропал, но изменился.
Сейчас она меня интересует больше как простого потребителя конкретных рекомендаций. В то время как прошлая тема интересовала меня именно в "филофском" аспекте, т.к. я считаю, что ЗНАТЬ, УМЕТЬ и ПОНИМАТЬ - это разные вещи.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #52 : 18-02-2010 16:12 » 

Цитата: ezus
Кроме того, проповедуется в общем-то неплохой принцип: не трожь то, что дышит.
Цитата: ezus
Система насчитывает более 15 тысяч исходных файлов ( 850 мегабайт ), причем некоторые  файлы размером до 20 тысяч строчек.
Система такого размера дышит всегда Улыбаюсь В ней может не работать что-то, но при этом всегда подмножество того, что работает, много больше подмножества того, что не работает, поэтому диагноз "работает" системе в целом никогда не меняется. А некоторые старые баги придают известный колорит, особенно, если появились оригинальные способы использования их побочных эффектов Улыбаюсь

Цитата: ezus
Кроме того, я приводил пример НЕ того как ПИСАТЬ, а пример того как ДУМАТЬ.
А это не одно и то же? Часто мы думаем на языке; формы языка определяют формы мысли.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #53 : 18-02-2010 17:47 » 

Мне тоже по работе приходится поддерживать старое ПО, которому более 10 лет (точно не известно - возможно 10-12 лет). Проектирования не было в помине. Писали не профессиональные программисты-одиночки (ezus, по твоей классификации), куда и себя причисляю. Язык/диалект/среда - Borland C++ Builder. Более сотни модулей на "сумму" 10 МБ (без учета сторонних библиотек), где GUI, данные, логика, SQL и система отчетов перемешаны в кучу. Тоже использую принцип "работает - не трожь", но когда необходимо модифицировать модуль, то первым делом форматирую его код (редактор BCB помогает ленивым создавать ужасно сформатированный, нечитаемый код), изучаю и переписываю. Самое плохое, когда модули взаимосвязанные и обмен данными происходит через свойства GUI-компонентов по числовому индексу. Так вот постепенно уменьшаю энтропию.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #54 : 18-02-2010 17:52 » 

Так вот постепенно уменьшаю энтропию.
которая, как известно, не уменьшается в принципе Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #55 : 18-02-2010 18:10 » 

Еще как уменьшается. Не линейно и не к полному нулю, но уменьшается. Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #56 : 18-02-2010 18:50 » 

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

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #57 : 18-02-2010 19:02 » 

Рома, теперь я за тебя буду волноваться ((
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #58 : 18-02-2010 21:01 » 

Dimka, это парадокс, но я сам сплошная энтропия Отлично
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #59 : 19-02-2010 07:09 » 

Я тут попал под нож хирурга, а им, как известно, все резать и резать. Поэтому какое-то время я был в неактивном состоянии...

ezus, с возвращением (а заодно, надеюсь, с выздоровлением). Очень интересно пообщаться с человеком, который знаком с другими платформами, кроме IBM PC, и размышляет о том, что делает, не на уровне кнопочек на формочках. Надеюсь, тема не будет зафлужена окончательно.

Поэтому, я думаю, понятно, почему в моих рассуждениях нет этих  foreach, итераторов и коллекций. Кроме того, я приводил пример НЕ того как ПИСАТЬ, а пример того как ДУМАТЬ.
...
Я задумывал нечто другое - не "Типичные ошибки при написании программ", а "Типичные ошибки при размышлении над программой".

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

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

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

Да, симптом действительно неважный. Впрочем, давайте уж довольствоваться тем, что есть.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #60 : 19-02-2010 07:19 » 

Dale, скажи честно, у тебя антипатия к GUI? Не стоит считать GUI чем-то элементарным.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #61 : 19-02-2010 08:11 » 

Говорю честно, как на духу.

Нет у меня к GUI ни симпатий, ни антипатий, сугубо потребительское отношение. Равно как и к библиотекам сокетов, к парсерам XML и т.д. Может, я не прав, но любовь или ненависть к подобным вещам в моем представлении вообще является признаком патологии. Нужно - пользуюсь, не нужно - откладываю в сторону.

Те, кто считает GUI сутью и солью программирования, имеют на это полное право. Жаль только, когда действительно интересная тема при этом отправляется на задворки. Но опять же - мое сугубо личное мнение. Отправляясь в чужой монастырь, устав оставляю дома.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #62 : 19-02-2010 08:58 » 

Я вот о том же говорю, что стоит вещи называть своими именами: мы помешали вашей беседе, а кнопочки тут не при чем.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #63 : 19-02-2010 09:11 » 

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #64 : 19-02-2010 09:15 » 

Парни, хватит ругаться! Автор нормальный чувак, ИМХО, необычные размышления - это правильно. Это же уметь надо Улыбаюсь Ударения в маразм вроде не отмечено
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #65 : 19-02-2010 15:31 » 

Цитата: Dale
Давайте попробуем подобрать пример, на котором в чистом виде видны будут сложности именно размышления над программой, а не борьбы с несовершенством С и ему подобных раритетов.
Давайте. Мне видятся сложными для программирования плохо структурируемые задачи. Например, такие, в которых граф состояний близок к полному, а количество состояний велико (от 7 и выше). При этом события асинхронные, частота их поступлений может превышать скорость реакции.
« Последнее редактирование: 19-02-2010 15:36 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #66 : 19-02-2010 16:12 » 

Переформулируя до неузнаваемости Улыбаюсь одну мне известную задачку (кстати, связанную с программированием пользовательского интерфейса):

Задача

Пусть есть переменная A, значение которой меняется в случайные моменты времени с существенными для человека интервалами (например, от 5 секунд до 5 часов). (Как меняется, не важно). Например, отображающая значение какого-то датчика. Программисту доступен сигнал оповещения об измении A.

Пусть есть переменная B, значением которой является вычисление некоторой функции F от A. Программисту доступен сигнал оповещения об изменении B.

Допустим, вычисление F - ресурсоёмкий и заметно длительный для человека процесс (длительностью 1-2 минуты), и решение о его запуске принимает человек. Программисту доступен сигнал о необходимости запуска вычисления F.

Пусть есть ресурсоёмкий и заметно длительный для человека процесс G (длительностью 5-15 минут), который тоже запускается человеком. Программисту доступен сигнал о необходимости запуска G и сигнал об окончании G.

При этом G не может быть запущен в моменты времени, когда значение B не соответствует значению A; F не может быть запущен в моменты времени, пока выполняется G.
Все сигналы асинхронны. Человек может подавать сигналы в любое время и допускать ошибки (т.е. посылать сигналы невовремя).

Нужно разработать индикаторы для человека, отображаемые в переменные C и D, разрешающие ему посылать сигналы на запуск процессов F и G соответственно.

Запрограммировать всё это дело.
« Последнее редактирование: 19-02-2010 20:07 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #67 : 19-02-2010 22:22 » 

При этом G не может быть запущен в моменты времени, когда значение B не соответствует значению A; F не может быть запущен в моменты времени, пока выполняется G.
А что происходит с G, если значение A меняется во время выполнения G? Соответствие A и B имеет значение только при запуске G, но не в процессе?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #68 : 19-02-2010 22:46 » 

Вад, да. Можно считать, что и F и G в самом начале читают текущие значения переменных; F в самом конце записывает новое значение B.

Запуск нескольких экземпляров F и G невозможен.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #69 : 20-02-2010 05:08 » 

самое первое, что нужно сделать, это то, что

 - F при запуске запрещает запуск G
 - по окончанию вычисления B=F(A), F должна проверить, поменялось ли значение A (в сравнении с A в начале вычислений). Если  не поменялось, разрешаем запускать G


Ещё можно автоматизировать: запуск G производить из F по флагу, установленному программистом. Когда работает F , могут установить флаг, F в конце проверит, менялась ли A и запустит G.

Если надо запустить только G, то запускается F, смотрит, менялась ли A, если менялась - вычисляет, если не менялась, берёт предыдущий результат и выполняет G
Записан

Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #70 : 20-02-2010 09:52 » 

А какова основная функция человека в этом процессе? Он является лишь частью системы, отвечая за решения о запуске F и G? Я так понимаю, он обслуживает процесс G и отвечает за то, чтобы данные для G были готовы (запускает процесс F)?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #71 : 20-02-2010 11:15 » 

Я выше сказал, что сигналы асинхронны, но процессы F и G работают в одном потоке исполнения.

Вад, да, задача человека - выбрать момент времени для запуска того или иного процесса (не в смысле ОС, а в смысле "вычислительный процесс").

Цитата: Алексей1153++
Ещё можно автоматизировать
Нельзя, так как процессы имеют существенную длительность, и такая стратегия невыгодна. Фактически ты предлагаешь объединить их в один процесс длительностью в худшем случае 17 минут. Бывают случаи, когда F завершился и можно запускать G, но выгоднее подождать очередного значения A, ещё раз запустить F и только потом G. A изменяется с разными частотами: бывают серии быстрых изменений A, потом большая пауза.

И вообще твоё предложение - это не решение поставленной задачи, а её додумывание. Додумывать и "автоматизировать" ничего не надо. Нужно запрограммировать.

Цитата: Алексей1153++
- F при запуске запрещает запуск G
 - по окончанию вычисления B=F(A), F должна проверить, поменялось ли значение A (в сравнении с A в начале вычислений). Если  не поменялось, разрешаем запускать G
Эта идея и ежу понятна. Тема же "о чём думает программист". В данном случае это не просто разработка алгоритма, а ещё и выбор новых переменных, может каких-то структур данных, решения о их взаимосвязях, организация управления вообще - в этом и весь интерес.
« Последнее редактирование: 20-02-2010 11:18 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #72 : 21-02-2010 09:32 » 

Как много всего за 2 дня.  И тема, неожиданно для меня, повернулась в мою сторону.

Ударения в маразм вроде не отмечено (у автора)
Ну спасибо, а то я уже начал сомневаться в своем интеллекте.

Цитата: ezus
Кроме того, я приводил пример НЕ того как ПИСАТЬ, а пример того как ДУМАТЬ.
А это не одно и то же? Часто мы думаем на языке; формы языка определяют формы мысли.
Я добавлю сюда еще одну очень актуальную цитату из этого же поста.
Цитата
Программировать - значит понимать (К. Нюгард)
Даже не знаю как и что ответить. Но попробую начать с байки, реальной.
Я дома; звонок от сотрудника соседнего отдела: "Мне сказали использовать ваш класс, как мне это сделать?". Использование класса требует некоторого понимания того, что он делает. Я пытаюсь что-то объяснить, но натыкаюсь на полное непонимание - стенка. В растерянности полу-шутя я задаю вопрос: "Вы сначала думаете или пишите?". На что получаю абсолютно серьезный несколько недоуменный ответ: "Конечно, сначала пишу, а потом думаю и разбираюсь, если что не так." Я был в шоке, но потом специально обратил внимание на то, что большенство программистов вокруг меня именно так и работают. Вот тут я действительно засомневался в своем интеллекте. Хотя мой вопрос был вполне легитимен: я мог объснить как работает класс, или без объяснение сказать ЧТО надо делать, или просто продиктовать код.
Второй пример: как-то в обеденное время за общим столом я абсолютно без задних мыслей при обсуждении какой-то худ.книжки, как что-то очевидное, сказал что в основе любой программы лежит некоторая идея, во всяком случае у меня так. На что все семь человек-программистов, сидевших в это время за столом, посмотрели на меня как на больного - какие еще идеи? Программа - это программа, и для ее написания идей не нужно.
Вот тут я почувствовал наступление на меня старческого маразма.
Если ты трезв, но все говорят тебе, что ты пьян - пойди и проспись.
Может быть все о чем я размышляю это чушь?
К счастью через какое-то время я это ощущение победил, просто запретив себе разговоривать на эти темы. Так что этот мой выход на форум редкое исключение в моем поведении.

Теперь по делу.
Знать , Уметь и Понимать.
Я знаю о существовании конкретного программистского приема
Я умею этим приемом пользоваться
Я понимаю какова причина появления этого приема, когда и почему надо\можно использовать этот прием, каковы его плюсы и минусы.

Мне кажется есть разница между:
Я использую данные прием, потому что он первый пришел мне в голову и
Я использую его, потому что осмысленно выбрал его и понимаю все последствия этого выбора. 
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #73 : 21-02-2010 10:29 » 

Цитата: ezus
Хотя мой вопрос был вполне легитимен: я мог объснить как работает класс, или без объяснение сказать ЧТО надо делать, или просто продиктовать код.
Насколько я понимаю, программист - понятие собирательное.

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

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

В данном случае описано общение за обедом между толпой кодеров и кем-то повыше в профессиональной иерархии Улыбаюсь Естественной, что каждый уровень подразумевает свой круг понятий, представлений и идеалов. Странно лишь обвинять кодеров в том, что они кодеры. Если организации нужны были не кодеры, а разработчики, нужно было либо нанять других людей, либо озаботиться повышением квалификации имеющихся. В последнем случае кодер становится "растущим кодером", его круг понятий, представлений и идеалов меняется, поэтому он больше слушает, чем озвучивает свои взгляды. Поскольку информация структурируется по иерархии сверху вниз, общение тоже идёт таким образом, что архитектор общается с разработчиком на языке разработчика, разработчик общается с кодером на языке кодера; это возможно, так как профессиональный рост шёл снизу вверх, и в душе и разработчика и даже архитектора живёт маленький кодер Улыбаюсь Правда, внутренний кодер архитектора гораздо более дисциплинирован и подконтролен, нежели внешний Улыбаюсь

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

Цитата: ezus
Мне кажется есть разница между:
Я использую данные прием, потому что он первый пришел мне в голову и
Я использую его, потому что осмысленно выбрал его и понимаю все последствия этого выбора.
Есть.

А насчёт задачки? Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #74 : 21-02-2010 10:54 » 

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

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #75 : 21-02-2010 11:22 » 

Попытаюсь на примере предложенной задачи показать о чем я ДУМАЮ.
Понятно, что это будет слишком развернуто и насыщено "философией", но в данном случае цель - не решение задачи, а разбор примера.

Сначала пытаюсь понять о чем речь.
Первый этап - этап черного ящика.
Этот этап опирается на более развернутое определение понятия система.
Обычно на вопрос " Что такое система?" получаешь ответ типа "Система - это совокупность взаимосвязанных объектов", что в общем-то правильно, но является только половиной определения. Система - это не только что-то состоящее из чего-то, но и как целое , она является частью чего-то более общего - частью среды, с которой она взаимодействует, или - подсистемой некой мета-системы.
На этом этапе меня не интересует внутреннее устройство системы. Здесь я только анализирую среды. Их можно представить как ромашка - в центре программа, а липестки - это различные среды. Например: человеко-машинная, информационая, операционная, временная, организационная, административная и др. В нашем случае интересны: человеко-машинная и временная среды.
Временная среда рассматривает развитие процессов во времени и их взаимодействия и взаимозависимости.
Человеко-машинная среда определяет интерактивную информацию(входную и выходную), точки принятия решений человеком и возможные воздействия человека на программу.

Прошу прощение - продолжение следует. Надеюсь.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #76 : 21-02-2010 12:28 » 

To Dimka & Dale:
Я Вам завидую:
Вам повезло работать в серьезных организациях с серьезными людьми - мне повезло меньше.

А насчёт задачки? Улыбаюсь
Попробую продолжить.

Ч-М среда.
Человек асинхронно получает 2 сигнала:
С - необходим расчет F
D - необходим расчет G

Человек может выполнить 2 команды:
К1 - выполнить расчет F
К2 - выполнить расчет G.

Точки принятия решений:
1. Нет сигналов - нет команд
2. Есть сигнал С - можно выдать К1
3. Есть сигнал D - можно выдать К2

Ошибки и реакция:
1. Если выдана команда при отсутствии сигнала, то команда игнорируется.

Анализ:
1. Не достаточно информации для принятие решений - нет данных, которые помогли бы принять решение нужно или нет выполнять соответствующую команду (не критично)
2. Нет полноты множества команд - если приходят оба сигнала и С и D , то нет команды К3 для последовательного расчета F и G (не критично)
3. Не определен момент погашения сигналов С и D ( не критично, если сигналы типа сообщений, и критично для сигналов типа транспорант или лампочка)
4. Отсутствует обратная связь по ошибкам человека. (не критично)

Возможно еще что-нибуть, но в принципе чМ интерфейс понятен.
« Последнее редактирование: 21-02-2010 12:59 от ezus » Записан
ezus
Опытный

il
Offline Offline

« Ответ #77 : 21-02-2010 13:01 » 

Возможно еще что-нибуть, но в принципе чМ интерфейс понятен.
Понятен, но не совсем. Моя попытка перейти к временной среде породила дополнительные вопросы к черному ящику.

Продолжение анализа на этапе черного ящика.
4. Команды К1 и К2 являются:
  • указанием\приказом о начале расчета
или
  • разрешением на выполнение расчета в ближайше возможное время
или
  • разрешением на выполнение расчета в подходящее время
  Критично с т.зр. выбора алгоритмов работы.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #78 : 21-02-2010 13:21 » 

Цитата: ezus
Ч-М среда.
Человек асинхронно получает 2 сигнала:
С - необходим расчет F
D - необходим расчет G
Поправка. Не необходим, а возможен. У человека нет задачи по загоранию лампочки рефлекторно нажимать кнопку. Человек может нажать кнопку, когда посчитает это нужным, от системы требуется лишь обозначить периоды времени, когда кнопку нажимать нельзя/можно.

Цитата: ezus
1. Не достаточно информации для принятие решений - нет данных, которые помогли бы принять решение нужно или нет выполнять соответствующую команду (не критично)
Это касается человека-оператора, но не касается программной системы. Зачем пытаться расширять границы системы?

Цитата: ezus
2. Нет полноты множества команд - если приходят оба сигнала и С и D , то нет команды К3 для последовательного расчета F и G (не критично)
Вот тут мне бы хотелось пояснения. Какими путями возникла такая мысль? (Кстати, весьма похожая на идею Алексей1153++). Как говорится, один раз - случайность, два раза - совпадение. Если третий человек выскажет ту же мысль, я начну беспокоиться Улыбаюсь

Цитата: ezus
3. Не определен момент погашения сигналов С и D ( не критично, если сигналы типа сообщений, и критично для сигналов типа транспорант или лампочка)
Формально - да. Но это решаемо и, собственно, составляет часть требуемого решения.

Цитата: ezus
4. Отсутствует обратная связь по ошибкам человека. (не критично)
Этим можно не усложнять.

Цитата: ezus
Продолжение анализа на этапе черного ящика.
4. Команды К1 и К2 являются:
указанием\приказом о начале расчета
или

разрешением на выполнение расчета в ближайше возможное время
или

разрешением на выполнение расчета в подходящее время
  Критично с т.зр. выбора алгоритмов работы.
Отчасти это даёт ответ на мои сомнения в пункте 2 Улыбаюсь Это приказ о немедленном начале расчёта.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #79 : 21-02-2010 14:49 » 

Это касается человека-оператора, но не касается программной системы. Зачем пытаться расширять границы системы?
Пометка о некритичности и говорит о том, что я не собираюсь расширять систему. НО...
  • Программа живет пока она изменяется
  • Аппетит заказчика приходит во время его еды
  • Развитие системы предусмотренное на этапе анализа задачи намного дешевле непредусмотренных изменений на этапе эксплуатации
  • и т.д и т.п.
Поэтому, если я вижу недостатки(на мой взгляд) в системе, я их отмечаю, пытаюсь убедиться в их необходимости, и если я в себе уверен, то, даже не смотря на отказ заказчика, я стараюсь предусмотреть не дорогие ветки с отложенной реализацией.

Цитата
Вот тут мне бы хотелось пояснения. Какими путями возникла такая мысль?
Это мысль скорее всего приходит ассоциативно: чаще всего человек реагирует на ситуацию, а не как обезьяна на сигнал. Сигнала у нас действительно 2, а возможных ситуаций три, следовательно и команд интуитивно должно быть 3.
Правда, если бы я начал анализ с времянной среды, то там сигналы бы рассматривались вне человеческого контекста, там было бы важно взаимодействие сигналов во времени, и вместо возникшего вопроса, скорее всего встал бы вопрос Как запретить ситуацию с двумя сигналами одновременно.

Мне кажется, это как раз иллюстрирует необходимость анализа задачи с разных точек зрения и не ограничиваться только анализом данными и алгоритмов.

Цитата
Цитата: ezus
3. Не определен момент погашения сигналов С и D ( не критично, если сигналы типа сообщений, и критично для сигналов типа транспорант или лампочка)
Формально - да. Но это решаемо и, собственно, составляет часть требуемого решения.
. Вот тут я не совсем согласен. Предложенная постановка не содержит критериев выбора. Возможны оба варианта, а критерий лежит в самой предметной области, а не в области программистской реализации.

Цитата
Это приказ о немедленном начале расчёта.
Отсюда вытикает или запрет на одновременности C и D, или наличие К3.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #80 : 21-02-2010 14:56 » 

Dimka, моя мысль состояла в том, чтобы избавиться от одной из вещей, которые требуется синхронизировать, а именно: G возможно начать только после выполнения F, да ещё если A одинаково в начале и в конце расчёта F. Поэтому эти две задачи нужно объединить в одну функцию. Эта функция позволяет выпольнить 2 различных сценария (в зависимости от заданной человеком задачи)

1) Задача: выполнить F. Действия функции:
    1 Выполнить F. (или взять результат из кеша)
    2 Завершение

2) Задача: выполнить G. Действия функции:
    1 Выполнить F. (или взять результат из кеша)
    2 Если поменялась A - завершение
    3 Выполнить G.


кстати, если A поменялась во время расчёта F, а затем вернулось в изначальное состояние - это тоже за изменение надо считать ? Улыбаюсь
Записан

ezus
Опытный

il
Offline Offline

« Ответ #81 : 21-02-2010 15:20 » 

Алексей1153++ ++
Т.к. асинхронность трудно воспринимаема нашим сознанием, то везде, где только возможно, я ищу возможность избежать асинхронности.
Поэтому в любом случае я выполнял бы F и G в одном потоке\процессе с алгоритмом типа:

Если К1, то выполнить F
иначе
если К2, то выполнить G

При наличии К3 - просто убрать "иначе"
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #82 : 21-02-2010 15:30 » 

ezus, ты забыл учесть, что возможность выполнения G зависит от смены A (и, соответственно, обязательного пересчёта F)
Записан

ezus
Опытный

il
Offline Offline

« Ответ #83 : 21-02-2010 16:24 » 

ezus, ты забыл учесть, что возможность выполнения G зависит от смены A (и, соответственно, обязательного пересчёта F)
Пардон, не понял, что я забыл? G  не зависит напрямую от A. И для выполнения G не требуется смена А и расчет F. Он мог быть выполнен ранее и только потом, через какое-то время запускается только G. Возможно для полноты и ясности в "если" необходимо добавить провекрки состояний, но привел не строгий алгоритм, а только его структуру.
« Последнее редактирование: 21-02-2010 16:29 от ezus » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #84 : 21-02-2010 16:31 » 

При этом G не может быть запущен в моменты времени, когда значение B не соответствует значению A; F не может быть запущен в моменты времени, пока выполняется G.
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #85 : 21-02-2010 18:06 » 

Вот читаю и думаю, как по-разному думают программисты об одном и том же Улыбаюсь


Лично я в первую очередь думал о состояниях и переходах между ними.

Первый вопрос: что на что влияет?



Отсюда видно, что начальным независимым элементом системы является A (в него стрелки зависимостей только входят), конечным зависимым элементом является G (из него стрелки только выходят). Элементы F и B являются по зависимостям транзитными.

Теперь учтём, что A и B - это переменные со значениями, а F и G - вычислительные процессы. Зависимость процесса от переменной интерпретируем как-то, что данная переменная является входной для процесса. Зависимость переменной от процесса интерпретируем как-то, что данная переменная является выходной для процесса. Как выше оговаривалось, в данной задаче считается, что процесс в начале читает значения входных переменных и в конце записывает значения выходных, в остальное время значения переменных "свободны".

Поскольку G имеет входными A и B, но B транзитивно через F зависит от A, и оговорено, что должно наблюдаться соответствие A и B как B=F(A). Это равенство существенно для запуска G (является одним из предусловий), поэтому обозначим его соблюдение как логический флаг Z1. Для запуска G также существенно (другое его предусловие), чтобы процесс F не выполнялся (в соответствии с оговоренными ограничениями). Наличие/отсутствие выполнения F обозначим логическим флагом Z2.

По смыслу процесса F нужно невыполнение равенства B=F(A), т.к. F это равенство восстанавливает. Это предусловие для запуска F выражается через уже введённый флаг Z1, но взятый с отрицанием. Второе предусловие запуска F - отсутствие выполнения процесса G, обозначим его логическим флагом Z3.

Эти три флага дают 8 возможных состояний:
Код:
# Z1 Z2 Z3 E
1 0  0  0  +
2 0  0  1  *
3 0  1  0  &
4 0  1  1  -
5 1  0  0  +
6 1  0  1  *
7 1  1  0  &
8 1  1  1  -
Некоторые из состояний заведомо невозможны - они обозначены "-" в столбце E (ошибка). По условию задачи невозможно одновременное исполнение процессов F и G - состояния 4 и 8 исключаются. Состояния выполняющихся процессов являются безразличными с точки зрения флага Z1, поэтому могут быть объединены: это пары состояний 2 и 6 (обозначены "*"), 3 и 7 (обозначены "&"). После этого анализа у нас остаётся следующая таблица состояний:
Код:
# Z1 Z2 Z3 C D
1 0  0  0  1 0
2 1  0  0  0 1
3 X  1  0  0 0
4 X  0  1  0 0
Из которой несложно определить значения искомых индикаторов C и D. Кроме того, можно определить логику смены состояний, а сами состояния разделить на 2 класса: вычислительных (соответствующих работе процессов) и управляющих (соответствующих периодам принятия решений). Получается, что каждый индикатор активен в соответствующем ему управляющем состоянии.



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

* dep.png (2.99 Кб - загружено 1141 раз.)
* stat.png (4.37 Кб - загружено 1117 раз.)
« Последнее редактирование: 21-02-2010 18:15 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #86 : 21-02-2010 18:58 » 

Любопытно Улыбаюсь Я размышление над этой задачей начал с человека.

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

А потому программа должна решать две задачи:
1. Доставить пользователю максимум необходимой информации, чтобы улучшить его экспертные знания (лучше понимать систему и работать над ошибками),
2. Предоставить интерфейс принятия решений, предоставляющий пользователю требование о принятии решения в таком виде, который не допускает некорректного представления об актуальном состоянии системы. То есть, пользователь не должен быть введён в заблуждение, и не имеет возможности принять решение, не допускаемое логикой работы системы (например, дважды запустить G, или запустить F при A=B).

Соответственно, я сразу стал думать о том, что человек получает не два, а большее количество сигналов. И задача - как можно нагляднее представить пользователю происходящее в системе, при этом исключив недопустимые переходы между состояниями. И тут мало просто показать, что "нужно выполнить F" или "можно выполнять G" - так утрачивается информация о динамике системы. И вот как раз способ отобразить эту динамику наиболее эффективно и показался мне основной задачей данной системы. Основная проблема для меня: как помочь пользователю?

Что касается самих состояний и переходов, то тут у меня сразу возникла финальная картинка Улыбаюсь Для этого не потребовалось выводить полный список состояний - достаточно было сосредоточиться на согласовании двух вычислительных процессов в системе.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #87 : 21-02-2010 19:42 » 

Цитата: Вад
Соответственно, я сразу стал думать о том, что человек получает не два, а большее количество сигналов. И задача - как можно нагляднее представить пользователю происходящее в системе, при этом исключив недопустимые переходы между состояниями. И тут мало просто показать, что "нужно выполнить F" или "можно выполнять G" - так утрачивается информация о динамике системы. И вот как раз способ отобразить эту динамику наиболее эффективно и показался мне основной задачей данной системы. Основная проблема для меня: как помочь пользователю?
Ну вот и третий Улыбаюсь

Тут отчасти моя вина, так как исходную задачу я зашифровал за буковками. И там ещё много всяких побочных ответвлений (например, значение B используется не только для G, но и в других местах, и поэтому человек решает не только "привести B в соответствие с A", но и "можно ли затереть текущее значение B новым").

Как говорил С. Королёв: "Луна - твёрдая!" - сим предлагаю дискуссию об удобствах юзера закрыть и считать, что индикаторы C и D - лучшее по эргономическим и прочим соображениям решение. А вот о будущих расширениях/изменениях системы думать можно, если нужно Улыбаюсь.

Сосредоточимся на программировании Улыбаюсь

Цитата: Вад
Что касается самих состояний и переходов, то тут у меня сразу возникла финальная картинка  Для этого не потребовалось выводить полный список состояний - достаточно было сосредоточиться на согласовании двух вычислительных процессов в системе.
Аналогично, т.е. всё вышеописанное возникает в голове "автоматически". Но поскольку телепатического чата к форуму мы ещё не прикрутили, то расписал Улыбаюсь. Расписывание, кстати, тоже бывает полезным - не теряются мелкие детали. Например, все переходы сразу я не "помню" - вместе с состояниями их многовато, - я могу их лишь выводить, раз за разом повторяя рассуждения, основанные на смысле состояний.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #88 : 21-02-2010 20:03 » 

Спасибо за модель состояний.
Почему то я забыл ее включить в свою коллекцию.
Хотя понятно почему, в то время я в основном сталкивался с задачами АСУ, в которых динамика состояний встречается редко.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #89 : 21-02-2010 20:26 » 

Цитата: ezus
динамика состояний
По-моему состояния и есть выражение динамики. Вне контекста динамики состояний не существует. Состояния потому выделяются, отделяются друг от друга, что для аналитика переход между ними считается значимым, если переходы между двумя состояниями не имеют значения, такие состояния объединяются в одно. Именно поэтому у меня получилось 4 состояния, не больше и не меньше.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #90 : 22-02-2010 11:32 » 

Сосредоточимся на программировании Улыбаюсь
Хорошо Улыбаюсь Тогда размышления дальше движутся по такому пути: система получает сигналы и отсылает ответные, информирующие окружение об изменениях в состоянии. Задержки при передаче и обработке сигналов, вообще говоря, могут приводить к тому, что окружение отправляет сигнал, ориентируясь на прежнее состояние системы, тогда как оно может успеть измениться. Например, пользователь сигнализировал "запустить G" (или "запустить F"), и в тот же момент система получила сигнал "A изменилось" - это может ввести в заблуждение пользователя: будет ли произведена операция? И если А изменилось после момента отправки и до момента обработки F - то для какого A будет вычислено F?

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

Допустим, все поступающие сообщения помещаются в очередь. Тогда, например, в случае поступления сигнала "изменяется A" уведомление о начале транзакции приводит к тому, что сбрасывается флаг Z1 (и об этом узнаёт UI), а затем уже нужно выполнить собственно модификацию A и закрыть транзакцию.

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

Однако что же делать с сигналами, которые успели наотправлять источники? Думаю, здесь нужна система приоритетов: очевидно, что если данное состояние системы позволяет, скажем, как изменение A, так и вычисление G, то вычислению G нужно отдать приоритет - иначе этот важный процесс может так никогда и не быть выполненным под градом частых изменений A. В то же время, процесс F является менее приоритетным, чем изменения A в том смысле, что в рамках конкретного отсечённого набора сообщений, поступивших до начала транзакции, выгоднее сначала иметь наиболее актуальное A, и лишь затем выполнить F.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #91 : 22-02-2010 12:49 » 

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

Всё это не отменяет приоритетов, т.к., например, сигнал о запуске G и сигнал об изменении A могут прийти одновременно (фактически последовательно, пусть упорядочиванием в очереди занимается внешняя среда, но в непредсказуемом порядке в самом начале кванта времени). Нужно принять меры, чтобы сначала получить все сигналы и запомнить, какие из них наблюдались, потом сделать выбор по приоритетам.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #92 : 14-03-2010 18:19 » 

To Dimka
Мне кажется, что обсуждение свелось к тонким деталям алгоритма. Это само по себе интересно, но, скорей всего, алгоритм вами уже разработан, и сейчас можно перейти к следующей стадии - разработка структуры программы. Не могли бы Вы привести основные соображения  по выбору структура программы и их возможные обоснования?
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #93 : 15-03-2010 04:29 » 

ИМХО, алгоритм и структура программы вещи связанные, но не настолько, чтобы одно навязывало другое.
Записан

Странно всё это....
ezus
Опытный

il
Offline Offline

« Ответ #94 : 15-03-2010 06:55 » 

ИМХО, алгоритм и структура программы вещи связанные, но не настолько, чтобы одно навязывало другое.
Согласен.
Вот мне и интересно,
какими критериями руководствуются спецы при проектировании структуры программы,
какие мысли их посещают,
какие из них помогают, а какие - мешают.
О чем думать сначала, а что откладывать на потом?
Как структуру программы сделать по возможности более объективной?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #95 : 17-03-2010 20:01 » 

Цитата: ezus
Не могли бы Вы привести основные соображения  по выбору структура программы и их возможные обоснования?

какими критериями руководствуются спецы при проектировании структуры программы,
какие мысли их посещают,
какие из них помогают, а какие - мешают.
О чем думать сначала, а что откладывать на потом?
Как структуру программы сделать по возможности более объективной?
Ну вообще программирование автомата, тем более простого, без памяти, задача типовая, и решается либо серией ветвлений или оператором множественного выбора (в данном случае предпочтительнее), либо шаблоном проектирования "Интерпретатор".

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

Дальше, если сигналы нужно обрабатывать группами, требуется определить способ распознавания конца группы - момента, когда нужно от накопления информации переходить к её обработке. А также определить структуры данных, в которых информация накапливается (в данном случае простые переменные).

Мешающих мыслей у меня не возникало.


Теперь об "объективности" структуры программы. Либо я не понимаю, о чём этот вопрос, либо, если понимаю, он требует длинной философской лекции на тему.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #96 : 23-03-2010 15:56 » 

в тему
http://habrahabr.ru/blogs/arbeit/88443/
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #97 : 23-03-2010 17:42 » 

Sla, я не знаю, к чему тяготею - всё как-то больше о семантике интерфейсов забочусь. Стадию новичка-энтузиаста как-то прошёл мимо; стадия подающего надежды гения до сих пор проявляется, но в несколько модифицированном стиле; стадия поборника абстракций прошла довольно быстро, и ко всему прочему сильно отпугнули матёрые поборники, код которых приходилось сопровождать - зарёкся и до сих пор не люблю особо богатых конфигов, чем ужасно не порадовали новые веяния .NET - не люблю зависимости от всяких wizard'ов; в стадии ветерана был, но сбежал; "гуру" не являюсь, но симпатизирую.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: 1 2 3 4 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines