Giter Club home page Giter Club logo

utp2017-5-excel's Issues

Баг с поиском циклических зависимостей

  • Список вершин из цикла, возвращаемый findCycleFrom, должен включать в себя все вершины из цикла, в том числе вершину, из которой производился поиск.
  • Если вершина имеет ребро из самой в себя, это тоже считается циклом, и findCycleFrom должен возвращать массив из одной этой вершины.

Model logic: Синтаксический анализатор

Задача: Создать синтаксический анализатор

Синтаксический анализатор работает методом рекурсивного спуска.
Входные данные: Последовательность токенов.
Выходные данные: Дерево разбора.

Грамматика синтаксического анализатора - #7 в БНФ

Разработка архитектуры проекта и распределение ролей

Требуется разработать архитектуру электронной таблицы:

  • выбрать подходы и технологии, которые будут использоваться при разработке, а именно паттерны проектирования;
  • определить, из каких крупных компонентов будет состоять решение;
  • распределить обязанности участников между различными компонентами и различными видами деятельности, создав на каждую подзадачу «issue» и назначив её на участника.

Уточнение постановки задачи

Необходимо сформулировать общее представление о проекте — как будет выглядеть электронная таблица и какими функциями она будет обладать. Полученное представление следует описать в README.md в виде одного или нескольких абзацев. После этого данную задачу можно закрывать.

Итоги

Сейчас ставим оценки! Вот прямо сейчас!

Неформальный рейтинг проектов:

  1. Лидер с большим отрывом — Чат.
  2. С большим отрывом — Excel.
  3. На одном месте — Форт и Paint
  4. Графики
  5. Аутсайдер — Форум

Дубанов А. В. @alex-qrcs и Коновалов А. В. @Mazdaywik.

Добавление новых функций

Математические:

ABS(x)
ACOS(x)
ACOT(x)
ASIN(x)
ATAN(x)
CEILING(x)
COS(x)
COT(x)
DEGREES(x) — перевод x из радианов в градусы
EXP([x])
FACT(x)
FLOOR(x)
GCD(x, y)
ISEVEN(x)
ISODD(x)
LCM(x, y)
LN(x)
LOG(x, base)
LOG10(x)
MOD(dividend, divisor)
PI()
POW(base, exponent)
QUOTIENT(dividend, divisor)
RADIANS(x)
RAND() — случайное число [0, 1)
RANDBETWEEN(low, high)
ROUND(x, places)
SIGN(x)
SIN(x)
SQRT(x)
TAN(x)

Статистические:

AVERAGE(...args) — аналогично SUM, только среднее арифметическое. См. задачу про диапазоны.
COUNT(...args) — считает количество числовых значений
COUNTUNIQUE(...args) — считает количество уникальных значений
MAX(...args) — максимум; все аргументы и значения в Range должны быть все number или все string
MEDIAN(...args) — медиана
MIN(...args)
MODE(...args) — мода
PRODUCT(...args)

Строковые:

CHAR(index) — возвращает строку из одного символа под номером index в Unicode
CODE(string) — возвращает индекс в Unicode первого символа строки
FIND(needle, haystack[, startPosition])
FIXED(number, placesAfterFloatingPoint) — формат десятичного числа в виде строки
LEFT(string, length) — префикс строки длиной length
LEN(string)
LOWER(string)
MID(string, start, length) — извлечение подстроки
RIGHT(string, length) — суффикс строки длиной length
SEARCH(needle, haystack[, startPosition]) — то же, что FIND, только не чувствительная к регистру 
UPPER(string)

Управляющие:

COLUMNS(range) — ширина диапазона
IF(condition, ifTrue, ifFalse)
INDEX(range, row, column) — возвращает значение ячейки с координатами row, column относительно диапазона range
ISLOGICAL(value)
ISNUMBER(value)
ISTEXT(value)
ROWS(range) — высота диапазона

Переименовать для совместимости с другими системами управления электронными таблицами:
(Мне это тоже не нравится, но что поделать.)

EQUALS -> EQ
GREATER -> GT
GREATER_OR_EQUALS -> GTE
LESS -> LT
LESS_OR_EQUALS -> LTE
NUMBER -> N
STRING -> TEXT
NEGATE -> UNMINUS
SUBTRACT -> MINUS

Ещё баги парсера

  • Не работают строки в формуле. Например, если набрать ="abc", значение в поле expression будет пустое.
  • Поле position в классе _Expression должно быть числом.
  • Некорректно обрабатываются ссылки на ячейку. Воспроизводим:
    1. Пишем в ячейку B1: =1
    2. Пишем в ячейку A1: =B1

Копирование ячейки

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

  • Реализуем метод move(fromRow, fromColumn, toRow, toColumn) класса Spreadsheet._CellReference. Он возвращает новый Spreadsheet._CellReference, в котором:
    • Если в исходной ссылке строка не фиксированная, индекс строки изменён на toRow - fromRow;
    • Если в исходной ссылке столбец не фиксированный, индекс столбца изменён на toColumn - fromColumn;
    • rowFixed и columnFixed имеют такие же значения.
  • Переопределяем метод toString класса Spreadsheet._Expression. Это метод "собирает" разобранное выражение обратно в строку-формулу.
  • Определяем метод generateFormula класса Spreadsheet._Cell. Он преобразует поле expression в строку и кладёт её в formula.
  • Разделяем метод setFormula на два: setFormula(i, j, formula) и setExpression(i, j, expression). Второй устанавливает пропарсенное выражение и используется в первом.
  • Реализуем метом copyCell(fromRow, fromColumn, toRow, toColumn) класса Spreadsheet. Он копирует expression из ячейки с первыми координатами рекурсивно, заменяя все _CellReference на .move(fromRow, fromColumn, toRow, toColumn), в ячейку со вторыми координатами. Затем вызывает generateFormula последней. Затем вызывает setExpression(toRow, toColumn, expression).

View: Базовый сайт

Задача: Создать базовую модель сайта.

Необходимо создать эскиз сайта. По эскизу построить модель.

  • Создать наброски/эскизы/зарисовки дизайна (@jkhizbullina)
  • Выявить удобное и эргономичное расположение кнопок, панелей, полей ввода сайта
  • Подобрать легко читаемые шрифты
  • Собрать базовую модель сайта (@SimpleCreations)
    • Сделать таблицу
    • Создать панель управления таблицей (Редактирование полей таблицы, изменение размера, стиля шрифта)

Требования:

  • Чистый дизайн (использование 3-х основных цветов)
  • Использование SCSS для конфигурации элементов сайта
  • Логически правильное расположение элементов управления сайтом
  • Понятный интерфейс

Model: Базовая структура данных

Задача: разработать структуру данных таблица

Разработать структуру данных таблица, реализованную в виде двумерного массива.
Создать методы:

  • Изменяющие данные в клетках таблицы
  • Возвращающие значение клетки, в случае, если в ней не записана формула
  • Изменяющие размер таблицы
  • Очищающие таблицу

Model logic: Лексический анализатор

Задача: Написать лексический анализатор

Лексический анализатор должен преобразовывать входную строку в последовательность токенов

Классификация токенов:

  • Число
  • Идентификатор — функция или ссылка на ячейку таблицы (примеры: A1, ZZ98, ABS, CONCATENATE)
  • Открывающаяся скобка (
  • Закрывающаяся скобка )
  • Оператор +, -, *, /, =, <, >, <=, >=
  • Логическая константа TRUE, FALSE
  • Строка, ограниченная символами ", причём символы \ и " могут содержаться в строке в виде \\ и \" соответственно

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

Пример формулы: CONCATENATE("Всё очень ", IF(AND(A1 >= B2 + 1.5, TRUE), "хорошо", "плохо"))

Диапазоны

Нужно добавить поддержку диапазонов как типа значений в формуле.
Пример использования: =CONCATENATE("Сумма: ", STRING(SUM(A1:A10)))

  • Добавляем токен : (COLON)
  • Создаём класс Spreadsheet._Range:
    • поле start типа Spreadsheet._CellReference — ссылка на первую угловую ячейку диапазона
    • поле end типа Spreadsheet._CellReference — ссылка на противоположную угловую ячейку
    • метод forEachCell(callback) вызвает функцию callback для каждой ячейки из диапазона, начиная с левой верхней и двигаясь справа налево, сверху вниз. callback(cell, row, column) вызывается с параметрами:
      • cell типа Spreadsheet._Cell — ячейка;
      • row, column -- координаты этой ячейки.
  • Обновлеяем парсер с учётом новой грамматики
  • В evaluate аналогично CellReference должна быть проверка, что все ячейки из диапазона существуют и определены
  • Пишем тестовую функцию SUM, код который примерно следующий:
    SUM(...args) {
        // Проверяем: количество args должно быть >= 1
        return args.reduce((sum, element) => {
              if (element instanceof Spreadsheet.Table) {
                    let rangeSum = 0;
                    element.forEachValue(cell => {
                          // Проверяем, что значение cell — number
                          rangeSum += cell.value;
                    });
                    return sum + rangeSum;
              } else if (typeof element === "number") {
                    return sum + element;
              } else {
                    // Ошибка
              }
        }, 0);
    }

Баги копирования ячеек

Первый баг

  1. Пишем в ячейку A1 =1
  2. Пишем в ячейку B1 =A1
  3. Пишем в консоли ui.spreadsheet.copyCell(0, 1, 0, 2). Видим в ячейке C3 мифическое =A0.

Второй баг

  1. Пишем в ячейку A1 =1
  2. Пишем в ячейку B1 =A1
  3. Пишем в консоли ui.spreadsheet.copyCell(0, 1, 1, 1). Видим в ячейке B2 =1 и ошибку зависимости, что ничем не объясняется.

Третий баг

  1. Пишем в ячейку A1 =1
  2. Пишем в ячейку B1 =$A1
  3. Пишем в консоли ui.spreadsheet.copyCell(0, 1, 0, 2). Видим в ячейке C3 =0.

Четвертый баг

  1. Пишем в ячейку A1 =1
  2. Пишем в ячейку B1 =A$1
  3. Пишем в консоли ui.spreadsheet.copyCell(0, 1, 0, 2). Видим в ячейке C3 неожиданное =A-1.

Model logic: Вычисление формул

Задача: Реализовать механизм вычисления формул

Требуется реализовать механизм вычисления формул в дереве разбора #8.

Импорт и экспорт формата ячеек в .xlsx

Изменения класса XLSXManager для импорта:

  • Добавляем метод import(blob) вместо fill(blob). fill() теперь не принимает аргументов и вызывается после import.
  • Добавляем метод getSelection, который возвращает {startRow, startColumn, endRow, endColumn} — диапазон сохранённой в файле выделенной области.
  • Добавляем метод getFormattedCells, который возвращает двумерный массив из FormattedCell

Для экспорта:

  • Добавляем метод setSelection(startRow, startColumn, endRow, endColumn)
  • Добавляем метод setFormattedCells(cells), где cells — двумерный массив из XLSXManager.FormattedCell.

Создаем класс XLSXManager.FormattedCell.
Он имеет поля: fontFamily, fontSize, color, bold, italic, underlined, textAlign, fillColor, borderLeft, borderTop, borderRight, borderBottom.

Создаем класс XLSXManager.FormattedCell.Border.
Он имеет поля: position, width, color.

Все поля обоих классов по умолчанию не определены.

Определенные поля XLSXManager.FormattedCell имеют значения:

  • fontSize — число точек (не пикселей).
  • bold, italic, underlinedtrue.
  • textAlign"left", "right", "center" или "justify".
  • border- — объект класса XLSXManager.FormattedCell.Border.

Определенные поля XLSXManager.FormattedCell.Border имеют значения:

  • position"top", "left", "right", "bottom".
  • width — число точек.

Баги парсера

  • Пустая формула (если набрать просто знак = в ячейку) не должна вызывать ошибку. Значение в событии должно быть undefined.
  • При парсинге токенов нужно проверять все символы. Некорректные символы должны вызывать синтаксическую ошибку. Сейчас если набрать =1.5, в парсере возникнет неперехваченное исключение

Относительные и абсолютные адреса ячеек

Нужно добавить поддержку относительных и абсолютных адресов строк и столбцов ячеек.
Адрес абсолютный, если он не меняется при копировании или перемещении ячейки.
Если адрес строки или столбца абсолютный, перед индексом стоит символ $. Например, $A1, A$1, $A$1

  • Добавляем токены: FUNCTION, CELL_REFERENCE.
    • Если токен, который раньше был IDENTIFIER, может представлять собой только функцию, тогда этот токен записывается как FUNCTION. Пример: SUM, STRING, LOLOLOLOL, A01
    • Если токен, который раньше был IDENTIFIER, может представлять собой только ссылку на ячейку, то этот токен записывается как CELL_REFERENCE. Пример: $A1, A$99, $ZZ$666
    • Если на этапе лексического анализа нельзя определить, является токен ссылкой на ячейку или функцией, он записывается как IDENTIFIER. Примеры: A1, ZZ666, LOG10
  • Как следствие, $ входит в токен CELL_REFERENCE (или IDENTIFIER согласно грамматике). Некорректные записи вроде A$B1, $$A1, A1$ должны вызывать синтаксическую ошибку.
  • При парсинге если ссылка на ячейку содержит абсолютный адрес, нужно устанавливать свойства соответствующего объекта класса Spreadsheet._CellReference соответственно rowFixed = true | false, columnFixed = true | false

Model logic: Вычисление формул

Задача: Реализовать механизм хранения формул в памяти

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

Входные данные: строка-формула
Выходные данные: объект, хранящий информацию о ссылках на ячейки таблицы и операциях, которые необходимо произвести, для вычисления значения клетки

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.