Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Международные и отечественные стандарты языков программирования, сходство и отличия стандартов

Содержание:

ВВЕДЕНИЕ

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

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

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

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

Цель данной курсовой работы – получить представление о классификации языков программирования и их стандартизации. Для достижения цели в курсовой работе были поставлены следующие задачи:

  • получить представление о классификации основных языков программирования;
  • рассмотреть развитие языков программирования и выделить ключевые стандарты этих языков;
  • выполнить реализацию приложения с использованием одного из современных стандартизированных языков;

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

1. Классификация первых языков программирования

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

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

Почти все современные языки программирования разработаны так, чтобы быть независимыми от машины. Другими словами, структура языка программирования не будет зависеть от внутренней структуры определенного компьютера; нужно уметь исполнять программу, написанную на языке программирования, на любом компьютере, независимо от того, кто его изобрел или какой моделью он является. Такие языки известны как машинно-независимые языки программирования высокого уровня a.1.].

Первым шагом в эволюции языков программирования была разработка того, что известно как язык ассемблера. На языке ассемблера мнемоника используется для представления операций, которые должны выполняться компьютером, и строки символов для представления адресов в памяти компьютера, где будут храниться операнды. Таким образом, язык соответствует структуре процессора конкретного компьютера и, таким образом, зависит от машины. Переводчик, называемый ассемблером, переводит программу, написанную на языке ассемблера, в набор машинных инструкций, которые могут быть выполнены компьютером. Современные программы написаны на ассемблере только в приложениях, которые чувствительны к затратам или критичны по времени, поскольку эффективность машинного кода имеет первостепенное значение в этих типах приложений. Чувствительное к затратам приложение – это приложение, в котором используются микропроцессоры для улучшения функциональности потребительских товаров, таких как стиральные машины или музыкальные системы. В этих случаях программа хранится в постоянной памяти, а ее размер невелик. Таким образом, оптимизация кода важна. Критически важным для применения является использование микропроцессоров в системах управления самолетом, где требуется работа системы в режиме реального времени. Здесь снова количество выполняемых машинных инструкций должно быть минимизировано.

Во время эволюции компьютеров, примерно до 1955 года, компьютеры были медленными и имели небольшую память. Таким образом, эффективность программирования была очень важна, и язык ассемблера был доминирующим. Благодаря совершенствованию технологий компьютеры были спроектированы с большей емкостью памяти, более высокой скоростью и повышенной надежностью. Был предусмотрен огромный потенциал компьютерных приложений в различных областях. Было очевидно, что этот потенциал может быть реализован только в том случае, если неопытный пользователь сможет эффективно использовать компьютер для решения проблем. Таким образом, стало ясно, что пользователь должен заниматься прежде всего разработкой соответствующих алгоритмов для решения проблем, а не внутренней логической структурой компьютера. Следовательно, хорошая нотация для выражения алгоритмов стала существенным требованием. Чтобы алгоритмы выполнялись компьютерами, нотация для их выражения должна быть простой, краткой, точной и однозначной. Обозначения также должны соответствовать типу алгоритма. Например, языки программирования для решения научных и инженерных задач должны поддерживать арифметику с использованием широкомасштабных, высокоточных действительных и комплексных чисел и должны иметь функции для выражения операций с массивами и матрицами. С другой стороны, алгоритмы для обработки бизнес-данных должны иметь операции, выполняемые с огромными объемами организованных данных, известных как файлы. В этом случае нотация должна облегчать описание файлов, форматирование и печать сложных отчетов. Такие нотации для выражения алгоритмов известны как высокоуровневые, машинно-независимые языки программирования. Языки программирования высокого уровня далее классифицируются как процедурные и непроцедурные [a.2.]. Языки, которые выражают пошаговые алгоритмы, написанные для решения проблемы, известны как процедурные языки, в то время как те, которые выражают спецификации программы, которая должна быть решена, известны как непроцедурные.

В начале 1970-х гг. Никлаус Вирт предложил язык Pascal, который сразу завоевал широкое признание. Язык получил свое название в честь французского математика, физика, литератора и философа Блеза Паскаля. Pascal разрабатывался с учетом недостатков, имеющихся в ALGOL-W, над которым также работал Вирт. Изначально он проектировался для однопроходного компилятора, наряду с которым существовал и интерпретатор P-кода. В 1983 г. вышел первый стандарт языка IEEE, а затем появился и стандарт ISO (стандарт Организации международных стандартов ISO 7185:1990).

В то же время команда во главе с Жаном Ичбиа из CII Honeywell Bull по контракту с Министерством обороны США с 1977 по 1983 год работала над созданием структурированного языка высокого уровня, получившего название Ada в честь Ады Лавлейс. Это был первый случай в истории, когда создание языка началось не с разработки конкретного транслятора, а с определения требований и выработки спецификаций. За основу был взят язык Pascal; промышленный компилятор языка Ada был разработан в начале 1980-х гг.

2. Международная и отечественная стандартизация языков

Спецификация языка программирования всегда отражена в его реализации. Для того, чтобы компиляция одной и той же программы с использованием различных компиляторов могла всегда давать одинаковый результат, разрабатываются стандарты языков программирования [a.4.]. На сегодняшний день существует ряд организаций, непосредственно занимающихся вопросами стандартизации. Это Американский национальный институт стандартов ANSI (American National Standards Institute), Институт инженеров по электротехнике и электронике IEEE (Institute of Electrical and Electronic Engineers), Организация международных стандартов ISO (International Standards Organization). В ISO вопросами стандартизации языков программирования занимается комитет JTC 1/SC 22.

ANSI C – это общее название для стандарта языка программирования C, и, хотя документ, из которого происходит это имя, уже давно заменен новым, это имя все еще иногда используется с текущим стандартом. Происхождение этого стандартного названия (которое, очевидно, происходит от Американского национального института стандартов), а также названия ISO C (также явно взятого из аббревиатуры Международной организации по стандартизации), связаны с документами, появившимися в результате добровольного консенсуса. Язык программирования C предшествует любой официальной стандартизации на десятилетие. C был разработан в Bell Laboratories в 1972 году Деннисом Ритчи, и многие из принципов и идей, которые он включил в язык, были взяты из более раннего языка программирования B, а также его предков B, BCPL и CPL. В 1983 году ANSI поручил комитету X3J11 стандартизировать язык Си. Эта задача находилась в ведении Аккредитованного комитета по стандартам X3 (ASC X3), и в результате стандарт ANSI X3.159-1989: язык программирования C был ратифицирован 14 декабря 1989 года и опубликован весной 1990 года. ASC X3 в настоящее время является Международным комитетом по стандартам информационных технологий (INCITS), аккредитованной ANSI организацией по разработке стандартов, занимающейся информационными и коммуникационными технологиями.

Стандарт, указанный в документе ANSI X3.159-1989, стал известен как ANSI C [a.3.], но вскоре он был заменен, поскольку был принят в качестве международного стандарта ISO / IEC 9899: 1990 под руководством ISO / IEC. JTC 1. В то время как это название произошло от ISO C, национальный стандарт и международный стандарт также различаются как C89 и C90 соответственно. За годы, прошедшие с момента установления международного стандарта ISO / IEC 9899, ​​было выпущено несколько обновлений и появилось несколько корректировок. Четвертое издание стандарта ISO / IEC 9899: 2018 – Информационные технологии. Языки программирования. C определяет текущий стандарт языка программирования C. Язык C, определенный в стандарте 2011 года, получил неофициальное название C11. Хотя ни это название, ни ANSI C и ISO C никогда явно не упоминаются в стандартном документе, их случайное использование отражает важность кропотливой работы, проделанной сообществом стандартов за последние тридцать лет по объединению этого языка программирования.

В середине XX века параллельно с алгоритмическими языками развивались языки, предназначаемые для обработки деловой информации, а также языки искусственного интеллекта. К первым относится язык COBOL (COmmon Business Oriented Language – рус. «Общий язык деловой ориентации»), а ко вторым — языки LISP (LISt Processing – рус. «Обработка списков») и PROLOG (PROgramming in LOGic – рус. «Программирование в логике»).

Язык COBOL, ориентированный на обработку экономической информации, был разработан рабочей группой программистов, созданной под эгидой исполнительного комитета по языкам систем обработки данных Кодасил (CODASYL – Conference on Data System Languages). COBOL был первым языком программирования, в котором средства описания данных соответствовали его процедурным возможностям. Впервые в нем был введен тип данных "запись", который являлся основной структурой данных. Рекурсивное описание данных – еще одна примечательная особенность КОБОЛа. Кроме того, программы на этом языке принято разбивать на части, называемые разделами, причем каждая программа состоит из четырех разделов: идентификации, оборудования (среды), данных и процедур. Измененный американский стандарт КОБОЛа был принят в 1974 г. с соответствующим названием – КОБОЛ-74. В СССР первые компиляторы с подмножества языка КОБОЛ реализованы в 1968 г. на ЭВМ "Днепр-21" и "Минск-32", а в 1977 г. был принят отечественный стандарт на язык программирования КОБОЛ (ГОСТ 22558-77).

Язык LISP, разработанный в 1960-х гг. под руководством Дж. Маккарти, был первым функциональным языком обработки списков, который нашел широкое применение в теории игр. Язык PROLOG ориентирован на решение задач на основе исчисления предикатов. Этот язык был разработан Аланом Кулмероэ и Филиппом Русселом в 1970 г., а первая реализация, использующая компилятор ALGOL-W, выполнена в 1972 г. Язык PROLOG развивался, и в настоящее время существует несколько его реализаций. Наиболее используемой реализацией принято считать разработку Эдинбургского университета. Первым стандартом ISO языка PROLOG был стандарт ISO/IEC 13211-1:1995 (Programming languages — Prolog — Part 1: General core), затем последовал стандарт ISO/IEC 13211-2:2000 (Programming languages — Prolog — Part 2: Modules), в настоящее время разрабатывается стандарт ISO/ IEC DTR 13211-3 (Programming languages — Prolog — Part 3: Definite clause grammar rules).

С появлением персональных компьютеров языки стали составными частями интегрированных сред разработки [a.5.]. Появились языки, применяемые в различных офисных программах, например VBA (Visual Basic for Application). Язык VBA представляет собой язык Visual Basic, встроенный в приложения Microsoft Office. Сам же язык Visual Basic является языком программирования, входящим в семейство языков, поддерживаемых инструментальной средой разработки Visual Studio фирмы Microsoft. Язык Visual Basic – это продвинутая версия языка Basic (стандарт ISO/IEC 10279:1991 – Programming languages – Full Basic). В настоящее время существует достаточно много различных версий и компиляторов языка Basic.

В конце ХХ в. с распространением Интернета расширилась возможность распределенной обработки данных, что отразилось и на развитии языков программирования. Появились языки, ориентированные на создание настольных и серверных приложений, такие как Java, C#, Perl и PHP, языки описания документов — HTML, описания данных — XML. На момент написания данной работы известно, что язык программирования C# стандартизирован в ECMA (ECMA-334) и ISO (ISO/IEC 23270).

Единственным отечественным языком программирования, получившим широкую известность, стал РЕФАЛ (РЕкурсивных Функций АЛгоритмический язык) – язык манипулирования символьными объектами (программы, формулы, тексты и т.д.). Помимо описания семантики алгоритмических языков РЕФАЛ нашел и другие, не менее важные применения. В первую очередь это машинное выполнение громоздких аналитических выводов в теоретической физике и прикладной математике, интерпретация и компиляция языков программирования, машинное доказательство теорем и т.п. Однако распространённость этого языка на сегодняшний день мала.

Первая версия языка РЕФАЛ была создана в 1966 году Валентином Турчиным в качестве метаязыка для описания семантики других языков. Затем, в результате появления достаточно эффективных реализаций на ЭВМ, он стал находить практическое использование в качестве языка программирования. На сегодняшний день основными диалектами языка являются РЕФАЛ-2 (1970-е), РЕФАЛ-5 (1985) и РЕФАЛ+ (1990), которые отличаются друг от друга деталями синтаксиса и набором дополнительных средств, расширяющих первоначальный вариант. 

3. Стандарты языков программирования для ПЛК

В начале 1970-х годов программируемые логические контроллеры (ПЛК) стали доступны в качестве замены для проводных релейных логических панелей [a.6.]. Развитие программирования релейных диаграмм (LD) увеличило признание отрасли, потому что графическая программная диаграмма позволила электрикам, практически не обученным программированию LD, следить за логическим ходом каждой ступени, точно так же, как схема электрического управления может использоваться для цели устранения неполадок.

Разработчики программ обычно рисуют релейно-логическую схему вручную. Затем диаграмма переводится в список, состоящий из инструкций и переменных. Фактический язык программирования, используемый для ввода команд в память ПЛК, называется списком команд (IL) или списком операторов (STL). Язык IL очень похож на язык ассемблера, используемый в программировании на ПК. Наконец, программа вводится в память контроллера с помощью цифровой клавиатуры.

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

В 1980-х годах появилось программное обеспечение для программирования основных ПЛК той эпохи. Интересно, что большая часть этого программного обеспечения была произведена сторонними компаниями, такими как Taylor Software, ICOM и другими, а не самими производителями ПЛК.

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

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

В результате эти сторонние поставщики программного обеспечения много раз переходили из рук в руки. Программное обеспечение Taylor было приобретено компанией Total Control Products, которая позднее была приобретена GE Fanuc. Schneider Electric также приобрела части программного обеспечения Taylor, которые включали компоненты Modicon. Программное обеспечение ICOM стало частью Rockwell Software.

В дополнение к доступности относительно недорогих ПК и программного обеспечения для программирования ПЛК, написанных для ПК, в 1980-х годах произошло еще одно значительное событие. Сегодня большинство крупных производителей производят платформы для разработки программного обеспечения, которые соответствуют спецификации Международной электротехнической комиссии (МЭК) 61131-3. Этот стандарт был запущен в 1982 году и опубликован в 1993 году как Международный стандарт МЭК 1131 для программируемых контроллеров.

Как отмечалось в стандарте МЭК, он был выпущен, в частности, «для определения для каждого из наиболее часто используемых языков программирования основных областей применения, синтаксических и семантических правил, простых, но полных базовых наборов элементов программирования, применимого теста и средства, с помощью которых производители могут расширять или адаптировать эти базовые наборы для своих собственных программируемых реализаций контроллера ». МЭК 61131 состоит из 10 частей, охватывающих различные аспекты контроллеров автоматизации производства. МЭК 61131-3 – та часть, которая охватывает программирование.

Стандарт МЭК 61131-3 важен, потому что он обеспечивает согласованность всех программных продуктов, соответствующих стандарту. Например, стандартная определенная МЭК функция в ПЛК Brand-X работает так же в ПЛК Brand-Y. Ценным результатом этой стандартизации является то, что функции и функциональные блоки выглядят одинаково и имеют одинаковые определенные входы и выходы, независимо от бренда интегрированной среды разработки (IDE) или рабочего стола с пользовательским интерфейсом, что позволяет инженеру или специалисту по техническому обслуживанию быстро понять логику и поток программ из программного обеспечения любого производителя.

Стандарт определяет пять языков программирования: LD, функциональная блок-схема (FBD), последовательная функциональная схема (SFC), структурированный текст (ST) и IL. МЭК 61131-3 определяет стандартные типы данных, соглашения об именах, поток программ и различные другие элементы программирования. Когда производитель ПЛК заявляет, что его программное обеспечение соответствует стандарту IEC 61131-3, это обычно означает, что программное обеспечение соответствует частям стандарта. МЭК заявляет, что для обеспечения совместимости программный пакет должен поддерживать как минимум один из пяти языков. CoDeSys может быть единственной платформой программирования, которая поддерживает все пять.

Производители и пользователи ПЛК могут также добавлять в стандарт пользовательские расширения, функциональные блоки и типы данных; это означает, что плавная передача проектов между платформами не вполне реальна, даже если платформы соответствуют стандарту IEC 61131-3. МЭК 61131-10 определяет форматы обмена файлами XML. Тем не менее, эта возможность все еще находится в стадии разработки. Остается только надеяться, что появится механизм для переноса проектов между платформами в один прекрасный день.

4. Создание приложения на стандартизированном языке

Настоящий раздел посвящен проектированию и программной реализации приложения на высокоуровневом языке программирования C# версии 7.0, поддерживающем стандарты ECMA-334 и ISO/IEC 23270. В качестве такого приложения рассматривается обучающая основам объектно-ориентированного программирования программа с тестовым контролем знаний, для реализации которой был выбран интерфейс программирования приложений Windows.Forms, являющийся частью Microsoft .NET Framework. С помощью Windows.Forms можно создавать приложения с полнофункциональным графическим интерфейсом, в то же время простые в использовании и обновлении [a.7.]. Выбранный язык программирования вместе со средой разработки позволяет полностью реализовать программу, отвечающую всем предъявленным ей требованиям.

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

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

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

Учебный материал, используемый в приложении, представлен документами в формате pdf. Для организации просмотра файлов с лекциями и семинарами необходимо наличие соответствующего программного обеспечения. В данной работе используется технология ActiveX – плагин, входящий в состав Adobe Acrobat Reader, бесплатного приложения международного стандарта для просмотра и редактирования pdf-документов. Компоненты ActiveX импортируются на панель элементов как объекты компонентной модели (рисунок 1).

Рисунок 1 – Импорт компонентов для чтения pdf

Каждая кнопка для выбора нужной темы, расположенная на главной форме, имеет целочисленный тег, соответствующий номеру pdf-файла данной темы. Это позволяет выполнять обработку выбора темы при помощи одной процедуры для всех кнопок, как показано в листинге 1.

Листинг 1. Обработка кнопок выбора лекции или семинара

private void buttons_Click(object sender, EventArgs e)

{

// получить номер лекции / семинара по тегу нажатой кнопки:

int theme = int.Parse((sender as Button).Tag.ToString());

// создать новую форму для просмотра лекции / семинара:

TheoryForm tf = new TheoryForm(theme);

tf.Show(); // показать форму

this.Dispose(false); // уничтожить текущую форму

}

Вызов конструктора формы TheoryForm позволяет создать форму с находящимися на ней компонентами, а также загрузить выбранную в главном модуле программы тему (лекцию либо семинар в формате pdf) на компонент данных axAcroPDF1, объект технологии ActiveX (листинг 2). Файлы расположены в директории по пути \bin\Debug\theory.

Листинг 2. Конструктор формы TheoryForm

public TheoryForm(int n)

{

InitializeComponent();

themeNumber = n; // получить номер темы из главной формы

path = Application.StartupPath + @"\theory\" + themeNumber + ".pdf"; // ввести путь к соответствующему теме pdf-файлу

// Если файл по заданному пути существует, то

if (File.Exists(path))

{

axAcroPDF1.src = path; // загрузить файл в pdf-ридер

// ввести в заголовок формы номер выбранной темы:

this.Text = "Тема " + themeNumber;

}

else // иначе

// вывести на экран сообщение о том, что файл не найден

MessageBox.Show("Файл " + themeNumber + ".pdf не найден!");

// Если номер темы = 1, то

// кнопка перехода к предыдущей теме должна быть неактивной

if (themeNumber == 1)

leftButton.Enabled = false;

// Если номер темы = 6, то

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

if (themeNumber == 6)

rightButton.Enabled = false;

}

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

Листинг 3. Обработка кнопок перехода к соседней теме

private void changeThemeButton(object sender, EventArgs e)

{

// Если номер темы >= 1, то

// кнопка перехода к предыдущей теме должна быть неактивной:

if (themeNumber >= 1)

leftButton.Enabled = true;

// Если номер темы <= 6, то

// кнопка перехода к следующей теме должна быть неактивной:

if (themeNumber <= 6)

rightButton.Enabled = true;

// Поиск направления сдвига по тегу соответствующей кнопки:

int shiftSign = int.Parse((sender as Button).Tag.ToString());

// Если направление - влево и номер темы = 1, то

if (shiftSign == -1 && themeNumber == 1)

return; // выполнить выход из обработчика

// Если направление - вправо и номер темы = 6, то

if (shiftSign == 1 && themeNumber == 6)

return; // выполнить выход из обработчика

// выполнить соответствующий сдвиг

// для перехода к соседней теме путем изменения номера темы:

themeNumber += shiftSign;

// ввод пути к соответствующему теме pdf-файлу:

path = Application.StartupPath + @"\theory\" + themeNumber + ".pdf";

// Если файл по заданному пути существует, то

if (File.Exists(path))

{

axAcroPDF1.src = path; // загрузить файл в pdf-ридер

// ввести в заголовок формы номер выбранной темы:

this.Text = "Тема " + themeNumber;

}

else // иначе

// вывести на экран сообщение о том, что файл не найден:

MessageBox.Show("Файл " + themeNumber + ".pdf не найден!");

}

Дополнительный учебный материал представлен каталогом электронных книг по основам объектно-ориентированного программирования. Книги в формате pdf расположены в директории по пути \bin\Debug\books. Как показано в листинге 4, обработчик кнопки для открытия каталога запускает ресурс системного процесса и связывает его с новым компонентом Process.

Листинг 4. Обработка кнопки «Дополнительные материалы»

private void addStuffButton_Click(object sender, EventArgs e)

{

Process.Start(Application.StartupPath + @"\books");

}

Структура приложения позволяет перейти к тестовому модулю из любого другого модуля программы. Вопросы и ответы для итогового теста загружаются из текстовых файлов «questions.txt» и «answers.txt», расположенных в директории по пути \bin\Debug. В листинге 5 приводятся все глобальные переменные этого модуля, необходимые для организации тестирования.

Листинг 5. Глобальные переменные класса TestForm

// путь к файлу с вопросами для теста:

string path = Application.StartupPath + @"/questions.txt",

// путь к файлу с номерами правильных ответов:

path2 = Application.StartupPath + @"/answers.txt",

// текст, считываемый из файла:

text = "";

// список строковых массивов, каждый из которых

// содержит вопрос, варианты ответа и правильный ответ:

List<string[]> test = new List<string[]>();

// список строк - выбранных ответов:

List<string> checkedAnswers = new List<string>();

int j = 0, // номер текущего вопроса

checkedAnswer = 1, // номер выбранного ответа

score = 0; // количество правильных ответов

Конструктор формы тестового модуля создает объект формы с компонентами, получает данные для теста из файла и загружает их на форму. Для этих целей предназначены функции FillTestInformation() (листинг 6) и FillTestForm() (листинг 7).

Листинг 6. Заполнение тестовой информации

private void FillTestInformation()

{

// считывание текста вопросов из файла:

text = File.ReadAllText(path);

// разбиение текста в массив строк, исключая пустые строки:

string[] ls = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

// считывание правильных ответов и разбиение в массив строк:

string[] rightAnswers = File.ReadAllText(path2).Split(new char[] { '[', ']', ',' }, StringSplitOptions.RemoveEmptyEntries);

// номер ячейки в массиве rightAnswers,

// содержащей правильный ответ на соответствующий вопрос:

int k = 1;

// Цикл по количеству считанных строк.

// Каждая пятая строка соответствует новому вопросу.

for (int i = 0; i < ls.Length; i += 5)

{

// получение строки вопроса:

string q = ls[i].Split(')')[1];

// получение строки с первым вариантом ответа:

string var1 = ls[i + 1].Split(')')[1];

// получение строки cо вторым вариантом ответа:

string var2 = ls[i + 2].Split(')')[1];

// получение строки с третьим вариантом ответа:

string var3 = ls[i + 3].Split(')')[1];

// получение строки с четвертым вариантом ответа:

string var4 = ls[i + 4].Split(')')[1];

// добавление массива строк в список:

test.Add(new string[6] { q, var1, var2, var3, var4, rightAnswers[k] });

k++; // переход к следующему правильному ответу

}

}

Листинг 7. Заполнение компонентов теста на форме

private void FillTestForm()

{

questionTextBox.Text = test.ElementAt(j)[0];

radioButton1.Text = test.ElementAt(j)[1];

radioButton2.Text = test.ElementAt(j)[2];

radioButton3.Text = test.ElementAt(j)[3];

radioButton4.Text = test.ElementAt(j)[4];

}

Обработка подтверждения ответа в тесте представлена в листинге 8.

Листинг 8. Обработка кнопки «Подтвердить»

private void acceptButton_Click_1(object sender, EventArgs e)

{

// получение правильного ответа для текущего вопроса:

int rightAnswer = int.Parse(test.ElementAt(j)[5]);

// добавление текста выбранного ответа в список:

checkedAnswers.Add(test.ElementAt(j)[checkedAnswer]);

// Если правильный ответ = выбранному, то

if (rightAnswer == checkedAnswer)

score++; // увеличить количество правильных ответов

// Если текущий вопрос не последний, то

if (j < test.Count - 1)

{

j++; // перейти к следующему вопросу

// и поменять заголовок формы

this.Text = "Вопрос " + (j + 1);

FillTestForm(); // ввести данные на форму

}

else // иначе

{

// строка с результатом:

string result = "Результат: " + score.ToString() + " правильных ответов из " + test.Count.ToString();

// процент правильных ответов:

double percentage = (double) score / test.Count * 100;

// если процент правильных ответов не превышает 40, // то оценка за тест = 2. Кнопка вывода результатов // по-прежнему неактивна.

if (percentage <= 40)

MessageBox.Show(result + "\n Ваша оценка: 2 (неудовлетворительно)");

else // иначе

// вывести оценку в зависимости от набранных баллов

// и сделать активной кнопку вывода результатов

{

if (percentage > 85)

MessageBox.Show(result + "\n Ваша оценка: 5 (отлично)");

if (percentage > 60 && percentage <= 85)

MessageBox.Show(result + "\n Ваша оценка: 4 (хорошо)");

if (percentage > 40 && percentage <= 60)

MessageBox.Show(result + "\n Ваша оценка: 3 (удовлетворительно)");

resultsButton.Enabled = true;

}

// сделать активной кнопку печати теста:

printTest.Enabled = true;

}

}

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

Листинг 9. Обработка создания документа для печати теста или его результатов

private void printDocument2_PrintPage(object sender, PrintPageEventArgs e)

{

int charactersOnPage = 0; // число символов на странице

int linesPerPage = 0; // число строк на странице

//Установить значение числа символов charactersOnPage и //числа строк linesPerPage, которое будет соответствовать //границам страницы:

e.Graphics.MeasureString(text,this.Font, e.MarginBounds.Size, StringFormat.GenericTypographic, out charactersOnPage, out linesPerPage);

// Нарисовать строку в пределах границы страницы:

e.Graphics.DrawString(text,this.Font,Brushes.Black, e.MarginBounds, StringFormat.GenericTypographic);

// Удалить часть строки, которая была напечатана:

text = text.Substring(charactersOnPage);

// Проверить, нужно ли еще печатать страницы:

e.HasMorePages = (text.Length > 0);

}

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

Рисунок 2 – Вид главной формы приложения

Теоретическая форма приложения позволяет просматривать pdf-файлы соответствующих учебных тем (лекций и семинаров), которые загружаются на форму автоматически из директории по пути \bin\Debug\theory. Здесь находятся кнопки для просмотра соседних тем из каталога, кнопки перехода к дополнительным материалам и итоговому тесту, а также кнопка возврата к главной форме программы. Вид формы после перехода к просмотру лекции 1 приведен на рисунке 3.

Рисунок 3 – Вид формы для просмотра учебных материалов

Вопросы и ответы итогового теста загружаются на тестовую форму из текстовых файлов «questions.txt» и «answers.txt», расположенных в директории по пути \bin\Debug. Вопросы теста имеют одиночный тип выбора ответов – варианты представлены радиокнопками, а непосредственный выбор осуществляется по нажатию на кнопку «Подтвердить». Кроме того, теоретическая форма содержит кнопку возврата к главной форме программы, а также кнопки для печати вопросов и просмотра результатов, которые неактивны во время прохождения теста. Вид формы после ответа на последний тестовый вопрос приведен на рисунке 4.

Рисунок 4 – Вид тестовой формы после ответа на последний вопрос теста

По окончании прохождения теста его вопросы можно распечатать. В случае оценки 3 и выше доступен переход к форме с результатами (рисунок 5).

Рисунок 5 – Вид тестовой формы после успешного прохождения теста

Форма для просмотра результатов теста содержит кнопки возврата к главной форме приложения и к тестовой форме, а также кнопку для печати результатов тестирования. Вид формы приведен на рисунке 6.

Рисунок 6 – Вид формы для просмотра результатов тестирования

ЗАКЛЮЧЕНИЕ

В рамках курсовой работы на языке программирования высокого уровня C# было разработано приложение для обучения основам объектно-ориентированного программирования. Созданная программа имеет понятный графический интерфейс, выводит все необходимые пояснения и подсказки, является законченной и удобной для использования.

В ходе работы были выполнены все поставленные задачи:

  • получено представление о классификации основных языков программирования;
  • рассмотрены основные этапы развития языков программирования и выделены их ключевые стандарты;
  • выполнена реализация приложения с использованием одного из современных стандартизированных языков;

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

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

        1. Ключарев А.А., Матьяш В.А., Щекин С.В. Структуры и алгоритмы обработки данных: Учебное пособие / СПбГУАП. СПб., 2004.
        2. Колдаев В.Д. Основы алгоритмизации и программирования: Учебное пособие / Колдаев В.Д; Под ред. проф.Л.Г. Гагариной - М.: ИД ФОРУМ, НИЦ ИНФРА-М, 2016. - 416 с.
        3. Страуструп, Б. Язык программирования C++ [Текст] = The C++ Programming Language : специальное издание / Б. Страуструп ; пер.: С. Анисимов, М. Кононов ; ред.: Ф. Андреев, А. Ушаков. - [Б. м.] : Бином-Пресс, 2008. - 1098 с.
        4. Кнут, Д. Искусство программирования [Текст] = The art of computer programming: [в 3 т.]. Т. 1. Основные алгоритмы / Д. Кнут ; ред. Ю. В. Козаченко. - 3-е изд. - М. : Вильямс, 2014. - 720 с.
        5. Демидович, Е.М. Основы алгоритмизации и программирования. Язык СИ [Текст] : учебное пособие / Е. М. Демидович. - 2-е изд., испр. и доп. - СПб. : БХВ - Петербург, 2008. - 440 с.
        6. Вирт, Н Алгоритмы и структуры данных. Новая версия для Оберона + CD [Текст] / Н. Вирт ; пер. Д. Б. Подшивалов. - 2-е изд., испр. - М. : ДМК Пресс, 2012. - 272 с.
        7. Prosise, J. – Programming Microsoft .NET [Текст] = Microsoft Press. 2002, p. 816.

Приложение 1. Исходный код модуля MainForm.cs

using System;

using System.Diagnostics;

using System.Windows.Forms;

namespace TeachingApp

{

// Главная форма (меню выбора)

public partial class MainForm : Form

{

/*

* Конструктор формы - создает объект формы с находящимися на нем компонентами

*/

public MainForm()

{

InitializeComponent();

}

/*

* Обработчик кнопок выбора лекции или семинара

*/

private void buttons_Click(object sender, EventArgs e)

{

int theme = int.Parse((sender as Button).Tag.ToString()); // получаем номер лекции / семинара по тегу нажатой кнопки

TheoryForm tf = new TheoryForm(theme); // создаем новую форму для просмотра лекции / семинара

tf.Show(); // показываем ее

this.Dispose(false); // уничтожаем текущую форму

}

/*

* Обработчик закрытия формы - выполняет выход из приложения

*/

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)

{

Application.Exit();

}

/*

* Обработчик кнопки "Дополнительные материалы" - открывает папку books при помощи системного процесса

*/

private void addStuffButton_Click(object sender, EventArgs e)

{

Process.Start(Application.StartupPath + @"\books");

}

/*

* Обработчик кнопки "Итоговый тест"

*/

private void testButton_Click(object sender, EventArgs e)

{

TestForm test = new TestForm(); // создаем новую форму для прохождения теста

test.Show(); // показываем ее

this.Dispose(false); // уничтожаем текущую форму

}

}

}

Приложение 2. Исходный код модуля TheoryForm.cs

using System;

using System.Diagnostics;

using System.IO;

using System.Windows.Forms;

namespace TeachingApp

{

// Теоретическая форма (чтение лекции по выбранной теме)

public partial class TheoryForm : Form

{

string path = ""; // путь к pdf-файлу

int themeNumber = 0; // номер выбранной темы

/*

* Конструктор формы - создает объект формы с находящимися на нем компонентами

*/

public TheoryForm(int n)

{

InitializeComponent();

themeNumber = n; // получение номера темы из главной формы

path = Application.StartupPath + @"\theory\" + themeNumber + ".pdf"; // ввод пути к соответствующему теме pdf-файлу

// Если файл по заданному пути существует, то

if (File.Exists(path))

{

axAcroPDF1.src = path; // загрузить файл в pdf-ридер

this.Text = "Тема " + themeNumber; // ввести в заголовок формы номер выбранной темы

}

else // иначе

MessageBox.Show("Файл " + themeNumber + ".pdf не найден!"); // вывести на экран сообщение о том, что файл не найден

// Если номер темы = 1, то кнопка перехода к предыдущей теме должна быть неактивной

if (themeNumber == 1)

leftButton.Enabled = false;

// Если номер темы = 6, то кнопка перехода к следующей теме должна быть неактивной

if (themeNumber == 6)

rightButton.Enabled = false;

}

/*

* Обработчик закрытия формы - выполняет выход из приложения

*/

private void TheoryForm_FormClosing(object sender, FormClosingEventArgs e)

{

Application.Exit();

}

/*

* Обработчик кнопки "Вернуться к выбору темы"

*/

private void menuButton_Click(object sender, EventArgs e)

{

MainForm mf = new MainForm(); // создаем новую форму для выбора темы

mf.Show(); // показываем ее

this.Hide(); // скрываем текущую форму

}

/*

* Обработчик кнопки "Пройти итоговый тест"

*/

private void testButton_Click(object sender, EventArgs e)

{

TestForm test = new TestForm(); // создаем новую форму для прохождения теста

test.Show(); // показываем ее

this.Hide(); // скрываем текущую форму

}

/*

* Обработчик кнопки "Дополнительные материалы" - открывает папку books при помощи системного процесса

*/

private void addStuffButton_Click(object sender, EventArgs e)

{

Process.Start(Application.StartupPath + @"\books");

}

/*

* Обработчик кнопок перехода к соседней теме

*/

private void changeThemeButton(object sender, EventArgs e)

{

// Если номер темы >= 1, то кнопка перехода к предыдущей теме должна быть неактивной

if (themeNumber >= 1)

leftButton.Enabled = true;

// Если номер темы <= 6, то кнопка перехода к следующей теме должна быть неактивной

if (themeNumber <= 6)

rightButton.Enabled = true;

// Находим направление сдвига по тегу соответствующей кнопки

int shiftSign = int.Parse((sender as Button).Tag.ToString());

// Если направление - влево и номер темы = 1, то выполнить выход из обработчика

if (shiftSign == -1 && themeNumber == 1)

return;

// Если направление - вправо и номер темы = 6, то выполнить выход из обработчика

if (shiftSign == 1 && themeNumber == 6)

return;

themeNumber += shiftSign; // выполнить соответствующий сдвиг для перехода к соседней теме путем изменения номера темы

path = Application.StartupPath + @"\theory\" + themeNumber + ".pdf"; // ввод пути к соответствующему теме pdf-файлу

// Если файл по заданному пути существует, то

if (File.Exists(path))

{

axAcroPDF1.src = path; // загрузить файл в pdf-ридер

this.Text = "Тема " + themeNumber; // ввести в заголовок формы номер выбранной темы

}

else // иначе

MessageBox.Show("Файл " + themeNumber + ".pdf не найден!"); // вывести на экран сообщение о том, что файл не найден

}

}

}

Приложение 3. Исходный код модуля TestForm.cs

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Printing;

using System.IO;

using System.Linq;

using System.Windows.Forms;

namespace TeachingApp

{

// Форма для прохождения тестирования

public partial class TestForm : Form

{

string path = Application.StartupPath + @"/questions.txt", // путь к файлу с вопросами для теста

path2 = Application.StartupPath + @"/answers.txt", // путь к файлу с номерами правильных ответов

text = ""; // текст, считываемый из файла

List<string[]> test = new List<string[]>(); // тест - список строковых массивов, каждый из которых содержит вопрос, варианты ответа и правильный ответ

List<string> checkedAnswers = new List<string>(); // список строк - выбранных ответов

int j = 0, // номер текущего вопроса

checkedAnswer = 1, // номер выбранного ответа

score = 0; // количество правильных ответов

/*

* Функция заполнения тестовой информации

*/

private void FillTestInformation()

{

text = File.ReadAllText(path); // считывание текста вопросов из файла

string[] ls = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); // разбиение текста в массив строк, исключая пустые строки

string[] rightAnswers = File.ReadAllText(path2).Split(new char[] { '[', ']', ',' }, StringSplitOptions.RemoveEmptyEntries); // считывание правильных ответов и разбиение в массив строк

int k = 1; // номер ячейки в массиве rightAnswers, содержащей правильный ответ на соответствующий вопрос (индексируется с единицы, т.к. rightAnswers[0] содержит строку текста, предшествующую числовым значениям

// Цикл по количеству считанных строк. Каждая пятая строка соответствует новому вопросу.

for (int i = 0; i < ls.Length; i += 5)

{

string q = ls[i].Split(')')[1]; // получение строки вопроса

string var1 = ls[i + 1].Split(')')[1]; // получение строки с первым вариантом ответа

string var2 = ls[i + 2].Split(')')[1]; // получение строки cо вторым вариантом ответа

string var3 = ls[i + 3].Split(')')[1]; // получение строки с третьим вариантом ответа

string var4 = ls[i + 4].Split(')')[1]; // получение строки с четвертым вариантом ответа

test.Add(new string[6] { q, var1, var2, var3, var4, rightAnswers[k] }); // добавление массива строк в список

k++; // переход к следующему правильному ответу

}

}

/*

* Функция заполнения компонентов теста на форме

*/

private void FillTestForm()

{

questionTextBox.Text = test.ElementAt(j)[0];

radioButton1.Text = test.ElementAt(j)[1];

radioButton2.Text = test.ElementAt(j)[2];

radioButton3.Text = test.ElementAt(j)[3];

radioButton4.Text = test.ElementAt(j)[4];

}

/*

* Конструктор формы - создает объект формы с находящимися на нем компонентами

*/

public TestForm()

{

InitializeComponent();

FillTestInformation(); // получаем данные теста из файла

FillTestForm(); // вводим данные на форму

this.Text = "Вопрос 1"; // меняем заголовок формы

}

/*

* Обработчик закрытия формы - выполняет выход из приложения

*/

private void TestForm_FormClosing(object sender, FormClosingEventArgs e)

{

Application.Exit();

}

/*

* Обработчик кнопки "Вернуться к выбору темы"

*/

private void backToMenuButton_Click(object sender, EventArgs e)

{

MainForm mf = new MainForm(); // создаем новую форму для выбора темы

mf.Show(); // показываем ее

this.Dispose(false); // уничтожаем текщую форму

}

/*

* Обработчик кнопки "Посмотреть ответы"

*/

private void resultsButton_Click(object sender, EventArgs e)

{

ResultsForm rf = new ResultsForm(test, checkedAnswers); // создаем объект формы результатов теста

rf.Show(); // показываем ее

this.Dispose(false); // уничтожаем текущую форму

}

/*

* Обработчик создания документа для печати теста

*/

private void printDocument2_PrintPage(object sender, PrintPageEventArgs e)

{

int charactersOnPage = 0; // число символов на странице

int linesPerPage = 0; // число строк на странице

// Устанавливаем значение числа символов charactersOnPage и числа строк linesPerPage, которое будет соответствовать границам страницы.

e.Graphics.MeasureString(text, this.Font,

e.MarginBounds.Size, StringFormat.GenericTypographic,

out charactersOnPage, out linesPerPage);

// Рисуем строку в пределах границы страницы

e.Graphics.DrawString(text, this.Font, Brushes.Black,

e.MarginBounds, StringFormat.GenericTypographic);

// Удаляем часть строки, которая была напечатана

text = text.Substring(charactersOnPage);

// Проверяем, нужно ли еще печатать страницы

e.HasMorePages = (text.Length > 0);

}

/*

* Обработчик печати теста

*/

private void printTest_Click(object sender, EventArgs e)

{

printDocument2.Print();

}

/*

* Обработчик кнопки "Подтвердить"

*/

private void acceptButton_Click_1(object sender, EventArgs e)

{

int rightAnswer = int.Parse(test.ElementAt(j)[5]); // получение правильного ответа для текущего вопроса

checkedAnswers.Add(test.ElementAt(j)[checkedAnswer]); // добавление текста выбранного ответа в список

// Если правильный ответ = выбранному, то

if (rightAnswer == checkedAnswer)

score++; // увеличиваем количество правильных ответов

// Если текущий вопрос не последний,

if (j < test.Count - 1)

{

j++; // переходим к следующему вопросу

this.Text = "Вопрос " + (j + 1); // меняем заголовок формы

FillTestForm(); // вводим данные на форму

}

else // иначе

{

string result = "Результат: " + score.ToString() + " правильных ответов из " + test.Count.ToString(); // строка с результатом

double percentage = (double) score / test.Count * 100; // процент правильных ответов

if (percentage <= 40) // если процент правильных ответов не превышает 40, то оценка за тест = 2. Кнопка вывода результатов по-прежнему неактивна.

MessageBox.Show(result + "\n Ваша оценка: 2 (неудовлетворительно)");

else // иначе выводим оценку в зависимости от набранных баллов и делаем активной кнопку вывода результатов

{

if (percentage > 85)

MessageBox.Show(result + "\n Ваша оценка: 5 (отлично)");

if (percentage > 60 && percentage <= 85)

MessageBox.Show(result + "\n Ваша оценка: 4 (хорошо)");

if (percentage > 40 && percentage <= 60)

MessageBox.Show(result + "\n Ваша оценка: 3 (удовлетворительно)");

resultsButton.Enabled = true; // делаем активной кнопку вывода результатов

}

printTest.Enabled = true; // делаем активной кнопку печати теста

}

}

/*

* Обработчик события изменения выбранного варианта ответа

*/

private void radioButtons_CheckedChanged(object sender, EventArgs e)

{

// Получение выбранного номера ответа по тегу соответствующей радиокнопки

checkedAnswer = int.Parse((sender as RadioButton).Tag.ToString());

}

}

}

Приложение 4. Исходный код модуля ResultsForm.cs

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Linq;

using System.Windows.Forms;

namespace TeachingApp

{

// Форма для просмотра результатов тестирования

public partial class ResultsForm : Form

{

string text = ""; // печатаемый текст

/*

* Конструктор формы - создает объект формы с находящимися на нем компонентами

*/

public ResultsForm(List<string[]> test, List<string> checkedAnswers)

{

InitializeComponent();

// Цикл по количеству вопросов в тесте

for (int i = 0; i < test.Count; i++)

{

resultsTextBox.Text += "Вопрос " + (i + 1) + ": " + test.ElementAt(i)[0]; // добавление строки вопроса

resultsTextBox.Text += Environment.NewLine; // переход на новую строку

resultsTextBox.Text += "Варианты ответов: ";

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += "а) " + test.ElementAt(i)[1]; // добавление первого варианта ответа

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += "б) " + test.ElementAt(i)[2]; // добавление второго варианта ответа

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += "в) " + test.ElementAt(i)[3]; // добавление третьего варианта ответа

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += "г) " + test.ElementAt(i)[4]; // добавление четвертого варианта ответа

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += "Ваш ответ: " + checkedAnswers.ElementAt(i); // добавление текста выбранного ответа

resultsTextBox.Text += Environment.NewLine;

int number = int.Parse(test.ElementAt(i)[5]); // нахождение номера правильного ответа

resultsTextBox.Text += "Правильный ответ: " + test.ElementAt(i)[number]; // добавление текста правильного ответа

resultsTextBox.Text += Environment.NewLine;

resultsTextBox.Text += Environment.NewLine; // доп. пустая строка между вопросами

}

text = resultsTextBox.Text;

}

/*

* Обработчик закрытия формы - выполняет выход из приложения

*/

private void ResultsForm_FormClosing(object sender, FormClosingEventArgs e)

{

Application.Exit();

}

/*

* Обработчик кнопки "Вернуться к выбору темы"

*/

private void backToMenuButton_Click(object sender, EventArgs e)

{

MainForm mf = new MainForm(); // создаем новую форму для выбора темы

mf.Show(); // показываем ее

this.Dispose(false); // уничтожаем текущую форму

}

/*

* Обработчик кнопки "Вернуться к прохождению теста"

*/

private void textButton_Click(object sender, EventArgs e)

{

TestForm test = new TestForm(); // создаем новую форму для прохождения теста

test.Show(); // показываем ее

this.Dispose(false); // уничтожаем текущую форму

}

/*

* Обработчик создания документа для печати теста

*/

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)

{

int charactersOnPage = 0; // число символов на странице

int linesPerPage = 0; // число строк на странице

// Устанавливаем значение числа символов charactersOnPage и числа строк linesPerPage, которое будет соответствовать границам страницы.

e.Graphics.MeasureString(text, this.Font,

e.MarginBounds.Size, StringFormat.GenericTypographic,

out charactersOnPage, out linesPerPage);

// Рисуем строку в пределах границы страницы

e.Graphics.DrawString(text, this.Font, Brushes.Black,

e.MarginBounds, StringFormat.GenericTypographic);

// Удаляем часть строки, которая была напечатана

text = text.Substring(charactersOnPage);

// Проверяем, нужно ли еще печатать страницы

e.HasMorePages = (text.Length > 0);

}

/*

* Обработчик печати результатов теста

*/

private void printButton_Click(object sender, EventArgs e)

{

printDocument1.Print();

}

}

}