Fichier CSV : Colonnes qui disparaissent

Avatar du membre
Mammouth du PHP | 1609 Messages

24 juin 2015, 10:47

Le cas de figure est déjà géré par le code :
/* si l'élève n'existe pas dans B on saute la ligne */
if(!isset($students_b[$student_id]))
  continue ;
J'ai pris la décision arbitraire d'ignorer la ligne. Rien ne t’empêches de faire autre chose qu'un continue.

Tu pourrais ajouter la ligne dans $students_a ou bien créer au préalable un tableau $students_c et ajouter la ligne à ce tableau pour à la fin l'enregistrer dans un autre fichier.

A toi de voir ce que tu veux en faire. ;)
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 14 Messages

24 juin 2015, 16:25

J'ai décidé de créer un tableau students_c qui regroupera les etudiants présents dans B et absents dans A
J'ai ecris ce code mais je crois mettre quelques peu emmelés les pinceaux dans les variables a/b/c

Code : Tout sélectionner

/* charge les fichiers */ $students_a = prepare_datas(file_get_contents('ApogeeSaisieFull.csv'), 'apogee'); $students_b = prepare_datas(file_get_contents('synthetiques_13_520.csv'), 'other'); /* compare les données et met à jour $a en fonction des comparaisons faites avec $b */ foreach($students_a as $student_id => $student_a) { // TODO : gerer présence étudiants dans B uniquement // si etudiant present dans B if(isset($students_b[$student_id])) { $student_c = $students_b[$student_id]; if($student_c['login'] != $student_a['login']) $student_a['note_'.$i] = $student_c['login']; for($i =1; $i <6; $i++){ if($student_c['note_'.$i] > $student_a['note_'.$i]) $student_a['note_'.$i] = $student_c['note_'.$i]; $student_a['note_'.$i] = str_replace('.', ',', $student_a['note_'.$i]); } $students_c[$student_id] = $student_a; /* si l'élève n'existe pas dans B on saute la ligne */ if(!isset($students_b[$student_id])) continue ;
Qu'en penses tu ?

Et au final

Code : Tout sélectionner

/* enregistre les données à jour */ // Fichier C avec absence des étudiants du B $fp = fopen('C.csv', 'w'); fputcsv($fp, array('Login','Nom','Prenom','Note','Note','Note','Note','Note'),';','"'); foreach ($students_a as $student) { fputcsv($fp, $student, ';', '"'); } fclose($fp); // Fichier D avec présence des étudiants du B $handle = fopen('D.csv', 'w'); fputcsv($handle, array('Login','Nom','Prenom','Note','Note','Note','Note','Note'),';','"'); foreach ($students_c as $student) { fputcsv($handle, $student, ';', '"'); } fclose($handle);

Avatar du membre
Mammouth du PHP | 1609 Messages

24 juin 2015, 17:11

J'en pense que le code ne fait pas ce que tu énonces ! ;)
Et j'ai dit une bêtise dans mon post précédent.

Ce que le test suivant permet de faire c'est de savoir qu'un étudiant du fichier A n'existe pas dans B et donc cela permettrait de stocker ces dits étudiants dans un troisième fichier.
/* si l'élève n'existe pas dans B on saute la ligne */
if(!isset($students_b[$student_id]))
  continue ;
Toi tu veux stocker dans un troisième fichier les étudiants présents dans B mais pas dans A.
Or la boucle ne passe jamais sur ces étudiants puisqu'elle boucle sur les étudiants de A.

Il faudrait donc ajouter une nouvelle boucle sur les étudiants de B et quand l'étudiant n'est pas présent dans A l'ajouter dans un tableau, disons $students_d comme le fichier va s'appeler D.csv.
$students_d = array();
foreach($students_b as $student_id => $student_b)
{
  /* si l'élève n'existe pas dans A on l'ajoute dans D */
  if(!isset($students_a[$student_id]))
    $students_d[] = $student_b;// inutile de mettre l'id en index car l'index ne sera jamais utilisé
}
Pour ce qui est de l'enregistrement c'est ok. Tu pourrais éventuellement faire une fonction pour ça.

A noter : la reconversion des , en . sur les notes n'est pas faite dans certains cas. Dans le cas des étudiants présents dans A mais pas dans B étant donné qu'on saute la ligne sans plus de traitement. Et maintenant dans le cas des étudiants présents dans B mais pas dans A.
Donc tu peux soit ajouter les traitements nécessaires pour faire ces conversions quand elles ne sont pas faites. Soit tu fais la conversion , vers . uniquement pour les comparaisons. Et je pense que personnellement je choisirai cette deuxième alternative.
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 14 Messages

25 juin 2015, 11:04

Bon je t'embête un dernière fois :P

Vu que je fais ca dans le cadre d'un stage, je dois bosser sous Mac et il m'est impossible d'afficher les erreurs quand je run le script :D ( a part de simples arrays vides)

Brievement, cela te sembles-t-il correct ?

Code : Tout sélectionner

$students_d = array(); foreach($students_b as $student_id =>$student_b) { /* si l'elève n'existe pas dans A on l'ajoute dans D */ if(!isset($students_a[$student_id])) $students_d[] = $student_b; if($student_b['login'] != $student_d['login']) $student_d['login'] = $student_b['login']; for($i = 1; $i<6; $i++){ if($student_b['note_'.$i] > $student_d['note_'.$i]) $student_d['note_'.$i] = $student_b['note_'.$i]; } $students_d[$student_id] = $student_d; } } // Fichier D avec présence des étudiants du B $handle = fopen('D.csv', 'w'); fputcsv($handle, array('Login','Nom','Prenom','Note','Note','Note','Note','Note'),';','"'); foreach ($students_d as $student) { fputcsv($handle, $student, ';', '"'); } fclose($handle); ?>

Avatar du membre
Mammouth du PHP | 1609 Messages

25 juin 2015, 11:25

Salut, alors pour forcer l'affichage des erreurs tu peux essayer d'ajouter ça au début du fichier :
ini_set('display_errors', 1);
error_reporting(E_ALL);
Mais une syntaxe error ne s'affichera pas. étant donné que le script ne sera pas exécuté dans ce cas.
Tu peux faire un tail -f sur le fichier de log d'erreurs dans le terminal.
Tu peux modifier la directive de configuration display_errors dans le php.ini.

Sinon j'ai l'impression qu'il y a un petit problème d'accolades, 3 fermantes pour 2 ouvrantes.
Il ne sert à rien de comparer $student_b et $student_d puisque tu pousses $student_b dans $students_d. $student_d est donc strictement identique à $student_b.
De plus tu utilises $student_d alors qu'il n'est jamais défini (attention au s à student, avec un s c'est le tableau, sans s c'est une ligne du tableau).
La boucle que je t'ai proposée dans mon post précédent est suffisante, il n'y a rien de plus à faire (à part éventuellement remettre des , à la place des . si c'est nécessaire).
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 14 Messages

26 juin 2015, 16:42

C'est encore moi :3
Le programmeur assisté par excellence.

Dis moi, saurais tu pourquoi mon fichier D.csv m'affiche des notes à zéro?
Aussi je n'ai pas réussi à afficher en majuscule les noms et prénoms, malgré un strtoupper, un array_map, ou encore un enieme tableau
http://www.innovativephp.com/converting ... functions/

Avatar du membre
Mammouth du PHP | 1609 Messages

26 juin 2015, 18:28

Salut, alors pour les notes à 0, la comme ça aucune idée. A priori avec le code que je t'ai proposé, il n'y a pas de raison.
Et pour les noms et prénoms en majuscule, if suffit de l'ajouter lors du prepare_datas :

Code : Tout sélectionner

$students[$student_id] = array( 'login' => $type == 'other' ? $login_converter[substr($login, 0, 2)].substr($login, 2) : $login, 'nom' => strtoupper($nom), 'prenom' => strtoupper($prenom) );
Le code complet repris et corrigé (avec arrondi à une décimal sur la note) :

Code : Tout sélectionner

/* tableau de convertion des logins */ $login_converter = array(); $chars = 'abcdefghijklmnopqrstuvwxyz'; for($i = 0; $i < strlen($chars); $i++) $login_converter['i'.$chars[$i]] = 208 + $i; /* fonction de préparation des données pour comparaisons */ function prepare_datas($datas, $type) { global $login_converter; $students = array(); foreach(explode("\n", $datas) as $student) { /* saute la première ligne du fichier */ if(strtolower(substr($student, 0, 5)) == 'login') continue ; /* extrais les colonnes de la ligne */ list($login, $nom, $prenom, $note_1, $note_2, $note_3, $note_4, $note_5) = explode(';', $student); /* stocke les données sous une forme exploitable pour les comparaisons */ /* indexe les données sur nom-prenom pour un accès simple lors des comparaisons */ $student_id = strtoupper($nom).'-'.strtoupper($prenom); $students[$student_id] = array( 'login' => $type == 'other' ? $login_converter[substr($login, 0, 2)].substr($login, 2) : $login, 'nom' => strtoupper($nom), 'prenom' => strtoupper($prenom) ); /* stocke les notes en remplaçant les , par des . dans le cas d'apogée (pour comparaison numérique) et en les mettant /20 dans l'autre cas */ for($i = 1; $i < 6; $i++) { $varname = 'note_'.$i; $note = $$varname; $students[$student_id][$varname] = $type == 'other' ? number_format(substr($note, 0, -2), 1, ',', '') / 5 : $note; } } return $students; } /* charge les fichiers */ $students_a = prepare_datas(file_get_contents('A.csv'), 'apogee'); $students_b = prepare_datas(file_get_contents('B.csv'), 'other'); /* compare les données et met à jour $a en fonction des comparaisons faites avec $b */ foreach($students_a as $student_id => $student_a) { /* si l'élève n'existe pas dans B on saute la ligne */ if(!isset($students_b[$student_id])) continue ; $student_b = $students_b[$student_id]; /* mets à jour le login le cas échéant */ if($student_b['login'] != $student_a['login']) $student_a['login'] = $student_b['login']; /* mets à jour les notes le cas échéant */ for($i = 1; $i < 6; $i++) { if(str_replace(',', '.', $student_b['note_'.$i]) > str_replace(',', '.', $student_a['note_'.$i])) $student_a['note_'.$i] = $student_b['note_'.$i]; } /* met à jour l'étudiant dans le tableau d'origine */ $students_a[$student_id] = $student_a; } /* enregistre les données à jour */ $students = array('Login;Nom;Pr_nom;Note;Note;Note;Note;Note'); foreach($students_a as $student) $students[] = implode(';', $student); file_put_contents('C.csv', implode("\n", $students)); /* traitement des étudiants présents dans B mais pas dans A */ $students_d = array(); foreach($students_b as $student_id => $student_b) { /* si l'élève n'existe pas dans A on l'ajoute dans D */ if(!isset($students_a[$student_id])) $students_d[] = $student_b;// inutile de mettre l'id en index car l'index ne sera jamais utilisé } /* enregistrement */ $students = array('Login;Nom;Pr_nom;Note;Note;Note;Note;Note'); foreach($students_d as $student) $students[] = implode(';', $student); file_put_contents('D.csv', implode("\n", $students));
Développeur web depuis + de 20 ans