Déclinaison des mots et des initiales en Delphi / Freepascal

Bonne année à tous! Dans cet article, je voudrais vous dire comment j'ai dû revenir sur un projet hérité en Pascal, et littéralement avant de lui dire au revoir, à Lazarus, et à l'absence d'un thème sombre hors de la boîte .





La dernière fois, j'ai expliqué que je ne suis pas un programmeur de profession, mais que j'utilise mon passe-temps préféré pour automatiser tout ce qui se présente dans le travail d'un avocat. Je suis sûr que 90% de toutes les formalités administratives juridiques peuvent être automatisées avec succès: gestion d'une variété de bases de données et de cartes, rédaction de documents selon des modèles, contrôle du calendrier des tâches, utilisation de services auxiliaires déjà dotés de leur propre API pour visser l'automatisation sur un lieu de travail spécifique, etc. etc. Il est nécessaire de lutter pour cela afin, selon les instructions d'Isaac Asimov, de libérer le temps d'un avocat pour mettre en œuvre la tâche principale - réfléchir aux termes du contrat et engendrer la démagogie devant les tribunaux.






Donc, il y a de nombreuses années, j'ai réalisé un très gros projet pour faciliter le travail de mon bureau. Il a collecté toutes les données sur les marques et les brevets (et il y en a plusieurs centaines), contrôlé le moment du paiement des taxes de brevet, formé des ordres de paiement, des contrats, des demandes et, bien sûr, publié divers rapports. En fait, pourquoi au passé? Le projet fonctionne assez bien. Il a juste été développé selon tous les anti-modèles possibles, avec tous les vélos et béquilles qui n'ont été trouvés que sur Terre. Pour revenir à ce code Rolton (ou doshirak) pour le refactoriser, oh, je ne voulais pas, parce que le meme " Réécrivons tout dans ... " est parfait ici .





Mais, malheureusement, tout réécrire dans une nouvelle langue pour une nouvelle plate-forme ou même plusieurs est une entreprise longue et prolongée, et les documents doivent être tamponnés ici et maintenant. Par conséquent, je dois revenir de temps en temps à Pascal.





Un des beaux jours, l'ensemble du projet a été reconstruit sur une plate-forme 64 bits et, à ma grande surprise, la partie la plus préférée est tombée: la génération de contrats et de déclarations avec une automatisation complète de toute la grammaire et de la morphologie - la déclinaison des initiales, des positions et d'autres mots dans les cas nécessaires, et Voir aussi singulier / pluriel. Le fait est que l'ancienne bibliothèque Delphic et padegUC propriétaire a cessé d'être gratuite dans sa version 64 bits.





32- , . .





- , . , :





IInitialsMorpher = interface
  function GetInitials(Initials: string): CasesResponse;
  function GetWordsCase(Words: string): CasesResponse;
  function GetGenderAndInitials(Initials: string; var Gender: TGender): CasesResponse;
end;
      
      



, , -: (.. ), , , , , , .. CasesResponse , Gender - :





TWordCase = (Nominative, Gentitive, Dative, Accusative, Instrumental, Prepositional);
TGender = (Male, Female, UnrecognizedGender);
CasesResponse = array[TWordCase] of string;
      
      



. , :

















DaData





-





-





-





- -





-





Pymorphy





github





- MIT , python





- Corpora ( )





- , .. , , , ..





- , , ..





Morphos





- MIT , php





-





-





- ,





, Morphos, / .





rest api, json, , http, :





generic function JSONfromRestUri<T>(Uri: string): T;
var
  HTTPSender: THTTPSend;
  JSONStreamer: TJSONDeStreamer;
  Json: TJSONObject;
begin
  HTTPSender := THTTPSend.Create;
  JSONStreamer := TJSONDeStreamer.Create(nil);
  HTTPSender.Clear;
  Result := T.Create;
  if not HTTPSender.HTTPMethod('GET', Uri) then 
  		raise EInOutError.Create(RESTOUT_ERROR);
  JSON := GetJSON(HTTPSender.Document) as TJSONObject;
  JSONStreamer.JSONToObject(JSON, Result);
  FreeAndNil(JSON);
  FreeAndNil(JSONStreamer);
  FreeAndNil(HTTPSender);
end;
      
      



Freepascal Synapse Fpjson, (httpsend, fpjson, fpjsonrtti) uses. json rtti, .. , -, published, -, (, , ), -, json. , @SerializedName , .





Morphos :





MORPHOS_URL = 'http://morphos.io/api/inflect-name?name=%s&_format=json';
      
      



json , - / , , name gender:





{
    "name": " ",
    "cases": [
        " ",
        " ",
        " ",
        " ",
        " ",
        "  "
    ],
    "gender": "m"
}
      
      



IInitialsMorpher Morpher. , json Fpjson ( , TPersistent):





TMorphosResponse = class(TPersistent)
  private
    fCases: TStrings;
    fGender: string;
    fName: string;
  public
    constructor Create;
    destructor Destroy; override;
  published
    property name: string read fName write fName;
    property cases: TStrings read fCases write fCases;
    property gender: string read fGender write fGender;
  end;
      
      



:





TMorphosImpl = class(TInterfacedObject, IInitialsMorpher)
  public
    function GetInitials (Initials: string): CasesResponse;
    function GetWordsCase (Words: string): CasesResponse;
    function GetGenderAndInitials(Initials: string; var Gender: TGender): CasesResponse;
  end;
      
      



, :





function TMorphosImpl.GetGenderAndInitials(Initials: string; var Gender: TGender): CasesResponse;
var
  inf: TWordCase;
  i: integer = 0;
  response: TMorphosResponse;
begin
  response := specialize JSONfromRestUri<TMorphosResponse>
                (Replacetext(Format(MORPHOS_URL, [Initials]), ' ', '+'));
  for inf in TWordCase do begin
      Result[inf] := response.cases[i];
      inc(i);
  end;
  case response.gender of
       'm': Gender := Male;
       'f': Gender := Female;
       else Gender := UnrecognizedGender;
  end;
  FreeAndNil(response);
end;
      
      



, . , ( ) , , - :





function TMorphosImpl.GetInitials(Initials: string): CasesResponse;
var
  MokeGender: TGender = UnrecognizedGender;
begin
  Result := GetGenderAndInitials(Initials, MokeGender);
end;

function TMorphosImpl.GetWordsCase(Words: string): CasesResponse;
var
  inf: TWordCase;
begin
  Result := GetInitials(Words);
  for inf in TWordCase do
    Result[inf] := UTF8LowerString(Result[inf]);
end;
      
      



, . , . . , , , DI- - "" .





- -, ( , , - ?) - http-. Morphos , DaData , 10 .





, . , json ashMap- Generics.Collections - , freepascal delphi. , - ( , http- , ).





Morphos :





Morpher := TMorphFabric.Create(MORPHOS);
//...
response := Morpher.GetInitials(Text)
StringList.AddStrings(response);
      
      



Pour tous ceux qui sont intéressés, je conserverai ma bibliothèque résultante avec une application de fenêtre de test pour win dans un référentiel ouvert . Très probablement, je ne commencerai rien là-dedans, car maintenant je me suis plongé dans la mer ouverte du développement mobile (kotlin) et de python pour implémenter le même "réécrire tout en ..."





Bonne année 2020 + '1' à tous!








All Articles