morpher.ru 8 (499) 647 86 54
nowhere@morpher.ru
 
 

Склонение по падежам на C# / VB.NET

Morpher.dll – это .NET-библиотека, реализующая функции склонения по падежам, автоматического определения рода словосочетания и прописи чисел на русском языке. Данная страница посвящена в основном технической стороне использования библиотеки; лингвистическая сторона вопроса раскрыта на странице Описание технологии склонения.

Реализованные функции

Весь API библиотеки можно представить следующим кодом:

namespace Slepov.Russian.Morpher
{
    public class Склонятель 
    {
        public Склонятель (string key, TextReader userDict = null);

        public IСклоняемое Проанализировать (
            string словосочетание, 
            params Признак [] признаки);

        public string Пропись (int n, ref string unit, 
            Падеж падеж = Падеж.Именительный);
    }
}

Технические характеристики

  • Поддерживаемые платформы: .NET 2.0 – 4.5, Silverlight 5, DIRECTUM 5.0.
  • Код библиотеки написан полностью на C# и скомпилирован для платформы MSIL (AnyCPU).
  • Библиотека не имеет никаких внешних зависимостей, не имеет интерфейса пользователя и не требует прав доступа к диску или сети.
  • Все public методы библиотеки потокобезопасны, что особенно актуально при её использовании в серверных приложениях. Потокобезопасность достигается без использования блокировок.

Комплект поставки

Morpher.dll ~400K Сама библиотека.
Morpher.xml ~10K Файл XML-комментариев для отображения подсказок в Visual Studio.

Функция склонения по падежам и числам

public IСклоняемое Проанализировать (string словосочетание, params Признак [] признаки);

Параметры:

словосочетание – слово или словосочетание для склонения. Должно быть на русском языке, иначе функция выдает null.

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

public enum Признак
{
    ФИО, 
    Нарицательное, 
    МужскойРод,
    ЖенскийРод,
    Одушевлённое,
    Неодушевлённое
}

Подробнее об использовании признаков

Возвращает IСклоняемое.

Использование функции склонения проще всего проиллюстрировать на примере. Вот пример кода на C# для формирования текста, в котором одно и то же ФИО фигурирует в различных падежах:

    class HelloIvanIvanych
    {
        static void Main ()
        {
            Склонятель склонятель = new Склонятель ();
 
            IСклоняемое получатель = склонятель.Проанализировать ("Иванов Иван Иваныч");
 
            string справка = @"
                             СПРАВКА
               Выдана {0} в том, что 
            {1} была получена справка
            в том, что {2} не нуждается 
            более в получении никаких справок.";
 
            System.Console.WriteLine (
                справка, 
                получатель.Дательный,
                получатель.Творительный,
                получатель.Именительный);
        }
    }

(Да, это C# – он допускает использование русских букв в именах переменных и классов.)

Программа выдает в консольное окно следующий текст:


                                 СПРАВКА
                   Выдана Иванову Ивану Иванычу в том, что
                Ивановым Иваном Иванычем была получена справка
                в том, что Иванов Иван Иваныч не нуждается
                более в получении никаких справок.
    

Склонение производится за три этапа:

  • Создание экземпляра класса Склонятель.
  • Вызов метода Проанализировать.
  • Чтение одного из свойств интерфейса IСклоняемое для получения формы нужного падежа.

Вы можете спросить, зачем такие сложности? Почему бы не сделать API в виде одной функции:

public static string Просклонять (string s, Падеж падеж);

Это сделано для повышения быстродействия. Первый этап – создание экземпляра класса Склонятель – включает в себя загрузку словаря в память и занимает 100-200 миллисекунд. Вроде бы немного, но помещать эту операцию в цикл не стоит.

Второй этап – анализ – относительно сложный процесс, который включает в себя поиск по словарю и анализ синтаксической структуры словосочетания. Результат этого анализа, объект IСклоняемое, используется на третьем, последнем, этапе для генерации форм различных падежей единственного и множественного числа. Если необходимо генерировать несколько падежных форм, как в примере выше, то время экономится, т.к. анализ проводится всего один раз.

Знание этих особенностей позволяет сделать программу молниеносной. Приведу пример. Для контроля качества склонения используется база тестов, где каждый тест состоит из трех частей:

  • пример словосочетания в именительном падеже
  • идентификатор падежа
  • «правильный ответ» – как это словосочетание должно выглядеть в данном падеже.

Все тесты были составлены вручную. Я постоянно экспериментирую с алгоритмом склонения и каждый раз, внося изменения в программу, прогоняю все тесты, чтобы быть уверенным, что качество склонения не ухудшилось. На данный момент (1 сентября 2011 г.) объем базы составляет более 18 тысяч тестов. Поэтому мне важно, чтобы тесты прогонялись как можно быстрее.

Теперь внимание, вопрос! Как вы думаете, сколько времени занимает прогон всех тестов? Подсказка Ответ

Свойства интерфейса IСклоняемое

Объект IСклоняемое представляет собой совокупность форм одного числа (единственного или множественного).

Название свойства Тип возвращаемого значения Описание
Именительный string Возвращает форму именительного падежа.
Родительный string Возвращает форму родительного падежа.
Дательный string Возвращает форму дательного падежа.
Винительный string Возвращает форму винительного падежа.
Творительный string Возвращает форму творительного падежа.
Предложный string Возвращает форму предложного падежа с предлогом О/ОБ/ОБО (о компьютере).
ПредложныйБезПредлога string Возвращает форму предложного падежа без предлога (компьютере).
Где string Возвращает форму, отвечающую на вопрос где?в России, во Франции, в Крыму, на Канарах. Предлог выбирается автоматически.
Куда string Возвращает форму, отвечающую на вопрос куда?в Россию, во Францию, в Крым, на Канары. Предлог выбирается автоматически.
Откуда string Возвращает форму, отвечающую на вопрос откуда?из России, из Франции, из Крыма, с Канар. Предлог выбирается автоматически.
РодЧисло РодЧисло Возвращает род и число словосочетания в виде enum РодЧисло {ЕдинМуж, ЕдинЖен, ЕдинСред, Множ}
Множественное IСклоняемое Возвращает объект IСклоняемое, представляющий набор форм множественного числа или null, если склоняемое уже во множественном числе.

Определение рода и числа

Пример вызова:

switch (склонятель.Проанализировать("Чулпан").РодЧисло)
{
    case РодЧисло.ЕдинМуж: return "мужской род";
    case РодЧисло.ЕдинЖен: return "женский род";
    case РодЧисло.ЕдинСред: return "средний род";
    case РодЧисло.Множ: return "множественное число";
} 

Идентификация фамилии, имени и отчества в строке

Эта функция позволяет выделить в строке имя, фамилию и отчество. Например:

[TestMethod]
public void Александр_Сергеевич_Пушкин()
{
    var склоняемое = склонятель.Проанализировать ("Александр Сергеевич Пушкин");

    Assert.AreEqual ("Пушкин",    склоняемое.ФИО.Фамилия);
    Assert.AreEqual ("Александр", склоняемое.ФИО.Имя);
    Assert.AreEqual ("Сергеевич", склоняемое.ФИО.Отчество);
}

Фамилия, имя и отчество могут располагаться в строке в любом (грамматически допустимом) порядке. Отдельные компоненты ФИО могут отсутствовать, например:

На входе Фамилия Имя Отчество
Александр Сергеевич   Александр Сергеевич
Валентина Маркова Маркова Валентина  
Михаил Богданович Барклай-де-Толли Барклай-де-Толли Михаил Богданович
АГАЕВ ФАРИД ЗАКИР ОГЛЫ АГАЕВ ФАРИД ЗАКИР ОГЛЫ

В случае, если входная строка не распознана как ФИО, свойство ФИО будет равно null.

Склонение прилагательных по родам

string ИзменитьРод (string прилагательное, РодЧисло родЧисло);
    

Функция принимает на вход прилагательное в форме именительного падежа мужского рода, а также род и число, в которые его необходимо поставить. Вот пример функции, которая согласует прилагательное с существительным:

string Согласовать (string прилагательное, string существительное)
{
    return склонятель.ИзменитьРод (прилагательное, 
           склонятель.Проанализировать (существительное).Род) + " " + существительное;
}

Для прилагательного острый и существительных нож, бритва, копье, ножницы функция выдаст соответственно:

  • острый нож
  • острая бритва
  • острое копье
  • острые ножницы

Функция возвращает null, если:

  • входная строка равна null;
  • входная строка не может быть распознана как одно полное прилагательное или причастие в форме мужского рода именительного падежа единственного числа.

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

Функция прописи чисел в заданном падеже

string Пропись (decimal n, ref string unit, Падеж падеж = Падеж.Именительный);
    

Возвращает пропись числа n, например, «сто двадцать пять» или «три целых две десятых» в указанном падеже (онлайн-демо). Если параметр unit не является словом или словосочетанием на русском языке или слово не имеет нужной падежной формы, то функция возвращает null.

Параметры:

n – число, пропись которого строится. Есть также перегруженный вариант метода для типа int. Функция работает для любых значений типов int и decimal. Для отрицательных значений пропись начинается со слова «минус». Для 0.0 – «ноль».

unit – единица измерения – слово или словосочетание на русском языке в именительном падеже единственного числа: «рубль», «доллар США», «календарный день», «новое письмо» и т.п. Если слово употребляется только во множественном числе, то указывается форма именительного падежа множественного числа: «сутки», «брюки», «ножницы».

падеж – при указании падежа пропись и единица измерения ставятся в заданный падеж. Единица измерения (unit) склоняется в большинстве случаев, даже если указан именительный падеж, как того требуют правила русского языка: «один рубль», «три рубля», «пять рублей», «пяти рублям», «пяти рублей» и т.п. Результат возвращается через тот же параметр unit (для этого указан модификатор ref).

Пример 1. Сумма прописью

Существует множество вариантов написания «суммы прописью». Программист, приступающий к решению этой задачи, должен ответить для себя на множество вопросов:

  1. Названия денежных единиц писать полностью или сокращенно?
  2. Выводить копейки числом или прописью или и так, и так?
  3. Брать в скобки только пропись или все выражение, следующее за суммой цифрами?
  4. Писать пропись со строчной или заглавной буквы?
  5. Писать ли названия денежных единиц после всей суммы цифрами?
  6. Как отображать ноль копеек: 00, словом «ровно» или знаком =?
  7. Как отображать ноль рублей?

В результате число возможных вариантов может исчисляться сотнями. Вот неполный список примеров:

  1. 333,12 руб. (Триста тридцать три рубля 12 копеек)
  2. 333 р. 12 коп. (Триста тридцать три рубля 12 копеек)
  3. 333,12 (триста тридцать три рубля двенадцать копеек)
  4. 333,12 (триста тридцать три рубля 12 копеек)
  5. 333,12 (триста тридцать три) рубля 12 копеек
  6. 333 (триста тридцать три) руб. 12 коп.
  7. 333 (триста тридцать три) рубля 12 копеек
  8. 333 (триста тридцать три) рубля 12 (двенадцать) копеек
  9. 333,12 (триста тридцать три и 12/100) руб.

На практике выбор того или иного варианта прописи определяется видом документа, где она фигурирует, и нормами конкретного предприятия. То есть проблема эта не лингвистическая, а бюрократическая. Поэтому в библиотеке нет готовой функции формирования суммы прописью, но ниже дан пример одного из возможных вариантов. Морфер делает за вас трудную работу по склонению и формированию прописи отдельных чисел, а как расставлять скобки и точки – решать вам:

    class ДенежнаяЕдиница 
    {
        public string ПолноеНаименованиеЦелойЧасти {get; set;}
        public string ПолноеНаименованиеДробнойЧасти {get; set;}
        public string СокращенноеНаименованиеЦелойЧасти {get; set;}
        public string СокращенноеНаименованиеДробнойЧасти {get; set;}

        public string СуммаПрописью (decimal summa, Падеж падеж = Падеж.Именительный)
        {
            var sb = new StringBuilder ();

            sb.Append (summa.ToString ("N2"));
            sb.Append (' ');
            sb.Append (СокращенноеНаименованиеЦелойЧасти);
            sb.Append (' ');
            sb.Append ('(');
            int i = sb.Length; // запомнить позицию первой буквы прописи
            sb.Append (Прописью (Math.Floor (summa), ПолноеНаименованиеЦелойЧасти, падеж));
            sb.Append (' ');
            sb.Append (Цифрами (summa * 100 % 100, ПолноеНаименованиеДробнойЧасти, падеж));
            sb.Append (')');

            sb [i] = char.ToUpper (sb [i]); // сделать первую букву прописи заглавной

            return sb.ToString ();
        }

        static string Прописью (decimal n, string unit, Падеж падеж)
        {
            return склонятель.Пропись (n, ref unit, падеж) + " " + unit;
        } 

        static string Цифрами (decimal n, string unit, Падеж падеж)
        {
            склонятель.Пропись (n, ref unit, падеж);
            return n.ToString ("00") + " " + unit;
        } 

        static readonly Склонятель склонятель = new Склонятель ();
    }

Вот как этот класс можно использовать:

        var рубли = new ДенежнаяЕдиница {
            ПолноеНаименованиеЦелойЧасти = "рубль",
            ПолноеНаименованиеДробнойЧасти = "копейка",
            СокращенноеНаименованиеЦелойЧасти = "руб."
        };

        var евро = new ДенежнаяЕдиница {
            ПолноеНаименованиеЦелойЧасти = "евро",
            ПолноеНаименованиеДробнойЧасти = "цент",
            СокращенноеНаименованиеЦелойЧасти = "евро"
        };

        Console.WriteLine (рубли.СуммаПрописью (100m));
        Console.WriteLine (рубли.СуммаПрописью (300333.12m));
        Console.WriteLine (евро.СуммаПрописью (400444.44m));
        Console.WriteLine ("За вычетом " 
            + рубли.СуммаПрописью (333.12m, Падеж.Родительный));

В результате получим:

100,00 руб. (Сто рублей 00 копеек)
300 333,12 руб. (Триста тысяч триста тридцать три рубля 12 копеек)
400 444,44 евро (Четыреста тысяч четыреста сорок четыре евро 44 цента)
За вычетом 333,12 руб. (Трёхсот тридцати трёх рублей 12 копеек)

Пример 2. Цена договора с НДС

string ПрописьРуб (Падеж падеж, int n)
{
    string unit = "рубль";  
    return n + " (" + склонятель.Пропись (n, ref unit, падеж) + ") " + unit;
} 

int цена = 1800;
Console.Write ("Цена договора составляет {0}, ", 
        ПрописьРуб (Падеж.Винительный, цена));
Console.Write ("в том числе НДС в размере {0}.", 
        ПрописьРуб (Падеж.Родительный, (int) (цена * 0.18 / 1.18)));

// Цена договора составляет 1800 (одну тысячу восемьсот) рублей, 
// в том числе НДС в размере 274 (двухсот семидесяти четырёх) рублей.

Пример 3. Перечень товаров

var товары = new []
{
    new {Наименование = "шампур из нержавеющей стали", Количество = 12},
    new {Наименование = "решетка-гриль", Количество = 2},
    new {Наименование = "щипцы для углей", Количество = 1},
};

foreach (var товар in товары)
{
    string unit = товар.Наименование;

    Console.WriteLine ("{0,-30} {1,2} ({2})", 
        товар.Наименование, 
        товар.Количество, 
        склонятель.Пропись (товар.Количество, unit));
}

// шампур из нержавеющей стали    12 (двенадцать)
// решетка-гриль                   2 (две)
// щипцы для углей                 1 (одни)

Пример 4. Социальная сеть

string Новых (int n, string unit)
{
    unit = склонятель.ИзменитьРод ("новый ", склонятель.Проанализировать (unit).РодЧисло) + unit;
    склонятель.Пропись (n, ref unit);
    return n + " " + unit;
} 

Console.WriteLine ("У вас " + Новых (5, "друг"));      // «У вас 5 новых друзей»
Console.WriteLine ("У вас " + Новых (1, "сообщение")); // «У вас 1 новое сообщение»
Console.WriteLine ("У вас " + Новых (2, "подарок"));   // «У вас 2 новых подарка»

Пример 5. День рождения

string Исполнилось (string кто, int сколько)
{
    string unit = "год";
    склонятель.Пропись (сколько, ref unit);
    return склонятель.Проанализировать (кто).Дательный 
        + " " + сколько + " " + unit;
}

Console.WriteLine (Исполнилось ("Анечка", 2)); // «Анечке 2 года»
Console.WriteLine (Исполнилось ("Вовочка", 5)); // «Вовочке 5 лет»
Console.WriteLine (Исполнилось ("Иван Иванович", 51)); // «Ивану Ивановичу 51 год»
Console.WriteLine (Исполнилось ("мы", 10)); // «нам 10 лет»

Попробуйте функцию «Пропись» в действии на сайте summa-pro.ru.

Защита от несанкционированного использования

Часть сборки Morpher.dll зашифрована и для ее правильной работы необходим лицензионный ключ. Ключ передается в конструктор класса Склонятель:

var склонятель = new Склонятель ("bApmPNweXmg=");
    

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

Пользовательский словарь

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

Чтобы подключить словарь к библиотеке, нужно передать его в конструктор класса Склонятель:

var склонятель = new Склонятель ("fbvB3vWfnrXQ==", new StreamReader ("MyDict.xml"));

Вызывать StreamReader.Dispose необязательно — за вас это сделает библиотека.

IUserDictionary

Имеется также конструктор, принимающий пользовательский словарь в виде интерфейса IUserDictionary:

public Склонятель (string key, IUserDictionary userDict);
    

Интерфейс имеет один метод, который возвращает словарную статью по заданной форме именительного падежа единственного числа:

public interface IUserDictionary
{
    Entry Lookup (string nominativeSingular);
}

Пока этот интерфейс используется только в Локальном веб-сервисе для кэширования словаря средствами ASP.NET.

История изменений

Дата Версия  
15.06.2012 2.3.3 В функцию Пропись добавлен учет единиц измерения, не имеющих единственного числа: двое суток, одни ножницы и т.п.
30.09.2012 2.3.4 Учет аббревиатуры "и.о." (исполняющий обязанности), небольшое пополнение словаря.
4.12.2012 2.3.5 К сборке добавлен атрибут AllowPartiallyTrustedCallers для решения проблемы с использованием сборки в Reporting Services.
23.12.2012 2.3.6 Реализована защита от несанкционированного использования.
12.01.2013 2.3.7 Исправлена ошибка в склонении отчества Николаевна и подобных.
30.01.2013 2.3.8 Исправлено склонение словосочетаний "Краснодарский край и Республика Адыгея" и "Республика Саха (Якутия)".
07.02.2013 2.3.9 В словарь добавлены названия минералов: анортоминасрагрит, балгарит, блёдит, вантгоффит...
24.03.2013 2.4.0 Добавлена возможность корректировки склонения при помощи пользовательского словаря.
18.06.2013 2.5.0 Добавлен интерфейс IUserDictionary для работы с пользовательским словарем.
23.06.2013 2.5.1 Пополнение словаря: проверено склонение более 200 стран и исправлены все ошибки. Особую трудность составило сокращение о-в (остров). Теперь это сокращение склоняется корректно: о-в Святой Елены, о-ва Туркс и Кайкос.
30.06.2013 2.5.2 Исправлена ошибка в функции Пропись: для единиц измерения во множественном числе (сутки) в косвенных падежах функция возвращала null. Теперь склоняется корректно: в течение трёх суток. Добавлены юнит-тесты, чтобы не допустить повторения этой проблемы в будущем. Количество юнит-тестов для функции Пропись перевалило за 200.
2.08.2013 2.6.0 Функция Пропись теперь работает с дробными числами: 5,3% (пять целых три десятых процента). Кроме того, расширен диапазон допустимых чисел и теперь он покрывает все возможные значения типа decimal. В связи с этим упразднено свойство MaxDecimal.
4.08.2013 2.6.1 В словарь добавлено более 400 популярных английских имен: Крис, Джеймс, Гарри, Уэйн... Элизабет, Уитни... Это поможет программе более правильно склонять английские имена и определять их пол.
23.09.2013 2.6.2 Исправлена ошибка в прописи числа 0,2 в винительном падеже. Эта ошибка касалась только чисел 0,2, 0,002, 0,000002 и т.д. и проявлялась только в винительном падеже ("двух десятых" вместо "две десятых").
20.11.2013 2.7.0
  • Поддержка числительных с наращением (1-я Парковая улица, 5-е колесо).
  • Из входной строки теперь удаляются мягкие переносы (U+00AD).
  • Добавлен встроенный словарь исключений.
  • Небольшое пополнение основного словаря (около 30 слов).
18.02.2014 2.7.3 Улучшено распознавание ФИО для составных имен. Теперь входное словосочетание признается ФИО, если хотя бы один из разделенных дефисом компонентов известен как имя. В результате стали правильно склоняться такие имена как ГЕЙ-ЛЮССАК Жозеф-Луи, Кени Шарль-Андре, Гильермо Гомес-Пенья и другие.
5.07.2014 2.7.4 Для помидоров, баклажанов и подобных названий (с пометой ["двойка в кружке"] по Зализняку) в родительном множественного теперь выдается форма с окончанием -ов, а не нулевым.
17.08.2014 2.8.0 Исправлена ошибка в прописи чисел вида ... x1y abc, где x=1..9, y=1..4, abc - любые 3 цифры, а ... - любая последовательность цифр, в т.ч. нулевой длины. Пример числа: 311 000. Ошибка проявлялась только в родительном падеже (трёхсот одиннадцати ТЫСЯЧИ вместо трёхсот одиннадцати ТЫСЯЧ).
17.08.2014 2.8.1 Пополнение словаря программы за счет Словаря новых слов (более 7200 статей).
27.08.2014 2.9.0 Добавлена возможность указания одушевленности входного слова или словосочетания при помощи значений Признак.Одушевлённое и Признак.Неодушевлённое. Такая возможность нужна для различения слов, которые могут называть лиц или предметы: укупорщик, взбиватель, тестер.
17.09.2014 2.9.2
  • Исправлено склонение наименования Наконечник E-Cu M 6/0,6/D=6,0/25,0 и подобных.
  • Названия со словом "набережная" теперь имеют предлог "на" в местном падеже: на Крутицкой набережной.
  • Пополнение словаря (106 новых слов)
17.09.2014 2.10.0 Добавлена функция разбивки ФИО на составляющие.
29.10.2014 2.10.1 Пополнение словаря (109 новых слов). В частности, исправлено склонение распространенного в Казахстане имени Бахыт, которое бывает и у мужчин, и у женщин, например:
МужчиныЖенщины
Бахыт КилибаевБахыт Жуматова
Бахыт АрыстановБахыт Сыдзыкова
Бахыт КенжеевБахыт Бегенова
11.11.2014 2.10.2
  • Улучшено склонение и определение рода имен, записанных полностью заглавными буквами. Например, раньше неправильно определялся род в имени ЧЕРНЫШЕВА ЮЛИЯ ВЛАДИМИРОВА. Теперь определяется как женский, несмотря на опечатку в отчестве.
  • Устранено исключение, возникавшее для "слов" на "-й" или "-ь", например Нью-Й или ночь-ь.
7.12.2014 2.10.3 Пополнение словаря (601 новое слово, в основном географические названия).
17.01.2015 2.11.0 Добавлена функция ИзменитьРод.
23.08.2015 2.12.0 В предыдущих версиях было невозможно вызвать метод Пропись из Visual Basic. Теперь это ограничение устранено путем удаления перегрузок метода, где параметр unit фигурировал без модификатора ref.


Комментарии

Добавить комментарий
Борис 30.07.2012 09:10 UTC

А как получить пропись дробной суммы? Почему функция Пропись принимает дробное, а возвращает только пропись целой части?



Сергей Слепов 30.07.2012 21:11 UTC

Борис, дробные числа пока не поддерживаются, т.к. в моей практике такая необходимость не встречалась. Вместо "сто целых двадцать три сотых рубля" обычно пишут "сто рублей 23 копейки", а вместо "пять целых восемь десятых метра" - "пять метров 80 сантиметров". Можете привести пример, где нужна будет пропись дробной части? В принципе, несложно добавить.



Борис 31.07.2012 08:18 UTC

Имеется ввиду пропись 150,45 рублей как "сто пятьдесят рублей сорок пять копеек" или типа того.



Сергей Слепов 31.07.2012 21:44 UTC




Алексей Ерпылёв 09.08.2012 21:46 UTC

Здравствуйте!

Спасибо огромное! Продукт у Вас великолепный. Одно удовольствие с Морфером работать.
Честно говоря, даже не встречал аналогов: все остальные работают строго по словарю, и незнакомое слово просклонять не способны.

Из пожеланий на будущее развитие:
- Не только из именительного падежа делать остальные, а из любого падежа (или явно задав падеж исходного словосочетания, или дав самому Морферу предположить, какой падеж использован).
- Помимо склонения существительных и именных групп сделать спряжение глаголов и глагольных групп.

Но это уже мечты. И имеющиеся возможности хороши.


С уважением,
Алексей Ерпылёв



Pavel B. Novikov 14.08.2012 06:25 UTC

Отличнейший продукт - вызывает стойкое желание приобрести и положить в коллекцию third-party библиотек.

Одно смущает - это русские символы в коде :( В большинстве проектов (особенно с иностранными коллегами, так же в силу ряда технических причин) наличествует ограничение - не использовать какие-либо иные символы помимо английских в коде (ресурсы не в счет). Было бы неплохо иметь подобную библиотеку все же с английским интерфейсом.



Сергей Слепов 14.08.2012 07:00 UTC

Спасибо, Павел! Да, не первый раз возникает такое замечание. Но в наличии "технических причин" меня пока никто не убедил - по-моему, все они остались в прошлом веке. Библиотека работает и на этом сайте (ASP.NET), и под Mono, и под SQL Server - нигде пока проблем не видел. Все больше убеждаюсь, что причины больше психологические (Вы вот и имя свое латиницей написали - тоже по техническим причинам?). Мне сложнее читать (и писать) Predlozhnyi padezh (или Predlognyi? или Predlogniy?), а кириллицей все просто, однозначно и привычно.

А вот довод про нерусскоговорящих коллег меня почти убедил. Представляю, если бы мне пришлось работать с подобной библиотекой для китайского с китайскими же названиями классов. Было бы сложнее (не говорю, что не возможно) отличить один класс от другого (все китайцы на одно лицо?). Уговорили, сделаю англоязычный интерфейс. Осталось только решить проблему с predlozhnym padegom.



Борис 15.08.2012 07:18 UTC

А зачем писать методы и классы транслитерацией, когда можно непосредственно на английском, типа: CaseGenitive, CaseDative, CaseAccusative, CaseInstrumental, CasePrepositional. По-моему Павел имел ввиду именно это. Поддерживаю необходимость английского интерфейса.



Сергей Слепов 15.08.2012 21:13 UTC

Да, наверное, это будет наилучший вариант. Сделаю. Чего только не сделаешь для руссконеговорящих коллег :)



Николай 29.08.2012 20:17 UTC

Да, английского интерфейса сильно не хватает... Даже для русскоговорящих разработчиков на .Net русские символы выглядят дико. Сделайте, пожалуйста, английский интерфейс в библиотеке. Конечно, самый идеальный вариант, если названия методов будут даны на английском языке, а не будут оттранслитерированы.



Сергей Слепов 03.09.2012 23:06 UTC

Делаю уже, немного терпения... Насчет "дикости" русских символов... дело привычки. Человек и не к такому привыкает. У русских слов большой плюс - их не надо переводить. В английском языке нет склонения и набор соответствующих терминов весьма беден. Например, сложно подобрать аналог для слова "просклонять". Пока получается что-то вроде ProvideDeclension или GetParadigm... SpellNumber ("число прописью") и т.п. В общем, не удивляйтесь, если вам понадобится словарь, чтобы разобраться в моем коде.



Борис 04.09.2012 07:38 UTC

По-моему приведенные выше наименования вполне очевидны - словарь не требуется



Борис 17.09.2012 11:52 UTC

Есть возможность согласовать глагол с числительным?
Например: скопирована 1 строка, скопированы 2 строки и т.п.



Сергей Слепов 17.09.2012 20:08 UTC

Пока нет, но стоит добавить. Уже не первый раз всплывает тема склонения по родам прилагательных и причастий. Сделаю. Кстати, тем, кто ждет английский интерфейс: он практически готов, сейчас пишу примеры использования и документацию. Это будет отдельная DLL, кроме английского интерфейса там будет еще много интересных возможностей - унификация API для русского и украинского языков, дающая возможность писать клиентский код, принимающий язык как параметр, унификация API DLL и веб-сервиса и еще много вкусного!



Борис 23.09.2012 04:24 UTC

Присоединяюсь к просьбам об английском интерфейсе. От себя хочу добавить, что очень неудобно постоянно переключать раскладку клавиатуры с русского на английский и наоборот.



Сергей Слепов 07.10.2012 18:58 UTC

Свершилось! Английский интерфейс готов. Но изменять интерфейс имеющейся библиотеки я не стал, так как у нее уже обширная база клиентов и при получении обновления они не обрадуются, если все названия методов поменяются. Поэтому я решил сделать обертку вокруг существующей библиотеки с английским интерфейсом. Но ценность получившейся обертки далеко не только в английском интерфейсе. Кроме этого она:
1) позволяет работать с веб-сервисом и локальной DLL через один и тот же API;
2) позволяет писать код, работающий и для русского, и для украинского языков.
Библиотека бесплатна и ее можно скачать вместе с исходным кодом и примерами.

Так что прошу любить и жаловать: Morpher.API.dll



Борис 08.10.2012 05:47 UTC

Мешок благодарностей и бесконечная уважуха за труды :)



Лев 13.01.2013 08:19 UTC

Здравствуйте. Присоединяюсь к просьбе добавить возможность получения прописи дробной части числа. Это необходимо, например, в случае, если выводится не сумма а процент. Например 2,3% = две целых три десятых процента.



Сергей Слепов 30.08.2013 15:57 UTC

Пропись дробной части готова. Жду ваших новых пожеланий!



Макс 25.06.2014 08:54 UTC

Можете добавить возможность прописи дат?
например первое сентября дветысячи четырнадцатого года

+ прописи чисел в виде:

первое, второе, ... две тысячи двести шестьдесят второе



Сергей Слепов 26.06.2014 12:31 UTC

Да, можно. Записал себе в список задач. Как только сделаю, сообщу сюда и вам на email.



Роман 24.12.2014 08:40 UTC

Сергей, а планируется ли возможность перевода существительных в относительные прилагательные? Например "железо" -> "железный", "стекло" -> "стеклянный".

А так же склонение прилагательного по всем родам, а не только по основному?



Сергей Слепов 24.12.2014 15:18 UTC

Роман, да, образование прилагательных можно сделать, как оно уже сделано для городов и стран. Загвоздка только в том, что в общем случае от одного существительного может быть несколько прилагательных с разными значениями: деревянный - древесный, свиной - свинячий - свинский, языковый - языковой. Какое значение вы хотели бы передать? "Сделанный из"?



Алексей 10.02.2015 12:06 UTC

А есть ли возможность склонять числительные без указания единиц измерения?



Сергей Слепов 10.02.2015 21:27 UTC

Алексей, я ответил на подобный вопрос на странице модуля для 1С.



Евгений 20.05.2015 10:47 UTC

Куда делся признак топоним? Что использовать вместо него?



Сергей Слепов 20.05.2015 23:17 UTC

Евгений, используйте признак Неодушевлённое. Именно в этом была суть признака Топоним - чтобы города типа Владимир, Кишинев склонялись как неодушевленные. Согласен, не очень красиво с моей стороны было убрать признак Топоним, да еще ничего не сказать об этом. Просто забыл, извините. Зато теперь набор признаков более логичный. Наряду с Неодушевлённое есть Одушевлённое - например, в прошлом веке "навигатор" был только одушевленный, то в этом веке чаще нет. Таким образом, если склоняете профессии, лучше указать Одушевлённое, а если товары или города - Неодушевлённое.



Эдуард 10.12.2015 08:03 UTC

А есть английская версия?
Не могу читать русские коды, 1С-ом пахнет. А не си шарпом это ужас писать так!



Сергей Слепов 11.12.2015 23:41 UTC

Эдуард, есть.



Евгений 19.09.2016 07:07 UTC

Добрый день.
Каковы перспективы портирования сборки на .NET Core?



Сергей Слепов 19.09.2016 23:16 UTC

Евгений, думаю, с портированием на .NET Core проблем быть не должно. Попробую и отпишусь.



Добавить комментарий


 

Библиотеки

Заметили опечатку? Выделите слово мышкой и нажмите Ctrl-Enter. Система Orphus

© Сергей Слепов, 2003 - 2016. Перепечатка материалов сайта только с разрешения автора.