International Baccalaureate Organization (IBO) Alexander Pushkin School Perm Russian Federation Муниципальное автономное общеобразовательное учреждение «Средняя общеобразовательная школа №9 им А.С.Пушкина с углублённым изучением предметов физико-математического цикла Персональный проект Создание сайта для помощи школьникам и студентам в обучении математике и информатике Автор – Цаплин Сергей, студент MYP 5 Ученик 9Г класса Супервайзер – Вязьмина Ольга Николаевна Учитель алгебры и геометрии 1 Содержание 1.Заглавная страница……………………………………………………………………1 2.Содержание…………………………………………………………………………....2 3. Введение……………………………………………………………………………….3 4. Основная часть………………………………………………………………………..5 5. Вывод…………………………………………………………………………………10 6. Библиография………………………………………………………………………...12 7. Приложение…………………………………………………………………………..13 2 Введение Тема: создание сайта для помощи учащимся в обучении математике и информатике. Цель: создание сайта, который будет помогать учащимся в информатике и математике. На сайте будут выложены программы, реализующие некоторые алгоритмы в математике, например программа, рисующая график функции, и множество алгоритмов по информатике. Для пользователя должно быть очень легко скачать любую программу с моего сайта. Для кого? Этот сайт будет полезен очень многим людям. В нём будут заинтересованы ученики, желающие проверить свои ответы по математике, например, если ученикам было дано задание построить несколько графиков функций, они могут воспользоваться программой с сайта, которая рисует эти графики, чтобы проверить свой результат. Также сайт будет полезен для программистов, так как намного быстрее и надёжнее вставить в программу готовый и проверенный алгоритм, чем писать ему самому. В любой программе можно установить язык: русский или английский. Это дает возможность использования программ не только в России, но и в других странах. Построение графика функции - очень популярная тема для школьников и студентов. Статистика Яндекса (http://wordstat.yandex.ru) показывает, что каждый месяц более 30000 человек ищут такие программы. Продукт. Продуктом будет являться сайт, написанный с помощью программы «Wordpress». Сайт будет содержать алгоритмы для программирования с комментариями, в каких случаях, какой алгоритм и почему надо использовать. Также там будет несколько полезных программ по математике. Продукт был проверен доцентом кафедры «математическое моделирование систем и процессов», кандидатом технических наук ПНИПУ (бывший ПГТУ), Няшиной Н. Д. Соответствующий отзыв есть в приложениях. Почему я выбрал именно эту тему? Я выбрал именно эту тему, так как в 9 классе мы проходили много сложных тем на уроках математики, и я подумал, что не каждый ученик способен справиться с ними, и это будет сделать намного легче, если будут программы, помогающие тебе в математике. Поискав их в интернете, я не обнаружил ни одного сайта, на котором было бы множество таких программ, поэтому я сам решил создать такой сайт. Также мной было решено, что сайт будет содержать часто используемые алгоритмы для программирования, так как не редко приходится искать неизвестные тебе алгоритмы для своей программы, а наличие их всех на одном сайте значительно поможет многим программистам и ускорит время написание кода. Мною было решено создать сайт с помощью «Wordpress», потому что мне посоветовал эту программу мой папа, который создал с помощью этой программы свой личный сайт http://tsaplin.ru/. Мне он очень понравился. Изучив эту программу, я понял, что с ней 3 будет очень легко и быстро работать, поэтому мой сайт тоже написан с помощью «Wordpress». Методы и приёмы. Устные опросы. Я опросил многих своих друзей и одноклассников и в результате опроса понял, какие типы заданий вызывают у них большую трудность и какие функции для программирования им бы хотелось иметь. Для решения этих типов заданий были написаны программы. И были описаны соответствующие функции для написания программ. Сравнение. После просмотра множества похожих программ в интернете, с учётом их недостатков и положительных черт мною были продуманы схема работы и интерфейс каждой программы. Область взаимодействия – Служение обществу. Мой сайт предназначен для того, чтобы помогать людям, занимающимся математикой или информатикой. Для создания проекта был создан следующий план: 1. Сбор и анализ информации. 2. Создание продукта 2.1. Создание оболочки сайта 2.2. Оценка похожих программ из интернета 2.3. Планирование каждой своей программы 2.4. Создание программ 2.5. Создание функций для программирования 2.6. Размещение программ на сайте 2.7. Размещение сайта в интернете 3. Тестирование проекта 3.1. Изменение и редактирование сайта и программ в соответствии с отзывами о них 4. Создание письменных работ на русском и английском языках 5. Подготовка презентации 6. Защита проекта 4 Описание процесса Опрос. После опроса моих друзей и одноклассников я понял, какие программы были бы полезны школьникам и студентам. Поэтому я решил создать программы, позволяющие рисовать графики функций и работать с системами счисления, а именно переводить число из одной системы счисления в другую и делать простые арифметические операции (сложение, вычитание, умножение и деление) с числами, записанными в одинаковой системе счисления. Создание оболочки сайта. Я создал оболочку сайта с помощью программы Denwer. Денвер – это набор для веб разработки. Название переводится как ДНВР – Джентльменский набор веб разработчика. С помощью этой программы я сделал мой компьютер сервером для моего сайта. Программа была скачана с официального сайта – http://www.denwer.ru. Установка и работа с программой очень ясная и понятная. Мне очень понравилась эта программа. После создания оболочки сайта мне понадобилось овладеть системой «Wordpress», с помощью которой я буду в дальнейшем заполнять сайт. В этом мне помог мой папа. Также я часто обращался к сайту http://codex.wordpress.org/ это официальный сайт, с ним было легко и удобно работать. Он дал мне много полезной информации. Оценка похожих программ из интернета Я нашёл в интернете 5 сайтов, строящие график функции онлайн: http://school35.ucoz.ru/grapher/grapher_e.htm, http://um-razum.ru/graph/, http://www.kontrolnaya-rabota.ru/s/grafik/xy/, http://matesha.ru/schedule_function.php, http://www.reshalki.ru/yasam/graph.htm. Программы на сайтах http://school35.ucoz.ru/grapher/grapher_e.htm, http://umrazum.ru/graph/ и http://www.reshalki.ru/yasam/graph.htm были абсолютно идентичны. Эти программы плохо работали с модулями, не всегда строили правильный график функции содержащей модуль переменной, там не было функций целой и дробной части от числа. Программа с сайта http://www.kontrolnaya-rabota.ru/s/grafik/xy/ содержит все те же недочёты, что и предыдущие три. На этом сайте нельзя при построении графика выбирать масштаб по оси Y (оси ординат), что может сильно помешать восприятию некоторых графиков. Мне не понравилась эта программа ещё тем, что после рисования очередного графика функции сайт переходит на другую страницу, и чтобы 5 построить следующий график, приходится возвращаться на предыдущую страницу, что отнимает много времени. Программа с сайта http://matesha.ru/schedule_function.php также содержит все недочёты, что и первые три, но ещё в программе нет констант – чисел е и 𝜋, которые часто нужны для построения графиков, например f(x) = e^x. Непонятно, какие функции есть в программе, и как их надо использовать. Таким образом, моя программа должна содержать кроме основных функций также и функции целой и дробной части от числа. Программа должна быть понятна в использовании и должна содержать инструкцию, чтобы у пользователей программы не возникло вопросов по её эксплуатации и чтобы они знали все её функции и как с ними работать. Также во всех просмотренных мною программах отсутствует визуальный эффект построения графика. Моя программа будет строить график постепенно. Мною были найдены 6 сайтов, с онлайн программами, похожими на мою вторую программу: http://math.semestr.ru/inf/index.php, http://eict.ru/calsystem.html, http://allcalc.ru/node/418, http://life-prog.ru/servis.php?id=1, http://numsys.ru/calculator, http://live.mephist.ru/show/calc/help/numeral-systems. На сайте http://life-prog.ru/servis.php?id=1 хороший перевод числа из одной системы счисления в другую, но нет возможности делать арифметические операции над числами. Сайт http://math.semestr.ru/inf/index.php позволяет переводить нецелые числа в другие системы счисления, но он работает только с двоичной, восьмеричной, десятичной и шестнадцатеричной системой счисления. На сайте http://allcalc.ru/node/418 можно переводить числа только из десятичной системы счисления в систему счисления с основанием 2, 8 или 16 или наоборот. На сайтах http://live.mephist.ru/show/calc/help/numeral-systems http://eict.ru/calsystem.html можно делать и перевод, и арифметические операции. и Сайт http://numsys.ru/calculator позволяет делать арифметические операции над длинными числами (до 50 знаков). Таким образом, моя программа должна уметь работать с очень большими числами (до 1000 знаков) и должна уметь, как переводить числа из одной системы счисления в другую, так и делать простые операции над числами, записанными в какой-либо системе счисления. Планирование программ Главной составляющей программы, строящей график функции будет процедура, которая по функции f(x) и значению x будет показывать её значение. После того, как 6 пользователь выберет крайние рассматриваемые значения переменной Х, программа разобьёт отрезок от минимального значения до максимального на равные части несколькими точками, посчитает значение функции в каждой точке, построит все точки на графике и последовательно соединит их. В программе, работающей со степенями счисления, будут две главные подпрограммы. Одна будет переводить число в привычную для нас десятичную систему счисления. Для хранения очень больших чисел в десятичной системе счисления будут созданы специальные структуры. Вторая подпрограмма будет переводить полученное после преобразований число, записанное в десятичной системе счисления, в нужную систему счисления. Создание программ. Мне посоветовали для написания моих программ использовать PascalABC.net. Эта среда программирования очень похожа на известную мне Delphi 7, поэтому я решил изучить её. В интернете был найден один сайт с самоучителями по этой программе: http://sunschool.math.rsu.ru/pabc/. На нём были презентации, показывающие все отличия PascalABC.net от Delphi 7, что мне и надо было, тем более обе презентации были созданы одним из авторов этого языка – С.С.Михалковичем. Поэтому я был уверен, что узнал все важные отличия этих двух программ и закончил на этом поиск сайтов с самоучителями. У меня было два варианта – писать программы на Delphi 7 или на PascalABC.net. У каждой из этих программ есть свои плюсы и минусы. В Delphi быстрее и удобнее создавать интерфейс программы, Delphi быстрее. Она совершает за секунду сто миллионов операций, а PascalABC.net только миллион, то есть PascalABC.net медленнее в сто раз, что скажется, например, на точности графика, так как за одно и то же время мы сможем построить в сто раз меньше точек для графика. В Delphi хуже графика и она часто вылетает при наличии маленькой оплошности, чем мне эта программа очень не нравится. В PascalABC.net удобнее писать код программы, так как там есть множество встроенных алгоритмов, которых нет в Delphi, что уменьшает код программы. После длительного размышления, взвесив все достоинства и недостатки каждой из программ, я решил писать свои программы на Delphi 7. Интерфейс в программах был создан с помощью книги C.Бобровского – «Delphi 7 учебный курс». В этой книге есть замечательное описание всех частей интерфейса. Также там есть правильные примеры и понятные инструкции для их использования. На сайте http://www.delphi-manual.ru/drawing.php были найдены описания и примеры использования функций, рисующих линии, точки и окружности в Delphi 7. На сайте было много примеров, что позволяло узнать все их возможности. Функции, 7 описанные на этом сайте, были использованы у меня в работе. Сайтом я остался доволен. В ходе работы над программами мне понадобилось установить их точное время работы. На разных сайтах было описано множество решений этой проблемы, но метод, описанный на сайте http://forum.3dnews.ru/archive/index.php/t-57874.html позволять считать время работы программы с высокой точностью, поэтому я выбрал именно его. Создание функций для программирования Также на моём сайте размещаются различные функции для программирования. Они были взяты с различных сайтов, например, http://codeforces.ru – это сайт интернет олимпиад по информатике, на котором после очередной олимпиады можно смотреть решения её участников. Оттуда были взяты множество функций. Они заведомо правильные и работают безотказно, так как взяты из решения задачи, получившего полный балл, то есть решение абсолютно правильное. Некоторые функции были взяты с сайта http://ejudge.179.ru – это сайт Летней Компьютерной Школы, в которой я был этим летом. На этом сайте были сохранены множество моих программ, которые были написаны мной и проверены в этой школе. Также несколько функций были написаны и проверенны лично мной, как например программы, написанные мной на уроках информатики в нашей школе. Они проверены тестирующей системой и хранятся на сайте нашей школы http://www.school9.perm.ru/gate/tester/ . Размещение программ на сайте Программа «Wordpress», позволяет помещать на сайт файлы весом до 2-х мегабайт. Мои программы весят меньше, что позволило разместить их на моём сайте. Размещение сайта в интернете Сайт был размещён под именем http://sergei.tsaplin.ru , так как он размещён под доменом моей семьи – tsaplin.ru. По моему мнению, создавать новый домен бессмысленно, так как за пользование доменом надо платить деньги, а за использование домена tsaplin.ru платить не надо. Тестирование сайта Сайт был запущен, и все пользователи могли отправить свой отзыв на мою электронную почту, указанную на сайте. На 16 февраля на 10 часов вечера было получено 3 отзыва по моему сайту и программам. Все они указаны в приложениях. Изменение работы 8 В одном из отзывов говорилось про интерфейс программ, и было описано, как сделать его лучше и понятнее для пользователей моих программ. Фон был сделан белым, так как в двух отзывах говорилось о том, что серый фон делает программу старомодной и некрасивой. С такой программой сразу не хочется работать. После изменений стало более понятно, как надо работать в программе, появилась инструкция по использованию различных функций и всей программы. Изменение интерфейса можно увидеть на следующих рисунках. В процессе работы я показывал свой сайт одноклассникам. Григорий Шарцев указал несколько ошибок моего продукта, например, программа не строила график функции корня из модуля Х. Благодаря этому, мной были найдены ошибки в коде моей программы, и она была усовершенствованна. На рисунке (см. приложение 1) показан старый некрасивый и неудобный интерфейс и неправильное построение графика функции f(x) =1/(x^2). Также бросается в глаза много свободного места справа от графика и непонятно что делать с некоторыми ячейками (см. приложение 2). Также неудобно, что все параметры функции и она сама прижаты к верхнему краю и вытянуты в одну строчку. Также непонятно, где находятся границы графика. В общем, всё это делает программу неудобной для пользования и некрасивой. С такой программой неудобно работать. На следующем рисунке (см. приложение 3) наблюдается понятный интерфейс и правильное построение графика. Видны границы графика. Отсутствуют лишние места, и всё понятно для использования. С такой программой очень удобно работать. Появившаяся анимация построения графика придаёт некую «изюминку» моей программе и выделяет её из остальных. Также появилась инструкция. 9 Вывод В целом, продукт моего проекта (сайт для тех, кто занимается математикой и информатикой) получился, как и было мною задумано. Я остался доволен своим проектом. Сайт выложен в интернете под именем http://sergei.tsaplin.ru. У меня получилось создать программу, рисующую графики функций. В ней содержатся все запланированные ранее функции. Программа оказалась очень полезна. Я сам использовал её для работ на уроке алгебры. Удалось уменьшить вес обоих программ. Они весят меньше Мегабайта, что позволяет очень быстро скачать программу без томительного ожидания загрузки. Также получилось избавиться от установки программы, то есть, чтобы начать пользоваться моими программами надо всего лишь их скачать и не надо запускать никакую загрузку. Это делает программу более удобной для пользования. Также получилось создать программу, работающую со степенями счисления, которая выполняет арифметические действия с числами в любой системе счисления и переводит числа в любые системы счисления. Получилось сделать возможным пользование программами на английском языке. Для пользования этой программы также достаточно лишь скачать её. Эта программа тоже весит очень мало, и её скачивание пройдёт мгновенно. Успешно были созданы функции для программирования. Почти все их них записаны на нескольких языках программирования, в основном это Pascal, C++ и Java – самые популярные языки программирования. Из-за обилия встроенных структур в С++ многие функции написаны очень коротко. Но были и вещи, которые мне не удалось сделать, например, в программе, рисующей графики функций, проявляется ошибка – программа соединяет в графике точки, которые не должны быть соединены (см. приложение 4). Это случилось из-за того, что программа строит график по точкам, и очень сложно определить, надо ли соединять линией очередные две точки – есть там разрыв графика или нет. Этот недочёт будет устранён в скором времени и на сайте появится новая программа. В другой программе не удалось сделать так, чтобы она работала с длинными числами, так как сложно работать с очень длинными числами и производить с ними арифметические операции. Программа будет исправлена в скором времени, когда мне будут известны операции деления длинных чисел. Эта операция появится на моём сайте вместе с остальными функциями. 10 На сайте отсутствуют некоторые функции на языке Java, так как я плохо владею им и все программы взяты из интернета или на сайте http://codeforces.ru. Некоторые функции я там не нашёл. В дальнейшем я планирую добавлять на сайт новые программы для помощи в обучении математике, обновлять старые. Может быть, там появятся какие-нибудь развлекательные программы для того, чтобы сделать сайт более интересным. Выбранная мной область взаимодействия содержит в себе два ключевых вопроса – Как я могу помочь другим? и чем я могу быть полезен людям? Своим проектом я помогаю другим в изучении математики и информатики. Помогаю им изучать эти науки. В ходе работы над проектом я улучшил свои знания в создании презентаций и работе с текстовым редактором. Я улучшил свои знания в математика и информатике. Научился создавать приложения. Научился проводить различные опросы, собирать отзывы и анализировать информацию. В конце хочу сказать спасибо людям, которые помогали мне в написании проекта, а именно моего папу – Цаплина Виталия Алексеевича, который познакомил меня с «Wordpress», помогал разбираться с сайтом и выложить его в интернет. Благодаря его советам по интерфейсу программ, они выглядят более красивыми и понятными. Также я хочу сказать спасибо моему однокласснику – Григорию Шарцеву за то, что во время написания программ он советовал мне как их лучше оформить и искал в них ошибки. Благодаря этому в моих программах отсутствуют ошибки, и они работают правильно. Ещё Григорий написал великолепную рецензию о моей программе, рисующей графики функций. 11 Библиография. http://wordstat.yandex.ru 2) http://codex.wordpress.org/ 3) http://wordpress.org/download/ 4) http://www.delphi-manual.ru/drawing.php 5) С. Бобровский. Delphi7. Учебный курс. 2008г. 6) http://forum.3dnews.ru/archive/index.php/t-57874.html 7) http://ejudge.179.ru 8) http://codeforces.ru 9) http://www.school9.perm.ru/gate/tester/ 10) http://www.denwer.ru 1) 12 Приложение 1) 2) 13 3) 4) 14 Отзыв Григория Шарцева: Скачал на днях эту программку. Что замечаешь ещё при скачивании, так это её вес. Меньше половины мегабайта! Такой размер поражает, ведь сейчас даже маленькие картинки весят больше! Ну что ж, запустил. Сразу бросается в глаза интерфейс… Неудобный, да и выглядит жутковато и старомодно… Запустим. График строится очень красиво, никогда не видел подобного и всегда хотел программу, где видно сам процесс рисования линии графика. Попробуем ещё раз… Неправильно, опять неправильно, и опять ошибка... А тут вообще зависла… Надо разбираться. Гиперболу с модулем или квадратом строит без прерывания. Тангенс вообще не строит… А, нет. Оказывается, надо писать не “tg”, а “tan". Инструкцию бы тогда… А при построении корня из модуля Х вообще зависла… Что ж, посмотрим новую версию. Строит правильно, хотя всё тот же жуткий интерфейс… И куда-то пропала та красивая анимация при построении… А вот и третья версия. Не часто ли обновляют программу? Может, стоит получше протестировать? О, обновили интерфейс! Уже лучше! О, и анимацию вернули! Ещё и инструкция появилась?! Строит вроде правильно теперь. Ну что можно сказать? Раньше я использовал Алгебратор для построения графиков. Но надо отметить, в этой программе интерфейс, конечно, не ахти, но она функциональней, проще, красиво строит, а главное невероятно проста! Не требует установки и весит не больше, чем это письмо! Обязательно себе оставлю. Хотя было бы неплохо, если бы ещё развивали продукт… Особенно касательно интерфейса… Отзыв пользователя от Sha-grisha@yandex.ru Шарцев Г.К. Программист ООО ФОТОМАГАЗИН.КОМ С надеждой о продолжении улучшения программы Тексты программ: Программа, работающая со степенями счисления: unit it1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus; const kol = 14; //const l = 1; 15 const lng: array[1..2, 1..kol] of string = (('Выполнить арифметические действия', 'Перевод в другую систему счисления', 'Посчитать', 'Запомнить', 'Система счисления', 'Число', '+,-,*,/', 'Выберите действие', 'Достать из памяти', 'Очистить ячейку памяти', 'Число не соответствует системе счисления','Нет свободной ячейки памяти', 'Ячейка памяти пуста','Вы выбрали русский язык'), ('Do arithmetic', 'Transfer to another scale of notation', 'Count', 'Remember', 'Scale of notation', 'Number', '+,-,*,/', 'Select the action', 'Get from memory', 'Clear memory cell', 'Number don''t feet in the scale of notation','No empty memory cell','Memory cell is empty','You choosed english language')); type TForm1 = class(TForm) Label2: TLabel; Button1: TButton; Label3: TLabel; Label4: TLabel; Button2: TButton; Button3: TButton; Button4: TButton; Edit1: TEdit; Label5: TLabel; Edit2: TEdit; Label6: TLabel; Edit3: TEdit; Edit4: TEdit; Label7: TLabel; Label8: TLabel; Button5: TButton; Button6: TButton; Label9: TLabel; RadioButton1: TRadioButton; RadioButton2: TRadioButton; RadioGroup1: TRadioGroup; Button7: TButton; MainMenu1: TMainMenu; File1: TMenuItem; Exit1: TMenuItem; Label1: TLabel; //procedure CheckBox1Click(Sender: TObject); //procedure CheckBox2Click(Sender: TObject); procedure CheckBox3Click(Sender: TObject); //procedure CheckBox4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure RadioButton1Click(Sender: TObject); procedure RadioButton2Click(Sender: TObject); procedure RadioGroup1Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Exit1Click(Sender: TObject); //procedure Button7Click(Sender: TObject); private { Private declarations } 16 public { Public declarations } end; var Form1: TForm1; l, i, activity: longint; st1, st2: int64; u1, u2, rg1: boolean; st, h: string; cod: integer; implementation function max(var a, b: integer): integer; begin if a > b then max := a else max := b; end; Procedure PutBig(var a: string); begin for i := 1 to length(a) do if a[i] in ['a'..'z'] then a[i] := chr(ord(a[i]) + ord('A') - ord('a')); end; Function chekSys(a: string; s: int64): boolean; var fail: boolean; begin fail := false; while length(a) > 0 do begin if (a[length(a)] >= '0') and (a[length(a)] <= '9') and (a[length(a)] >= chr(ord('0') + s)) then fail := true else if (a[length(a)] >= chr(ord('A') + s - 10)) then fail := true; delete(a, length(a), 1); end; chekSys := fail; end; Function Tto10(var a: string; s1: int64): int64; var k, p, h: int64; i, j: longint; begin k := 0; p := 1; while length(a) > 0 do begin if (a[length(a)] <= '9') then h := ord(a[length(a)]) - ord('0') else h := ord(a[length(a)]) - ord('A') + 10; k := p * h + k; p := p * s1; delete(a, length(a), 1); end; Tto10 := k; end; Function Tfrom10(var a, s: int64): string; var k, h, p: int64; st: string; 17 begin p := s; st := ''; while a > 0 do begin h := a mod p; if h <= 9 then st := chr(ord('0') + h) + st else st := chr(ord('A') + h - 10) + st; a := a div p; end; Tfrom10 := st; end; Function trans(var a: string; s1, s2: int64): string; var k, p, q: int64; b: int64; begin b := Tto10(a, s1); trans := Tfrom10(b, s2); end; {$R *.dfm} procedure TForm1.CheckBox3Click(Sender: TObject); begin L := 1; Label2.Caption := lng[l, 8]; Form1.Label5.Caption := ''; Form1.Label6.Caption := ''; Form1.Label7.Caption := ''; Form1.Label8.Caption := ''; Button5.Caption := lng[l, 3]; Button6.Caption := lng[l, 4]; Button1.Caption := lng[l, 9]; Button2.Caption := lng[l, 9]; Button3.Caption := lng[l, 10]; Button4.Caption := lng[l, 10]; Label3.Caption := ''; Label9.Caption := ''; Label4.Caption := ''; Edit1.Text := ''; Edit2.Text := ''; Edit3.Text := ''; Edit4.Text := ''; Form1.RadioButton1.Caption := lng[l, 2]; Form1.RadioButton2.Caption := lng[l, 1]; Form1.RadioGroup1.Items.Add('Ðóññêèé'); Form1.RadioGroup1.Items.Add('English'); Form1.Canvas.Rectangle(5, 75, 510, 37); end; procedure TForm1.Button5Click(Sender: TObject); var s1: string; ste1, ste2: integer; begin s1 := Edit1.text; PutBig(s1); 18 ste1 := strtoint(Edit2.Text); ste2 := strtoint(Edit3.Text); if ChekSys(s1, max(ste1, ste2)) then Label9.Caption := lng[l, 11] else if activity = 1 then begin val(Edit4.Text, st1, cod); Label9.Caption := ''; st := Edit1.Text; h := Edit3.Text; if (cheksys(st, st1) = false) or (cheksys(h, st1) = false) then Label9.Caption := lng[l,11] else begin st := Edit1.Text; h := Edit3.Text; if Edit2.Text = '+' then st2 := TTo10(st,st1) + TTo10(h, st1); if Edit2.Text = '-' then begin st2 := TTo10(st,st1) + TTo10(h, st1); if st2 < 0 then Label9.Caption := '-'; st2 := -st2; end; if Edit2.Text = '/' then st2 := round(Tto10(st,st1) / Tto10(h,st1)); if Edit2.Text = '*' then st2 := TTo10(st,st1) * TTo10(h, st1); Label9.Caption := Tfrom10(st2, st1); end; end else begin st := Edit1.Text; val(Edit2.Text, st1, cod); val(Edit3.Text, st2, cod); st := trans(st, st1, st2); Label9.Caption := st; end; end; procedure TForm1.RadioButton1Click(Sender: TObject); begin if l = 0 then l := 1; Form1.Label5.Caption := lng[l, 6]; Form1.Label6.Caption := lng[l, 5] + ' 1'; Form1.Label7.Caption := lng[l, 5] + ' 2'; Form1.Label8.Caption := ''; activity := 0; Form1.Edit4.Text := '-'; end; procedure TForm1.RadioButton2Click(Sender: TObject); begin if l = 0 then l := 1; Form1.Label5.Caption := lng[l, 6] + ' 1'; Form1.Label6.Caption := lng[l, 7]; Form1.Label7.Caption := lng[l, 6] + ' 2'; Form1.Label8.Caption := lng[l, 5]; Form1.Edit4.Text := ''; activity := 1; end; 19 procedure TForm1.RadioGroup1Click(Sender: TObject); begin if Form1.RadioGroup1.ItemIndex = 0 then begin L := 1; Button5.Caption := lng[l, 3]; Button6.Caption := lng[l, 4]; Button1.Caption := lng[l, 9]; Button2.Caption := lng[l, 9]; Button3.Caption := lng[l, 10]; Button4.Caption := lng[l, 10]; Label3.Caption := ''; Label4.Caption := ''; Edit1.Text := ''; Edit2.Text := ''; Edit3.Text := ''; Edit4.Text := ''; Label9.Caption := ''; Form1.RadioButton1.Caption := lng[l, 2]; Form1.RadioButton2.Caption := lng[l, 1]; Form1.Canvas.Rectangle(5, 75, 510, 37); activity := 2; Form1.Label9.Caption := lng[l, 14]; Form1.Label2.Caption := lng[l, 8]; end; if Form1.RadioGroup1.ItemIndex = 1 then begin L := 2; Label2.Caption := lng[l, 8]; Button5.Caption := lng[l, 3]; Button6.Caption := lng[l, 4]; Button1.Caption := lng[l, 9]; Button2.Caption := lng[l, 9]; Button3.Caption := lng[l, 10]; Button4.Caption := lng[l, 10]; Label3.Caption := ''; Label9.Caption := ''; Label4.Caption := ''; Edit1.Text := ''; Edit2.Text := ''; Edit3.Text := ''; Edit4.Text := ''; Form1.RadioButton1.Caption := lng[l, 2]; Form1.RadioButton2.Caption := lng[l, 1]; // Form1.RadioGroup1.InsertComponent(RadioButton1); Form1.Canvas.Rectangle(5, 75, 510, 37); activity := 2; Form1.Label9.Caption := lng[l, 14]; Form1.Label2.Caption := lng[l, 8]; end; end; procedure TForm1.Button6Click(Sender: TObject); begin st := Form1.Label9.Caption; if (u1) and (u2) then 20 begin Form1.Label9.Caption := lng[l, 12]; end else if not u1 then begin label3.Caption := st; u1 := true; end else if not u2 then begin label4.Caption := st; u2 := true; end; end; procedure TForm1.Button1Click(Sender: TObject); begin if not u1 then Form1.Label9.Caption := lng[l, 13] else Edit1.Text := Label3.Caption; end; procedure TForm1.Button2Click(Sender: TObject); begin if not u2 then Form1.Label9.Caption := lng[l, 13] else Edit1.Text := Label4.Caption; end; procedure TForm1.Button3Click(Sender: TObject); begin u1 := false; Label3.Caption := ''; end; procedure TForm1.Button4Click(Sender: TObject); begin u2 := false; Label4.Caption := ''; end; procedure TForm1.Button7Click(Sender: TObject); begin L := 1; RadioGroup1.Caption := ''; if not rg1 then begin Form1.RadioGroup1.Items.Add('Ðóññêèé'); Form1.RadioGroup1.Items.Add('English'); rg1 := true; end; Form1.Canvas.Rectangle(5, 75, 510, 37); end; procedure TForm1.Exit1Click(Sender: TObject); begin halt; end; end. Программа, рисующая графики функций: unit grafics_fail; interface 21 uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math; const eps = 0.00000001; const dotes = 8000; type Temas = array[1..10000] of extended; type Tdmas = array[1..10000] of integer; type Wh = record str: string; oth: Temas; end; type Wfail = record x: extended; fail: boolean; end; type TForm1 = class(TForm) Edit1: TEdit; Label1: TLabel; Edit2: TEdit; Label2: TLabel; Edit3: TEdit; Edit4: TEdit; Label3: TLabel; Label4: TLabel; CheckBox1: TCheckBox; Edit5: TEdit; Button1: TButton; Label6: TLabel; Label7: TLabel; ListBox1: TListBox; Label5: TLabel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; hait_of_form, hait, wid: longint; implementation procedure set_constants; begin hait_of_form := 800; 22 wid := 690; hait := 690; end; procedure draw_osi; var x, y, m: longint; h, xmin1, ymin1, xmin, ymin, xmax, ymax: longint; size: longint; s: string; begin Form1.Canvas.MoveTo(3, hait_of_form - 3); Form1.Canvas.LineTo(712, hait_of_form - 3); Form1.Canvas.LineTo(712, hait_of_form - 11 - hait); Form1.Canvas.LineTo(3, hait_of_form - 11 - hait); Form1.Canvas.LineTo(3, hait_of_form - 3); Form1.Canvas.MoveTo(5, hait_of_form - 5); Form1.Canvas.LineTo(710, hait_of_form - 5); Form1.Canvas.LineTo(710, hait_of_form - 9 - hait); Form1.Canvas.LineTo(5, hait_of_form - 9 - hait); Form1.Canvas.LineTo(5, hait_of_form - 5); xmin := strtoint(Form1.Edit1.text); xmax := strtoint(Form1.Edit2.text); ymin := strtoint(Form1.Edit3.text); ymax := strtoint(Form1.Edit4.text); if xmin * xmax < 0 then begin xmin1 := -xmin; x := round(wid * xmin1 / (xmin1 + xmax)); Form1.Canvas.MoveTo(x + 10, hait_of_form - 10); Form1.Canvas.LineTo(x + 10, Hait_of_form - hait); Form1.Canvas.LineTo(x + 8, hait_of_form - hait + 6); Form1.Canvas.LineTo(x + 12, Hait_of_form - hait + 6); Form1.Canvas.LineTo(x + 10, Hait_of_form - hait); end; if ymin * ymax < 0 then begin ymin1 := -ymin; y := round(hait_of_form - hait * ymin1 / (ymin1 + ymax)); Form1.Canvas.MoveTo(10, y); Form1.Canvas.LineTo(wid, y); Form1.Canvas.LineTo(wid - 6, y + 2); Form1.Canvas.LineTo(wid - 6, y - 2); Form1.Canvas.LineTo(wid, y); end; Form1.Canvas.TextOut(x - 5, hait_of_form - hait - 5, 'Y'); Form1.Canvas.TextOut(wid - 5, y + 8, 'X'); Form1.Canvas.TextOut(x - 5, y + 8, '0'); size := 1; m := x + round(wid / (xmax - xmin) * size); str(size, s); Form1.Canvas.TextOut(m + 5, y + 8, s); Form1.Canvas.MoveTo(m + 10, y + 3); Form1.Canvas.LineTo(m + 10, y - 3); size := 1; m := y - round(hait / (ymax - ymin) * size); Form1.Canvas.TextOut(x - 5, m, s); Form1.Canvas.MoveTo(x + 13, m); Form1.Canvas.LineTo(x + 7, m); end; function tan(x: extended): extended; begin tan := sin(x) / cos(x); end; 23 function find_close(var s: string; num: integer): integer; var i, k: integer; begin k := 1; i := num; while k <> 0 do begin inc(i); if s[i] = '(' then inc(k); if s[i] = ')' then dec(k); end; find_close := i; end; function end_of_sin(var s: string; n: integer): integer; var i: integer; begin if s[n + 3] = '2' then end_of_sin := find_close(s, n + 4) else end_of_sin := find_close(s, n + 3); end; procedure prepare(var s: string); var l, r, i: integer; begin for i := 1 to length(s) do begin if s[i] in ['s', 'c', 't'] then begin r := end_of_sin(s, i); if s[i + 3] = '2' then l := 4 else l := 3; delete(s, i + 1, l); if (l = 3) and (s[i] = 's') then begin s[i] := '@'; s[r - l] := '#'; end; if (l = 3) and (s[i] = 'c') then begin s[i] := '$'; s[r - l] := '%'; end; if (l = 3) and (s[i] = 't') then begin s[i] := '&'; s[r - l] := '?'; end; if (l = 4) and (s[i] = 's') then begin s[i] := '"'; s[r - l] := ';'; end; if (l = 4) and (s[i] = 'c') then begin s[i] := ':'; s[r - l] := '\'; end; if (l = 4) and (s[i] = 't') then begin s[i] := '`'; s[r - l] := '~'; end; end; if s[i] = '|' then if (i = 1) or (s[i - 1] in ['+', '-', '*', '/', '^', '!', '<', '[', '{', '(', '@', '$', '&', '"', ':', '`']) then s[i] := '!'; end; end; function sk(ch: char): boolean; begin if ch in ['<', '>', '(', ')', '[', ']', '{', '}', '|', '!', '@', '#', '$', '%', '&', '?', '"', ';', ':', '\', '`', '~'] then sk := true else sk := false; end; function count_in_skoba(var sk: char; n: extended): extended; var rez: extended; begin rez := 0; if sk in ['<', '>'] then if n + eps > 0 then rez := sqrt(n) else rez := -1; if sk in ['[', ']'] then rez := trunc(n); if sk in ['{', '}'] then rez := n - trunc(n); if sk in ['(', ')'] then rez := n; if sk in ['|', '!'] then rez := abs(n); 24 if sk in ['@', '#'] then rez := sin(n); if sk in ['$', '%'] then rez := cos(n); if sk in ['&', '?'] then rez := tan(n); if sk in ['"', ';'] then rez := sin(n) * sin(n); if sk in [':', '\'] then rez := cos(n) * cos(n); if sk in ['`', '~'] then rez := tan(n) * tan(n); count_in_skoba := rez; end; function pr(ch: char): integer; begin if ch in ['+', '-'] then pr := 2 else if ch in ['*', '/'] then pr := 3 else if ch = '^' then pr := 4 else if sk(ch) then pr := 1 else pr := -1; end; function checkoz(var o, z: char): boolean; begin if ((o = '!') and (z = '|')) or ((o = '{') and (z = '}')) or ((o = '[') and (z = ']')) or ((o = '(') and (z = ')')) or ((o = '<') and (z = '>')) or ((o = '@') and (z = '#')) or ((o = '$') and (z = '%')) or ((o = '&') and (z = '?')) or ((o = '"') and (z = ';')) or ((o = ':') and (z = '\')) or ((o = '`') and (z = '~')) then checkoz := true else checkoz := false; end; function make_string(var s: string; l, r: integer): string; var k: string; i: integer; begin k := ''; for i := l to r do k := k + s[i]; make_string := k; end; function mins(var s: string; i: integer): boolean; begin if s[i] <> '-' then mins := false else begin if i = 1 then mins := true else begin if s[i - 1] = '(' then mins := true else mins := false; end; end; end; function make(var s: string; x: extended): Wh; var j, i, kol, cot: integer; q: string; w: extended; n: Temas; k: string; minus: longint; begin kol := 0; k := ''; fillchar(n, sizeof(n), 0); i := 1; while i <= length(s) do begin if (pr(s[i]) > 0) or (s[i] in ['s', 'c', 't']) then begin if s[i] in ['s', 'c', 't'] then begin k := k + make_string(s, i, end_of_sin(s, i)); i := end_of_sin(s, i); 25 end else k := k + s[i]; end; inc(i); end; i := 1; kol := 0; while i <= length(s) do begin q := 'z'; while pr(s[i]) > 0 do inc(i); if s[i] in ['s', 'c', 't'] then begin i := end_of_sin(s, i); inc(kol); end; minus := 1;//if mins(s, i - 1) then minus := -1 else minus := 1; while (i <= length(s)) and ((pr(s[i]) < 0) or ((q[1] in ['s', 'c', 't']) and (not sk(s[i])))) do begin if q = 'z' then q := ''; q := q + s[i]; inc(i); end; val(q, w, cot); if cot = 0 then begin inc(kol); n[kol] := w * minus; end; if q = 'x' then begin inc(kol); n[kol] := x * minus; end; if (q = 'pi') or (q = 'p') then begin inc(kol); n[kol] := pi * minus; end; if q = 'e' then begin inc(kol); n[kol] := 2.71828182846 * minus; end; inc(i); if i <= length(s) then end; kol := 0; {for i := 1 to length(k) do begin if not sk(k[i]) then inc(kol); if k[i] = '-' then begin j := i + 1; if pr(k[j]) = 2 then begin k[i] := '+'; n[kol + 1] := -n[kol + 1]; end; end; end; } kol := 0; for i := 1 to length(k) do begin if not sk(k[i]) then inc(kol); if k[i] = '/' then begin j := i + 1; if pr(k[j]) = 3 then begin k[i] := '*'; if n[kol + 1] <> 0 then n[kol + 1] := 1 / n[kol + 1]; end; end; end; make.str := k; make.oth := n; end; function op(var s: string; n: integer): boolean; begin if s[n] in ['(', '{', '[', '<', '!', '@', '$', '&', '"', ':', '`'] then op := true else op := false; end; function cl(var s: string; n: integer): boolean; begin if s[n] in [']', '}', ')', '>', '|', '#', '%', '?', ';', '\', '~'] then cl := true else cl := false; 26 end; function krut(var s: string; n: integer): boolean; var f, w: boolean; begin f := false; w := false; if (n = 1) or ((not cl(s, n - 1)) and (pr(s[n]) >= pr(s[n - 1]))) then f := true; if(n = length(s)) or ((not op(s, n + 1)) and (pr(s[n]) >= pr(s[n + 1]))) then w := true; if (f) and (w) then krut := true else krut := false; end; function operation(var ch: char; a, b: extended; err: integer): WFail; var st: longint; ans: WFail; begin if err = 0 then begin if ch = '+' then b := a + b; if ch = '-' then b := a - b; if ch = '*' then b := a * b; if ch = '^' then begin if (a < 0) and (abs(b - round(b)) < eps) then begin st := round(b); if st mod 2 = 0 then b := power(-a, b) else b := -power(-a, b); end else if ((a = 0) and (b = 0)) or (a < 0) then err := 1 else b := power(a, b); end; if ch = '/' then if abs(b) < eps then err := 1 else b := a / b; end else b := 0; ans.x := b; if err = 1 then ans.fail := true else ans.fail := false; operation := ans; end; procedure ydal(var k: string; u: Tdmas); var s: string; i: integer; begin s := ''; for i := 1 to length(k) do if u[i] <> 100500 then s := s + k[i]; k := s; end; function get_value(var s: string; x: extended): WFail; var n: Temas; u, uk: Tdmas; k, t: string; y, q, kl, l, r, i, j, kol, err, op: integer; rez, m: extended; yd, fail: boolean; wth: Wh; b, ans: Wfail; daleko: longint; 27 begin err := 0; prepare(s); wth := make(s, x); k := wth.str; n := wth.oth; i := 1; kol := 0; err := 0; for i := 1 to length(k) do u[i] := 0; fail := false; while not fail do begin kol := 0; fillchar(u, sizeof(u), 0); fillchar(uk, sizeof(uk), 0); op := 0; i := 1; while i <= length(k) do begin yd := false; if not sk(k[i]) then inc(kol); if (i <> 1) and (checkoz(k[i - 1], k[i])) then begin n[kol + 1] := count_in_skoba(k[i], n[kol + 1]); if (k[i] in ['<', '>']) and (n[kol + 1] < 0) then err := 1; delete(k, i - 1, 2); i := i - 2; yd := true; end; if (not yd) and (length(k) > 0) and (not sk(k[i])) and (krut(k, i)) then begin ans := operation(k[i], n[kol], n[kol + 1], err); n[kol + 1] := ans.x; if ans.fail then err := 1; u[kol] := 1; uk[i] := 100500; inc(op); if err = 1 then fail := true; end; inc(i); end; kl := 0; i := 1; q := 1; while q <= length(k) + 1 do begin while u[q] = 1 do inc(q); n[i] := n[q]; inc(i); inc(q); end; ydal(k, uk); kol := 0; for i := 1 to length(k) do begin if not sk(k[i]) then inc(kol); if k[i] = '-' then begin j := i + 1; if pr(k[j]) = 2 then begin k[i] := '+'; n[kol + 1] := -n[kol + 1]; end; end; end; kol := 0; for i := 1 to length(k) do begin 28 if not sk(k[i]) then inc(kol); if k[i] = '/' then begin j := i + 1; if pr(k[j]) = 3 then begin k[i] := '*'; if n[kol + 1] = 0 then begin fail := true; err := 1; break; end else n[kol + 1] := 1 / n[kol + 1]; end; end; end; if length(k) = 0 then fail := true; end; if err = 0 then fail := false; if err = 1 then fail := true; get_value.x := n[1]; get_value.fail := fail; end; procedure get_reed_of_minus(var s: string); var i: longint; begin i := 1; while i <= length(s) do begin if (s[i] = '-') and ((i = 1) or (s[i - 1] = '(')) then insert('0', s, i); inc(i); end; end; procedure final(); var i, code: integer; s: string; xprz, yprz, yd, x0, ypr, ylast, xd, xpr, x, y, xl, xh, yl, yh: extended; mid, ylst, ycan: Wfail; prev: boolean; begin if Form1.CheckBox1.State = cbUnchecked then Form1.refresh; s := Form1.Edit1.text; val(s, xl, code); s := Form1.Edit2.text; val(s, xh, code); s := Form1.Edit3.text; val(s, yl, code); s := Form1.Edit4.text; val(s, yh, code); s := Form1.Edit5.text; get_reed_of_minus(s); x := xl; prev := false; for i := 1 to dotes do begin x := x + ((xh - xl) / (dotes - 1)); ycan := get_value(s, x); y := ycan.x; if x > -15 then x := x; if (not ycan.fail) and (y - yl + eps > 0) and (yh - y + eps > 0) then begin xd := wid * ((x - xl) / (xh - xl)); yd := hait_of_form - hait * ((y - yl) / (yh - yl)); if prev then 29 begin mid := get_value(s, (x + xpr) / 2); if (not mid.fail) and ((mid.x - y) * (mid.x - ypr) < eps) then begin Form1.Canvas.MoveTo(round(xprz) + 10, round(yprz)); Form1.Canvas.LineTo(round(xd) + 10, round(yd)); end; end; prev := true; xpr := x; ypr := y; xprz := xd; yprz := yd; end else prev := false; end; end; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin set_constants; final; draw_osi; end; procedure TForm1.Button2Click(Sender: TObject); begin Form1.ListBox1.Items.Add('Тригонометрические функции записываются:'); Form1.ListBox1.Items.Add('sin(), cos(), tan(), sin2(), cos2(), tan2().'); Form1.ListBox1.Items.Add('Квадратный корень - <...>.'); Form1.ListBox1.Items.Add('Выражение, из которого извлекается'); Form1.ListBox1.Items.Add('квадратный корень должно быть'); Form1.ListBox1.Items.Add('записано в следующих скобках: < и >.'); Form1.ListBox1.Items.Add('Например, корень и х должен быть'); Form1.ListBox1.Items.Add('записан, как <x>.'); Form1.ListBox1.Items.Add('Программа умеет работать с функциями'); Form1.ListBox1.Items.Add('модуля - |x|, целой части - [x] и'); Form1.ListBox1.Items.Add('дробной части - {x}.'); Form1.ListBox1.Items.Add('Пожалуйста, записывайте функции правильно,'); form1.ListBox1.Items.Add('иначе вылезет ошибка.'); end; end. 30