Bonjour,
https://github.com/laurentbouleau/Exemple : Juillet 03 (01/07/2024)
Ok !
Merci
Bonjour,
https://github.com/laurentbouleau/Exemple : Juillet 03 (01/07/2024)
Ok !
Merci
Maintenant, c'est bon.
Vous pouvez enchainer en renommant "correctement" les variables/champs/fonctions/paramètres.
Vous pouvez en profiter en utilisant aussi des "bons" types pour ces variables/champs/valeur de retour des fonctions et de leurs paramètres.
Je viens de comprendre le "problème" avec le nom de répertoire "Azertyuiop £££.[2024].Mini-série".
Effectivement, l'expression régulière, que j'ai donné, ne fonctionne pas sur ce nom car elle attends toujours un espace entre la ou les années et le nom du canal de diffusion.
Ici, ce n'est pas le cas.
Faut juste rendre cet espace optionnel.
J'ai aussi mis la formule pouvant récupérer les 2 années avant les autres pour gérer la priorité de capture :
(.+?)(?:\.\[(\d{4}\-\d{4}\s?|\d{4}\-\s?|\d{4}\s?)?([^\]]*)\])?(?:\.(.+))?
https://regex101.com/r/32IXMi/1 donne la nouvelle version et les 2 exemples de textes : remarquez en hait à droite le décodage en groupe des éléments capturés par l'expression régulière.
Pouvez-vous mettre cette nouvelle expression dans le code ?
Il faut juste ajouter l'escaping C++ à la formule.
Courage !
(C'est juste ajouter 3 "?" pour gérer un nouveau format de chaine de caractères, c'est quand même cool les expressions régulières, non ?)
Bonsoir,
https://github.com/laurentbouleau/Exemple : Juillet 04 (03/07/2024)
Pas fini !
Mais : serie.cpp
Je suis crevé !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 ... const std::wstring Serie::calculer_Annee_Debut() { std::size_t pos = m_annees.size(); std::wstring tmp; std::vector<std::wstring> annees_vec; std::wstringstream annees(m_annees); // ??? while (getline(annees, tmp, L'-')) {// ??? annees_vec.push_back(tmp); break; } std::tm tm; tm = saisons[0].m_dossier.first; assert(std::stoi(annees_vec[0], &pos) == (1900 + tm.tm_year) && L"année != saisons[0].m_dossier.first !!!"); return std::to_wstring(std::stoi(annees_vec[0])); } const std::wstring Serie::calculer_Annee_Fin(std::wstring& wstr) { std::wstring tmp; std::vector<std::wstring> annees_vec; std::wstringstream annees(m_annees); // ??? while (getline(annees, tmp, L'-')) {// ??? annees_vec.push_back(tmp); } std::tm tm; tm = saisons.back().m_dossier.first; return std::to_wstring(std::stoi(annees_vec.back())); } ... const std::wstring Serie::format_Annees() { //assert(m_annees.length() > 0 && L"L'année---");// ??? //assert(m_annees.size() < 10 && L"L'année 2---");// ??? bool found = false; std::wstring annees_str = calculer_Annee_Debut(); std::size_t pos = 0; std::wstring wstr = m_annees.substr(4); if (!found && wstr[0] != L'-') found = true; if (!found) { try { test_date_tire(wstr[0]); } catch (exception_date_tiret e2) { std::wcout << L"Exception a été capturée : " << e2.get_message() << std::endl; } annees_str += keyColor[1] + L'-'; wstr = wstr.substr(1); if (!found && wstr.length() == 0) { found = true; } if (!found) { found = true; annees_str += valuesColor + calculer_Annee_Fin(wstr); } } return keyColor[0] + L" (" + valuesColor + annees_str + keyColor[0] + L')' + valuesColor; } ...
Merci beaucoup
Bonjour,
Pas fini !
https://github.com/laurentbouleau/Exemple : Juillet 05 (04/07/2024)
Ok ou pas ?
Mais, serie.cpp :
Merci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 ... const std::wstring Serie::calculer_Annee_Debut() { std::wstring tmp; std::vector<std::wstring> annees_vec; std::wstringstream annees(m_annees); // ??? while (getline(annees, tmp, L'-')) {// ??? annees_vec.push_back(tmp); break; } std::tm tm; tm = saisons[0].m_dossier.first; assert(std::stoi(annees_vec[0]) == (1900 + tm.tm_year) && L"année != saisons[0].m_dossier.first !!!"); return std::to_wstring(std::stoi(annees_vec[0])); } ... const std::wstring Serie::calculer_Annee_Fin(std::wstring& wstr) { std::wstring tmp; std::vector<std::wstring> annees_vec; std::wstringstream annees(m_annees); // ??? while (getline(annees, tmp, L'-')) {// ??? annees_vec.push_back(tmp); } std::tm tm, tm2; tm = saisons[0].m_dossier.first; assert((std::stoi(annees_vec.back()) > (1900 + tm.tm_year)) && L"année != saisons.back().m_dossier.first !!!"); tm2 = saisons.back().m_dossier.first; assert((std::stoi(annees_vec.back()) == (1900 + tm2.tm_year)) && L"année != saisons.back().m_dossier.first !!!"); return annees_vec.back(); } ...
Expliquez-moi !
Serie.h
serie.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 ... class Serie { public: Serie(std::filesystem::path racine); ... std::wstring format_Annees(); std::pair<int, int> calculer_Annees_Diffusion(); std::pair<std::optional<int>, std::optional<int>> m_f_anneesProduction; ... };
Comment faire ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 std::pair<int, int> Serie::calculer_Annees_Diffusion() { ??? }
Merci
Vous continuez à produire du code bien trop complexe.
Pourquoi ???
Je vous ai déjà indiqué d'utiliser les "bons" types de données pour ne pas faire des usines à gaz.
Pourquoi "m_annees" est une "std::wstring" et pas une "std::pair<std::optional<int>, std::optional<int>>" ???
Simplement en reprenant mon code sur le champ "m_f_anneesProduction" réduirait considérablement la complexité de votre code, comme je l'ai déjà montré dans un précédent post.
Vous pouvez aussi faire ces simplifications dans "Saison::Saison", dans "Saison::initialiser_Fichier" et bien d'autres fonctions qui doivent extraire des "années" d'un nom de fichier (ou tout autre entier).
Vous avez voulu utiliser cette antiquité de "std::tm",ok , mais utilisez aussi des types plus adapter à votre besoin comme un int pour l'année.
Vous n'êtes pas dans de l'embarqué où chaque octet compte.
Vous semblez galérer pour utiliser la version corrigée de l'expression régulière :
Faut juste un peu de soin :
Code : Sélectionner tout - Visualiser dans une fenêtre à part // std::wregex filename_pattern{ L"(.+?)(?:\.\[(\d{4}\-\d{4}\s?|\d{4}\-\s?|\d{4}\s?)?([^\]]*)\])?(?:\.(.+))?" };
Code : Sélectionner tout - Visualiser dans une fenêtre à part std::wregex filename_pattern{ L"(.+?)(?:\\.\\[(\\d{4}\\-\\d{4}\\s?|\\d{4}\\-\\s?|\\d{4}\\s?)?([^\\]]*)\\])?(?:\\.(.+))?" };Code horriblement complexe qui ne fait pas vraiment ce que son nom indique (mais c'est un peu mieux qu'avant). (Pas de mention de l'utilisation des saisons etc...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 const std::wstring Serie::calculer_Annee_Debut() { ... }
L'approche objet "classique", c'est de construire un objet valide dés la fin du constructeur atteinte.
Puis, à chaque modification de l'objet, on vérifie que les invariants de l'objet reste respecté et signaler le problème dès sa détection.
Donc, faire appel à "calculer_Annee_Debut" lors de l'appel à "Serie::format_Annees" qui est en fin de vie de l'objet (son affichage dans la console), c'est pas vraiment le "bon" moment.
C'est plus lors de l'ajout d'une saison qu'il faut vérifier ces années, je pense.
Pour savoir quand toutes les saisons ont été prises en compte, il faudrait que le traitement de tous les répertoires d'une série soit fait dans le contexte du constructeur de la classe Serie et pas dans la fonction "wmain".
A la fin de ce constructeur, vous pouvez lancer un ensemble de fonction pour détecter/corriger les problèmes.
Dans le cas où on "corrige" les dates :
Si je reprends mon champ "m_f_anneesProduction" (une "std::pair<std::optional<int>, std::optional<int>> donc) et que saison dispose d'un champ "m_f_anneesDiffusion" et type de type "std::optional<int>", initialisé de la même manière que "m_f_anneesProduction" mais dans le constructeur de Session, le code ressemblerait à :
On n'est d'accord que ce code est plus explicite que la tambouillle avec les "std::tm", non ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void Serie::corriger_Annee_Debut() { assert((m_f_anneesProduction.first || (saisons.size() > 0 && saisons[0].m_f_anneesDiffusion)) && "Il faut au moins une date de début."); if (!m_f_anneesProduction.first || (saisons.size() > 0 && saisons[0].m_f_anneesDiffusion && m_f_anneesProduction.first > saisons[0].m_f_anneesDiffusion)) m_f_anneesProduction.first = saisons[0].m_f_anneesDiffusion; }
Pour la date de fin, on fait la même chose, juste en faisant gaffe aux indices et au "<" à la place de ">" . En faisant l'assertion que "saisons" ordonne les saisons, ce qui n'est pas le cas actuellement.
Pourquoi votre fonction "Serie::format_Annees" et si compliqué quand j'en ai fourni une triviale ???
FAITES SIMPLE !!! (pas de try/catch, pas d'exit, pas de trace à la noix, pas faire 100 fois les mêmes bidouilles sur les chaines de caractères, etc...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 std::wstring Serie::format_Annees() { if (m_f_anneesProduction.first && m_f_anneesProduction.second) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[1] + L'-' + valuesColor + std::to_wstring(m_f_anneesProduction.second.value()) + keyColor[0] + L')' + valuesColor; } else if (m_f_anneesProduction.first) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[1] + L')' + valuesColor; } else { std::pair<int, int> anneesDiffusion = calculerAnneesDiffusion(); return keyColor[0] + L" (" + valuesColor + std::to_wstring(anneesDiffusion.first) + keyColor[1] + L'-' + valuesColor + std::to_wstring(anneesDiffusion.second) + keyColor[0] + L')' + valuesColor; } }
EDIT :
Vous gagnez quoi avec "std::pair<int, int>" à la place de "std::pair<std::optional<int>, std::optional<int>>", à part le fait de ne plus gérer le caractère "optionnel" des dates ?
Si c'est obligatoire, Ok, mais j'ai pas l'impression que les assert de votre code soient "carrés" sur le sujet.
Moi, pas-à-pas !!!
Vous : Complexe !Dans le cas où on "corrige" les dates :
Si je reprends mon champ "m_f_anneesProduction" (une "std::pair<std::optional<int>, std::optional<int>> donc) et que saison dispose d'un champ "m_f_anneesDiffusion" et type de type "std::optional<int>", initialisé de la même manière que "m_f_anneesProduction" mais dans le constructeur de Session, le code ressemblerait à :
Moi : Simple !!!
Et :
const std::wstring Serie::calculer_Annee_Debut()???
ou
void Serie::corriger_Annee_Debut()
Aller, j'en ai marre !!!
https://github.com/laurentbouleau/Exemple : Juillet 06 (04/07/2024)
Bon, je vais être moins directif.
Ce que je reproche à vos "Serie::calculer_Annee_xxx", c'est de faire un truc à la fin de vie de votre objet, alors que les informations doivent être correctes dès la fin de la création de l'objet.
Et aussi que vous vous enquiquinez à faire de la bidouille sur de la chaine de caractère au lieu d'avoir des "int" pour des années.
Si on n'a besoin de l'information pendant l'utilisation de l'objet, on fait quoi ? On calcule 2 fois le machin (avec peut-être d'autres informations pas encore "correctes") ?
J'ai fait exprès de mentionner "anneesProduction" et "anneesDiffusion" pour que vous vous posiez des questions sur l'ambiguïté des ces "années", mais vous n'avez pas réagi.
Pourquoi y des "dates"(années) dans les noms des répertoires de séries et aussi dans les nom des répertoires des saisons, si on peut déduire les premières (années des séries) à partir des secondes ("dates" des saisons), toute en sachant toujours pas à quoi correspondent ces dates.
Vous faites des manipulations sur les années, les années sont des entiers, donc dégagez moi cette cochonnerie de "std::wstring m_annees" qui n'a plus aucun sens.
Vous avez mis en commentaire "std::tm Date_Diffusee_a_partir_de" mais pourtant ce champ à plus de sens que "std::wstring m_annees".
Pourquoi n'avez-vous pas initialisé le champ "m_f_anneesDiffusion" de la classe saison ?
Un simple :
dans le constructeur de Saison est largement opérationnel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part m_f_anneesDiffusion = y;
Vous trouvez votre code simple, pas moi. Quand vous pondez des dizaines de lignes de code qui font (mal) 10 choses à la fois, je les résume souvent en 2 lignes qui font une seule chose à la fois (en supprimant des trucs qui ne servent pas immédiatement).
Donc, commencez par supprimer le champ "std::wstring m_annees" de la classe Serie et remplacez son usage par un ou des champs qui a/ont un sens précis et un type de variable qui leur correspondent.
Et réféchissez pour avoir des mécanismes qui font en sorte que ces champs aient des données "correctes".
Ok !
Avant L'AVC, le GREP (UNIX) !!! Ok !!!
Programmation C++/Expressions rationnelles : wregex !!! J'ai compris !!! Mais, difficile a lire !!
Les phrases simples ! Ok !
Les chiffres : Compliqués !!!
Les exemples :
- 0, 1, 3, ..., 8, 9 : je suis crevé !
- Les dates : 02/07/2024, 15h36 : pas compris !!!
- Les années : pas compris !!!
- Etc...
Complexes, non ?
Pourquoi ?
Et :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 Serie::Serie(std::filesystem::path racine) { this->racine = racine; auto nomDossier = racine.filename().wstring(); assert(nomDossier.length() > 0 && L"Nom de dossier vide"); std::wstring annees; // ??? std::wregex filename_pattern{ L"(.+?)(?:\\.\\[(\\d{4}\\s|\\d{4}\\-\\d{4}\\s|\\d{4}\\-\\s)?([^\\]]*)\\])?(?:\\.(.+))?" }; //std::wregex filename_pattern{ L"(.+?)(?:\.\[(\d{4}\-\d{4}\s?|\d{4}\-\s?|\d{4}\s?)?([^\]]*)\])?(?:\.(.+))?" }; std::wsmatch match; if (std::regex_match(nomDossier, match, filename_pattern)) { std::wstring titres = match[1]; m_titres = Dossier_Titres(titres); m_annees = (match[2].matched) ? match[2].str() : L""; if (match[2].matched) { std::wstring annees_str = match[2].str(); std::wsmatch dummy; if (std::regex_match(annees_str, dummy, std::wregex(L"\\d{4}\\-\\d{4}\\s"))) { m_f_anneesProduction.first = stoi(annees_str); m_f_anneesProduction.second = stoi(annees_str.substr(5)); } else { m_f_anneesProduction.first = stoi(annees_str); } } std::size_t pos; pos = m_annees.find(L' '); if (pos != std::wstring::npos) m_annees = m_annees.substr(0, pos); m_sur = (match[3].matched) ? match[3].str() : L""; std::wstring sous_genre = (match[4].matched) ? match[4].str() : L""; m_sous_genre = sous_genre; } else { assert(false == true && "Le nom du répertoire n'est pas un nom valide."); } }
Et :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 std::pair<int, int> Serie::calculer_Annees_Diffusion() { return std::make_pair(???, ???); }
Comment faire ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part m_f_anneesDiffusion = y;
Ou qu'il ait ? Expliquez-moi !
Et :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 ??? Saisin::???_Annees_Diffusion(???) { ??? m_f_anneesDiffusion = y; ??? }
Etc...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void Saison::initialiser_Fichier(fs::path const& cheminFichier) { ... if (nomFichier == L"???.txt") { ???_Annees_Diffusion(cheminFichier); return; } ... }
Alors pas "std::wstring m_annees", mais "int m_annees" et "std::vector<int> m_annees" ???
Ça aille, je suis crevé !!!
Merci
Et pourquoi ?
Titre : The Mandalorian (2019-) ...
et non pas :
Les chiffres : calculer !!! C'est dure !!!
J'ai oublié !!!Ce que je reproche à vos "Serie::calculer_Annee_xxx", c'est de faire un truc à la fin de vie de votre objet, alors que les informations doivent être correctes dès la fin de la création de l'objet.
Et aussi que vous vous enquiquinez à faire de la bidouille sur de la chaine de caractère au lieu d'avoir des "int" pour des années.
Pas compris !!!
Je suis pas sûr de comprendre vos interrogations.
Oui GREP utilise une sorte de syntaxe à base d'expression régulière.
Donc, si vous avez l'habitude de GREP, c'est très proche.
C'est vrai que l'escaping du C/C++ rend les expressions régulières moins lisibles, malheureusement.difficile a lire !!
Pour "capturer" les nombres, c'est assez simple :
"\d", c'est pour un chiffre, un peu comme "[0-9]"
"\d{4}", on capture 4 chiffres consécutifs.
Pour une date de la forme "02/07/2024", c'est 2 chiffres suivi d'un slash ("/") suivi de 2 autres chiffres suivi par un second slash "/" suivi de 4 chiffres.
Si on reprend la définition mais avec la syntaxe des expressions régulière :
\d{2}/\d{2}/\d{4}
(Attention, dans les noms des fichiers de votre projet, les dates ont d'autres formats)
Pour une "date-heure" (datetime) de la forme "02/07/2024, 15h36", c'est assez ambigu car je ne sais pas si 9 heure sera écrit "09h00" ou "9h00".
Si c'est "09h00", cela sera assez proche du format de la date (je vous le laisse en exercice).
Si c'est "9h00", cela veut dire que l'heure est exprimé soit avec 1 chiffre soit avec 2 chiffres, ce qui donne en expression régulière "\d{1,2}". (le 1 à gauche, c'est le nombre minimum de chiffre; le 2 à droite, c'est le nombre maximum de chiffre).
"\s", c'est pour tous les types d'espace (caractère "espace", le caractère tabulation, etc...)
Donc pour une "(datetime)" de la forme "02/07/2024, 15h36", c'est capturable avec une expression de la forme :
\d{2}/\d{2}/\d{4},\s\d{1,2}h\d{2}
Les années, ça dépend, mais dans une date, c'est généralement les 4 chiffres qui se suivent.
"2024" dans "02/07/2024".
Dans les expressions régulières, ça correspondra donc à un truc comme "\d{4}".
Une année, c'est juste un nombre entier, comme 2024, contrairement au mois (Janvier, Février, etc...), donc c'est très simple de stocker une année (pas une date "complète") dans une variables entière type "int" ou "long".
Vous vous obstinez à stocker cette information dans le champ "tm_year" d'un "std::tm", où vous devez ajouter ou supprimer "1900" à chaque manipulation, car il ne stocke pas une année mais le nombre d'années à partir de 1900, c'est chiant.
Ca n'a aucun sens si vous n'avez que l'année mais pas le mois ou le jour d'en le mois, vous n'avez pas l'année "simplement" accessible.
Donc, pour vous simplifier la vie, créez un champ qui stockera directement l'année en plus ou à la place de remplir un "std::tm". (en plus si vous avez besoin de stocker le mois ou le jour dans le mois, à la place si vous n'avez besoin que de l'année)
Vous trouvez "(\d{2})/(\d{2})/(\d{4}),\s(\d{1,2})h(\d{2})" complexe pour décoder toute une "datetime" juste en 2 lignes de code ??? (on récupère 5 données en une seule fois)Complexes, non ?
Vous vous posez beaucoup de questions qui se résument souvent à "Comment nommer un truc" ou "Quel type utiliser ou retourner" :
"Comment nommer un truc" : nommez en fonction de ce qu'il fait ou représente, s'il fait ou représente plusieurs choses, c'est que vous avez mal conçu la chose.
"Quel type utiliser ou retourner" : utilisez ou retournez un type correspondant à la chose que la variable représente/stocke. Si c'est un entier (comme une année) utilisez un "int", si c'est un film, une instance d'objet de type Film, si c'est un clafouti, une instance d'objet de type Clafouti, etc...
En mettant les années sous forme d'entier, cela permet de les classer (du plus vieux/ancien au plus récent/grand, par exemple), ou de gérer facilement leur formatage pour affichage (sur X caractères, avec des 0 devant s'il est trop petit, etc...).
Pour une série, vous avez une information qui correspond à une ou 2 années (on sait toujours pas si c'est des années de production ou de diffusion, au demeurant).
Une année, c'est un entier (en première approximation) : int
Vous n'avez pas forcement l'information sur l'année : std::optional<int>
Vous avez besoin d'au plus 2 années (début/fin) non obligatoire : std::pair<std::optional<int>, std::optional<int>>
Ceci n'est valable que pour une série.
Pour les autres classes, il faut reprendre ce qu'ils doivent stocker/gérer et en déduire des types potentiellement différents pour leurs champs, les types des valeurs retournées par leurs fonctions, les types que ces fonctions prennent en paramètre, etc...
Donc, à partir de là, j'ai vraiment l'impression que les réponses ne sont l'application que de ces 2 règles.
"annees" variable locale qui ne sert pas ou plus, donc pourquoi se poser la question ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 Serie::Serie(std::filesystem::path racine) { ... std::wstring annees; // ??? ... if (std::regex_match(nomDossier, match, filename_pattern)) { ... m_annees = (match[2].matched) ? match[2].str() : L""; if (match[2].matched) { std::wstring annees_str = match[2].str(); std::wsmatch dummy; if (std::regex_match(annees_str, dummy, std::wregex(L"\\d{4}\\-\\d{4}\\s"))) { m_f_anneesProduction.first = stoi(annees_str); m_f_anneesProduction.second = stoi(annees_str.substr(5)); } else { m_f_anneesProduction.first = stoi(annees_str); } } ... }
Ça dégage.
"m_annees" qui n'a pas le bon type pour une utilisation simple et que le champ "m_f_anneesProduction" remplace avantageusement (avec un nom plus précis, mais peut-être faux).
Donc, comme d'habitude, "m_annees", ça dégage. (Quitte à renommer le champ "m_f_anneesProduction" plus "correctement")
Je sais que c'est moi qui ait "donné" cette fonction mais c'était plus pour illustrer le fait de découper le travail en petites fonctions simples rend les choses simples et lisibles.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 std::pair<int, int> Serie::calculer_Annees_Diffusion() { return std::make_pair(???, ???); }
Le typage des valeurs de retour y était approximatif, car ce n'était pas le sujet du propos.
Il faut donc faire une conception "réfléchie" du type de retour de la fonction avant même de réfléchir à son implémentation :
Pour une paire d'int, quand on sait qu'on n'a pas forcément les "années" ? (pas de saisons ou des saisons sans dates, etc...)
Vous voulez vraiment "forcer" un affichage d'années ??? (sans savoir si c'est les années de productions ou les années de diffusion qui seront affichées dans la console ?)
Pourquoi pas un "std::pair<std::optional<int>, std::optional<int>>" en type de retour qui n'oblige pas à trouver des années sorties du chapeau ?
En plus, elle calcule rien.
Franchement, je pense qu'elle ne sert à rien cette fonction.
Mais bon on va faire simple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 std::pair<int, int> Serie::calculer_Annees_Diffusion() { return make_pair<int, int>(m_f_anneesProduction.first.value_or(0), m_f_anneesProduction.second.value_or(0)); }Et :
Comment faire ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part m_f_anneesDiffusion = y;
Ou qu'il ait ? Expliquez-moi !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 ??? Saison::???_Annees_Diffusion(???) { ??? m_f_anneesDiffusion = y; ??? }dans le constructeur de Saison est largement opérationnel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Saison::Saison(fs::path const& cheminFichier, const Serie& serie) : m_serie{ serie } { ... m_f_anneesDiffusion = y; }C'est quoi la question ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void Saison::initialiser_Fichier(fs::path const& cheminFichier) { ... if (nomFichier == L"???.txt") { ???_Annees_Diffusion(cheminFichier); return; } ... }
Surtout que vous avez mis en commentaire le code qui devrait gérer la majorité des fichiers .txt :
Avec le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 if (std::regex_match(nomFichier, std::wregex{L"([[:digit:]]{1,2})x(.)+"})) { return; //InfosVisionnage info_vis{*this, m_cheminFichier}; //bool none(); /*if (m_liste_episodes.find(info_vis.m_NumeroEpisode) != m_liste_episodes.end()) { m_liste_episodes[info_vis.m_NumeroEpisode]->ajouter_SequenceVisionnage(info_vis); } else { m_liste_episodes.emplace(std::pair<const int, shared_ptr<Episode>>{ info_vis.m_NumeroEpisode, make_shared<Episode>(info_vis) }); }*/ }
cela fonctionne jusqu'à la ligne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 if (std::regex_match(nomFichier, std::wregex{L"([[:digit:]]{1,2})x(.)+"})) { InfosVisionnage info_vis{*this, cheminFichier }; if (m_liste_episodes.find(info_vis.m_NumeroEpisode) != m_liste_episodes.end()) { m_liste_episodes[info_vis.m_NumeroEpisode]->ajouter_SequenceVisionnage(info_vis); } else { m_liste_episodes.emplace(std::pair<const int, shared_ptr<Episode>>{ info_vis.m_NumeroEpisode, make_shared<Episode>(info_vis) }); } }
dans le constructeur de "InfosVisionnage".
Code : Sélectionner tout - Visualiser dans une fenêtre à part m_titres[0] = t[0].substr(0, pos);
Parce que vous gérez n'importe comment le champ "m_titres" de cette classe.
Bin Non, et de quelles années on parle ?Alors pas "std::wstring m_annees", mais "int m_annees" et "std::vector<int> m_annees" ???
Pourquoi pas juste :
???
Code : Sélectionner tout - Visualiser dans une fenêtre à part std::pair<std::optional<int>, std::optional<int>> m_f_anneesProduction;
EDIT :
Juste l'histoire de la couleur de la parenthèse fermante ?Et pourquoi ?
Titre : The Mandalorian (2019-) ...
Juste une typo (faute de frappe) facile à repérer et à corriger :
"keyColor" sous la forme d'un tableau, c'est pas top.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 std::wstring Serie::format_Annees() { if (m_f_anneesProduction.first && m_f_anneesProduction.second) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[1] + L'-' + valuesColor + std::to_wstring(m_f_anneesProduction.second.value()) + keyColor[0] + L')' + valuesColor; } else if (m_f_anneesProduction.first) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[0] + L')' + valuesColor; } else { std::pair<int, int> anneesDiffusion = calculer_Annees_Diffusion(); return keyColor[0] + L" (" + valuesColor + std::to_wstring(anneesDiffusion.first) + keyColor[1] + L'-' + valuesColor + std::to_wstring(anneesDiffusion.second) + keyColor[0] + L')' + valuesColor; } }
Mais vous ne vous simplifiez pas la vie non plus.Les chiffres : calculer !!! C'est dure !!!
Si vous avez un champ ""std::pair<std::optional<int>, std::optional<int>> m_f_anneesProduction" que vous initialisez dans le constructeur de Serie, pourquoi vous emmerdez à faire des calculs ?
Bonsoir,
https://github.com/laurentbouleau/Exemple : Juillet 07 (07/07/2024)
Attention :
Non ===> (2019-) : ok !
Pas grave !!!
Mais exemple :
Kaleidoscope.[2023 Netflix]???
Azertyuiop - qsdfghjklm.[2021-2023 Netflix].Manga
Etc...
???
Je suis fatigué !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 void SequenceVisionnage::Print() { ; system("PAUSE"); } /*void SequenceVisionnage::Print() { std::wstring wstr; bool chiffre_et_point_ou_pas = Print_Titre_chiffre_et_point_ou_pas(m_NumeroEpisod); if (chiffre_et_point_ou_pas) { wstr = std::to_wstring(m_saison) + keyColor[1] + L'x' + valuesColor + std::to_wstring(m_episode) + keyColor[1] + L" : " + valuesColor; } wstr += keyColor[1] + m_titre + valuesColor; if (m_deux_points != L"") wstr += m_deux_points + keyColor[1] + m_sous_titre + valuesColor; if (m_numero == 1) { wstr += keyColor[1] + L" (" + valuesColor + std::to_wstring(m_duree_en_seconde / 60) + keyColor[1] + m_min + L')' + valuesColor; } else { //wstr += keyColor[1] + L" [" + valuesColor + std::to_wstring(numero++) + keyColor[1] + L']' + valuesColor; //wstr += keyColor[1] + L" [" + valuesColor + std::to_wstring(saison_episode.numero++) + keyColor[1] + L']' + valuesColor; //wstr += keyColor[1] + L" [" + valuesColor + std::to_wstring(1 + saison_episode.numero++) + keyColor[1] + L']' + valuesColor; //numero++; //saison_episode.numero++; } wstr += keyColor[1] + L" : " + valuesColor; wstr += Print_Dates_de_visionnage(m_dates); // phrases if (m_numero == 1)//titre != L"") { wstr += L"\r\n" + m_phrases; //saison_episode.numero = 1; } std::wcout << wstr; }*/ // ###################################################################################################################################################### // # # // # std::wstring SequenceVisionnage::Print_Dates_de_visionnage(std::vector<DateRecord>& m_DatesVisionnage) # // # # // ###################################################################################################################################################### std::wstring SequenceVisionnage::Print_Dates_de_visionnage(std::vector<DateRecord>& m_DatesVisionnage) { const std::wstring date_format = L"%d" + keyColor[1] + L"/" + valuesColor + L"%m" + keyColor[1] + L"/" + valuesColor + L"%Y"; const std::wstring between_parenthesis = keyColor[1] + L"(" + valuesColor + L"%s" + keyColor[1] + L")" + valuesColor; const std::wstring same_date_format = between_parenthesis; const std::wstring prequel_format = between_parenthesis; const std::wstring streaming_format = keyColor[1] + L" : " + valuesColor + L"%s"; const std::wstring step_by_step_tag = L' ' + keyColor[1] + L'[' + valuesColor + L"pas-à-pas" + keyColor[1] + L']' + valuesColor; std::wstring dates_de_visionnage_wstr = L""; std::vector<std::wstring> v_wstr; std::time_t last_date{ 0 }; int same_date_counter = 0; for (auto dr : m_DatesVisionnage) { std::time_t time = std::mktime(&dr.date); if (last_date != time) { std::tm localtime = *std::localtime(&time); std::wstringstream target_stream; target_stream << std::put_time(&localtime, date_format.c_str()); std::wstring date_str = target_stream.str(); v_wstr.push_back(date_str); same_date_counter = 0; } else { same_date_counter++; if (same_date_counter == 1) { v_wstr.back() += wstring_format(same_date_format, L"1"); } v_wstr.back() += wstring_format(same_date_format, std::to_wstring(same_date_counter + 1).c_str()); } last_date = time; } for (auto i = 0; i < v_wstr.size(); i++) { if (i != 0) dates_de_visionnage_wstr += L", "; dates_de_visionnage_wstr += v_wstr[i]; } if (m_DatesVisionnage.size() == 1) { if (m_DatesVisionnage[0].someFlag) dates_de_visionnage_wstr += wstring_format(prequel_format, L"stop ou pas !"); } else { if (m_DatesVisionnage.size() > 0) { if (m_DatesVisionnage.back().someFlag) { dates_de_visionnage_wstr += wstring_format(prequel_format, L"à suivre"); } dates_de_visionnage_wstr += step_by_step_tag; } } if (m_streaming != L"" && dates_de_visionnage_wstr.length() > 0) dates_de_visionnage_wstr += wstring_format(streaming_format, m_streaming.c_str()); // return dates_de_visionnage_wstr; } // ###################################################################################################################################################### // # # // # bool SequenceVisionnage::Print_Titre_chiffre_et_point_ou_pas(unsigned short int episode) # // # # // ###################################################################################################################################################### bool SequenceVisionnage::Print_Titre_chiffre_et_point_ou_pas(unsigned short int episode) { if (episode == 0) return false; return true; } // ###################################################################################################################################################### // ###################################################################################################################################################### // ###################################################################################################################################################### // # # // # void Episode::Episode(InfosVisionnage const& seq_vis) :m_saison{ info_vis.m_saison } {}; # // # # // ###################################################################################################################################################### // Ok !!! /*Episode::Episode(InfosVisionnage const& seq_vis) { m_saison{ info_vis.m_saison }; }*/ /*Episode::Episode(SequenceVisionnage const& seq_vis) { //auto nomFichier = seq_vis.filename().wstring(); //auto nomFichier = seq_vis; m_liste_sequence_visionnages.push_back(seq_vis); //system("PAUSE"); //assert(nomFichier.length() > 0 && L"Nom de fichier vide"); //Episode episode(cheminFichier); //episodes.push_back(episode); // Episode //SequenceVisionnage sequencevisionnage(seq_vis); //titre = sequencevisionnage.titre; }*/ // ###################################################################################################################################################### // # # // # void Episode::ajouter_SequenceVisionnage(const InfosVisionnage& seq_vis) # // # # // ###################################################################################################################################################### void Episode::ajouter_SequenceVisionnage(const InfosVisionnage& info_vis) { m_liste_sequence_visionnages.push_back(SequenceVisionnage(*this, info_vis)); } // ###################################################################################################################################################### // # # // # void Episode::Print() # // # # // ###################################################################################################################################################### void Episode::Print() { //Print_Data(); // ??? for (auto vis : m_liste_sequence_visionnages) { vis.Print(); } } // ###################################################################################################################################################### // # # // # bool Episode::Print_Data() # // # # // ###################################################################################################################################################### /*void Episode::Print_Data() { }*/ /*bool Episode::Print_Titre_chiffre_et_point_ou_pas(unsigned short int episode) { if (episode == 0) return false; return true; }*/
Merci
Vous voulez que le "-" apparaisse ???Non ===> (2019-) : ok !
Pas grave !!!
C'est quoi la logique d'affichage ou non du "-" ?
Vous ne pouvez plus vous basez uniquement sur le répertoire racine de la série car vous utilisez les années des saisons pour "corriger" ces valeurs.
Est-ce que c'est pour indiquer qu'une série est encore en production ?
Normalement, avec notre "nouvelle" architecture, il est simple de voir où est construit cet affichage :
Vous devriez maitriser assez le code pour trouver vous-même la source de l'affichage, non ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 std::wstring Serie::format_Annees() { if (m_f_anneesProduction.first && m_f_anneesProduction.second) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[1] + L'-' + valuesColor + std::to_wstring(m_f_anneesProduction.second.value()) + keyColor[0] + L')' + valuesColor; } else if (m_f_anneesProduction.first) { return keyColor[0] + L" (" + valuesColor + std::to_wstring(m_f_anneesProduction.first.value()) + keyColor[0] + L')' + valuesColor; } else { std::pair<int, int> anneesDiffusion = calculer_Annees_Diffusion(); return keyColor[0] + L" (" + valuesColor + std::to_wstring(anneesDiffusion.first) + keyColor[1] + L'-' + valuesColor + std::to_wstring(anneesDiffusion.second) + keyColor[0] + L')' + valuesColor; } }
On revient à l'usage "classique" du débogueur.Mais exemple :
Kaleidoscope.[2023 Netflix]
Azertyuiop - qsdfghjklm.[2021-2023 Netflix].Manga
Etc...
Vous n'avez qu'à cliquer sur le bouton "Recommencer" pour que le débugueur arrête le programme à la ligne où le problème a été détecté.
Vous verrez dans la pile d'appel (1 frame plus bas que l'endroit de détection) que la ligne problématique dans votre code est ligne 339 du fichier "serie.cpp" :
On est encore sur du code où une variable est utilisée des dizaines de fois pour des choses complètement différentes et où vous ne testez pas les conditions d'utilisation d'une expression avant de vous en servir.
Code : Sélectionner tout - Visualiser dans une fenêtre à part initialiser_Duree(t[0]);
Ici, le fichier "1x8.2024-03-03.txt" est vide, donc "t[0]" plante.
Vous avez mis en commentaire l'utilisation de 4 expressions régulières, qui peuvent très facilement fusionner en une seule : "(.+)(?:\\s?\\:\\s|/|\\s\\-\\s)(.+)" (encore plus simplifiable si le motif à trouver est plus "logique").
Pour la remplacer par une usine à gaz à passe de "find" et d'utilisation anarchique de nom de variable comme "t".
Pourquoi faire aussi compliqué ???
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 InfosVisionnage::InfosVisionnage(const Saison& saison, fs::path const& m_cheminFichier) : m_saison{ saison } { ... std::vector<std::wstring> file_content = lire_fichierTxt(m_cheminFichier.wstring(), { L"\n" }, false); m_NumeroEpisode = std::stoi(match[filename_numero_episode_index]); if (file_content.size() > 0) { std::wsmatch soustitre_match; const std::wregex soustitre_format_rg{ L"(?:(\\d+)\\.)?(.+)(?:\\s?\\:\\s|/|\\s\\-\\s)(.+)" }; if (std::regex_match(file_content[0], soustitre_match, soustitre_format_rg)) { m_NumeroEpisode = soustitre_match[1].matched ? std::stoi(soustitre_match[1]) : 0; m_titres.push_back(soustitre_match[2]); m_titres.push_back(soustitre_match[3]); } else { m_titres.push_back(file_content[0]); } } if (file_content.size() > 1) initialiser_Duree(file_content[1]); if (file_content.size() > 2) { file_content.erase(file_content.begin()); //bof à revoir file_content.erase(file_content.begin()); //bof à revoir m_resume = file_content; } }Quel rapport avec les fonctions "Print" de SequenceVisionnage ???
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void SequenceVisionnage::Print() { ; system("PAUSE"); // <----WTF }
Le débogueur est votre ami.
"system("PAUSE");"n non mais, sérieux !!! Les points d'arrêt dans le débogueur, B***** !!!
Bonsoir,
Non, esthétiquement !Vous voulez que le "-" apparaisse ???
C'est quoi la logique d'affichage ou non du "-" ?
Vous ne pouvez plus vous basez uniquement sur le répertoire racine de la série car vous utilisez les années des saisons pour "corriger" ces valeurs.
Est-ce que c'est pour indiquer qu'une série est encore en production ?
Exemple :
Mais : Pourquoi ?
Exemple : The Mandalorian (dossiers)
2019-11-12Pouvez-vous expliquer ???
2020-10-30
2023-03-01
https://github.com/laurentbouleau/Exemple : Juillet 08 (08/07/2024)
Mais :
Pourquoi ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void Saison::initialiser_Fichier(fs::path const& cheminFichier) { ... if (int j = std::stoi(nomFichier)) { m_numero = j; // initialiser_Resume(cheminFichier); // ??? return; } ... }
Pas fini !!! Je suis crevé !!!
Merci
Ok, mais c'est quoi la "règle" esthétique ?Non, esthétiquement !
Je ne suis pas sûr de comprendre la question.Exemple : The Mandalorian (dossiers)
2019-11-12
2020-10-30
2023-03-01
Oui, il y a une différence de format entre le nom du fichier et ce qui est affiché.
C'est "vous" qui maitrisez le format de sortie via la ligne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 td::wstring SequenceVisionnage::Print_Dates_de_visionnage(std::vector<DateRecord>& m_DatesVisionnage) { const std::wstring date_format = L"%d" + keyColor[1] + L"/" + valuesColor + L"%m" + keyColor[1] + L"/" + valuesColor + L"%Y"; ...Je sais pas moi, c'est vous qui avez écrit ce code, que je ne trouve pas logique.Pourquoi ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void Saison::initialiser_Fichier(fs::path const& cheminFichier) { ... if (int j = std::stoi(nomFichier)) { m_numero = j; // initialiser_Resume(cheminFichier); // ??? return; } ... }
C'est vraisemblablement pour "gérer" des fichiers dont le nom ressemble à "8.txt", etc...
Mais des fichiers comme "1x8.2024-03-03.txt" devrait aussi passer dans le if, et c'est encore moins logique.
Bonjour,
Expliquez-moi ! Mais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 ... void Episode::Print() { Print_Data(); // ??? for (auto vis : m_liste_sequence_visionnages) { vis.Print(); } } ... void Episode::Print_Data() { ??? } ...
Merci
https://github.com/laurentbouleau/Exemple : Juillet 09 (09/07/2024)
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager