-
Notifications
You must be signed in to change notification settings - Fork 4
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
230 extending khiops entries with a lightweight json structure for scenarios #419
230 extending khiops entries with a lightweight json structure for scenarios #419
Conversation
b76ea38
to
0f72bc7
Compare
0bb19e8
to
68b47a7
Compare
68b47a7
to
3b9985b
Compare
Preparation du deplacement des services JSON vers Norm - objectif: - reutilisation du parser JSON dans Norm pour le pilotage par fichiers scenarios et json - extraction ce qui n'est pas specifique a Learning: tout, sauf JSONFile - nettoyage et mise en conformite avec la bibliotheque Norm Impacts principaux - suppression des references au type Continuous - renommages: - KWTextService en TextService - KWIntVectorSorter en IntVectorSorter - TextService: - enrichissement de la classe en rappatriant des methdoes de services generique provenant de JSONFile - maintenant, classe ancetre de - JSONFile - JSONTokenizer - KWTextTokenizer - IntVectorSorter: nouveau fichier dedie au classes IntPairVector et IntVectorSorter, extrait de KWSortableIndex Impacts detailles - Supression des references à Continuous dans les services JSON - JsonLex.lex: utilisation desormais de strtod pour parser les doubles - supression des include inutiles - JSONTokenizer.h: plus d'inclusion de KWContinuous.h - KWTextService.h: plus d'inclusion de KWTokenFrequency.h - JSONTokenizer - supression de la dependance au type Continuous - supression des methodes ReadContinuousValue et ReadKeyContinuousValue - methode interne DoubleToInt, pour se passer de KWContinuous::ContinuousToInt - impacts dans CCCoclusteringReport, lecture de fichier json - TextServive: - issue d'un renommage de KWTextService en TextService - impacts mineurs lies au renommage - KWClass - KDTextFeatureConstruction - KDTextTokenSampleCollectionTask - KWTokenFrequency - JSONLex.lex - KWDRRuleLIbrary/KWDRTextualAnalysis - KWTest/Test - recupere l'essentiel des methodes de service provenant de JSONFile - maintenant classe ancetre de: - JSONFile - JSONTokenizer - KWTextTokenizer - IntVectorSorter - nouveau fichier dedie au classes IntPairVector et IntVectorSorter - issu du renommage de KWIntVectorSorter en IntVectorSorter - impacts: - KWDatabaseFormatDetector - TextService - issu de KWSortableIndex, dont il est extraiut - usages dans KWDatabaseFormatDetector et TextService
Les fichiers suivants sont deplacés de Learning/KWData vers Norm/base: - IntVectorSorter.* - JSONTokenizer.* - JsonLex.* - TextService.* Les fichiers CMakeLists.txt des deux librairies concernees sont adaptes: - chacun ne decrit que ses cibleq Flex et Bison - nouvelle gestion de la liste GLOB cppfiles, pour la rendre generique, en excluant explicitement les fichiers issus de Flex et Bison
Initialisation d'un analyseur syntaxique de json base sur l'analyseur lexical. Adaptation de l'analyseur lexical pour etre utilse a la fois dans la classe existante JSONTokenizer utilise pour le parsing specifique des rapport de coclustering, et le nouveau parser generique genere depuis Yacc. Modification dans Dans Norm/base Parametrage des analyseurs lexical et syntaxique - CMakeLists.txt: mise en place de la compilation d'un parser - JsonYac.yac: ebauche d'un parser vide - Initialisation du parser json avec des regles de grammaire correctes, inspirees de https://www.json.org/json-en.html - JsonYac.hpp, JsonYac.cpp: fichier generes pour le parser - JsonYac.lex: adaptation pour que les valeurs associee aux tkens soient utilisable depuis JsonYac.yac et la classe JSONTokenizer TextService: - rappatrieement de JsonToCString et AppendSubString en provenance de JSONTokenizer - Test: rappatriement des test de conversions provenant de JSONTokenizer - renommages: - CStringToJsonString -> CToJsonString - CStringToCAnsiString -> CToCAnsiString Nouveau fichier JsonObject, avec toutes les classes de gestion d'un objet Json, avec implementation vide pour l'instant - JsonValue - JsonObject - JsonArray - JsonString - JsonNumber - JsonBoolean - JsonNull - JsonMember JsonObject: - debut d'implementation de la methode ReadFile - acces aux fonctions de l'analyseur lexical, en friend pour la classe JSONTokenizer JSONTokenizer - utilisation des methodes protected de JsonObject pour acceder au methode du parser - valeurs de l'enum initialisee avec les constantes de JsonYac.hpp - JSONSTYPE jsonLastTokenValue: memorisation de la valeur du dernier token - on utilise desormais le nouvel analyseur lexical - la gestion du parametre ForceAnsi est desormais effectuee dans la classe elle meme, et non dans l'analyseur lexical genere depuis JsonLex.lex CCCoclusteringReport (impact dans Learning/MODL_Coclustering) - ReadJSONInterval: pas de conversion en Continuous des bornes des intervalles, pour pouvoir les comparer correctement
Implementation des classes - JsonValue - JsonObject - JsonArray - JsonString - JsonNumber - JsonBoolean - JsonNull - JsonMember Implementation du parser JsonYac.yac - gestion des erreurs - detection en erreur des cles dupliquees dans les objets json - detection basique d'erreur lexicale ou syntaxiques - liberation memoire en cas d'erreurs de parsing Mise au point, par lecture/ecriture de fichier json Refactoring leger - Object::GetTranslatedClassLabel: supression de cette methode obsolete et non utlisee
Creation d'une nouvelle classe CommandFile, pour encapsuler la gestion du parametrage par des fichiers de commande - gestion de fichiers de commande en entree et en sortie - gestion du parametrage par search/replace - gestion du fichier de parametrage json La classe UIObject delegue desormais ses services de gestion des fichiers de commande a cette nouvelle classe Refactoring de UIObject, qui desormais redirige ses services vers un objet interne statique commandFile - supression des methodes de gestion des parametres de search/replace - supression des parametres de gestion des ficgier de commande en entree et sorties - renommage des fonctions de parametrage des options de la ligne de commande, qui ne font plus que du parametrage - OpenInputCommandFile -> InputCommand - OpenOutputCommandFile -> OutputCommand - renommage des services nettoyage lie a la gestioopn de la ligne de commande - CloseCommandFiles -> CleanCommandLineManagement - ExitHandlerCloseCommandFiles -> ExitHandlerCleanCommandLineManagement - UIObject::ParseMainParameters: impacts principaux - renommage - CheckOptions -> CheckCommandLineOptions
f3873f7
to
4ac2db9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meets requirements. Functionally Approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- A couple of comments on the Python code (see in the review)
- Some comments on the spec (https://github.com/KhiopsML/khiops/wiki/Feature-V11:-Extension-du-pilotage-de-Khiops-via-les-sc%C3%A9narios):
- Regarding the "quoted-printable" (QuoPri) format:
- to my understanding, QuoPri is optimized for readability and was designed for data blobs where there are relatively few non-printable characters (e.g. in e-mails), while Base64 is designed for being more compact when there are lots of such non-printable characters (e.g. in non-textual files such as raw data, images etc)
- hence, I think that the QuoPri alternative vs Base64 could also be discussed in light of the kinds of data that we would need to keep as bytes, in practice: if Base64 is used for bytes when we need to be "agnostic" about the encoding of the data (such as when we mix several encodings), then it seems that we cannot make any assumption about the ratio of non-printable characters with respect to the payload of the value in question, right? If this is true, then perhaps we could take out QuoPri from the spec?
- regarding the decision of streaming the reading of the scenario file, as opposed to the JSON file which is read in-memory at once: at first sight, I would imagine the JSON file as being "bigger" (as it can contain rather big arrays for
LOOP
s), while the scenario file could be quite compact, at least in the "template" form, if used for a specific "task". Was this decision made to support iterative instantiation of a scenario template from potentially several JSON files, applied in a sequence on the scenario template?
- Regarding the "quoted-printable" (QuoPri) format:
Concernant le choix d'encodage Base64, comme indiqué, c'est essentiellement parce qu'il s'agit d'un encodage plus populaire. Concernant le choix de streamer ou non le json et le scénario:
|
4ac2db9
to
bcb37d6
Compare
Mise en place de tests complet pour la verification des fichiers de parametre json en entree de la ligne de commande UIObject - ParseMainParameters - nouvelle option -j pour les fichiers de parametrage json - nouvelle option -O, comme -o mais sans rejouer les comandes - CheckCommandLineOptions: ajout des contraintes entre les options CommandFile - LoadJsonParameters: lecture et verification du fichier de parametres json en entree - CheckVariableName - IsByteVariableName - ToByteVariableName, ToStandardVariableName - CheckStringValue - ... CommandFile - nMaxVariableNameLength = 100: taille max des noms de variable - lMaxInputParameterFileSize lMB: taille max des fichier de commande - nMaxStringValueLength = 300: longueur max des avleurs de type chaine de caracteres KWTextService: service d'encodege et decodage au format base64 - Base64StringToBytes - BytesToBase64String Tests unitaires - ajout du test TextService::Test dans test/UnitTests/Norm_test.cpp, avec la reference base_TestService.txt LearningTestTool - extension de kht_test tester la gestion des fichiers de parametre json en entree - uniquement s'il existe un fichier test.json associe au test.prm dans le repertoire de test courant - ajout d'une famille de test LearningTest/TestKhiops/JsonParameters - kht_export.py: analyse heuristique du fichier de parametre json pour extraire les datasets utilises Tests intensifs dans LearningTest\TestKhiops\JsonParameters
Reference - issue #230 Extending Khiops entries with a lightweight json structure for scenarios #230 - #230 - cette issue contient les specification detaillees de la fonctionnalité, donc on pourra extraire la documentation - cf. commentaire "Extension du pilotage de Khiops via les scénarios" - #230 (comment) Choix d'implementation principaux - le fichier de parametre json est lu et traite en entier de facon prealable, avec une taille limitee - le fichier de commande est traite en flux, ce qui permet de n'avoir aucune limite de taille - toute ligne de commande peut etre commentee, y compris les lignes du langage de pilotage de type IF ou LOOP - les lignes d'un fichier de commande template n'ont pas besoin de se terminer par un commentaire - toute __key__ du fichier de commande doit se trouver dans le fichier json - toute key du fichier json doit etre utilise dans le fichier de commande - les __key__ de parametrage json ne peuvent concerner que la partie parametrage utilisateur d'une valeur - toute erreur ou incoherence dans les fichiers de commande et de parametrage json provoquent une erreur fatale CommandFile - methodes publiques - ReadInputCommand: refactoring et simplification - ReadWriteCommandFiles: pour ecrire le scenario en sortie sans rejouer les commandes - CloseInputCommandFile: detction potentielle d'erreur fatale a la fermeture, si scenario ou json incorrecte - methodes privees principales de parsing des scenario et de leur langage - ResetParser - RecodeCurrentLineUsingJsonParameters - ParseInputCommand: analyse syntaxique des lignes d'un fichier de commande en entree - TokenizeInputCommand - GetFirstInputToken - variables de travail du parser - prefixees par parser (ex: nParserState, sParserBlockKey, nParserLineIndex...) - maintenues le temps d'une session d'analyse, pour gerer le parser de scenario en flux - contraintes - nMaxLineLength = 500: longueur max d'une ligne de fichier de commande - nLoopMaxLineNumber = 1000: Taille max d'un bloc d'instruction IF ou LOOP d'un fichier de commande - constantes: renommees et etendues pour harmonisation - sCommentPrefix - sJsonKeyDelimiter - sByteJsonKeyPrefix - ... JsonLex.lex - STRINGERROR: variante de STRINGVALUE dans le cas d'erreur d'encodage utf8 JsonYac.yac - regles impliquant STRINGERROR pour avoir des erreurs interpretable en cas de STRINGERROR UIObject: prise en compte de l'option -O, pour les scenarios en sortie sans rejouer les commandes - ParseMainParameters - CheckCommandLineOptions TextService::Set|GetForceUnicodeToAnsi - parametrage avance de la conversion de lencodage Json vers un encodage C pas necessairement Utf8 pour le cas des rapport Khiops - modifie le comportement de la methode JsonToCString utilisee par le parser de Json - utilise uniquement dans CCCoclusteringReport LearningTestTool - kht_test.py - --nop-output-scenario: "create an output scenario nop_output_test.prm in results dir, without replaying commands" - _kht_families - ajout de la famille JsonParameters Ajout de tests unitaires: test\UnitTests\Norm\results.ref\base_TextService.txt Ajout de test CI/CD: test\LearningTest\TestKhiops\Standard\JsonSpliceJunction Batterie de tests LearningTest\TestKhiops\JsonParameters - une petite cinquantaine de test, les trois-quart concernant la detection des erreurs
Renommage pour des raisons d'homogenisation avec les classes JSONTokenizer et JSONFile - classe JSONObject et ses sous classes - JSONLex.lex, JSONYac.yac: parser de json
…files La classe JSONFile possede deux types de methodes pour l'ecriture des nombres reel: - WriteContinuous, WriteKeyContinuous: - niveau de precision des donnees elles-memes, gerees via le type Continuous, avec 10 digits de precision - null si valeur manquante - pour les valeur provenant des donnees (min, max, mean...) - WriteDouble, WriteKeyDouble - niveau de precision des double en sortie (7 digits), suffisant pour l'interpretation utilisateur - pour les valeurs provenant des modeles (Level, Importance, Interest, courbes de lift...) La correction porte ici sur deux indicateurs provenant des donnees, qui passe de double a Continuous pour l'ecriture dans les fichiers json: - CCCoclusteringReport::WriteDimensionSummary: ecriture du min et du max - KWDescriptiveSymbolStats::WriteJSONFields: ecriture du modeFrequency
bcb37d6
to
edd97f8
Compare
Okay, I get the argument that, unlike the JSON format, scenario template structure (except the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM:
- from a functional standpoint.
- the Python code.
Update the spec with:
- deletion of the QuoPri format mention
- statement of the limits for:
- the size of the JSON file (1 MB)
- the number of lines of a
LOOP
structure (1000).
Tout est implémenté et testé: cf. commit notes