Aligner des chaines de textes

Résolu/Fermé
alexo28 Messages postés 460 Date d'inscription dimanche 9 septembre 2012 Statut Membre Dernière intervention 23 juin 2017 - 6 mai 2017 à 22:53
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 - 15 mai 2017 à 08:11
Bonjour, j'aimerai de vos conseils pour arriver à produire un résultat visuel correct dans mes travaux de programmation.

Je suis étudiant en programmation et dans presque chaque devoir il est demandé de produire un résultat visuel à l'écran (soit dans un fichier, soit dans la console).

Lorsqu'il y a plusieurs éléments à afficher à l'écran, il faut les aligner (https://prnt.sc/f4wx2j sauf que j'ai de la difficulté à moi-même arriver à un résultat similaire. La seule facon que j'ai d'y arriver, c'est par essais-erreur à l'aide de PadLeft et PadRight, mais j'ai toujours de la difficulté à comprendre comment y arriver dans prendre des heures à jouer dans les "pad" pour arriver à un résultat comme sur la photo.

J'aimerai savoir si je peux faire plus facilement cela? Ma technique actuelle est de créer un string avec les balises {0} {1} etc pour pouvoir ajouter NomDeString.ToString().PadLeft(Nombre), sauf que les résultats sont assez moyens et je n'arrive pas à avoir une technique uniforme qui n'inclut pas "essais erreur"

le code actuel est mis en bas du post et le résultat visuel actuel aussi


public override string ChaineAffichage()
{
return string.Format("{0} {1} {2} {3} {4:f2} {5} {6} $", Type.ToString().PadLeft(6), Marque.ToString().PadLeft(8), Modèle.ToString().PadLeft(6), Année.ToString().PadLeft(6),
NbKilomètreAutonomie.ToString().PadLeft(6), NbKm.ToString().PadLeft(6), Cout.ToString().PadLeft(6));
}
public override string ChaineCassée(int codeErreur)
{
string chaineDeRetour;
if (codeErreur == 1)
{
chaineDeRetour = string.Format("{0} {1} {2} {3} {4:f2} {5} Autonomie insuffisante", Type.ToString().PadLeft(6),
Marque.ToString().PadLeft(8), Modèle.ToString().PadLeft(6), Année.ToString().PadLeft(6), NbKilomètreAutonomie.ToString().PadLeft(6), NbKm.ToString().PadLeft(6));
}
else if (codeErreur == 2)
{
chaineDeRetour = string.Format("{0} {1} {2} {3} {4:F2} {5} Nombre de Km invalide", Type,
Marque.ToString().PadLeft(8), Modèle.ToString().PadLeft(6), Année.ToString().PadLeft(6), NbKilomètreAutonomie.ToString().PadLeft(6), NbKm.ToString().PadLeft(6));

}
else
{
chaineDeRetour = "Erreur dans le code > Dérivé véhicule, ChaineCassée";
}
return chaineDeRetour;
}


Le résultat: https://prnt.sc/f4x0wa

4 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
7 mai 2017 à 01:33
Bonsoir

Avant de parler de ta question ton code comporte quelques erreurs:
  • déjà tu utilises des variables avec des accents, les truc interdits en programmation son rares (y'a plein de choses déconseillées), mais les accents c'est interdit.

Imagine que tu doives compiler ton code sur un PC en anglais. Rien ne fonctionnera.
  • Ensuite j'imagine qu'au moins Type, Marque et Modèle sont des string, pas la peine de faire ToString sur un string.
  • Enfin qu'il y ait une erreur ou pas, jusqu'à NbKm la chaine est toujours la même, donc au lieu de coder 3 fois la même chose (et donc de corriger 3 fois si nécessaire), il est conseillé d'écrire une méthode que tu appelleras 3 fois.



Pour ton problème à proprement parlé, il n'y a malheureusement pas 50 méthodes pour aligner à droite.
Par contre, l’intérêt de string.Format est d'appliquer toutes les méthodes de formatage dans une seule, à partir de la valeur "brute", t'as bien fait
{4:f2}
, pour mettre l'autonomie au format f2, faire des ToString et des PadLeft est redondant avec le ToString.

"{0,8}" va compléter avec des espace à droite à concurrence de 8 caractères.
"{0,-8}" va compléter avec des espace à gauche à concurrence de 8 caractères.
"{0:C2} va mettre au format Currency avec 2 décimales.
Dans ton modèle, l'autonomie est arrondie à la valeur inférieure, pour ça on peut utiliser Math.Floor


Pour le test, j'ai écrit cette classe
    class ClassAlexo
    {
        public string Type { get; set; }

        public string Marque { get; set; }

        public string Modele { get; set; }

        public int Annee { get; set; }

        public double Autonomie { get; set; }

        public double NbKm { get; set; }

        public double Cout { get; set; }

        public string Erreur { get; set; }
    }


Je me suis simplifié la vie pour savoir s'il y a une erreur je regarde si elle vaut null ou pas

            ClassAlexo test1 = new ClassAlexo
            {
                Type = "VE-123",
                Marque = "Nissan",
                Modele = "Leaf",
                Annee = 2013,
                Autonomie = 215.0,
                NbKm = 75.0,
                Cout = 0.9
            };
            ClassAlexo test2 = new ClassAlexo
            {
                Type = "VE-123",
                Marque = "Nissan",
                Modele = "Leaf",
                Annee = 2013,
                Autonomie = 215.0,
                NbKm = 216.0,
                Cout = 0.9,
                Erreur = "Autonomie Insuffisante"
            };
            ClassAlexo test3 = new ClassAlexo
            {
                Type = "VI-014",
                Marque = "Nissan",
                Modele = "Altima",
                Annee = 2008,
                Autonomie = 842.6967,
                NbKm = 842.0,
                Cout = 82.4318
            };
            ClassAlexo test4 = new ClassAlexo
            {
                Type = "VH-001",
                Marque = "Chevrolet",
                Modele = "Volt",
                Annee = 2015,
                Autonomie = 963.9535,
                NbKm = 963.0,
                Cout = 42.372
            };

            List<ClassAlexo> liste =new List<ClassAlexo> { test1, test2, test3, test4 };
            List<string> sortie = new List<string>();

            foreach(ClassAlexo v in liste)
            {
                if (v.Erreur == null)
                    sortie.Add(string.Format("{0}{1,9:C2}", DebutLigne(v), v.Cout));
                else
                    sortie.Add(string.Format("{0}  {1}", DebutLigne(v), v.Erreur));

            }

            File.WriteAllLines("FichierSortie.txt", sortie);
            
        }


        private string DebutLigne(ClassAlexo Voiture)
        {
            return string.Format("{0,-8}{1,-11}{2,-8}{3,-6}{4,-5}{5,3}", Voiture.Type, Voiture.Marque, Voiture.Modele, Voiture.Annee, Math.Floor(Voiture.Autonomie), Voiture.NbKm);
        }


Le résultat
VE-123  Nissan     Leaf    2013  215   75   0,90 €
VE-123 Nissan Leaf 2013 215 216 Autonomie Insuffisante
VI-014 Nissan Altima 2008 842 842 82,43 €
VH-001 Chevrolet Volt 2015 963 963 42,37 €



PS pour la coloration, en précisant le langage c'est mieux (il suffit de choisir dans la liste déroulante, voir procédure)
PS2 on peut mettre des images dans la discussion c'est plus pratique pour le lecteur que de jongler sur plusieurs pages, c'est aussi expliqué dans la FAQ que je t'ai mis en lien
PS3 mettre les données faciles à copier coller fait gagné du temps au lecteur qui tente de t'aider.

2
alexo28 Messages postés 460 Date d'inscription dimanche 9 septembre 2012 Statut Membre Dernière intervention 23 juin 2017 61
8 mai 2017 à 04:17
Merci énormément! Ta réponse va beaucoup me simplifier la vie pour la suite!

J'apprécie beaucoup la qualité et le temps pris à faire cette réponse

Pour ton PS : J'ai un bug qui fait apparaitre la liste déroulante derrière la boite de texte, alors je n'ai pas pu choisir C#
Pour le PS2 et PS3- Je vais me renseigner.

Tu m'a appris encore plus que ce que j'étais venu chercher, merci et remerci!
0
alexo28 Messages postés 460 Date d'inscription dimanche 9 septembre 2012 Statut Membre Dernière intervention 23 juin 2017 61
8 mai 2017 à 05:38
et pour ce qui est des accents je ne peux rien y faire dans le cadre du cours, j'en ai déjà parlé au professeur, il a approuvé du regard puis il m'a annoncé que l'établissement d'enseignement demandait d'apprendre toutes les matières en français (sauf les cours de langue étrangère, bien sûr)

tl:dr les dirigeants de mon école veulent un apprentissage en français, même si ce n'est pas la réalité du monde professionnel
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
8 mai 2017 à 08:31
Bonjour

Québécois je suppose.

J'ai toujours admiré (et je pèse mes mots) votre pugnacité à défendre notre belle langue bien mieux que nous. Moi aussi je mets un point d'honneur à coder en français (Au grand damne de mon chef de projet).
Mais le risque que par mégarde je clique sur la configuration du clavier dans la barre des taches et change en Allemand ou Hollandais existe. Alors NonbreKilometres est bien en français mais sans accents (ni cédilles, tildes, etc...)
Cela dit ne va pas te mettre ton prof et ta direction à dos pour ça.

Sinon, pour les balises de code, et bien il te faudra les taper à la main, tu clique sur les
<>
ça t'affiche <code></code> et tu ajoutes le langage <code csharp></code>.
(Pour info, afin que tu puisses voir j'ai tapé à la main une autre balise qui annule une balise sinon tu aurais vu
 et 
)



Enfin pour l'alignement, j'ai choisi des valeurs en fonctions des quelques lignes d'exemples que tu as mis.
Si tu connais la taille maximun de chaque colonne, il suffit de prendre 1 ou 2 espaces de plus. Après il est possible de trouver l'espacement optimisé en fonction des données actuelles, mais c'est plus compliqué. Je peux te montrer un exemple si tu veux.
0
alexo28 Messages postés 460 Date d'inscription dimanche 9 septembre 2012 Statut Membre Dernière intervention 23 juin 2017 61
9 mai 2017 à 05:20
enfin j'imagine que pour choisir l'alignement en fonction des données connues tu t'arrange pour prendre la plus grande chaine de caractères et tu rajoute au minimum un espace, comme sa peu importe la chaine sa fonctionne

Si tu as une technique plus sophistiquée ou efficace, tu peux toujours m'expliquer, tes explications sont autant voir plus claires que celles de mon professeur!

Pour faire mes lignes de rapport, ce que j'ai surtout compris avec ton aide c'est de ne pas mélanger les espaces entre les {0}{1} etc. et les padleft ou right. Ensuite aussi la simplification du code bien sûr.

Je sais comment simplifier mon code, c'est juste qu'à un moment quand j'ai mis 30 heures sur un programme inintéressant, j'ai tendance à me laisser aller vers la fin.

Pour la langue, oui je suis Québecois, oui je suis fier de défendre la langue, mais je ne l'applique pas à la programmation, parce que j'ai appris les bases de la programmation en anglais et parce que la documentation est toujours en anglais
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
9 mai 2017 à 07:21
enfin j'imagine que pour choisir l'alignement en fonction des données connues tu t'arrange pour prendre la plus grande chaine de caractères et tu rajoute au minimum un espace, comme sa peu importe la chaine sa fonctionne

c'est ça


parce que la documentation est toujours en anglais
et les langages (à par windev) sont en anglais
0
alexo28 Messages postés 460 Date d'inscription dimanche 9 septembre 2012 Statut Membre Dernière intervention 23 juin 2017 61
Modifié le 15 mai 2017 à 06:11
Je me permet une petite question pour toi, promis c'est la dernière, je suis en vacances après!

Donc j'ai un schéma de classes comme suit: https://prnt.sc/f7wzjk (je n'arrive toujours pas à intégrer les images)

Je dois donner à la classe Monstre une méthode qui puisse être utilisée par le programme client, sauf que la méthode ne peut être définie que en bas dans les deux classes de vampires spécifiques. Donc je ne sais pas trop quoi faire.

1) Vu que la méthode ne va que dans les vampires et non les loup-garou, je ne peux pas mettre "abstract"

2) Si met quand même abstract, il m'arrête quand j'essais de réécrire la même fonction abstract dans la classe Vampire avec comme messages: https://prnt.sc/f7x0wg

Bref, je suis un peu perdu, mais pour tout le reste du développement du programme tout a bien été
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
15 mai 2017 à 08:11
Bonjour

En théorie, c'est un sujet par fil.
Là t'as clairement changé de sujet, il aurait donc fallu ouvrir un nouveau sujet.
Pour les images, c'est une limitation du site, on peut les poster dans les réponses mais pas dans les commentaires ( enfin si, mais en la chargeant depuis une réponse, copiant le code généré et supprimant la réponse....)

Pour ton problème, si seul les enfants de Vampire doivent implémenter cette méthode, le plus simple et le plus logique serait de la créer dans Vampire et pas dans Monstre.

Si c'est imposé, à tester là je ne peux pas, tu peux la déclarer abstraite et protégée dans Monstre.
Dans Vampire tu l'overrides et la passe publique.
public override void MaMethode


0