Question Amélioration de code

Plus d'informations
il y a 12 ans 1 semaine #17175 par Vincent
Amélioration de code a été créé par Vincent
Bonjour,

je suis nouveau sur ce forum, j'ai fais un petit programme powershel qui fonctionne mais que je ne trouve pas très esthétique et performant.

Il est fait à l'ancienne.

c'est mon premier programme en PS, donc j'ai beaucoup à apprendre.
le BUT suite à réception d'un fichier CSV, il me faut créer une aborescence de dossiers windows.

le fichier est structure comme SUIT:

CODE Libelle Niveau CODE -1
___________________________________________________
3005 , FRUIT , 2 , 3000
5000 , AGRUME , 3 , 3005
5005 , CITRON , 4 , 5000
5011 , ORANGE , 4 , 5000
5012 , MENDARINE , 4 , 5000
5013 , CLEMENTINE , 4 , 5000
5031 , ABRICOT , 4 , 3005
3006 , POMME , 2 , 3000


Le but est d'utiliser la notion de code -1 pour voir à quel niveau dans l'arborescence créer le dossier.

3000
|_> 3005
|_> 5000
|_> 5005
|_> 5011
|_> 5012
|_> 5013
|_> 5031
|_> 3006

Au départ je voulais faire une fois la lecture du fichier et le stocker dans un tableau à plusieurs dimensions mais ca n'a pas marché....

Voici mon code[code:1]clear
$fichier = Get-Content C:\toto.csv
cd 'C:\Arbo code'

Foreach ($line in $fichier) {
$line_splitted = $line.split(\",\"«»)
$CODE=$line_splitted[0]
$LIB=$line_splitted[1]
$NIV=$line_splitted[2]
$CODE1=$line_splitted[3]
if (($niv -eq \"1\"«») -and ($CODE -eq \"3000\" -or ($CODE -eq \"2010\"«»))){
Write-Host \"$CODE $LIB $NIV $CODE1\"
New-Item -Name \"$CODE\" -ItemType directory
$entite=$CODE

Foreach ($line in $fichier) {
$line_splitted = $line.split(\",\"«»)
$CODE=$line_splitted[0]
$LIB=$line_splitted[1]
$NIV=$line_splitted[2]
$CODE1=$line_splitted[3]
if ($CODE1 -eq $Entite){
New-Item -Name \"$Entite\$CODE\" -ItemType directory
$Categ=$CODE

Foreach ($line in $fichier) {
$line_splitted = $line.split(\",\"«»)
$CODE=$line_splitted[0]
$LIB=$line_splitted[1]
$NIV=$line_splitted[2]
$CODE1=$line_splitted[3]
if ($CODE1 -eq $Categ){
New-Item -Name \"$Entite\$Categ\$CODE\" -ItemType directory
$Esp=$CODE

Foreach ($line in $fichier) {
$line_splitted = $line.split(\",\"«»)
$CODE=$line_splitted[0]
$LIB=$line_splitted[1]
$NIV=$line_splitted[2]
$CODE1=$line_splitted[3]
if ($CODE1 -eq $Esp){
New-Item -Name \"$Entite\$Categ\$Esp\$CODE\" -ItemType directory
}
}

}
}
}
}
}

} [/code:1]

Si vous avez des idées

merci

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 12 ans 1 semaine #17177 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Amélioration de code
Salut,
Wince34 écrit:

...
j'ai fais un petit programme powershell qui fonctionne mais que je ne trouve pas très esthétique et performant.

Je dois être fatigué, mais j'ai du mal à comprendre ton code et la construction autour de la relation \"code-1\" :pinch:
Donc ici, pour moi, l'esthétisme( qui selon moi n'a rien à faire dans le dev) et la performance est le cadet de mes soucis.
Wince34 écrit:

Il est fait à l'ancienne.

De le savoir me rassure :P

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 12 ans 5 jours #17180 par Philippe
Réponse de Philippe sur le sujet Re:Amélioration de code
bonjour Wince34

j'ai fais un petit programme powershell qui fonctionne mais que je ne trouve pas très esthétique et performant.

Il est fait à l'ancienne.


déjà tu peut utilisé l'indentation, ca améliore l'esthétique et par là la lisibilité.
tu peut aussi utilisé IMPORT-CSV

ainsi tu pourra transformé cette partie de code :

[code:1] $line_splitted = $line.split(\",\"«»)
$CODE=$line_splitted[0]
$LIB=$line_splitted[1]
$NIV=$line_splitted[2]
$CODE1=$line_splitted[3]
[/code:1]
en
[code:1] $CODE=$line.code
$LIB=$line.libelle
$NIV=$line.niveau
$CODE1=$line.\"code-1\"
[/code:1]
MAIS ca impose deux chose :
1 - que la première ligne de label soit au même format que le reste du fichier (pas comme dans l'exemple)
2 - soit tu renomme le libelle \"CODE-1\", soit il faut faire très attention dans ton code car ca être mal interprété par powershell celons le code (en chaine de caractères ou en une soustraction)


autre chose simplifiable :
[code:1] $CODE=$line.code
$LIB=$line.libelle
$NIV=$line.niveau
$CODE1=$line.\"code-1\"
if (($niv -eq \"1\"«») -and ($CODE -eq \"3000\" -or ($CODE -eq \"2010\"«»))){
Write-Host \"$CODE $LIB $NIV $CODE1\"
New-Item -Name \"$CODE\" -ItemType directory
$entite=$CODE
[/code:1]
en
[code:1]
if (($line.niveau -eq \"1\"«») -and ($line.code -eq \"3000\" -or ($line.code -eq \"2010\"«»))){
Write-Host $line.code $line.libelle $line.niveau $line.\"code-1\"
New-Item -Name $line.code -ItemType directory
$entite=$line.code
[/code:1]


exemple de ce que pourrais etre le code apres simplification et adaptation du CSV
ATTENTION JE N'EST NI TESTE LE SCRIPT, NI VERIFIER LA SYNTAXE CA RESTE UN EXEMPLE DE PRESENTATION

[code:1]$fichier = import-csv C:\toto.csv
cd 'C:\Arbo code'

Foreach ($line in $fichier) {

if (($line.niveau -eq \"1\"«») -and ($line.code -eq \"3000\" -or ($line.code -eq \"2010\"«»))){
Write-Host $line.code $line.libelle $line.niveau $($line.\"code-1\"«»)
New-Item -Name $line.code -ItemType directory
$entite=$line.code

Foreach ($line in $fichier) {
if ($($line.\"code-1\"«») -eq $Entite){
New-Item -Name \"$Entite\$($line.code)\" -ItemType directory
$Categ=$line.code

Foreach ($line in $fichier) {
if ($line.\"code-1\" -eq $Categ){
New-Item -Name \"$Entite\$Categ\$($line.code)\" -ItemType directory
$Esp=$line.code

Foreach ($line in $fichier) {
if ($line.\"code-1\" -eq $Esp){
New-Item -Name \"$Entite\$Categ\$Esp\$($line.code)\" -ItemType directory
}
}
}
}
}
}
}
}[/code:1]

bon courage pour la suite, et revient vers nous pour d'éventuelle erreur ou pour d'autre question

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 12 ans 5 jours #17181 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Amélioration de code
6ratgus écrit:

ça améliore l'esthétique et par là la lisibilité.

Effectivement, donc avant tout se préoccuper de la lisibilité.

En regardant de plus près, tout en renommant, les champs on comprend mieux les données.
[code:1]
\"Parent\",\"Child\",\"Niveau\",\"Libelle\"
\"3000 \",\"3006\",\"2\",\"POMME\"
[/code:1]
J'ai eu la même approche que toi, mais je ne suis pas allé plus loin, car le code ne se faisait rien ou si peu.
J'ai donc recherché si qq avait déjà eu ce besoin, j'ai trouvé ceci . Ce qui dans un premier temps évite de coder des classes natives du framework.

La fonction est récursive et reste basée sur des boucles. Ce code n'est pas très efficace, mais pour qq centaines de lignes on peut s'en contenter.
De plus il ne peut créer que 100 niveaux, car Ps n'autorise que 100 appels récursifs.

Les données doivent utiliser des délimiteurs, et la suppression des espaces sur les champs Parent et Child ne serait pas de trop.
Après qq tests et adaptation, voici une autre solution :
[code:1]
@'
\"Parent\",\"Child\",\"Niveau\",\"Libelle\"
\"3000\",\"3006\",\"2\",\"POMME\"
\"3000\",\"3005\",\"2\",\"FRUIT\"
\"3005\",\"5000\",\"3\",\"AGRUME\"
\"3005\",\"5031\",\"4\",\"ABRICOT\"
\"5000\",\"5011\",\"4\",\"ORANGE\"
\"5000\",\"5013\",\"4\",\"CLEMENTINE\"
\"5000\",\"5005\",\"4\",\"CITRON\"
\"5000\",\"5012\",\"4\",\"MANDARINE\"
'@ > c:\temp\datas.csv

#'Facilite' la recherche
$DirectoryInfos=Import-csv c:\temp\datas.csv|Sort Parent,Child

function Set-ChildDirectory
{
#from powershell.cz/2012/11/27/generate-tree-structure/
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,Position = 0)]
$InputObject,

[Parameter(Mandatory = $true,Position = 1)]
[string] $Id,

[Parameter()]
[int] $Shift = 0,

[Parameter()]
[string] $RootName
)

if ($PSBoundParameters.ContainsKey('RootName'))
{ $Name=$RootName }

$indent = ' ' * $shift

$Name=$Name+'\'+$ID
MD $Name > $null
$InputObject |
Where {
$_.Parent -eq $id
} |
ForEach {
Write-Debug (\"{0} {1}\" -f $indent, $_.Child)
Set-ChildDirectory -InputObject $InputObject -id $_.Child -shift $($shift+2)
}
}
$DirectoryInfos = Import-csv c:\temp\datas.csv|sort parent,Child
md 'C:\temp\TestDirByCode' -ea SilentlyContinue > $null
Set-Location 'C:\temp\TestDirByCode'
Set-ChildDirectory -InputObject $DirectoryInfos -Id 3000 -Root $Pwd

# C:\temp\TestDirByCode> show-tree #voir PSCX
# C:\temp\TestDirByCode
# \--3000
# |--3005
# | |--5000
# | | |--5005
# | | |--5011
# | | |--5012
# | | \--5013
# | \--5031
# \--3006
#
#ou Dir -rec |Select fullname
# C:\temp\TestDirByCode> dir -rec |select fullname
#
# FullName
#
# C:\temp\TestDirByCode\3000
# C:\temp\TestDirByCode\3000\3005
# C:\temp\TestDirByCode\3000\3006
# C:\temp\TestDirByCode\3000\3005\5000
# C:\temp\TestDirByCode\3000\3005\5031
# C:\temp\TestDirByCode\3000\3005\5000\5005
# C:\temp\TestDirByCode\3000\3005\5000\5011
# C:\temp\TestDirByCode\3000\3005\5000\5012
# C:\temp\TestDirByCode\3000\3005\5000\5013
[/code:1]
L'information Niveau n'est pas nécessaire ici.<br><br>Message édité par: Laurent Dardenne, à: 17/03/14 14:57

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 12 ans 5 jours #17182 par Philippe
Réponse de Philippe sur le sujet Re:Amélioration de code
Laurent Dardenne écrit :

L'information Niveau n'est pas nécessaire ici.

je pense aussi la meme chose mais je connais pas l'ensemble du projet
de plus il me semble que une simple boucle avec quelque if ou un switch devrais suffire

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 12 ans 5 jours #17183 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Amélioration de code
6ratgus écrit:

il me semble que une simple boucle avec quelque if ou un switch devrais suffire

Le if je veux bien, voir le Where de la fonction Get-Child, mais pour le switch je suis curieux de voir ça :)

Un switch est statique ce que n'est pas un arbre binaire, à moins que tu veuilles gérer un nombre de niveaux fixe...

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.079 secondes
Propulsé par Kunena