Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(project): rational project blogpost #134

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/content/project/rational/index.en.svx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <abbr title="Object Oriented Programming">OOP</abbr> 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 <abbr title="Object Oriented Programming">OOP</abbr> 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.
41 changes: 41 additions & 0 deletions src/content/project/rational/index.ru.svx
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,44 @@
"title": "rational"
}
---

## Истоки проекта

Проект уходит корнями к дальнему прошлому, датируемому ещё до моего увлечения веб-разработкой. На тот момент я только изучал основы *python* (дальше знакомства с основами дело, увы, не зашло). Ознакомившись с различными типами данных и изучая <abbr title="Объектно-ориентированное программирование">ООП</abbr>, пришла идея реализовать поддержку рациональных чисел c более обширным интерфейсом, нежели предоставленный в то время и в том виде модуль [`Fraction`](https://docs.python.org/3/library/fractions.html). Вполне возможно, что в контексте самого языка с учётом имеющегося уже модуля, я переизобретал велосипед. Вполне возможно так оно и было. Тем не менее, задача была мне под силам и непосредственно интересна.

Проект получился и я был доволен результатом; благодаря нему смог лучше проникнуться принципами <abbr title="Объектно-ориентированное программирование">ООП</abbr>, узнать достаточно много нового. Разумеется, проект нигде не был опубликован и был благополучно забыт где-то в архивах файловой системы ноутбука.

## Мотивация

Спустя время, как это можно заметить за многими моими проектами, решил вернуться вновь и попытаться реализовать проект снова. Только в тот момент я уже был веб-разработчикам и основным моим языком был (какая неожиданность!) — *JavaScript*. В отличие от того времени я уже имел некоторый опыт, уверенно владел языком и лучше понимал процесс работы над проектами и процессы, связанные с ними.

*JavaScript* сложно сравнивать с *python*, подходы к <abbr title="Объектно-ориентированное программирование">ООП</abbr> разительно отличаются друга от друга (да, в *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 раз).

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