Письмо слепого программиста

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

Уважаемый Константин.

Прочитал вашу книгу «Путь в программисты». Она породила много самых разнообразных мыслей. У меня богатый опыт самообразования в области ИТ, и давно зрело желание как-то его систематизировать, хотя бы для самого себя. Но поскольку вы сами рекомендуете учиться программированию самообразованием и даете рекомендации новичкам, возможно, для вас тоже будет интересно, чего может достичь и с какими проблемами сталкивается человек, достаточно далеко продвинувшийся в данной области. К сожалению, букв будет много, ибо без предыстории и примеров никак…

О себе

Меня зовут Михаил Духонин. 37 лет. Живу в Саратове. Холост. Получил высшее образование по специальности «Социальная философия», закончил аспирантуру, защитил диссертацию. В общем, незамутненной чистоты гуманитарий.

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

Предваряя стандартный вопрос о том, как же я, слепой, работаю на компьютере (хотя, как специалист в ИТ-сфере, возможно, вы и в курсе…), замечу, что существуют так называемые программы экранного доступа (скринридеры, screen reader), которые озвучивают интерфейс ОС и программ. Они позволяют ориентироваться на компьютере на слух.

Компьютер у меня появился достаточно поздно — в 2002 г. До этого несистематически учился на нем работать в школе и спец-библиотеке. Даже DOS слегка зацепил… Но вообще, обучать меня работе на компьютере особо было некому. Поэтому я с самого начала привык действовать методом научного тыка, логикой и читать разного рода хелпы, руководства и прочую тому подобную литературу. Так что на сегодняшний момент без ложной скромности могу назвать себя очень продвинутым пользователем. Работаю на Win7. Эту ОС, правда, не изучал столь же глубоко, как Win98 и WinXP.

Где-то в году 2005-м попал мне в руки диск с актуальными на тот момент средами программирования. Именно с этого момента начинается мой путь в программирование.

Цели и задачи

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

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

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

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

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

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

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

Выбор инструмента и общий план пути

На вышеупомянутом диске помимо всяких ассемблеров были Borland Visual C++, Borland Delphi 6 и Visual Basic 6. Само собой первой проблемой, которая встала передо мной, был вопрос выбора. Выбор я вполне сознательно сделал в пользу Delphi. И вот почему. Становиться профессиональным программистом я не собирался. Программирование было для меня исключительно средством решения тех или иных проблем, для которых не удалось найти готовых решений Ну или чего-то совсем специфичного. В то время я располагал следующей информацией. VB — интерпретируемый язык, где код выполняется интерпретатором. Это мне не нравилось (потенциальные тормоза и т.п.). Ну и репутация у Бэйcика была как у чего-то совсем детсадовского.

В то же время C и C++ позиционировался как сложный в освоении язык, ориентированный на профессиональных программистов. Это мне также не подходило. Хотелось чего-то среднего по сложности и в то же время универсального. Всем этим требованиям отлично соответствовала Delphi. С одной стороны Pascal позиционировался как достаточно простой в освоении язык, с другой — Delphi была вполне современной и профессиональной средой разработки. Ну и то, что разработанные с ее помощью программы исполнялись без дополнительных посредников вроде интерпретаторов, тоже было плюсиком. Забегая вперед скажу, что относительно недавно я пытался освоить плюсы в варианте Visual Studio, но для меня это оказалось действительно очень сложной задачей. В общем, пока остановился на Python.

Честно говоря, для меня так и осталось загадкой, почему Borland перестала поддерживать Delphi. ИНХО именно это стало причиной упадка данной среды разработки. Монструозность… Хм… Ну Visual Studio от Microsoft тоже не сказать, чтобы такая уж компактная… Кстати, насколько мне известно, потомок Delphi до сих впор вполне себе существует под другим брендом, а к Visual Studio есть расширение для разработки на Pascal от той же компании. Тем не менее, не знаю, как за бугром, но в России эта среда считай, что не существует. Ничего на русском я о ней не видел.

В заключение этого раздела немного о периодизации. Первым моим крупным этапом в освоении программирования стала, как уже понятно, Delphi. Года два — три я интенсивно ее осваивал, даже CGI-приложение на ней написал, вполне себе рабочее. Жаль только, пропало все практически с убитым диском. Затем у меня был достаточно длительный перерыв. К тому времени я устроился на работу, где сильно увлекся MS-Excel. Первоначально глубоко изучил штатные возможности программы. Но их мне оказалось недостаточно. В конце-концов возникла потребность в изучении VBA, что я с успехом и сделал. Показателем успеха стало то, что сейчас я пишу макросы не только для себя, но и по рабочим задачам, т.е. стал профессиональным программистом в вашем понимании этого понятия. Правда, больших денег за это я не имею… Но это тонкости. По VBA я даже прошел один из курсов на Интуит и обладаю соответствующим сертификатом. Правда, не могу сказать, что этот курс сам по себе сделал меня программистом…

Между делом я попытался освоить Visual C++, причем чистый, не под NET. Все таки хотелось чего-то такого, на чем можно писать программы любого типа. Но увы. Язык этот оказался на данном этапе мне не по зубам. И литературы для начинающих, кстати, для него на удивление очень мало. Не идет ни в какое сравнение ни с Delphi времен ее расцвета, ни с тем же Python. Пытался также изучать PHP, но оно тоже не пошло. Видно не судьба мне писать на C-подобных языках…

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

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

Методика изучения

Изучал программирование я исключительно по книгам. Честно говоря, для меня является загадкой, как можно изучать его по видеокурсам. Хотя надо бы попробовать… Копипастить же код в любом разе удобнее из книги, чем переписывать из окна плейера. Да и печатный текст, по-моему, гораздо доступнее для освоения, нежели речь. Но тут готов допустить, что на вкус и цвет все фломастеры разные.

Здесь есть одна любопытная особенность, которая несмотря на свой привходящий характер имеет большое значение для освоения предмета. Дело в том, что литература по программированию в подавляющем большинстве случаев выложена в формате PDF. Сам по себе он является картинкой, для чтения скринридерами недоступной. Поэтому я обычно читал книги, распознанные с помощью FineReader в формате TXT. Файнридер же совершенно безобразно распознает листинги. Причем, это касается как OCR-слоя в PDF, так и книг в скринридеро-доступных форматах (вроде html, doc, chm и т.п.) В общем чистый копипаст в подавляющем большинстве случаев не катил никак. Прежде чем изучить работу тех или иных примеров из книг, эти примеры приходится дешифровывать. И этот этап для меня является вполне себе обычным. Именно поэтому, думаю, я совершенно не заметил того «большого барьера», о котором вы пишете в своей книге. Для меня вполне естественно, прежде чем что-то заработает, это нечто надо тщательно вылизать. Да и если сам набираешь код, тоже от опечаток никуда не деться. И вообще, уж не помню почему, но я изначально был ориентирован на то, что программирование это не совсем написание литературного произведения.

Поэтому, первым шагом в освоении любого языка или технологии программирования является поиск подходящей книги. В идеале не больше одной — двух. Delphi я начинал изучать по «Delphi 6» Фаронова и «Иллюстрированному самоучителю по Delphi 7 для начинающих». Огромное значение для меня в последствии сыграла «Библия Delphi» Фленова.

Excel и VBA я изучал по книгам Джона Уокенбаха. Кстати, 3 тома почти по 1000 стр. Целиком я их, конечно, не осилил, но тем не менее, программировать на VBA научился. Об интуитовском курсе уже упоминал, хотя нового там было только то, что касалось Word.

C++ пытался изучать по Хортону. Но, как уже писал, не пошло. Хотя несколько глав я таки прошёл. Были еще книги Прохорёнка, но этого автора я вообще почему-то воспринимаю очень плохо. С Python’ом мне вообще повезло — первой же мне под руку попалась книга Майкла Макграта «Программирование на Python для начинающих», где этот язык был описан с той детализацией, что доктор прописал.

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

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

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

Ну и, наконец, никак нельзя забывать о документации, идущей в комплекте с инструментами разработки. Для тех, кто пишет на Visual Studio — MSDN — наше все… Кстати, одним из показателей профессионализма является то, что для решения поставленных задач программисту достаточно заглянуть в документацию, посмотреть описание тех или иных функций и т.п., а не искать заготовки решений в книгах и интернете. То есть человек уже знает, что ему требуется, остается лишь уточнить детали.

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

Остановлюсь немного на том, какие книги стоит выбирать. Для освоение азов лучше всего подойдут книги типа «… шаг за шагом». Дело в том что мне не очень интересно читать сотню — другую страниц, прежде чем можно будет открыть IDE и написать первые строки кода. Процесс изучения должен быть исключительно активным: прочитал параграф, тут же набросал что-нибудь запускающееся, иллюстрирующее прочитанный материал. Примеры также можно самостоятельно переписывать, а в идеале, и как-нибудь модифицировать, и воочию смотреть, как всё это работает. Впрочем, кому-то, наверное, будет под силу прочитать учебник от корки до корки, да ещё и не один раз, прежде чем начать писать программы… Но это явно не я! Выбирать лучше всего книги, объёмом не более 200 — 300 страниц. Ну или талмуды с хорошо прописанной первой частью (где про основы). Большую роль играет и то, кто написал книгу. Выбирать надо такого автора, которого хорошо воспринимаешь и понимаешь.

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

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

  1. какого результата хочу добиться и
  2. какие исходные данные у меня есть.

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

Ну вот пишу я макрос для извлечения данных из XML и добавления их в таблицу Excel (штатных функций Excel в силу ряда причин оказалось недостаточно). Первым делом мне пришлось изучать работу библиотеки функций для работы с XML, работу с этими функциями из Excel. Само собой пришлось посмотреть, что вообще представляет собой XML, а также проникнуться такой штукой, как xPath. Когда я освоил извлечение нужных мне данных из XML-файла, дальнейшее стало достаточно тривиальной задачей — извлечь, забить в массив, вставить готовый массив на лист… Единственно, что потребовало действительно написания алгоритма — это работа с одним из полей, в котором содержался текст. Нужно было предусмотреть ситуацию, когда объем текста превышал размер ячейки и разбить текст на несколько блоков.

Вообще, при продумывании программы чаще всего достаточно представить, как бы эта задача решалась вручную.

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

Достижения

Прежде чем описать те проблемы, с которыми я столкнулся, хотелось бы систематизировать свои достижения. Когда я писал на Delphi, главным моим достижением стал иерархический блокнот. Он представлял собой дерево, каждый узел которого был ассоциирован с неким текстом. Данные хранились в базе Access (2003 тогда еще). Соответственно, там были и SQL-запросы, и активное использование событий (не только OnClick) и куча всего другого. Даже класс простенький написал. К сожалению, исходный код был утрачен, хотя экзешник где-то валяется. Я успел сделать много вкусных для себя плюшек, вроде манипулирования расположением узлов с клавиатуры, создания нескольких блокнотов, причем, кроме универсального блокнота можно было создать специальный, где с каждым узлом можно было связать ссылку, которая по желанию открывалась в браузере прямо из программы. К сожалению, не успел прописать импорт/экспорт данных, без чего на постоянной основе программой не пользовался, хотя несколько блокнотов и создал. Сейчас пользуюсь близким по функционалу Flash Note. Но многого из того, чего хотелось бы, там нет.

На VBA у меня также есть макросы, причем некоторыми из них пользуюсь по работе буквально каждый день. Основные успехи связаны с конвертацией данных из определенным образом оформленных файлов Word или XML в таблицу Excel. Есть одна смешная вещь — я могу на VBA легко написать формулу массива (Ну она возвращает variant, который является массивом), а вот с готовыми функциями массива у меня жесткие сложности. Для меня до сих пор осталось загадкой, почему СУММ не захотела суммировать массив, возвращаемый ВПР (массив точно возвращался). Пришлось идти другим путем, и получать нужный массив комбинацией ИНДЕКС и ПОИСКПОЗ. Он прекрасно просуммировался. Есть в моей коллекции и пользовательские функции массива.

Также написал функции, конвертирующие десятичное число в 62-ричное и обратно (захотелось получить числа, где малым числом символов можно было записать возможно большее количество чисел. Числа записывались символами 0..9, a..z, A..Z — ну вот и 62…)

Причем меня не особо смущает, если приходится писать кучу вложенных друг в друга условий и циклов. Эх, есть у меня один макрос… Даже самому страшно, чего я там наворочал, но же работает!..

На Python’е, так уж повелось, я сосредоточился на работе с архивами, парсинге HTML/XML. Экспорт в CSV… В общем, библиотеки/классы ElementTree, BeautifulSoup, zipfile, csv, os и т.п. — наше все…И также есть скрипты, которые используются как мной любимым, так и другими. Недавно вот jSon разбирал. Главным достижением стала библиотечка по извлечению метаданных из FB2-книг. Потом они складировались в CSV, который можно скопировать в таблицу Excel. Правда, тут столкнулся с некоторыми проблемами, решить которые пока не удалось.

Проблемы

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

В ваших маркетинговых материалах вы высказываете мысль, что для того, чтобы стать программистом, совсем необязательно профильное образование. Более того, некоторые ваши высказывания можно трактовать в том смысле, что таковое образование вообще не делает человека программистом, нагружая его массой совершенно лишней информации с одной стороны, и не давая знаний собственно по программированию с другой. Чем-то мне это напомнило ворчание школьника — типа «нафига мне учить математику, если я хочу стать юристом?..» Нет, ну понятно, что у 40-летнего дядечки это снимет одно из типичных возражений: «Как я могу стать программистом, если у меня нет профильного образования, и вообще я гуманитарий…» Но вы позиционируете ваш курс и для 14-летних подростков. Мне даже страшно подумать, что будет, если кто-нибудь из них воспримет ваши слова всерьез. И те кумиры, которых вы упоминаете (ну которые не закончили образования) станут примером для подражания для этих детей…

В моем случае, чем дальше я изучаю программирование, тем острее ощущаю нехватку профильных знаний. Я уже писал о том, что у меня нет проблем с применением логических конструкций языка и построения алгоритмов. Но, например, совершенно неожиданно не дается ООП. Хотя обычно в книжках пишут, что понимание объектно-ориентированного программирования не обязательно в повседневной практике, тем не менее — интересно же… К тому же сама идея ООП мне очень импонирует, как философу. Ведь очень многие идеи, которые лежат в основе программирования, восходят еще к Аристотелю с его логикой. Вообще, формальная логика, которую нам читали весь первый курс, позволила мне без проблем освоить булеву логику, которая, по сути, является практическим приложением формальной аристотелевской логики, быть может с небольшими усовершенствованиями, внесенными средневековыми схоластами.

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

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

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

В Python за работу с ZIP-архивами отвечает модуль zipfile, а парсер XML содержится в библиотеке xml.etree.ElementTree, где сам парсер содержится в классе ElementTree.

Первой засадой стало то, что напрямую распаковать файл в переменную не получается. В конце-концов, я это сделал, но в итоге получил строку байтов. А конструкторы ElementTree требуют именно файла. Пришлось использовать функции из этой библиотеки, которые предназначены для анализа XmL из строк. А они возвращают не целостный объект XML, а объекты узлов. Не смертельно, но неприятно. Поясню — у меня несколько сот тыс. fb2-книг. Мне до ужаса не охота при пакетной их обработке распаковывать каждый архив на диск, анализировать распакованный файл, а потом его стирать… Это, боюсь, и долго будет, да и винчестер жалко… То ли дело все проворачивать в оперативной памяти…

Но и это еще не все. Некоторые архивы обрабатываются некорректно. Возникают ошибки двух типов. Во-первых, парсер не захотел обрабатывать некоторые fb2-файлы в кодировке ANSI (CP-1251). Он падал на некоторых символах, например &, или с кодом 7. В то же время, все файлы в кодировке UTF-8 в этом смысле обрабатывались корректно. Во-вторых, метод FromString класса ElementTree почемуто некорректно извлекал данные из некоторых строк, считанных из архивов. Причем, будучи распакованными, эти файлы парсились корректно. В чем разница между архивами, которые читались неправильно, и всеми остальными — понять мне так и не удалось.

Еще одной проблемой, с которой я столкнулся, стало создание графического интерфейса. Собственно, для зрячих тут никакой проблемы нет. Практически каждая IDE в своем составе имеет простые инструменты для построения GUI. Когда я работал с Delphi, тоже без особых напрягов создавал графические приложения на основе библиотеки VCL. Пользоваться палитрой и дизайнером, правда, я не мог, но IDE Delphi имела список всех компонентов, из которого эти компоненты можно было добавлять на форму. А затем ужевручную можно было настроить свойства TOP, Height, Left и Bottom каждого компонента. Моей способности к пространственному мышлению вполне хватало на то, чтобы представить, как компоненты должны были располагаться на форме и вычислить значения соответствующих свойств. А если пользоваться различными заданными значениями свойства Align, то и вычислять было не обязательно.

В общем, с Delphi было почти все отлично. «Почти» было связано с еще одной проблемой — сам по себе интерфейс, это хорошо, но он должен корректно озвучиваться скринридерами. VCL в этом плане была вполне достойной библиотекой. Судя по всему она представляла собой обёртку вокруг стандартных графических компонентов Windows. А эти компоненты, в свою очередь, более или менее нормально озвучиваются. Тем не менее, неприятные моменты и тут имелись. Например, там был компонент TCheckListView, — обычный ListView, но с каждым элементом списка в нём связан флажок. Так вот, как этот флажок, так и его состояние не озвучивались совсем…

Здесь имеется еще один путь — Скринридер, которым я пользуюсь, имеет инструменты, которые позволяют пользователю настраивать озвучивание новых приложений. В том числе, он содержит собственный скриптовый язык. Вообще говоря, в действительности первым языком программирования, который я изучал, был именно данный скриптовый язык. Основы языка я освоил без особых проблем. Но вот полноценно решать сколь-нибудь сложные проблемы озвучивания приложений я так и не научился. Суть проблемы в том, что озвучка основана на знаниях структуры окон Windows и свойств этих окон, умении работать с интерфейсами COM вообще и MSAA в частности, а также навыках обработки событий Windows. Ну там еще кое-какую информацию иногда можно получить, посылая сообщения функциями send-и postmessage. Чисто теоретически я все это понимаю, даже могу написать какой-нибудь перехватчик события или что-то извлечь из MSAA. Но всё равно — написание полноценного пакета скриптов для озвучки чего-нибудь у меня ниразу не получалось.

В настоящее время (Напомню, что основными моими инструментами являются VBA и Python) с созданием удобного графического интерфейса совсем все плохо. Создавать формы в среде VBA у меня не получается чисто технически — скринридер совершенно не взаимодействует с инструментом для размещения компонентов на форме. Проще говоря, я просто не могу зацепить, скажем, кнопку, и добавить ее на форму. Кроме того, скринридер с трудом взаимодействует с пользовательскими контролами, добавленными, в частности, на лист Excel. А те возможности, которые предусмотрены, очень неудобны.

С Питоном тоже не все ладно. Во-первых, программное создание GUI в Python неразрывно связано с ООБ. Это само по себе для меня сложно, о чём уже писал. Во-вторых, встаёт вопрос о выборе библиотеки. Выбирать приходится между QT5 и Tkinter. Никаких других вариантов, которые можно было бы освоить самостоятельно, я не нашёл. Есть еще WX, которая, на самом деле, является наилучшим вариантом, но ее до сих пор не портировали на Python3. Неизвестно, когда это случится, случится ли вообще и напишут ли для нее русский мануал…

GUI, написанные на ранних версиях QT не озвучиваются скринридерами в принципе. Спецсофт просто ничего не видит в соответствующих окнах. Кстати, именно поэтому слепым абсолютно недоступна десктопная версия Telegram. В последних версиях библиотеки были добавлены инструменты Accessibility. Теперь кнопки и прочие контролы более или менее озвучиваются. Насколько я мог понять, информация берется из MSAA. Но люди, работавшие с библиотекой, пишут, что корректно озвучивается далеко не всё. Например, проблемы возникают с работой в многострочных полях редактирования. Ну и возникает вопрос — имеет ли смысл тратить кучу времени и сил на изучение сложного материала, чтобы в очередной раз понять, что всё бесполезно?

Библиотека Tkinter, также меня не вдохновила. Во-первых, судя по той информации, которая мне доступна, она достаточно бедна компонентами. Я не смог понять, как на ее основе писать оболочку вокруг БД. Ну и если дефолтная IDE Python действительно написана на Tkinter, озвучку придётся доводить напильником. И без гарантий, что я с этим напильником совладаю…

У меня даже была мысль изучить PHP или Django (под Python), чтобы уйти от проблемы GUI, ограничившись Web-интерфейсом. Но, как ни крути, а браузер достаточно ограничен в плане интерфейса. Нет, как раз оболочку к БД я сделаю. Может для этого даже не обязательно изучать язык, а можно ограничится PHPAdmin’ом. Но вот обеспечить тот функционал, который мне нужен, вряд ли получится. Например, как в браузере работать с архивами, в которых лежат далеко не всегда HTML-файлы? А ведь эти файлы нужно открывать либо в ассоциированных программах, либо во внутреннем просмотрщике, создать который в Web-интерфейсе та еще задача…

Собственно, всё… Что делать дальше, я пока не знаю. По-видимому, мне таки не хватает тех фоновых знаний, которые даются студентам в ВУЗах. Изучать новые инструменты? — Какие?.. Тоже и по литературе — не понятно что читать, за что браться…

Заключение

Итак, какие выводы можно сделать на основании моего опыта самообразования в области программирования?

1. Изучить основы языка и начать писать на нём типовые программы, используя современные IDE, — относительно просто.
2. Последовательность шагов при освоении программирования путём самообразования.

  • Осознание того, что при работе на компьютере встают задачи, которые затруднительно или неудобно решать существующими средствами, а также, того, что программирование — это безумно интересно.
  • Выбор инструментария (язык, IDE).
  • сбор библиотеки материалов, посвящённых выбранным инструментам.
  • Выбор одной — двух, максимум трёх книг (и/или, возможно, видеокурса) «для чайников», где рассказывается о работе с выбранными инструментами.
  • Последовательное освоение учебных материалов, пока не будут изучены основы языка; тренировка на написании простых типовых программ.
  • придумать, какую бы программу хотелось написать, чтобы ею можно было пользоваться.
  • переход от последовательного изучения учебника к поиску средств решения возникающих программистских задач по всей библиотеке и в интернете.
  • обучение работе с документацией по языку и IDE.
  • Обращение к экспертному сообществу на форумах за помощью в решении нестандартных задач.
  • По-видимому, поиск преподавателя, который бы помог дальнейшему развитию при исчерпании возможностей самообразования. Возможно, прохождение обычных (не дистанционных) курсов.
  • Попытаться заработать, занимаясь программированием…

3. Для успеха самообразования определяющую роль играет профиль образования. В общем случае инженер, выпускник естественнонаучных факультетов или математик освоит программирование лучше и глубже, нежели гуманитарий.
4. Освоение инструментов программирования радикально расширит возможности пользователя по решению тех или иных задач, возникающих при работе за компьютером.
5. Рано или поздно пользователь столкнётся с тем, что возможности самообразования постепенно исчерпываются. Это будет выражаться в росте количества задач, которые не решаются изученными инструментами. О многом не пишется в книгах для начинающих и непонятно, откуда брать информацию. В моём случае всё осложняется тем, что я чисто технически кардинальным образом ограничен в выборе инструментов (не всё озвучивается скринридерами…)


С уважением, Михаил Духонин

Комментарии 16

  • Я в программировании с 1975 года. Поэтому прочитала все с большим интересом. Огромный мой респект автору. Не буду размазывать сопли, у нас в фирме работал плоховидящий программист. Я живу не в России. Важнее всего голова.
    Я совершенно согласна, что если у вас есть задача, реальная задача, которая вам не дает покоя, вы выучите язык программирования. Это не сложнее иностранных языков. Я много лет работала с физиками, они осваивали программирование очень быстро, так как изложить свою идею программисту бывает себе дороже. Если вы хотите только зарабатывать деньги, то может быть скучно и непонятно. Программирование -процесс азартный, не хуже компьютерных игр. Михаил, с объектным программированием у меня был затык, когда оно появилось. Те, кто начинал с чистого листа, все брали легко. Знания могут мешать.

  • Супер! Грандиозно! Даже вспомнилось написание книги ослепшим коммунистом, как у Островского. Но это еще круче!!! Не просто пишет, а ПРОГРАММИРУЕТ!!!!!!!!!
    Просто нет слов, одни эмоции… Столько проблем и ни перед одной не спасовал!
    Можно привести слова известного изобретателя: «После очередного неудачного опыта с аккумулятором Томас Эдисон сказал, что ошибки как таковой и не было, просто он нашел 10 000 неработающих методов.» Так и Михаил — никаких сетований на неудачи, а только стремление двигаться дальше и найти решения к своим проблемам.
    Какая сила духа! Воля к развитию и самосовершенствованию!
    Огромнейшее спасибо за мотивацию к жизни и деятельности! И спасибо Константину за публикацию этого письма!

  • Пора ИТ гуру подумать о создании постоянно действующего УНИВЕРСИТЕТА для лиц с ограничениями. Без возрастного ограничения. И для Учёбы и для Работы. ПОРА

    Когда то, со слезами на глазах, прочёл книгу «Я гений» — мальчика испанца, он уехал к себе от нас, его нашла и забрала мать домой в Испанию. Там тоже было о друзьях программистах.
    Попробовал учить внуков Питону, школа — убивает время перегрузкой. Программирую сам для себя.
    Успехов ребята ПОРА Гринёв Геннадий

  • Выражаю своё уважение автору письма! Удачи на просторах IT !

  • Михаил, я Вами восхищаюсь! Константин, а можете ли вы помочь ему?
    Он ведь уникальный, целеустремленный человек. С огромным уважением из Канады- Регина.

  • Какой высокий дух! Восхитительно! Успехов тебе, Михаил, во всем. А помощь тебе обязательно придет и, быть может, совсем не с той стороны, откуда ты думаешь, но придет. Вперед и с песней!

  • Безмерное уважение автору! Такой подход мне близок (то же гуманитарий).

  • Мне 77. На работе разрабатываю электрические схемы. Дома занимаюсь программированием под Андроид.

  • За Питон не знаю, но по поводу VBA предлагаю запрограммировать свой собственный инструмент разработки.
    Почти все в MS Office управляется программно. Например, этот макрос просматривает все элементы на форме и, в данном случае, очищает все текстовые поля:

    Sub All_TextBoxes()
    Dim oControl As Control
    For Each oControl In UserForm1.Controls
    If TypeOf oControl Is MSForms.TextBox Then oControl.Value = «»
    Next oControl
    End Sub

    Значение любого атрибута Контрола можно програмно получить и прослушать через буфер обмена в программе типа «Балаболка».
    В простых случаях размещение элементов на форме можно делать программно, руководствуясь дизайнерскими правилами.
    На листах Excel элементы управления — это Shape, но с ними все сложнее.

    Удачи!

    • Алексей, благодарю за подсказку. Но печалька состоит в том, что программное создание контролов в приложениях VBA нигде сколь-нибудь системно не излагается. По крайней мере на русском я такого не видел. А осваивать технологию по обрывочным фрагментам в статьях и на форумах Я не умею, к сожалению… В Delphi, кстати, я компоненты программно создавал, но чтобы это стало возможно, я много работал с ними стандартным способом. И, следовательно, хорошо знал, как они себя ведут.

  • Михаил, извини за задержку — из этого форума нет оповещений об ответах на комментарии. Стандартные контролы (Label, TextBox и другие) неплохо описаны у Уокенбаха в книге по VBA. Думаю, они похожи на дельфийские. Но при программном управлении есть одна неприятность — форма должна быть создана или добавлена в проект в VBA-редакторе. Программно на форму можно добавлять любые контролы (пример ниже), но обработчики событий должны быть в модуле формы и привязаны к уже имеющимся на форме элементам. Поэтому как добавить на форму форму, реагирующую на клик мышкой, я не знаю. У меня была такая техника: Создаю в редакторе форму и кидаю на нее контролы по максимуму, то есть все, для которых надо обрабатывать события — то есть, кнопки и поля ввода, если только надо сразу проверить правильность ввода. При открытии формы в цикле, как в примере предыдущего поста, нужные контролы делаю видимыми, лишние — невидимыми, добавляю контролы без обработки событий и задаю каждому контролу и самой форме свойства: Height, Left, Top, Width и другие, если нужно. Можно составить алгоритм для определения значений положения и размеров элементов, чтобы они не налезали друг на друга и соблюдались правила эргономики и было красиво.
    Ниже пример: имеется проект с формой, имеющей две кнопки и обработчики событий от самой формы и кнопок и модуль с макросом. Макрос открывает два экземпляра формы и добавляет на одну два я TextBox, а на другую — еще одну кнопку. кнопку на форму с двумя кнопками. Последний оператор выводит в MsgBox содержимое полей ввода из формы.

    Простой Модуль:
    Option Explicit

    Sub TestForm()
    Dim frm1 As UserForm1
    Dim frm2 As UserForm1

    Set frm1 = UserForms.Add(«UserForm1»)
    frm1.Width = 450
    frm1.Caption = «Forma1»
    Dim oBox As Control, oBox2 As Control, oBox3 As Control
    ‘ добавить поле ввода
    Set oBox = frm1.Controls.Add(«Forms.TextBox.1»)
    oBox.BorderStyle = 0
    ‘ параметры текста поля ввода
    oBox.ForeColor = vbRed
    oBox.BackColor = vbBlack
    oBox.FontName = «Courier New»
    oBox.FontBold = True
    oBox.FontSize = 12
    ‘ Положение и размер полдя на форме
    oBox.Top = 40
    oBox.Left = 50
    oBox.Height = 50
    oBox.Width = 100
    oBox.Text = «Привет!»
    oBox.Visible = True ‘ поле видим
    ‘ добавить еще поле ввода
    Set oBox2 = frm1.Controls.Add(«Forms.TextBox.1»)
    frm1.Show vbModeless ‘ немодальный режим
    ‘ откроем еще одну форму
    Set frm2 = UserForms.Add(«UserForm1»)
    frm2.Caption = «Forma2»
    ‘ добавить кнопку
    Set oBox3 = frm2.Controls.Add(«Forms.CommandButton.1»)
    oBox3.Name = «cmd1»
    oBox3.Caption = «Не работает»
    frm1.Hide ‘ скрыть первую
    frm2.Show ‘ показать вторую, модальный режим
    Unload frm2 ‘ выгрузить форму из памяти
    frm1.Show ‘ показать первую, модальный режим
    MsgBox «Text1 » + oBox.Text + » Text2 — » + oBox2.Text
    End Sub
    Модуль форомы:
    Option Explicit

    Private Sub cmd1_Click()
    MsgBox «ClickKnopka » + Me.Caption
    End Sub

    Private Sub CommandButton1_Click()
    Me.Hide
    End Sub

    Private Sub UserForm_Click()
    MsgBox «ClickForma»
    End Sub

  • P.S. Нашелся способ как все делать программно! В примере создается новая книга Excel и в ней форма с 4 разными контролами и расчетом их расположения колонкой. Для кнопки программно создается обработчик события Click.
    Из книг по Excel очень уважаю «Руководство программиста по Visual Basic для Microsoft Office 97» от Microsoft Press. Там целая глава посвящена управлению контролами.
    Начало примера:
    Option Explicit

    Sub CreateForm()
    Dim MyForm As Object
    Dim newForm As MSForms.UserForm
    ‘Dim NewControl As MSForms.CommandButton
    ‘Dim NewControl As MSForms.Label
    Dim NewControl As Control
    Dim Line As Integer, nLeft As Long, nWidth As Long, nNext As Long
    Dim oBook As Workbook
    Set oBook = ActiveWorkbook
    Set oBook = Workbooks.Add() ‘ создаем новый проект VBA
    ‘ параметры размещения элементов
    nLeft = 5 ‘ отступ от левого края
    nWidth = 120 ‘ Ширина элементов
    nNext = 5 ‘ расстояние между элементами

    ‘ Создаем форму
    Set MyForm = oBook.VBProject.VBComponents.Add(3) ‘ папка Forms
    ‘ Microsoft Visual Basic for Applications Extensibility
    With MyForm
    .Properties(«Caption») = «My Form»
    .Properties(«Width») = nLeft * 2 + nWidth + 5
    .Properties(«Height») = 600
    .Properties(«Name») = «MyName»
    End With

    ‘ заголовок
    Line = nNext * 2 ‘ верхняя граница нового контрола
    Set NewControl = MyForm.Designer.Controls.Add(«forms.Label.1», «lb1», True)
    With NewControl
    .Left = nLeft
    .Top = Line
    .Width = nWidth
    .Caption = «Контролы»
    .Font.Bold = True
    .TextAlign = fmTextAlignCenter
    End With
    ‘ текстовое поле
    Line = NewControl.Top + NewControl.Height + nNext
    Set NewControl = MyForm.Designer.Controls.Add(«forms.TextBox.1», «tb1», True)
    With NewControl
    .Left = nLeft
    .Top = Line
    .Width = nWidth
    .Text = «TextBox»
    End With
    ‘ поле со списком
    Line = NewControl.Top + NewControl.Height + nNext
    Set NewControl = MyForm.Designer.Controls.Add(«forms.ComboBox.1», «cmb1», True)
    With NewControl
    .Left = nLeft
    .Top = Line
    .Width = nWidth
    .Text = «ComboBox»
    End With
    ‘ кнопка
    Line = NewControl.Top + NewControl.Height + nNext
    Set NewControl = MyForm.Designer.Controls.Add(«forms.CommandButton.1», «kn1», True)
    With NewControl
    .Left = nLeft
    .Top = Line
    .Width = nWidth
    .Caption = «My Click»
    End With

    Line = NewControl.Top + NewControl.Height + nNext + 20
    MyForm.Properties(«Height») = Line

    ‘ добавить в модуль формы для кнопки обработчик события Click
    With MyForm.CodeModule
    Line = .CountOfLines
    .InsertLines Line + 1, «Sub kn1_Click()»
    .InsertLines Line + 2, «MsgBox «»My Click!»»»
    .InsertLines Line + 4, «End Sub»
    End With

    ‘ VBA.UserForms.Add(MyForm.Name).Show ‘ Открыть форму — не получается
    End Sub

    Конец примера
    Недостаток данного примера — при каждом отладочном прогоне создается новая книга и ее надо закрывать вручную. Но зато все, в отличие от предыдущего способа, сохраняется в файле и дальше с книгой можно работать как обычно.
    И еще, в параметрах безопасности, «параметры макросов» надо установить флажок «Доверять доступ к объектной модели проектов VBA».
    Надеюсь, это как-то поможет Вам сделать из Visual свой Audio Basic 🙂

  • Алексей, спасибо за столь подробный и содержательный ответ. Буду внимательно разбираться и пробовать. Обсуждать здесь, действительно не очень удобно.
    Форму, как раз, в проект добавить не вопрос. Это можно сделать из меню. Проблема именно с добавлением контролов на форму. Книгу, о которой вы пишете, тоже у себя гляну. Хотя, у меня есть некое предубеждение против книг по старым версиям программ. Всегда кажется, что всё, о чём читаешь, уже устарело и на текущих версиях программ не работает…

  • Привет, Михаил!
    Про ООП вы можете почитать на https://inexsu.wordpress.com/%D0%BE%D0%BE%D0%BF-%D0%B2%D0%B5%D1%81%D1%82/

  • Выражаю огромное уважение автору. Какие выдающиеся работоспособность, целеустремлённость и воля.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.