Решу егэ api

SdamGIA Api

SdamGIA Api – Python модуль для взаимодействия с образовательным порталом СДАМ ГИА

Структура СдамГИА

Чтобы было проще понять, как устроена база заданий СдамГИА, предлагаю воспользоваться следующей схемой:

СдамГИА
└── Предмет (subject)
    ├── Каталог заданий (catalog)
    │   └── Задание (topic)
    │       └── Категория (category)
    │           └── Задача (problem)
    └── Тест (test)
        └── Задача (problem)       

У каждой задачи, категории или теста есть свой идентификатор.
Задания тоже имеют номера, которые в свою очередь могут иметь такие значения как «Д1» или «C4». Этим они отличаются от идентификаторов.

Установка

$ pip3 install sdamgia-api

Установка зависимостей

Для поиска задач по тексту на изображении необходимо установить pytesseract:

$ pip3 install pytesseract

А также Tesseract-OCR

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

Использование

Инициализация

from sdamgia import SdamGIA

sdamgia = SdamGIA()

Поиск задачи по ее идентификатору

subject = 'math'
id = '1001'
sdamgia.get_problem_by_id(subject, id)
{
  'id': '1001',
  'topic': '4',
  'condition': {
    'text': 'На экзамен вынесено 60 вопросов, Андрей не выучил 3 из них. Найдите вероятность того, что ему попадется выученный вопрос.', 
    'images': []
  }, 
  'solution': {
    'text': 'Решение.Андрей выучил 60xa0–xa03xa0=xa057 вопросов. Поэтому вероятность того, что на экзамене ему попадется выученный вопрос равнаxa0Ответ: 0,95.',
    'images': ['https://ege.sdamgia.ru/formula/svg/9f/9fbf55ab44a507fb47ba8a2666cd7644.svg']
  }, 
  'answer': '0,95', 
  'analogs': ['1001', '1002', '1003', '1004', '1005', '1006', '1007', '1008', '1009', '1010'], 
  'url': 'https://math-ege.sdamgia.ru/problem?id=1001'
}

Можно сгенерировать задачу в виде изображения:

path_to_img = '/imgs/problem.png'
sdamgia.get_problem_by_id(subject, id, path_to_img=path_to_img)

Поиск задач по запросу

subject = 'math'
request = 'Найдите количество'
sdamgia.search(subject, request)
['6407', '8795', '8799', '27501', '519508', '519534', '525371', '512436', '6401', '6421', '6427', '7321', '7325', '7801', '7803', '7807', '7809', '8037', '8039', '8045']

Поиск теста по его идентификатору

subject = 'math'
id = '1770'
sdamgia.get_test_by_id(subject, id)
# Возвращает список задач, входящих в тест
['77345', '28765', '77374', '27903', '26675', '27700', '77411', '27506', '27132', '28008', '26703', '99592']

Поиск категории по ее идентификатору

subject = 'math'
id = '1'
sdamgia.get_category_by_id(subject, id)
# Возвращает список задач, входящих в категорию
['77334', '323512', '501201', '509077', '509106']

Получение каталога

subject = 'math'
sdamgia.get_catalog(subject)
[
  {
    'topic_id': '1',
    'topic_name': 'Простейшие текстовые задачи', 
    'categories': [
      {'category_id': '174', 'category_name': 'Вычисления'}, 
      {'category_id': '1', 'category_name': 'Округление с недостатком'}, 
      {'category_id': '2', 'category_name': 'Округление с избытком'},
      {'category_id': '249', 'category_name': 'Проценты'},
      {'category_id': '5', 'category_name': 'Проценты и округление'}
    ]
  },
  {
    ...
  }        
]

Генерация теста

По умолчанию генерируется тест, включающий по одной задаче из каждого задания предмета.
Так же можно вручную указать одинаковое количество задач для каждого из заданий: {‘full’: <кол-во задач>}
Указать определенные задания с определенным количеством задач для каждого: {<номер задания>: <кол-во задач>, … }

subject = 'math'
problems = {1: 1, 2: 2, 3: 4}
sdamgia.generate_test(subject, problems)
# Возвращает идентификатор сгенерированного теста

Обратите внимание, что в этом случае идентификатор задания — только науральное число. Т.е. если после задания 15 идет задание Д1, оно должно будет записываться как 16 задание.

Генерация pdf-версии теста

sdamgia.generate_pdf('math', '38299510', pdf='h')
https://math-ege.sdamgia.ru/pdf/1fe7d7d8408f8d5195fabfd8ab393d63.pdf

Список параметров:

subject: Наименование предмета
testid: Идентифигатор теста
solution: Пояснение
nums: № заданий
answers: Ответы
key: Ключ
crit: Критерии
instruction: Инструкция
col: Нижний колонтитул
pdf: Версия генерируемого pdf документа
    По умолчанию генерируется стандартная вертикальная версия
    h - горизонтальная версия
    z - версия с крупным шрифтом
    m - версия с большим полем

Поиск задач по изображению beta

С помощью sdamgia-api вы можете искать задачи по тексту на изображении. Например, на фотографии распечатки.

Для начала, необходимо указать путь к исполняемому файлу Tesseract-OCR:

sdamgia.tesseract_src = "C:/Program Files/Tesseract-OCR/tesseract.exe"

Теперь мы можем запустить поиск:

sdamgia.search_by_img('rus', 'Image.jpg')
# Возвращает список найденных задач
['12629', '14062', '2846', '2836', '2837', '2838', '2839', '2845', '2847', '7776', '10242', '874', '864', '865', '866', '867', '873', '2359', '456', '446', '447', '448', '449', '455', '2348', '7815', '691', '863', '14426', '7867', '1262', '1889', '6716', '6706', '6707', '6708', '6709', '6715', '6717', '8899', '8895', '8896', '8897', '8898', '8900', '4194', '4184', '4185', '4186', '4187', '4193', '4195', '30', '28', '29', '31', '37', '38', '2337', '676', '674', '675', '677', '683', '684', '2168', '1094', '1092', '1093', '1095', '1101', '1102', '2365', '6893', '6891', '6892', '6894', '6900', '6901', '6902', '599', '598', '600', '601', '607', '608', '2352', '1710', '1700', '1701', '1702', '1703', '1709', '2381', '3600', '3599', '3601', '3602', '3608', '3609', '3610', '8327', '8323', '8324', '8325', '8326', '8328', '950', '940', '941', '942', '943', '949', '2361', '11087', '11065', '1304', '1299', '1342', '1337', '1474', '1472', '1473', '1475', '1481', '1482', '2375', '105', '104', '106', '107', '113', '114', '2339', '181', '180', '182', '183', '189', '190', '2341', '257', '256', '258', '259', '265', '266', '1321', '2343', '333', '332', '334', '335', '341', '342', '2345', '380', '370', '371', '372', '373', '379', '2346', '532', '522', '523', '524', '525', '531', '2350', '656', '652', '759', '750', '751', '752', '753', '760', '2356', '789', '788', '790', '791', '797', '798', '2357', '844', '842', '988', '978', '979', '980', '981', '987', '2362', '997', '995', '1026', '1016', '1017', '1018', '1019', '1025', '2363', '1254', '1244', '1245', '1246', '1247', '1253', '2369', '1292', '1282', '1283', '1284', '1285', '1291', '2370', '7568']

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

SdamGIA Api – Python модуль для взаимодействия с образовательным порталом СДАМ ГИА

Структура СдамГИА

Чтобы было проще понять, как устроена база заданий СдамГИА, предлагаю воспользоваться следующей схемой:

СдамГИА
└── Предмет (subject)
    ├── Каталог заданий (catalog)
    │   └── Задание (topic)
    │       └── Категория (category)
    │           └── Задача (problem)
    └── Тест (test)
        └── Задача (problem)       

У каждой задачи, категории или теста есть свой идентификатор.
Задания тоже имеют номера, которые в свою очередь могут иметь такие значения как «Д1» или «C4». Этим они отличаются от идентификаторов.

Установка

$ pip3 install sdamgia-api

Установка зависимостей

Для поиска задач по тексту на изображении необходимо установить pytesseract:

$ pip3 install pytesseract

А также Tesseract-OCR

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

Использование

Инициализация

from sdamgia import SdamGIA

sdamgia = SdamGIA()

Поиск задачи по ее идентификатору

subject = 'math'
id = '1001'
sdamgia.get_problem_by_id(subject, id)
{
  'id': '1001',
  'topic': '4',
  'condition': {
    'text': 'На экзамен вынесено 60 вопросов, Андрей не выучил 3 из них. Найдите вероятность того, что ему попадется выученный вопрос.', 
    'images': []
  }, 
  'solution': {
    'text': 'Решение.Андрей выучил 60xa0–xa03xa0=xa057 вопросов. Поэтому вероятность того, что на экзамене ему попадется выученный вопрос равнаxa0Ответ: 0,95.',
    'images': ['https://ege.sdamgia.ru/formula/svg/9f/9fbf55ab44a507fb47ba8a2666cd7644.svg']
  }, 
  'answer': '0,95', 
  'analogs': ['1001', '1002', '1003', '1004', '1005', '1006', '1007', '1008', '1009', '1010'], 
  'url': 'https://math-ege.sdamgia.ru/problem?id=1001'
}

Можно сгенерировать задачу в виде изображения:

path_to_img = '/imgs/problem.png'
sdamgia.get_problem_by_id(subject, id, path_to_img=path_to_img)

Поиск задач по запросу

subject = 'math'
request = 'Найдите количество'
sdamgia.search(subject, request)
['6407', '8795', '8799', '27501', '519508', '519534', '525371', '512436', '6401', '6421', '6427', '7321', '7325', '7801', '7803', '7807', '7809', '8037', '8039', '8045']

Поиск теста по его идентификатору

subject = 'math'
id = '1770'
sdamgia.get_test_by_id(subject, id)
# Возвращает список задач, входящих в тест
['77345', '28765', '77374', '27903', '26675', '27700', '77411', '27506', '27132', '28008', '26703', '99592']

Поиск категории по ее идентификатору

subject = 'math'
id = '1'
sdamgia.get_category_by_id(subject, id)
# Возвращает список задач, входящих в категорию
['77334', '323512', '501201', '509077', '509106']

Получение каталога

subject = 'math'
sdamgia.get_catalog(subject)
[
  {
    'topic_id': '1',
    'topic_name': 'Простейшие текстовые задачи', 
    'categories': [
      {'category_id': '174', 'category_name': 'Вычисления'}, 
      {'category_id': '1', 'category_name': 'Округление с недостатком'}, 
      {'category_id': '2', 'category_name': 'Округление с избытком'},
      {'category_id': '249', 'category_name': 'Проценты'},
      {'category_id': '5', 'category_name': 'Проценты и округление'}
    ]
  },
  {
    ...
  }        
]

Генерация теста

По умолчанию генерируется тест, включающий по одной задаче из каждого задания предмета.
Так же можно вручную указать одинаковое количество задач для каждого из заданий: {‘full’: <кол-во задач>}
Указать определенные задания с определенным количеством задач для каждого: {<номер задания>: <кол-во задач>, … }

subject = 'math'
problems = {1: 1, 2: 2, 3: 4}
sdamgia.generate_test(subject, problems)
# Возвращает идентификатор сгенерированного теста
38299510

Обратите внимание, что в этом случае идентификатор задания — только науральное число. Т.е. если после задания 15 идет задание Д1, оно должно будет записываться как 16 задание.

Генерация pdf-версии теста

sdamgia.generate_pdf('math', '38299510', pdf='h')
https://math-ege.sdamgia.ru/pdf/1fe7d7d8408f8d5195fabfd8ab393d63.pdf

Список параметров:

subject: Наименование предмета
testid: Идентифигатор теста
solution: Пояснение
nums: № заданий
answers: Ответы
key: Ключ
crit: Критерии
instruction: Инструкция
col: Нижний колонтитул
pdf: Версия генерируемого pdf документа
    По умолчанию генерируется стандартная вертикальная версия
    h - горизонтальная версия
    z - версия с крупным шрифтом
    m - версия с большим полем

Поиск задач по изображению beta

С помощью sdamgia-api вы можете искать задачи по тексту на изображении. Например, на фотографии распечатки.

Для начала, необходимо указать путь к исполняемому файлу Tesseract-OCR:

sdamgia.tesseract_src = "C:/Program Files/Tesseract-OCR/tesseract.exe"

Теперь мы можем запустить поиск:

sdamgia.search_by_img('rus', 'Image.jpg')
# Возвращает список найденных задач
['12629', '14062', '2846', '2836', '2837', '2838', '2839', '2845', '2847', '7776', '10242', '874', '864', '865', '866', '867', '873', '2359', '456', '446', '447', '448', '449', '455', '2348', '7815', '691', '863', '14426', '7867', '1262', '1889', '6716', '6706', '6707', '6708', '6709', '6715', '6717', '8899', '8895', '8896', '8897', '8898', '8900', '4194', '4184', '4185', '4186', '4187', '4193', '4195', '30', '28', '29', '31', '37', '38', '2337', '676', '674', '675', '677', '683', '684', '2168', '1094', '1092', '1093', '1095', '1101', '1102', '2365', '6893', '6891', '6892', '6894', '6900', '6901', '6902', '599', '598', '600', '601', '607', '608', '2352', '1710', '1700', '1701', '1702', '1703', '1709', '2381', '3600', '3599', '3601', '3602', '3608', '3609', '3610', '8327', '8323', '8324', '8325', '8326', '8328', '950', '940', '941', '942', '943', '949', '2361', '11087', '11065', '1304', '1299', '1342', '1337', '1474', '1472', '1473', '1475', '1481', '1482', '2375', '105', '104', '106', '107', '113', '114', '2339', '181', '180', '182', '183', '189', '190', '2341', '257', '256', '258', '259', '265', '266', '1321', '2343', '333', '332', '334', '335', '341', '342', '2345', '380', '370', '371', '372', '373', '379', '2346', '532', '522', '523', '524', '525', '531', '2350', '656', '652', '759', '750', '751', '752', '753', '760', '2356', '789', '788', '790', '791', '797', '798', '2357', '844', '842', '988', '978', '979', '980', '981', '987', '2362', '997', '995', '1026', '1016', '1017', '1018', '1019', '1025', '2363', '1254', '1244', '1245', '1246', '1247', '1253', '2369', '1292', '1282', '1283', '1284', '1285', '1291', '2370', '7568']

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

Делаем расширение для браузера, проверяющее результаты ЕГЭ +17

JavaScript, Из песочницы, Расширения для браузеров, Google Chrome


Рекомендация: подборка платных и бесплатных курсов дизайна интерьера — https://katalog-kursov.ru/

image

Я, как и любой другой выпускник, переживаю по поводу экзаменов. От баллов, полученных на ЕГЭ зависит слишком многое, поэтому сейчас трудно думать о чем то другом. Чтобы не обновлять сайт check.ege.edu.ru каждые две минуты, я решил написать расширение, которое будет делать это за меня, а заодно присылать уведомления, в случае, если какой-то из экзаменов проверили.

Задача не очень сложная, но есть один неприятный момент. Сайт, на котором публикуются результаты, требует, чтобы информация о участнике, при каждом закрытии браузера, заполнялась заново. Это очень не удобно, поэтому пришлось немного по-импровизировать. Было замечено, что вся необходимая информация хранится в файлах cookie, поэтому можно просто сохранять и обновлять их когда потребуется, без необходимости вводить данные заново. Таким образом, логика работы расширения такова:

Расширения для браузера пишутся на js, оформляются с помощью html и css. В целом, разработка расширения мало чем отличается от создания сайта. Обычно любое расширение имеет следующий «скелет»:

Manifest.json

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

manifest.json

{
  "manifest_version": 2,
  "name": "Результаты ЕГЭ",
  "description": "Расширение следит за обновлениями на сайте check.ege.edu.ru и оповещает о новых результатах",
  "version": "1.0.0",
  "icons": {"128": "icon.png"},
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },

  "background": {
    "scripts": ["jquery.js","background.js"], //фоновые страницы
    "persistent": false
// Эта строка включает режим Event Pages, который призван улучшить производительность за счет того, что расширение будет работать только тогда, когда это необходимо. Именно поэтому в дальнейшем будет использоваться alarms вместо setInterval.
  },
  "permissions": [ //разрешения
    "cookies",
    "tabs",
    "alarms",
    "notifications",
    "storage",
    "http://check.ege.edu.ru/*",
    "https://check.ege.edu.ru/*"

  ],
  "web_accessible_resources": [
// Это необходимо для правильной работы оповещений
    "icon.png"
  ]
}

Background.js

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

background.js

chrome.alarms.create("1min", {  // Повторяем код ниже каждую минуту
  delayInMinutes: 1,
  periodInMinutes: 1,
});

chrome.alarms.onAlarm.addListener(function(alarm) {
  if (alarm.name === "1min") {
    chrome.cookies.getAll({"url": 'http://check.ege.edu.ru'}, function(cookie) { 
    if (cookie.length){  
      chrome.storage.local.set({'sCookie': cookie}); 
// Если на сайте есть cookie файлы, то сохраняем их
      checkUpdates(); // и проверяем обновления
    }else{
      chrome.storage.local.get(['sCookie'], function(result) {
        if (!jQuery.isEmptyObject(result)){ 
// Если нет, то загружаем сохраненные ранее
          chrome.cookies.set({
              "url": 'http://check.ege.edu.ru',
              "name": result["sCookie"][0]["name"],
              "value": result["sCookie"][0]["value"]
          }, function(){
            checkUpdates(); // и тоже проверяем обновления
          });
        }
      });
    }
  });
  }
});

function checkUpdates(){
  var myInit = { 
      method: 'GET',
      credentials: 'include'};
  fetch('http://check.ege.edu.ru/api/exam', myInit).then(r => r.text()).then(result => { // Загружаем результаты ЕГЭ
    var examRes = {};
    jQuery.parseJSON(result)['Result']['Exams'].forEach(function(element) {
      examRes[element['Subject']] = element['TestMark']; 
// Сохраняем их в массив examRes
    });
    chrome.storage.local.get(['examRes'], function(result) {
      for (var element in result['examRes']){
        if (result['examRes'][element] != examRes[element]){ 
            showNotification(element, examRes[element]);  
            chrome.storage.local.set({'examRes': examRes});
// Если они не совпадают, с прошлыми данными, то 
// показываем уведомление
// и сохраняем новые данные
        }
      }
    });
  })
}

function showNotification(subName, mark){ 
// показываем уведомление, состоящее их названия предмета и баллов
  chrome.notifications.create('reminder', {
        type: 'basic',
        iconUrl: 'icon.png',
        title: 'Новые результаты!',
        message: subName + ' - ' + mark
     });
}

Popup.html

В этом файле хранится разметка popup окна, которое открывается при нажатии на иконку расширения. В нашем случае, в этом окне будет отображаться небольшая таблица с результатами ЕГЭ.

popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Результаты ЕГЭ</title>
  <script type="text/javascript" src="jquery.js"></script>
  <script src="popup.js"></script>
  <style>
<!-- Здесь ничего интересного -->
  </style>  
</head>
<body>
  <table border="1" id="mainTable">
  <caption><b>Ваши результаты ЕГЭ</b></caption>
  <tr>
    <th>Предмет</th>
    <th>Тестовый балл</th>
    </tr>
  </table>
</body>
</html>

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

popup.js

chrome.cookies.getAll({"url": 'http://check.ege.edu.ru'}, function(cookie) {
// Смотрим, установлены ли на сайте необходимые cookie
  if (cookie.length){
    chrome.storage.local.set({'sCookie': cookie});
    createTable();
// Если они есть, то сохраняем их и отрисовываем таблицу
  }else{
    chrome.storage.local.get(['sCookie'], function(result) {
// Если нет, то смотрим, нет ли у нас сохраненных ранее cookie файлов
      if (!jQuery.isEmptyObject(result)){
        chrome.cookies.set({
          "url": 'http://check.ege.edu.ru',
          "name": result["sCookie"][0]["name"],
          "value": result["sCookie"][0]["value"]
        }, function(){
// Если есть, то устанавливаем их и отрисовываем таблицу
          createTable();
        });
      }else{
// А если нет, то открываем сайт check.ege.edu.ru в новой вкладке
        chrome.tabs.create({url : "http://check.ege.edu.ru"}); 
      }
    });
  }
});

function createTable(){
  var myInit = { 
      method: 'GET',
      credentials: 'include'};
  fetch('http://check.ege.edu.ru/api/exam', myInit).then(r => r.text()).then(result => {
// Получаем результаты и парсим их
    jQuery.parseJSON(result)['Result']['Exams'].forEach(function(element) {
      if (element['HasResult'] == false){
// Если результата еще нет, то выводим название предмета и надпись "не проверено"
        $("#mainTable").append('<tr><td>'+element['Subject']+'</td><td>Не проверено</td></tr>');
      }else{
// Если есть, то выводим название предмета и баллы
        $("#mainTable").append('<tr><td>'+element['Subject']+'</td><td>'+element['TestMark']+'</td></tr>');
      }
    });
  })
}

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

Like this post? Please share to your friends:
  • Решу егэ 99619
  • Решу егэ 99617
  • Решу егэ 99606
  • Решу егэ 99590
  • Решу егэ 9927 химия