From ebd8b8f6c7dbd76b0e1f33c84bfdf2378d4d9ca9 Mon Sep 17 00:00:00 2001 From: EricRovell Date: Mon, 23 Oct 2023 15:07:42 +0300 Subject: [PATCH] feat(project): rational project blogpost --- src/content/project/rational/index.en.svx | 49 +++++++++++++++++++++++ src/content/project/rational/index.ru.svx | 41 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/content/project/rational/index.en.svx b/src/content/project/rational/index.en.svx index 3badd8c5..43c01b9d 100644 --- a/src/content/project/rational/index.en.svx +++ b/src/content/project/rational/index.en.svx @@ -22,3 +22,52 @@ "title": "rational" } --- + +## Starting point + +This project's starting point goes way back to the distant path, dating back before I became a web-developer. At that time I was learning the basics of *python* language (things did not go further than basics). Becoming familiar with OOP I have got the idea of implementing the rational numbers support. At that moment *python* provided built-in [`Fraction`](https://docs.python.org/3/library/fractions.html) module, but the interface seemed to basic for me. + +Quite possible considering the language, the problem, and existing module, I was reinventing the wheel. At that moment it should not be a problem, in my opinion. The task seemed to be possible for my level and it was really interesting for me. + +The project was finished and I was pleased with the result. Thanks to the project I learned more about OOP and *python* itself. Obviously, the project was not published and was completely forgotten deep in file system of my laptop. + +## Second encounter + +After quite a while, as can be seen in most of my projects, I decided to come back to the project. There were some rationale behind this decision. At that moment I was on my way to become a web-developer and the language I was using to do the job was (what a surprise!) *JavaScript*, and I already had some experience of planning and deploying projects. + +Most importantly, *JavaScript* do not have a rational numbers support. And I was thinking that it would be a nice idea to create a library for it. I could get some experience, refresh the knowledge of more or less simple math topic. And, maybe, just maybe if a library turned out to be good, the community may find it useful. + +So, I have decided to implement a library, call it `rational` and publish it on *npm*. + +## The process + +The development process was quite pleasing and productive. I have already got the experience of package publishing and other stuff required to do the job. + +Before the work I did some research, learned from existing libraries what does such a library should have under it's belt to be competitive. After that the interface was planned and it was developed using *TypeScript*. + +As a result, the zipped package was just a *2 kb* in size, it seemed like a really good result considering the functionality was built in. + +### User input + +More or less most such a libraries has the same interface. You can create instances and make some operations. You can read what a `rational` can do in [documentation](https://github.com/EricRovell/rational). But I would like to highlight the flexibility of user input: + +- `(n?: int = 0, d?: int = 1)` — integer *numerator* and *denominator* values as parameters; +- `(input: [ n: int = 0, d?: int = 1 ])` — integer *numerator* and *denominator* values as an array; +- `(input: { int?: number = 0, n: int, d?: int = 1 })` — integer *numerator* and *denominator* values and optional *integer* part as an object; +- `(input: StringFraction)` — a string in format of `"{sign?}{numerator}/{sign?}`; +- `(input: RepeatingDecimal)` — a periodic continued fraction as an object; +- `(input: StringRepeatingDecimal)` — a string as periodic continued fraction in format of `{sign?}{int?}.{non-repeating}?({repeating})`; +- `(input: Degrees)` — degree measure value as an object; +- `(input: StringDegrees)` — a degree measure string in format of `{sign?}{degrees?}.{minutes'?}{seconds''?}`. + +What makes it even greater the same user input can be used in most methods where another `rational` instance would be required. + +## Summarizing + +The project itself cannot be considered something outstanding; any developer with a couple of years experience can easily write such a project. However, I was pleased with the result considering my self-criticism and attention to details. + +The library is packed with types, the user input types are included for a developer, covered with unit tests, has a good documentation and a functionality covering all needs you may need working with rational numbers. In case a developer need something specific, library is naturally extendable and written using modern *JavaScript* syntax. + +There are some limitations considering the `Number` data type. I was considering using [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) instead, but I had doubts that people may need such an extreme values using this library and the performance dropped significantly (up to 10x). + +There are some plans for this project to be a part of some other educational projects in future. The project itself is maintained and always is up to date. diff --git a/src/content/project/rational/index.ru.svx b/src/content/project/rational/index.ru.svx index 6a3bc862..8e745d5a 100644 --- a/src/content/project/rational/index.ru.svx +++ b/src/content/project/rational/index.ru.svx @@ -22,3 +22,44 @@ "title": "rational" } --- + +## Истоки проекта + +Проект уходит корнями к дальнему прошлому, датируемому ещё до моего увлечения веб-разработкой. На тот момент я только изучал основы *python* (дальше знакомства с основами дело, увы, не зашло). Ознакомившись с различными типами данных и изучая ООП, пришла идея реализовать поддержку рациональных чисел c более обширным интерфейсом, нежели предоставленный в то время и в том виде модуль [`Fraction`](https://docs.python.org/3/library/fractions.html). Вполне возможно, что в контексте самого языка с учётом имеющегося уже модуля, я переизобретал велосипед. Вполне возможно так оно и было. Тем не менее, задача была мне под силам и непосредственно интересна. + +Проект получился и я был доволен результатом; благодаря нему смог лучше проникнуться принципами ООП, узнать достаточно много нового. Разумеется, проект нигде не был опубликован и был благополучно забыт где-то в архивах файловой системы ноутбука. + +## Мотивация + +Спустя время, как это можно заметить за многими моими проектами, решил вернуться вновь и попытаться реализовать проект снова. Только в тот момент я уже был веб-разработчикам и основным моим языком был (какая неожиданность!) — *JavaScript*. В отличие от того времени я уже имел некоторый опыт, уверенно владел языком и лучше понимал процесс работы над проектами и процессы, связанные с ними. + +*JavaScript* сложно сравнивать с *python*, подходы к ООП разительно отличаются друга от друга (да, в *JavaScript* нет ООП как такого). В *JavaScript* отсутствует возможность работы с рациональными числами и наличие такой возможности могло бы действительно принести пользу моим потенциальным проектам, а возможно и даже сообществу. Было решено написать полноценную библиотеку и опубликовать её на *npm*. + +## Процесс + +Работа над библиотекой оказалась довольно приятной и продуктивной. Перед тем как написать первую строчку кода, изучил уже существующие решения для лучшего понимания функционала для достаточной конкуренции и в целом, понимания пользовательских требований к аналогичным решениям. Создание проекта оказалось разумным шагом, так как существующие альтернативы были написаны относительно давно, без использования современных возможностей *JavaScript* и все же не было того проекта, который бы собрал всё лучшее воедино. + +К тому моменту уже имелся опыт публикаций пакетов, понимание необходимых для того процессов, настройки окружения и умения писать модульные тесты. Проект был реализован с использованием *TypeScript*. По итогу, в сжатом виде библиотека умещалась в *2кб*, что мне показалось весьма неплохим показателем, учитывая реализованный функционал. + +### Пользовательский ввод + +Все библиотеки с поддержкой рациональных чисел имеют более или менее схожий интерфейс: предоставляется возможность создавать экземпляры объекта и проводить с ними операции. Почитать более подробно о функциональности *rational* можно в [документации](https://github.com/EricRovell/rational). Здесь же хотелось бы выделить достаточно гибкий пользовательский ввод: + +- `(n?: int = 0, d?: int = 1)` — целочисленные значения числителя и знаменателя двумя параметрами; +- `(input: [ n: int = 0, d?: int = 1 ])` — целочисленные значения числителя и знаменателя массивом; +- `(input: { int?: number = 0, n: int, d?: int = 1 })` — целочисленные значения целой части, числителя и знаменателя объектом; +- `(input: StringFraction)` — строки в формате дробного выражения в формате `"{sign?}{numerator}/{sign?}`; +- `(input: RepeatingDecimal)` — периодической дроби в виде объекта; +- `(input: StringRepeatingDecimal)` — строки в виде периодической дроби в формате `{sign?}{int?}.{non-repeating}?({repeating})`; +- `(input: Degrees)` — градусной меры в виде объекта; +- `(input: StringDegrees)` — градусной меры в виде строки в формате `{sign?}{degrees?}.{minutes'?}{seconds''?}`. + +И ещё большее удобство достигается не только за счёт гибкости ввода, но и поддержки аналогичных опций при работе с экземплярами объектов. Например, при суммировании не обязательно предоставлять другой экземпляр, достаточно передать валидный пользовательский ввод. + +## Резюмируя + +Библиотека сама по себе не является чем-то выдающимся, написать такое вполне может любой разработчик с парой лет опыта. Тем не менее, я оказался доволен результатом, что случается крайне редко из-за завышенных требований к самому себе. Библиотека типизированна, предоставляет необходимые типы, покрыта тестами, имеет достаточно неплохую документацию и покрывающий все потребности функционал. В случае необходимости `rational` поддерживает расширяемость и в целом, использовался современный JavaScript. + +У библиотеки присутствуют некоторые очевидные ограничения связанные с числовым типом `Number`, а именно с максимальным целочисленным значением. Была идея использовать [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt), но меня посещали сомнения касательно необходимости в таких больших значениях при использовании библиотеки. Особенно учитывая падение производительности (до 10 раз). + +Планирую в будущем написать несколько учебных проектов с её использованием. Проект поддерживается, и всегда находится в актуальном состоянии.