Разработка программного комплекса для SEO-аналитики и оптимизации веб-приложений

Описание приложения в виде пользовательского сценария. Проектирование обмена сообщениями между модулями. Разработка общей структуры приложения. Обзор структуры файлов. Разработка получения данных со страницы. Характеристика результата работы программы.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 22.03.2018
Размер файла 1,5 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

JavaScript обычно используется как встраиваемый язык для программного доступа к объектам приложений. Наиболее широкое применение находит в браузерах как язык сценариев для придания интерактивности веб-страницам. [11]

Основные архитектурные черты:

динамическая типизация;

слабая типизация;

автоматическое управление памятью;

прототипное программирование;

функции как объекты первого класса.

Синтаксис языка JavaScript во многом напоминает синтаксис Си и Java, семантически же язык гораздо ближе к Self, Smalltalk или Лиспу.

В JavaScript:

язык является регистрозависимым;

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

названия переменных не могут начинаться с цифры;

для оформления однострочных комментариев используются //, многострочные и внутристрочные комментарии начинаются с /* и заканчиваются */.

Структурно JavaScript можно представить в виде объединения трёх чётко различимых друг от друга частей:

ядро (ECMAScript);

объектная модель браузера (Browser Object Model или BOM (en));

объектная модель документа (Document Object Model или DOM).

Область применения JavaScript:

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

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

Comet -- понятие, описывающее механизм работы веб-приложений, использующих постоянные HTTP-соединения, это позволяет отправлять данные с сервера на браузер без запроса от браузера.

Браузерные операционные системы

Букмарклеты. JavaScript используется для создания небольших программ, размещаемых в закладки браузера.

Пользовательские скрипты в браузере --программы, написанные на JavaScript, выполняемые в браузере пользователя при загрузке страницы.

Серверные приложения

Мобильные приложения.

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

Прикладное программное обеспечение.

2.4 Проектирование обмена сообщениями между модулями

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

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

Рисунок 2.7 -- Схема обмена сообщения модулей popup и background

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

После получения параметров расширения модулю popup необходимо получить данные со страницы. Для этого необходим обмен сообщениями с модулем content. Модуль popup отправляет сообщение модулю content. Затем модуль content получает данные со страницы, преобразует их и отправляет данные модулю popup.

Схема обмена сообщениями между модулями popup и content представлена на рисунке 2.8.

Рисунок 2.8 -- Схема обмена сообщения модулей popup и content

2.5 Проектирование проверки SEO-правил

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

В данной системе предусмотрено два основных действия пользователя:

Открытие расширения

Ввод ключевой фразы

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

2.5.1 Проверки при открытии расширения

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

Проверка пересечения заголовка и описания. Данная проверка определяет наличие заголовка в описании.

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

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

Схема вышеописанного события и правил представлена на рисунке 2.9.

Рисунок 2.9 -- Схема обработки события «Открыть расширение»

2.5.2 Проверки при вводе ключевой фразы

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

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

Проверка заспамленности текста. В данной проверке подчитывается количество вхождений ключевой фразы в текст.

Схема вышеописанного события и правил представлена на рисунке 2.10.

Рисунок 2.10 -- Схема обработки события «Ввод ключевого слова»

2.6 Проектирование проверки правописания

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

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

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

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

Сервис в настоящее время поддерживает три языка:

русский - словарь содержит 3.6 миллиона словоформ (разработка компании «Информатик»);

украинский - словарь содержит 1.8 миллиона словоформ (разработка компании «Информатик»);

английский - словарь содержит 150000 словоформ (разработка компании «Яндекс»).

Web Service API включает в себя два метода, которые позволяют проверять правописание в одном или нескольких фрагментах текстов:

Метод checkText. Проверяет орфографию в указанном отрывке текста. В XML-интерфейсе возвращает ответ в виде XML-документа с корневым элементом SpellResult.

Входные параметры могут передаваться либо с помощью запроса HTTP GET, либо с помощью HTTP POST. Во втором случае параметры передаются в теле запроса.

В XML-интерфейсе возвращает ответ в виде XML-документа с корневым элементом SpellResult.

В JSON-интерфейсе вместо XML-элементов возвращаются JavaScript-объекты с теми же именами и семантикой:

В JSONP-интерфейсе те же самые JavaScript-объекты возвращаются в callback-функции (например, myCallback).

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

Входные параметры могут передаваться либо с помощью HTTP GET-запроса, либо с помощью HTTP POST-запроса, где параметры передаются в body HTTP-запроса.

В XML-интерфейсе возвращает элемент ArrayOfSpellResult, содержащий последовательность элементов SpellResult по одному для каждого фрагмента текста.

В JSON-интерфейсе вместо XML-элементов возвращаются JavaScript-объекты с теми же именами и семантикой:

В JSONP-интерфейсе те же самые JavaScript-объекты возвращаются в callback-функции (например, myCallback). [12]

Класс Speller позволяет запустить проверку правописания, показать диалог настроек Яндекс.Спеллера, а также содержит средства для управления параметрами сервиса.

Методы класса:

Check (ctrls). Показывает диалоговое окно «Проверка правописания» и начинает проверять правописание в указанных полях.

OptionsDialog(). Показывает диалоговое окно «Параметры», в котором пользователь может выбрать язык словаря и изменить настройки Яндекс.Спеллера.

2.7 Проектирование модуля для склонения существительных

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

Так как метаданные составляются не только для роботов, но и для пользователей, то они должны нести смысловую нагрузку и быть правильно составлены грамматически. Именно поэтому склонять слова в ключевых словах необходимо. Так как в разрабатываемом программном обеспечении производится аналитика метаданных с точки зрения ключевых слов и происходит поиск «ключевиков» в title и description, то необходимо реализовать модуль для склонения существительных.

Например, для материала про Александра Пушкина, title будет следующим: «Александр Пушкин: биография, произведения поэта», description: «Читать о жизни и творчестве Александра Пушкина. …»

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

2.8 Проектирование пользовательского интерфейса

Интерфейс расширения должен органично вписываться в интерфейс самого браузера, поэтому было принято решения использовать паттерн пользовательского интерфейса material design, разработанный компанией Google.

Material Design (рус. Материальный дизайн) -- дизайн программного обеспечения и приложений операционной системы Android от компании Google.

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

Для реализации данного паттерна был найден фреймворк пользовательского интерфейса materialize.css. Данный фреймворк предоставляет различные компоненты.

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

Выводы

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

3. Разработка программного обеспечения

3.1 Разработка общей структуры приложения

3.1.1 Файл manifest.json

Основополагающей частью любого расширения для Google Chrome является файл manifest.json. Ниже приведены некоторые поля этого файла в данном проекте с описанием значения.

"content_scripts": [{

"matches": ["http://*/*", "https://*/*"],

"js": ["content.js"],

"run_at": "document_end"

}]

Данное поле описывает Content модуль и состоит из нескольких подполей:

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

Поле js указывает все файлы, которые требуется встроить в проверяемую страницу, в данном случае это файл модуля content.

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

"options_page": "options/options.html"

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

"browser_action": {

"default_icon": "icon.png",

"default_popup": "popup/popup.html"

}

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

"background": {

"scripts": ["background.js"],

"persistent": false

}

Данное поле описывает background модуль. В данное случае в поле scripts указывается путь к файлу, описывающей этот модуль. В поле persistent находится булевое значение false, указывающее на то, что данный модуль использует разновидность background модуля - event page.

"permissions": [

"tabs",

"storage"

]

Это поле описывает разрешения, которые требуются для работы расширения. Данному проекту необходимы 2 разрешения:

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

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

3.1.2 Структура файлов

Была выбрана классическая структура файлов, где каждый модуль представляет либо один файл, либо папку с набором различных файлов. Так же была выделена отдельная папка lib, в которой хранятся сторонние вспомогательные модули. На рисунке 3.1 представлен скриншот структуры файлов в текстовом редакторе.

Рисунок 3.1 -- Структура файлов проекта

3.2 Разработка обмена сообщениями между модулями

В данном проекте реализовано два немного различающихся способа коммуникации между модулями из-за их специфики. Оба способа используют Chrome API.

3.2.1 Разработка обмена сообщениями между модулями background и popup

Для реализации этой коммуникации используются модуль Chrome API chrome.runtime, его метод runtime.sendMessage и событие runtime.onMessage.

Функции модуля chrome.runtime:

получение background page

получение данных из manifest.json

обработка и ответ на события приложения или жизненного цикла расширения

конвертации относительного URL в абсолютный

Метод sendMessage предназначен для отправки одиночного сообщения обработчикам событий внутри или вне расширения. Параметры метода sendMessage:

extensionId: уникальный ID расширения, к которому посылается сообщение. Если не указан, сообщение посылается текущему расширению.

message: отправляемое сообщение. Сообщение обязано быть объектом, который можно привести в json-формат.

options: объект параметров.

responseCallback: функция, которая вызовется после ответа на отправляемое сообщение.

Событие onMessage появляется, когда вызывается функция sendMessage. Событие onMessage предоставляет функцию addListener, которая позволяет добавить обработчик каких-либо событий. [13]

Ниже представлены примеры добавления обработчика событий, отправления событий и ответа на него.

chrome.runtime.onMessage.addListener(

function(message, sender, sendResponse) {

if (message.initializing) {

sendResponse(options);

return true;

}

}

);

chrome.runtime.sendMessage(

{initializing: true},

function(initOptions) {

options = initOptions;

}

);

3.2.2 Разработка обмена сообщениями между модулями content и popup

Пользователь браузера имеет возможность открыть множество вкладок одновременно. Из этого вытекает отличие обмена сообщениями между модулями content и popup от вышеописанного способа. Так как модуль content запускается в каждой вкладке браузера модулю popup необходимо:

во-первых, найти открытую вкладку в активном окне браузера.

во-вторых, отправить сообщение и получить ответ именно от данной вкладки.

Для реализации такого поведения используется модуль Chrome API под названием chrome.tabs. Именно для использования данного модуля в разрешения файла manifest.json было добавлено значение tabs.

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

Метод tabs.query предназначен для получения всех вкладок браузера, удовлетворяющим определенным условиям задаваемым пользователем данного метода. Данная функция принимает два параметра на вход:

query - объект, описывающий характеристики вкладки с помощью таких полей, как active (активная вкладка), currentWindow (актиное окно браузера), title (поиск по заголовку страницы) и многие другие параметры.

callback - функция, которая вызовется по завершению поиска и получит искомые вкладки на вход.

Метода tabs.sendMessage очень похоже на аналогичный метод у модуля chrome.runtime, за исключением того, что данный метод принимает на вход уникальный ID вкладки вместо ID расширения и отправляет сообщение именно указанной вкладке. [14]

Пример поиска активной вкладки в текущем окне браузера, отправки ей сообщения и получения ответа представлен ниже.

chrome.tabs.query({

active: true,

currentWindow: true

}, function (tabs) {

chrome.tabs.sendMessage(

tabs[0].id,

{from: 'popup', action: 'getData'},

function(contentData) {

….

}

);

});

3.3 Разработка получения данных со страницы

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

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

querySelectorAll. Этот метод осуществляет поиск элементов по указанному селектору. В данном проекте используется для нахождения элемента описания страницы по селектору «meta[name="description"]».

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

getAttribute. Данный метой возвращает значение указанного атрибута элемента. Используется для получения значения описания страницы, так как это значение хранится в атрибуте content элемента заголовка.

3.4 Использование регулярных выражений

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

Регулярные выражения -- формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов. Для поиска используется строка-образец, состоящая из символов и метасимволов и задающая правило поиска. Для манипуляций с текстом дополнительно задаётся строка замены, которая также может содержать в себе специальные символы.

Регулярные выражения в JavaScript являются объектами класса RegExp. Кроме того, методы для поиска по регулярным выражениям встроены прямо в обычные строки String, например, методы match (возвращает результаты сопоставления строки и регулярного выражения) и replace (заменяет найденные регулярным выражением подстроки указанной строкой).

Конструктор RegExp создает объект регулярного выражения для сопоставления текста с шаблоном.

Свойства объекта RegExp:

RegExp.prototype.constructor. Определяет функцию, создающую прототип объекта.

RegExp.prototype.global. Определяет, нужно ли проверять регулярное выражение на возможные сопоставления со строкой, или же достаточно одной проверки.

RegExp.prototype.ignoreCase. Определяет, важен ли регистр символов при сопоставлении со строкой.

RegExp.prototype.lastIndex. Индекс, по которому начинается следующее сопоставление.

RegExp.prototype.multiline. Определяет, нужно ли искать по нескольким строкам.

RegExp.prototype.source. Текст шаблона.

RegExp.prototype.sticky. Определяет, включён ли режим «липкого» поиска.

RegExp.prototype.flags. Строка, состоящая из флагов объекта регулярного выражения.

Методы:

RegExp.prototype.exec(). Выполняет поиск сопоставлений регулярного выражения в своем строковом параметре.

RegExp.prototype.test(). Пытается сопоставить регулярное выражение своему строковому параметру.

RegExp.prototype.toSource(). Возвращает объектный литерал, представляющий указанный объект; это значение можно использовать для создания нового объекта. Переопределяет метод Object.prototype.toSource().

RegExp.prototype.toString(). Возвращает строку, представляющую указанный объект. Переопределяет метод Object.prototype.toString().

Так как поиск ключевого слова в какой-либо строке частая операция в данном программном обеспечении, то была написана функция getWordRegExp, составляющая объект класса RegExp по ключевому слову и набору параметров. Формат получаемого регулярного выражения выглядит так: «[ключевое слово в именительном падеже]|[ключевое слово в родительном падеже]|…». Блок-схема алгоритма данной функции представлен на рисунке 3.2.

3.5 Разработка проверки правописания

Для обращения к сторонним сервисам была использована технология AJAX.

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

Рисунок 3.2 -- Блок-схема алгоритма получения регулярного выражения

Под AJAX подразумевают любое общение с сервером без перезагрузки страницы, организованное при помощи JavaScript.

При использовании AJAX:

Пользователь заходит на веб-страницу и нажимает на какой-нибудь её элемент.

Скрипт (на языке JavaScript) определяет, какая информация необходима для обновления страницы.

Браузер отправляет соответствующий запрос на сервер.

Сервер возвращает только ту часть документа, на которую пришёл запрос.

Скрипт вносит изменения с учетом полученной информации (без полной перезагрузки страницы).

Для проверки правописания программное обеспечение обращается по адресу «http://speller.yandex.net/services/spellservice.json/checkText» с методом POST и параметрами text и options. Параметр options получается суммой чисел 1, 2, 4, 8 и 512. Возможные слагаемые параметра options представлена в таблице 3.1.

Таблица 3.1 - Возможные опции метода checkText

Опция

Значение

Описание (пример)

IGNORE_UPPERCASE

1

Пропускать слова, написанные заглавными буквами, например, "ВПК".

IGNORE_DIGITS

2

Пропускать слова с цифрами, например, "авп17х4534".

IGNORE_URLS

4

Пропускать интернет-адреса, почтовые адреса и имена файлов.

FIND_REPEAT_

WORDS

8

Подсвечивать повторы слов, идущие подряд. Например, "я полетел на на Кипр".

IGNORE_LATIN

16

Пропускать слова, написанные латиницей, например, "madrid".

NO_SUGGEST

32

Только проверять текст, не выдавая вариантов для замены.

FLAG_LATIN

128

Отмечать слова, написанные латиницей, как ошибочные.

BY_WORDS

256

Не использовать словарное окружение (контекст) при проверке. Опция полезна в случаях, когда на вход сервиса передается список отдельных слов.

IGNORE_

CAPITALIZATION

512

Игнорировать неверное употребление ПРОПИСНЫХ/строчных букв, например, в слове "москва".

IGNORE_ROMAN_NUMERALS

2048

Игнорировать римские цифры ("I, II, III, ...").

Отдельного внимания заслуживает проверка правописания текста самой страницы. Блок-схема алгоритма проверки текста страницы на ошибки представлена на рисунке 3.3.

Рисунок 3.3 -Алгоритм проверки текста страницы на орфографию

Так как максимальное количество символов, проверяемых сервисом Yandex Speller за один запрос, является 10000, а количество символов на странице может быть намного больше данного значения, то необходимо разбить весь текст страницы на части не более 10000 символов.

Так как сервис Yandex Speller проверяет не только орфографические, но и простые лексические ошибки, то было бы неправильно просто разбить весь текст на части по 10000 символов. Для решения данной проблемы текст разбивается на предложения с помощью регулярного выражения «/\(?[^\.\?\!]+[\.!\?]\)?/g». Затем предложения конкатенируются в части по 10000 или менее символов.

3.6 Разработка проверки заспамленности

Данный модуль проверяет, что расстояние между ключевыми словами в тексте не менее определенной величины. Блок-схема данного алгоритма представлена на рисунке 3.4.

3.7 Разработка пользовательского интерфейса

Для упрощения взаимодействия и изменения страницы в проекте используется библиотека jQuery.

jQuery -- библиотека JavaScript, фокусирующаяся на взаимодействии JavaScript и HTML. Библиотека jQuery помогает легко получать доступ к любому элементу DOM, обращаться к атрибутам и содержимому элементов DOM, манипулировать ими. Также библиотека jQuery предоставляет удобный API для работы с AJAX. [15]

JQuery отделяет поведение от структуры HTML. Например, вместо прямого указания на обработчик события нажатия кнопки, управление передаётся JQuery, которая идентифицирует кнопки и затем преобразует его в обработчик события клика.

Библиотека jQuery содержит функциональность, полезную для максимально широкого круга задач. Тем не менее, разработчиками библиотеки не ставилась задача совмещения в jQuery функций, которые подошли бы всюду, поскольку это привело бы к большому коду, большая часть которого не востребована. Поэтому была реализована архитектура компактного универсального ядра библиотеки и плагинов[16]. Это позволяет собрать для ресурса именно ту JavaScript-функциональность, которая на нём была бы востребована.

Рисунок 3.4 - Алгоритма проверки текста страницы на заспамленность

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

Работу с jQuery можно разделить на 2 типа:

Получение jQuery-объекта с помощью функции $().

Вызов глобальных методов у объекта $.

Методы, начинающиеся с $., удобно применять для обработки глобальных объектов. $.ajax и соответствующие функции позволяют использовать методы AJAX.

В данном проекте используются следующие классы из materialize.css:

Col, row, s5, s2 - предназначены для базовой разметки страницы, разбивки ее на колонки

Red-text, blue-text - предназначены для окраса текста в определенный цвет

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

Рисунок 3.5 - пример Tooltipped

input-field - используется для стилизации поля ввода и его текстового обозначения

btn, waves-effect, waves-light - предназначен для стилизации кнопки и добавления ей эффекта волны

collapsible, collapsible-body, collapsible-header - в сочетании с jQuery плагином представляют собой раскрывающийся при клике список элементов

hide - используется для скрытия любого элемента страницы

badge - предназначены для оповещения пользователя о каком-то количественном показателе. В случае данного программного обеспечения используется для вывода количества символов в метаданных.

material-icons - используются для установления различных иконок на странице

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

Рисунок 3.6 - Внешний вид расширения

Для отрисовки метаданных используется функция renderText. Ее алгоритм представлен на рисунке 3.7.

Рисунок 3.7 - Алгоритм отрисовки метаданных

3.8 Разработка страницы настроек

Данная страница в своем интерфейсе использует только поля ввода и кнопки, стилизованные с помощью классов materialize.css. При этом поля ввода имею тип number. Это сделано для того, чтобы пользователь мог ввести только числа. Интерфейс страницы настроек представлен на рисунке 3.8.

Рисунок 3.8 -- Интерфейс страницы настроек

3.9 Результат работы программы

После выполнения программы, пользователю представляется отчет по основным SEO-характеристикам проверяемой страницы:

текст title и количество символов в нем;

текст description и количество символов в нем;

количество ключевых слов в title и description;

положение ключевых слов в title и description;

заспамленность в процентах;

грамматические ошибки -- перечисление слов, в которых присутствуют ошибки.

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

если количество символов в title менее 65 символов -- результат будет выделен зеленым цветом (положительный результат), если более 65 -- красным (отрицательный результат, который необходимо исправить);

если количество символов в description менее 165 символов -- результат будет выделен зеленым цветом, если более 65 -- красным;

если количество ключевых слов в title больше двух -- результат выделяется красным, иначе -- зеленым;

если количество ключевых слов в description больше трех -- результат выделяется красным, иначе -- зеленым;

eсли ключевое слово в title находится от его начала на расстоянии более 30 символов -- результат выделяется красным, иначе -- зеленым;

если ключевое слово в description находится от его начала на расстоянии более 70 символов -- результат выделяется красным, иначе -- зеленым;

если между ключевыми словами менее 400 символов -- выделяется красным цветом, иначе -- зеленым.

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

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

Кроме того, пользователю предоставляются рекомендации по улучшению SEO-показателей страницы. А именно, нужно ли уменьшить количество символов в title и description, уменьшить ли количество заимствований из сторонних ресурсов и количество вхождений ключевых фраз в текст.

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

Выводы

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

Заключение

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

Данное программное обеспечение применяется в работе SEO-аналитика и оптимизатора портала «Культура.РФ».

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

В ходе реализации системы были изучены способы создания расширений для браузера Google Chrome.

Изучены различные подходы для веб-программирования.

Список литературы

1. Ранжирование сайта. Внешние и внутренние факторы [Электронный ресурс]: PR-CY. - Режим доступа: http://pr-cy.ru/lib/seo/Ranzhirovanie-sayta-Vneshnie-i-vnutrennie-faktory (свободный доступ).

2. Индексирование сайтов роботами [Электронный ресурс]: Яндекс Помощь. - Режим доступа: https://yandex.ru/support/webmaster/robot-workings/robot.html (свободный доступ).

3. Что такое органический трафик [Электронный ресурс]: Stijit. - Режим доступа: http://www.stijit.com/sem-seo/organic-traffic (свободный доступ).

4. Пестерев П.В. Анализ нововведений в алгоритмах поисковых систем Yandex и Google // Вестник Белгородского государственного технологического университета им. В. Г. Шухова. 2017. № 3. С. 145-148. (свободный доступ).

5. Сравнение двух текстов на схожесть [Электронный ресурс]: Онлайн сервисы для досуга и работы. - Режим доступа: http://onlinevsem.ru/web/sravnenie-dvux-tekstov-na-sxozhest.htm (свободный доступ).

6. Онлайн-сервис проверки текста на уникальность [Электронный ресурс]: Text.ru. - Режим доступа: https://text.ru/ (свободный доступ).

7. Полный семантический анализ текста онлайн (seo-анализ) [Электронный ресурс]: Миратекст. - Режим доступа: https://miratext.ru/seo_analiz_text (свободный доступ).

8. Адвего: биржа контента № 1 [Электронный ресурс]: Advego. - Режим доступа: https://advego.ru/ (свободный доступ).

9. Сервис для семантического анализа текстов [Электронный ресурс]: Istio.com. - Режим доступа: https://istio.com/rus/text/analyz/#top (свободный доступ).

10. Руководство разработчика [Электронный ресурс]: Яндекс.Спеллер. - Режим доступа: https://tech.yandex.ru/speller/doc/dg/reference/interesting-solutions-docpage/ (свободный доступ).

11. Флэнаган Д. JavaScript. Карманный справочник. Сделайте веб-страницы интерактивными! / Перевод А.Г. Сысонюк. -- Москва.: Издательский дом «Вильямс», 2015. -- С. 320. -- 1000 экз. -- ISBN 978-5-8459-1948-9 (рус.).

12. Google Chrome Extensions?--?Часть 1. Архитектура [Электронный ресурс]: Google Chrome Extensions. - Режим доступа: https://medium.com/@aleksanderzinewicz/google-chrome-extensions

13. (свободный доступ).

14. Chrome.runtime --?Часть 1. Архитектура [Электронный ресурс]: chrome.runtime. - Режим доступа: https://developer.chrome.com/extensions/runtime (свободный доступ).

15. Chrome.tabs--?Часть 1. Архитектура [Электронный ресурс]: chrome.tabs. - Режим доступа: https://developer.chrome.com/extensions/tabs (свободный доступ).

16. Введение в БЭМ [Электронный ресурс]: Методология БЭМ - Режим доступа: https://ru.bem.info/methodology/quick-start/ (свободный доступ).

17. Соглашение по именованию [Электронный ресурс]: Методология БЭМ - Режим доступа: https://ru.bem.info/methodology/naming-convention/#Соглашение-по-именованию-css-селекторов (свободный доступ).

18. Адам Фримен. jQuery для профессионалов = Pro jQuery. -- М.: «Вильямс», 2012. -- 960 с. -- ISBN 978-5-8459-1799-7.

19. Русская документация по API jQuery [Электронный ресурс]: jQuery Русская документация - Режим доступа: https://jquery-docs.ru/ (свободный доступ).

Приложение

Options.html

<!doctype html>

<html>

<head>

<title>SeoHelper Options</title>

<meta charset="utf-8">

<link rel="stylesheet" href="../lib/css/materialize.min.css">

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<script src="../lib/js/jquery-3.2.1.min.js"></script>

<script src="../lib/js/materialize.min.js"></script>

<script src="options.js"></script>

</head>

<body class="body">

<div class="container">

<h4>Настройки SeoHelper</h4>

<div class="divider"></div>

<div class="input-field">

<label for="title-length">Рекомендуемая длина заголовка</label>

<input id="title-length" placeholder="Например, 50" type="number">

</div>

<div class="input-field">

<label for="description-length">Рекомендуемая длина описания</label>

<input id="description-length" placeholder="Например, 150" type="number">

</div>

<div class="input-field">

<label for="title-key-count">Рекомендуемое количество ключевых слов в заголовке</label>

<input id="title-key-count" placeholder="Например, 2" type="number">

</div>

<div class="input-field">

<label for="description-key-count">Рекомендуемое количество ключевых слов в описании</label>

<input id="description-key-count" placeholder="Например, 3" type="number">

</div>

<div class="input-field">

<label for="title-key-position">Рекомендуемое положение ключевого слова в заголовке</label>

<input id="title-key-position" placeholder="Например, 30" type="number">

</div>

<div class="input-field">

<label for="description-key-position">Рекомендуемое положение ключевого слова в описании</label>

<input id="description-key-position" placeholder="Например, 70" type="number">

</div>

<div class="input-field">

<label for="key-distance">Рекомендуемое расстояние между ключевыми словами</label>

<input id="key-distance" placeholder="Например, 400" type="number">

</div>

<button id="save" type="button" class="btn">Сохранить</button>

</div>

</body>

</html>

'use strict';

Options.js

function saveData() {

var options = {

titleLength: $('#title-length').val(),

descriptionLength: $('#description-length').val(),

titleKeyCount: $('#title-key-count').val(),

descriptionKeyCount: $('#description-key-count').val(),

titleKeyPosition: $('#title-key-position').val(),

descriptionKeyPosition: $('#description-key-position').val(),

keyDistance: $('#key-distance').val()

};

chrome.storage.sync.set(options, function() {

Materialize.toast('Опции сохранены', 4000);

});

}

function restoreData(options) {

$('#title-length').val(options.titleLength);

$('#description-length').val(options.descriptionLength);

$('#title-key-count').val(options.titleKeyCount);

$('#description-key-count').val(options.descriptionKeyCount);

$('#title-key-position').val(options.titleKeyPosition);

$('#description-key-position').val(options.descriptionKeyPosition);

$('#key-distance').val(options.keyDistance);

}

$(document).ready(function(){

chrome.runtime.sendMessage({initializing: true}, function(options) {

restoreData(options);

$('#save').click(saveData);

});

});

Popup.js

.body {

min-width: 700px;

}

.block {

padding: 0 20px

}

.title {

font-size: 22px;

font-weight: bold;

}

.row__no-margin {

margin: 0 !important;

}

Popup.html

<!doctype html>

<html>

<head>

<title>SeoHelper Popup</title>

<meta charset="utf-8">

<link rel="stylesheet" href="../lib/css/materialize.min.css">

<link rel="stylesheet" href="popup.css">

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<script src="../lib/js/jquery-3.2.1.min.js"></script>

<script src="../lib/js/materialize.min.js"></script>

<script src="../lib/js/name.js"></script>

<script src="popup.js"></script>

</head>

<body class="body">

<div class="block">

<div class="valign-wrapper row row__no-margin">

<div class="col s5">

<span class="title">SEO Helper</span>

</div>

<div class="col s5">

<div class="input-field">

<input id="key-word" type="text">

<label for="key-word">Ключевое слово</label>

</div>

</div>

<div class="col s2">

<button id="options-button" type="button" class="waves-effect waves-light btn">

<i class="small material-icons">settings</i>

</button>

</div>

</div>

</div>

<div class="divider"></div>

<div class="block">

<ul class="collapsible" data-collapsible="expandable">

<li>

<div class="collapsible-header">

<span id="title-length" class="new badge red" data-badge-caption="символов">0</span>

<span id="title-key-count" class="badge hide"></span>

Title

</div>

<div class="collapsible-body">

<span id="title-text"></span>

</div>

</li>

<li>

<div class="collapsible-header">

<span id="description-length" class="new badge red" data-badge-caption="символов">0</span>

<span id="description-key-count" class="badge hide"></span>

Description

</div>

<div class="collapsible-body">

<span id="description-text"></span>

</div>

</li>

<li>

<div class="collapsible-header">Рекомендации</div>

<div class="collapsible-body">

<div id="title-length-recommendation" class="hide">Сократите длину заголовка;</div>

<div id="description-length-recommendation" class="hide">Сократите длину описания;</div>

<div id="title-key-to-much" class="hide">Сократите количество ключевых фраз в заголовке;</div>

<div id="description-key-to-much" class="hide">Сократите количество ключевых фраз в описании;</div>

<div id="title-no-key" class="hide">Добавьте ключевую фразу в заголовок;</div>

<div id="description-no-key" class="hide">Добавьте ключевую фразу в описания;</div>

<div id="title-key-to-far" class="hide">Переместите ключевую фразу ближе к началу заголовка;</div>

<div id="description-key-to-far" class="hide">Переместите ключевую фразу ближе к началу описания;</div>

<div id="meta-intersection" class="hide">Описание не должно содержать в себе заголовка;</div>

<div id="title-mistakes" class="hide">Исправьте ошибки в заголовке;</div>

<div id="description-mistakes" class="hide">Исправьте ошибки в описании;</div>

<div id="text-errors" class="hide"></div>

<div id="text-spam" class="hide">Уменьшите количество ключевых фраз в тексте;</div>

</div>

</li>

</ul>

</div>

</body>

</html>

Popup.js

'use strict';

var data = {},

options = {},

errors = {},

keyWord;

function renderText(key) {

var text = data[key];

if (keyWord) {

text = text.replace(

getWordRegExp('gi'),

function(str) {

return '<span class="blue-text">' + str + '</span>';

}

);

}

if (errors[key]) {

errors[key].forEach(function(data) {

var replaceText;

if (data.s && data.s.length) {

replaceText = '<span class="red-text tooltipped" data-position="top" data-tooltip="' + data.s[0] + '">' + data.word + '</span>';

} else {

replaceText = '<span class="red-text">' + data.word + '</span>';

}

text = text.replace(new RegExp(data.word, 'gi'), replaceText);

});

}

$('#' + key + '-text').html(text);

$('.tooltipped').tooltip();

}

function checkMetaLength(key) {

var lengthElement = $('#' + key + '-length'),

string = data[key];

lengthElement.text(string ? string.length : 0);

if (string.length > options[key + 'Length'] || !string) {

$('#' + key + '-length-recommendation').removeClass('hide');

lengthElement.addClass('red');

} else {

$('#' + key + '-length-recommendation').addClass('hide');

lengthElement.addClass('green');

}

}

function getWordRegExp(flags) {

var wordClass = new RussianName(keyWord)

return new RegExp([

'nominative',

'genitive',

'dative',

'accusative',

'instrumentative',

'prepositional'

].map(function(caseName) {

return wordClass.fullName(caseName);

}).join('|'), flags);

}

function checkKeyInMeta(key) {

renderText(key);

var keyWordElement = $('#' + key + '-key-count');

if (!keyWord) {

keyWordElement.addClass('hide');

return;

}

var count = (data[key].match(getWordRegExp('gi')) || []).length;

if (count > options[key + 'KeyCount']) {

$('#' + key + '-key-to-much').removeClass('hide');

} else {

$('#' + key + '-key-to-much').addClass('hide');

}

if (count) {

$('#' + key + '-no-key').addClass('hide');

} else {

$('#' + key + '-no-key').removeClass('hide');

}

keyWordElement.text('Вхождений ключевой фразы: ' + count);

keyWordElement.removeClass('hide')

var match = data[key].match(getWordRegExp('i'));

if (match && match.index > options[key + 'KeyPosition']) {

$('#' + key + '-key-to-far').removeClass('hide');

} else {

$('#' + key + '-key-to-far').addClass('hide');

}

}

function checkMetaIntersection() {

if (data.description.indexOf(data.title) != -1) {

$('#meta-intersection').removeClass('hide');

} else {

$('#meta-intersection').addClass('hide');

}

}

function sendSpellingRequest(string, callback) {

$.ajax({

method: 'POST',

url: 'http://speller.yandex.net/services/spellservice.json/checkText',

data: {

text: string,

options: 1 + 2 + 4 + 8 + 512

}

}).done(callback);

}

function checkMetaSpelling(key) {

sendSpellingRequest(data[key], function(response) {

errors[key] = response;

if (response.length) {

$('#' + key + '-mistakes').removeClass('hide');

} else {

$('#' + key + '-mistakes').addClass('hide');

}

renderText(key);

});

}

function splitTextToSentenses(string) {

return string.match(/\(?[^\.\?\!]+[\.!\?]\)?/g).map(function(sentense) {

return sentense.trim();

});

}

function checkTextSpelling() {

var texts = splitTextToSentenses(data.text).reduce(function(texts, sentense) {

if (texts.length && (texts[texts.length - 1].length + sentense.length) < 10000) {

texts[texts.length - 1] = texts[texts.length - 1].concat(sentense);

} else {

texts = texts.concat([sentense]);

}

return texts;

}, []);

var textErrors = [],

index = 0;

texts.forEach(function(text) {

sendSpellingRequest(text, function(response) {

index++;

textErrors = textErrors.concat(response);

if (index === texts.length) {

var setOfErrors = [];

textErrors = textErrors.filter(function(error) {

if (setOfErrors.indexOf(error.word) === -1) {

setOfErrors.push(error.word);

return true;

}

return false;

});

var textErrorsElement = $('#text-errors');

if (textErrors.length) {

var textToUser = textErrors.map(function(error) {

var part = error.word;

if (error.s && error.s.length) {

part += ' (' + error.s.join(', ') + ')';

}

return part;

}).join(', ');

textErrorsElement.text('Исправьте возможные ошибки в тексте: ' + textToUser + ';');

textErrorsElement.removeClass('hide');

} else {

textErrorsElement.addClass('hide');

}

}

})

});

}

function checkTextKeySpam() {

if (!keyWord) {

return;

}

var indexes = [];

var match,

regex = getWordRegExp('ig');

while (match = regex.exec(data.text)) {

indexes.push(match.index);

}

for (var i = 0; i < indexes.length - 1; i++) {

if (indexes[i] - indexes[i + 1] < options.keyDistance) {

$('#text-spam').removeClass('hide');

return;

}

}

$('#text-spam').addClass('hide');

}

$(document).ready(function() {

chrome.runtime.sendMessage({initializing: true}, function(initOptions) {

options = initOptions;

$('.collapsible').collapsible();

$('#options-button').click(function() {

chrome.runtime.openOptionsPage();

});

chrome.tabs.query({

active: true,

currentWindow: true

}, function (tabs) {

chrome.tabs.sendMessage(

tabs[0].id,

{from: 'popup', action: 'getData'},

function(contentData) {

data = contentData

$('#key-word').change(function() {

keyWord = $('#key-word').val();

checkKeyInMeta('title');

checkKeyInMeta('description');

checkTextKeySpam();

});

renderText('title');

renderText('description');

checkMetaLength('title');

checkMetaLength('description');

checkMetaIntersection();

checkMetaSpelling('title');

checkMetaSpelling('description');

checkTextSpelling();

}

);

});

});

});

Background.js

'use strict';

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {

if (message.initializing) {

chrome.storage.sync.get({

titleLength: 50,

descriptionLength: 150,

titleKeyCount: 2,

descriptionKeyCount: 3,

titleKeyPosition: 30,

descriptionKeyPosition: 70,

keyDistance: 400

}, function(options) {

chrome.storage.sync.set(options, function() {

sendResponse(options);

});

});

return true;

}

});

Content.js

'use strict';

chrome.runtime.onMessage.addListener(function (msg, sender, response) {

if (msg.from === 'popup' && msg.action === 'getData') {

var titleEl = document.head.getElementsByTagName('title')[0],

descriptionEl = document.head.querySelectorAll('meta[name="description"]')[0];

response({

text: document.body.innerText.replace(/\s{2,}/g, ' '),

title: titleEl && titleEl.innerText,

description: descriptionEl && descriptionEl.getAttribute('content')

});

return true;

}

});

Manifest.json

{

"manifest_version": 2,

"name": "Seo Helper",

"description": "Helps seo optimization",

"version": "0.0.1",

"content_scripts": [{

"matches": ["http://*/*", "https://*/*"],

"js": ["content.js"],

"run_at": "document_end"

}],

"options_page": "options/options.html",

"browser_action": {

"default_icon": "icon.png",

"default_popup": "popup/popup.html"

},

"background": {

"scripts": ["background.js"],

"persistent": false

},

"permissions": [

"tabs",

"storage"

]

}

Размещено на Allbest.ru


Подобные документы

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

    дипломная работа [2,2 M], добавлен 08.06.2017

  • Разработка программного продукта - приложения, позволяющего заносить данные анкетирования в базу данных MS SQL. Описание логики работы приложения, особенности пользовательского интерфейса. Формы просмотра анкет, описание процедур и функций программы.

    курсовая работа [1,2 M], добавлен 16.08.2012

  • Разработка системы, базирующейся на протоколе LIMone, для обмена мгновенными сообщениями и пересылки файлов в процессе деловой переписки. Реализация системы в виде клиент-серверного приложения. Расчет экономических показателей программного продукта.

    дипломная работа [4,7 M], добавлен 22.08.2016

  • Технология создания многопоточных приложений в современных системах программирования с использованием языка C# в Visual Studio.NET. Разработка алгоритма и структуры программы. Описание и особенности тестирования приложения с разным количеством потоков.

    курсовая работа [773,0 K], добавлен 14.03.2013

  • Проектирование системы управления базами данных. Особенности реализации в MS SQL. Разработка пользовательского интерфейса. Тестирование и отладка приложения. Руководство пользователя и системного администратора. Анализ и методы разработки приложений.

    курсовая работа [867,9 K], добавлен 16.07.2013

  • Компоненты приложения и технологии, используемые для связи между ними. Обзор программных средств и технологий, используемых в ходе работы. Трансляция кода JSP страницы в код сервлета. Создание структуры базы данных c применением фреймворка Hibernate.

    курсовая работа [1,1 M], добавлен 16.07.2016

  • Разработка приложений баз данных Delphi. Построение концептуальной модели, атрибуты сущностей и связей. Проектирование приложения для ведения базы данных телефонных номеров с возможностью поиска по всем имеющимся полям. Тестирование программного средства.

    курсовая работа [641,7 K], добавлен 17.08.2013

  • Проектирование программного модуля: сбор исходных материалов; описание входных и выходных данных; выбор программного обеспечения. Описание типов данных и реализация интерфейса программы. Тестирование программного модуля и разработка справочной системы.

    курсовая работа [81,7 K], добавлен 18.08.2014

  • Обзор подходов к разработке музейных приложений с элементами дополненной реальности, формирование требований к ним. Выбор методов разработки приложения, разработка пользовательского интерфейса. Принципы тестирования. Реализация раздела "Распознавание".

    дипломная работа [2,8 M], добавлен 03.07.2017

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

    курсовая работа [637,7 K], добавлен 14.01.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.