📚 go-propisyu - Awesome Go Library for Natural Language Processing

Go Gopher mascot for go-propisyu

Convert numbers to Russian words with correct grammatical gender and noun declension

🏷️ Natural Language Processing
📂 Morphological Analyzers
0 stars
View on GitHub 🔗

Detailed Description of go-propisyu

go-propisyu · Числа прописью на Go

Русская версия · English version

CI Go Reference Go Report Card codecov License: MIT Go Version

go-propisyu — Go-библиотека для конвертации чисел в слова на русском языке с правильными склонениями и грамматическими родами. Числа прописью нужны в счетах, фискальных чеках, бухгалтерских документах, банковских выписках, голосовых ассистентах, чат-ботах и любых сервисах, где необходимо грамотно записывать суммы и количества словами.

propisyu.IntToWords(42)                              // "сорок два"
propisyu.Decline(5, "рубль", "рубля", "рублей")      // "рублей"
propisyu.DecimalToWords("1234.56")                    // "одна тысяча двести тридцать четыре целых пятьдесят шесть сотых"

Кому подходит

СфераПример
Финтех и банкингСумма прописью в платёжных поручениях и выписках
Бухгалтерия и 1СГенерация счетов-фактур, актов, накладных
Фискальные чекиКасса / ОФД — сумма словами по 54-ФЗ
Голосовые ассистентыTTS-озвучка сумм и количеств
Чат-ботыОтветы с суммами на естественном языке
Генерация документовШаблоны договоров, доверенностей, актов

Ключевые особенности

  • Поддержка огромных чисел вплоть до дуодециллионов (10³⁹)
  • Грамматические роды: мужской, женский и средний для корректных окончаний
  • Функция Decline для автоматического склонения существительных
  • Работа с десятичными числами через строки или decimal.Decimal
  • Нулевые внешние зависимости для базовых функций
  • Высокое покрытие тестами, CI/CD, линтер

Содержание

Установка

go get github.com/rekurt/go-propisyu

Для работы с decimal.Decimal:

go get github.com/shopspring/decimal

Публичные функции

ФункцияОписание
IntToWords(n int) stringКонвертирует целое число в слова (мужской род)
IntToWordsGender(n int, gender Gender) stringКонвертирует целое число в слова с указанием рода
DecimalToWords(decimalStr string) (string, error)Конвертирует десятичное число из строки в слова
DecimalValueToWords(d decimal.Decimal) (string, error)Конвертирует decimal.Decimal значение в слова
Decline(n int, one, two, five string) stringВыбирает правильную форму склонения существительного

Константы рода

const (
    GenderMasculine Gender = 1  // Мужской род: "один", "два"
    GenderFeminine  Gender = 2  // Женский род: "одна", "две"
    GenderNeuter    Gender = 3  // Средний род: "одно", "два"
)

Ошибки

  • ErrNumberTooLarge - число слишком велико для конвертации (не помещается в int)

Быстрый старт

Целые числа

package main

import (
	"fmt"

	"github.com/rekurt/go-propisyu"
)

func main() {
	// Базовая конвертация (мужской род по умолчанию)
	fmt.Println(propisyu.IntToWords(321))
	// триста двадцать один

	// Конвертация с указанием рода
	fmt.Println(propisyu.IntToWordsGender(2, propisyu.GenderFeminine))
	// две

	fmt.Println(propisyu.IntToWordsGender(2, propisyu.GenderMasculine))
	// два

	// Автоматическое склонение существительных
	fmt.Println(propisyu.Decline(1, "рубль", "рубля", "рублей"))   // рубль
	fmt.Println(propisyu.Decline(2, "рубль", "рубля", "рублей"))   // рубля
	fmt.Println(propisyu.Decline(5, "рубль", "рубля", "рублей"))   // рублей
	fmt.Println(propisyu.Decline(21, "рубль", "рубля", "рублей"))  // рубль
}

Десятичные числа

Способ 1: Используя строку

package main

import (
	"fmt"
	"log"

	"github.com/rekurt/go-propisyu"
)

func main() {
	result, err := propisyu.DecimalToWords("123.45")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result)
	// сто двадцать три целых сорок пять сотых
}

Способ 2: Используя decimal.Decimal

package main

import (
	"fmt"
	"log"

	"github.com/rekurt/go-propisyu"
	"github.com/shopspring/decimal"
)

func main() {
	d := decimal.NewFromFloat(123.45)
	result, err := propisyu.DecimalValueToWords(d)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result)
	// сто двадцать три целых сорок пять сотых
}

Примеры использования

Сумма прописью для чека

package main

import (
	"fmt"

	"github.com/rekurt/go-propisyu"
)

func main() {
	amount := 1234
	rubles := propisyu.IntToWords(amount)
	rublesDecl := propisyu.Decline(amount, "рубль", "рубля", "рублей")

	fmt.Printf("%s %s 00 копеек", rubles, rublesDecl)
	// одна тысяча двести тридцать четыре рубля 00 копеек
}

Большие числа

package main

import (
	"fmt"
	"log"

	"github.com/rekurt/go-propisyu"
)

func main() {
	result, err := propisyu.DecimalToWords("6453345242432.42")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result)
	// шесть триллионов четыреста пятьдесят три миллиарда
	// триста сорок пять миллионов двести сорок две тысячи четыреста тридцать два
	// целых сорок две сотых
}

Склонение с разными существительными

package main

import (
	"fmt"

	"github.com/rekurt/go-propisyu"
)

func main() {
	count := 5

	// Валюты
	fmt.Println(count, propisyu.Decline(count, "доллар", "доллара", "долларов"))
	// 5 долларов

	// Единицы измерения
	fmt.Println(count, propisyu.Decline(count, "метр", "метра", "метров"))
	// 5 метров

	// Предметы
	fmt.Println(count, propisyu.Decline(count, "товар", "товара", "товаров"))
	// 5 товаров

	// Для 21
	count = 21
	fmt.Println(count, propisyu.Decline(count, "день", "дня", "дней"))
	// 21 день
}

API

Функции для целых чисел

IntToWords(n int) string

Конвертирует целое число в слова (мужской род по умолчанию).

propisyu.IntToWords(42)    // "сорок два"
propisyu.IntToWords(1000)  // "одна тысяча"

IntToWordsGender(n int, gender Gender) string

Конвертирует целое число в слова с указанием рода.

Доступные роды:

  • GenderMasculine (1) - мужской род
  • GenderFeminine (2) - женский род
  • GenderNeuter (3) - средний род
propisyu.IntToWordsGender(2, propisyu.GenderMasculine)  // "два"
propisyu.IntToWordsGender(2, propisyu.GenderFeminine)   // "две"
propisyu.IntToWordsGender(1, propisyu.GenderNeuter)     // "одно"

Функции для десятичных чисел

DecimalToWords(decimalStr string) (string, error)

Конвертирует десятичное число из строки в слова. Дробная часть обрезается до 2 знаков.

result, err := propisyu.DecimalToWords("3.14")
// "три целых четырнадцать сотых"

DecimalValueToWords(d decimal.Decimal) (string, error)

Конвертирует decimal.Decimal значение в слова. Дробная часть обрезается (не округляется!) до 2 знаков.

d := decimal.NewFromFloat(3.14159)
result, err := propisyu.DecimalValueToWords(d)
// "три целых четырнадцать сотых" (не округляет 3.14159 до 3.14, а обрезает)

Важно: Функция обрезает (truncate), а не округляет:

  • 1.999 → "один целых девяносто девять сотых"
  • 1.995 → "один целых девяносто девять сотых"

Функция склонения

Decline(n int, one, two, five string) string

Выбирает правильную форму существительного в зависимости от числа.

Параметры:

  • n - число
  • one - форма для 1, 21, 31... (рубль, день, товар)
  • two - форма для 2-4, 22-24... (рубля, дня, товара)
  • five - форма для 0, 5-20, 25-30... (рублей, дней, товаров)
propisyu.Decline(1, "рубль", "рубля", "рублей")   // "рубль"
propisyu.Decline(2, "рубль", "рубля", "рублей")   // "рубля"
propisyu.Decline(5, "рубль", "рубля", "рублей")   // "рублей"
propisyu.Decline(11, "рубль", "рубля", "рублей")  // "рублей"
propisyu.Decline(21, "рубль", "рубля", "рублей")  // "рубль"

Почему go-propisyu

  • Чистый Go — не обёртка над C-библиотекой, легко компилировать и деплоить
  • Корректная грамматика — три рода, правильные склонения для всех числовых диапазонов
  • Без зависимостейIntToWords и Decline работают без сторонних пакетов
  • production-ready — CI с линтером, тесты, семантическое версионирование, goreleaser
  • Открытая лицензия — MIT, можно использовать в коммерческих проектах

Ограничения

  • Целые числа: поддерживаются значения в диапазоне int (обычно -2³¹ до 2³¹-1 или -2⁶³ до 2⁶³-1)
  • Десятичные числа: поддерживаются только 2 знака после запятой (остальное обрезается)
  • DecimalValueToWords вернет ошибку ErrNumberTooLarge, если число не помещается в int

Тесты

go test ./...              # Запустить все тесты
go test -v ./...           # С подробным выводом
go test -cover ./...       # С покрытием кода

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

Лицензия

MIT