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

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

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

При любом ответе - Спасибо за Ваши комментарии.
Записан
Страниц: [1] 2 3 4  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines