Langages

HTML

HTML

Tous mes trucs & astuces en HTML

Etiquettes: 

Comment bien gérer les caractères accentués dans les pages HTML

ISO-8859-1 ou UTF-8/16.

Quel encodage choisir pour afficher correctement tous les caractères accentués qu'il y a dans la langue française ?

Tous les caractères accentués de la langue française sont gérés par la norme ISO-8859-1.

En HTML, il y a une astuce qui consiste à ne pas s'occuper du type de l'encodage des caractères mais utiliser à la place le nom d'entité des caractères (entity name).

Grâce à cette technique, tous les caractères seront toujours affichés correctement.

Source http://www.w3schools.com/


Par exemple, au lieu d'écrire ceci dans une page HTML

<html>
<body>
<p>Ceci est un caractère accentué</p>
</body>
</html>

Qui pourrait provoquer un problème à l'affichage si le codage des caractères est mal défini (comme ceci)

Ceci est un caractère accentué

Il vaut mieux écrire cela

<html>
<body>
<p>Ceci est un caract
&egrave;re accentu&eacute;</p>
</body>
</html>

Ce qui donne comme résultat

Ceci est un caractère accentué

Plus besoin de se soucier de l'encodage du fichier.

Autres caractères supportés en HTML

Autres caractères supportés en HTML

Character Entity Number Entity Name Description
Π&#338; &OElig; capital ligature OE
œ &#339; &oelig; small ligature oe
Š &#352; &Scaron; capital S with caron
š &#353; &scaron; small S with caron
Ÿ &#376; &Yuml; capital Y with diaeres
ƒ &#402; &fnof; f with hook
ˆ &#710; &circ; modifier letter circumflex accent
˜ &#732; &tilde; small tilde
&#8194; &ensp; en space
&#8195; &emsp; em space
&#8201; &thinsp; thin space
&#8204; &zwnj; zero width non-joiner
&#8205; &zwj; zero width joiner
&#8206; &lrm; left-to-right mark
&#8207; &rlm; right-to-left mark
&#8211; &ndash; en dash
&#8212; &mdash; em dash
&#8216; &lsquo; left single quotation mark
&#8217; &rsquo; right single quotation mark
&#8218; &sbquo; single low-9 quotation mark
&#8220; &ldquo; left double quotation mark
&#8221; &rdquo; right double quotation mark
&#8222; &bdquo; double low-9 quotation mark
&#8224; &dagger; dagger
&#8225; &Dagger; double dagger
&#8226; &bull; bullet
&#8230; &hellip; horizontal ellipsis
&#8240; &permil; per mille 
&#8242; &prime; minutes
&#8243; &Prime; seconds
&#8249; &lsaquo; single left angle quotation
&#8250; &rsaquo; single right angle quotation
&#8254; &oline; overline
&#8364; &euro; euro
&#8482; &trade; trademark
&#8592; &larr; left arrow
&#8593; &uarr; up arrow
&#8594; &rarr; right arrow
&#8595; &darr; down arrow
&#8596; &harr; left right arrow
&#8629; &crarr; carriage return arrow
&#8968; &lceil; left ceiling
&#8969; &rceil; right ceiling
&#8970; &lfloor; left floor
&#8971; &rfloor; right floor
&#9674; &loz; lozenge
&#9824; &spades; spade
&#9827; &clubs; club
&#9829; &hearts; heart
&#9830; &diams; diamond

 

Etiquettes: 

Caractères Grec supportés en HTML

Caractères Grec supportés en HTML

Character Entity Number Entity Name Description
Α &#913; &Alpha; Alpha
Β &#914; &Beta; Beta
Γ &#915; &Gamma; Gamma
Δ &#916; &Delta; Delta
Ε &#917; &Epsilon; Epsilon
Ζ &#918; &Zeta; Zeta
Η &#919; &Eta; Eta
Θ &#920; &Theta; Theta
Ι &#921; &Iota; Iota
Κ &#922; &Kappa; Kappa
Λ &#923; &Lambda; Lambda
Μ &#924; &Mu; Mu
Ν &#925; &Nu; Nu
Ξ &#926; &Xi; Xi
Ο &#927; &Omicron; Omicron
Π &#928; &Pi; Pi
Ρ &#929; &Rho; Rho
Σ &#931; &Sigma; Sigma
Τ &#932; &Tau; Tau
Υ &#933; &Upsilon; Upsilon
Φ &#934; &Phi; Phi
Χ &#935; &Chi; Chi
Ψ &#936; &Psi; Psi
Ω &#937; &Omega; Omega
α &#945; &alpha; alpha
β &#946; &beta; beta
γ &#947; &gamma; gamma
δ &#948; &delta; delta
ε &#949; &epsilon; epsilon
ζ &#950; &zeta; zeta
η &#951; &eta; eta
θ &#952; &theta; theta
ι &#953; &iota; iota
κ &#954; &kappa; kappa
λ &#955; &lambda; lambda
μ &#956; &mu; mu
ν &#957; &nu; nu
ξ &#958; &xi; xi
ο &#959; &omicron; omicron
π &#960; &pi; pi
ρ &#961; &rho; rho
ς &#962; &sigmaf; sigmaf
σ &#963; &sigma; sigma
τ &#964; &tau; tau
υ &#965; &upsilon; upsilon
φ &#966; &phi; phi
χ &#967; &chi; chi
ψ &#968; &psi; psi
ω &#969; &omega; omega
ϑ &#977; &thetasym; theta symbol
ϒ &#978; &upsih; upsilon symbol
ϖ &#982; &piv; pi symbol

 

Etiquettes: 

Caractères ISO 8859-1

Caractères ISO 8859-1

Character Entity Number Entity Name Description
À &#192; &Agrave; capital a, grave accent
Á &#193; &Aacute; capital a, acute accent
 &#194; &Acirc; capital a, circumflex accent
à &#195; &Atilde; capital a, tilde
Ä &#196; &Auml; capital a, umlaut mark
Å &#197; &Aring; capital a, ring
Æ &#198; &AElig; capital ae
Ç &#199; &Ccedil; capital c, cedilla
È &#200; &Egrave; capital e, grave accent
É &#201; &Eacute; capital e, acute accent
Ê &#202; &Ecirc; capital e, circumflex accent
Ë &#203; &Euml; capital e, umlaut mark
Ì &#204; &Igrave; capital i, grave accent
Í &#205; &Iacute; capital i, acute accent
Î &#206; &Icirc; capital i, circumflex accent
Ï &#207; &Iuml; capital i, umlaut mark
Ð &#208; &ETH; capital eth, Icelandic
Ñ &#209; &Ntilde; capital n, tilde
Ò &#210; &Ograve; capital o, grave accent
Ó &#211; &Oacute; capital o, acute accent
Ô &#212; &Ocirc; capital o, circumflex accent
Õ &#213; &Otilde; capital o, tilde
Ö &#214; &Ouml; capital o, umlaut mark
Ø &#216; &Oslash; capital o, slash
Ù &#217; &Ugrave; capital u, grave accent
Ú &#218; &Uacute; capital u, acute accent
Û &#219; &Ucirc; capital u, circumflex accent
Ü &#220; &Uuml; capital u, umlaut mark
Ý &#221; &Yacute; capital y, acute accent
Þ &#222; &THORN; capital THORN, Icelandic
ß &#223; &szlig; small sharp s, German
à &#224; &agrave; small a, grave accent
á &#225; &aacute; small a, acute accent
â &#226; &acirc; small a, circumflex accent
ã &#227; &atilde; small a, tilde
ä &#228; &auml; small a, umlaut mark
å &#229; &aring; small a, ring
æ &#230; &aelig; small ae
ç &#231; &ccedil; small c, cedilla
è &#232; &egrave; small e, grave accent
é &#233; &eacute; small e, acute accent
ê &#234; &ecirc; small e, circumflex accent
ë &#235; &euml; small e, umlaut mark
ì &#236; &igrave; small i, grave accent
í &#237; &iacute; small i, acute accent
î &#238; &icirc; small i, circumflex accent
ï &#239; &iuml; small i, umlaut mark
ð &#240; &eth; small eth, Icelandic
ñ &#241; &ntilde; small n, tilde
ò &#242; &ograve; small o, grave accent
ó &#243; &oacute; small o, acute accent
ô &#244; &ocirc; small o, circumflex accent
õ &#245; &otilde; small o, tilde
ö &#246; &ouml; small o, umlaut mark
ø &#248; &oslash; small o, slash
ù &#249; &ugrave; small u, grave accent
ú &#250; &uacute; small u, acute accent
û &#251; &ucirc; small u, circumflex accent
ü &#252; &uuml; small u, umlaut mark
ý &#253; &yacute; small y, acute accent
þ &#254; &thorn; small thorn, Icelandic
ÿ &#255; &yuml; small y, umlaut mark

 

Etiquettes: 

Les caractères réservés en HTML

Les caractères réservés en HTML

Character Entity Number Entity Name Description
" &#34; &quot; quotation mark
' &#39; &apos; (does not work in IE) apostrophe 
& &#38; &amp; ampersand
< &#60; &lt; less-than
> &#62; &gt; greater-than

 

Etiquettes: 

Symbols ISO 8859-1

Symbols ISO 8859-1

Character Entity Number Entity Name Description
  &#160; &nbsp; non-breaking space
¡ &#161; &iexcl; inverted exclamation mark
¢ &#162; &cent; cent
£ &#163; &pound; pound
¤ &#164; &curren; currency
¥ &#165; &yen; yen
¦ &#166; &brvbar; broken vertical bar
§ &#167; &sect; section
¨ &#168; &uml; spacing diaeresis
© &#169; &copy; copyright
ª &#170; &ordf; feminine ordinal indicator
« &#171; &laquo; angle quotation mark (left)
¬ &#172; &not; negation
  &#173; &shy; soft hyphen
® &#174; &reg; registered trademark
¯ &#175; &macr; spacing macron
° &#176; &deg; degree
± &#177; &plusmn; plus-or-minus 
² &#178; &sup2; superscript 2
³ &#179; &sup3; superscript 3
´ &#180; &acute; spacing acute
µ &#181; &micro; micro
&#182; &para; paragraph
· &#183; &middot; middle dot
¸ &#184; &cedil; spacing cedilla
¹ &#185; &sup1; superscript 1
º &#186; &ordm; masculine ordinal indicator
» &#187; &raquo; angle quotation mark (right)
¼ &#188; &frac14; fraction 1/4
½ &#189; &frac12; fraction 1/2
¾ &#190; &frac34; fraction 3/4
¿ &#191; &iquest; inverted question mark
× &#215; &times; multiplication
÷ &#247; &divide; division

 

Symbols mathématiques supportés en HTML

Symbols mathématiques supportés en HTML

Character Entity Number Entity Name Description
&#8704; &forall; for all
&#8706; &part; part
&#8707; &exist; exists
&#8709; &empty; empty
&#8711; &nabla; nabla
&#8712; &isin; isin
&#8713; &notin; notin
&#8715; &ni; ni
&#8719; &prod; prod
&#8721; &sum; sum
&#8722; &minus; minus
&#8727; &lowast; lowast
&#8730; &radic; square root
&#8733; &prop; proportional to
&#8734; &infin; infinity
&#8736; &ang; angle
&#8743; &and; and
&#8744; &or; or
&#8745; &cap; cap
&#8746; &cup; cup
&#8747; &int; integral
&#8756; &there4; therefore
&#8764; &sim; similar to
&#8773; &cong; congruent to
&#8776; &asymp; almost equal
&#8800; &ne; not equal
&#8801; &equiv; equivalent
&#8804; &le; less or equal
&#8805; &ge; greater or equal
&#8834; &sub; subset of
&#8835; &sup; superset of
&#8836; &nsub; not subset of
&#8838; &sube; subset or equal
&#8839; &supe; superset or equal
&#8853; &oplus; circled plus
&#8855; &otimes; circled times
&#8869; &perp; perpendicular
&#8901; &sdot; dot operator

 

Etiquettes: 

Un squelette de page HTML

Voici un petit squelette afin de mettre en place une page HTML facilement et rapidement.

Elle inclut le CSS et le javascript Bootstrap ainsi que le javascript JQuery.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>My Page</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
    <h1>My Page</h1>
    <h2>Start here</h2>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/latest/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  </body>
</html>

Un simple copier/coller dans un fichier "index.html" et le tour est joué.

Etiquettes: 

Java

Logo Java

Tous mes trucs et astuces pour utiliser Java

Ajouter / retrancher 1 année à une date en JAVA

package fr.quennec.date.custom;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;	

public class customDate {

	public static void dateMoinsUneAnnee(){

		GregorianCalendar calStr1 = new GregorianCalendar(); // Création d'un nouveau calendrier
		calStr1.setTime(new Date()); // Initialisation du calendrier avec la date du jour
		calStr1.add(GregorianCalendar.YEAR, -1); // On retranche 1 année
		String formatDate = "yyyy"; // Création du format pour afficher l'année sur 4 chiffres
		SimpleDateFormat sdf = new SimpleDateFormat(formatDate); // Initialisation du format de l'année sur 4 chiffres
		System.out.println(sdf.format(calStr1.getTime())); // Affichage du résultat

	}

}
Avec cette méthode, il est également possible d'ajouter une année au lieu de la retrancher :
calStr1.add(GregorianCalendar.YEAR, +1);
Il est également possible de manipuler les jours :
calStr1.add(GregorianCalendar.DAY_OF_YEAR, +1);
Et les mois :
calStr1.add(GregorianCalendar.MONTH, +1);
etc, etc ...
Etiquettes: 

Calculer l'écart entre 2 dates

Ce code calcul l'écart en années / mois / jours  (complets) entre 2 dates :

Ajouter les imports suivants :

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class ecartDate {

    static int UN = 1;
    static int DOUZE = 12;

    public static void main(String[] args) {
  
        Calendar calStr1 = Calendar.getInstance();
        Calendar calStr2 = Calendar.getInstance();
        Calendar calStr0 = Calendar.getInstance();
  
        Date date1 = null;
        Date date2 = null;
   
        int nbMois = 0;
        int nbAnnees = 0;
        long nbJours = 0;
   
        try {
                date1 = new SimpleDateFormat("dd/MM/yyyy").parse("25/01/2006");
        } catch (ParseException e) {
                e.printStackTrace();
        }
        try {
                date2 = new SimpleDateFormat("dd/MM/yyyy").parse("11/02/2014");
        } catch (ParseException e) {
                e.printStackTrace();
        }

        if (date1.equals(date2)) {
                return;
        }

        calStr1.setTime(date1);
        calStr2.setTime(date2);

        nbMois = 0;
        while (calStr1.before(calStr2)) {
                calStr1.add(GregorianCalendar.MONTH, UN);
                if (calStr1.before(calStr2) || calStr1.equals(calStr2)) {
                        nbMois++;
                }
        }
        nbAnnees = (nbMois / DOUZE);
        nbMois = (nbMois - (nbAnnees * DOUZE));

        calStr0 = Calendar.getInstance();
        calStr0.setTime(date1);
        calStr0.add(GregorianCalendar.YEAR, nbAnnees);
        calStr0.add(GregorianCalendar.MONTH, nbMois);
        nbJours = (calStr2.getTimeInMillis() - calStr0.getTimeInMillis()) / 86400000;

        System.out.print("Nb Annees : "+nbAnnees+"\n");
        System.out.print("Nb Mois : "+nbMois+"\n");
        System.out.print("Nb Jours : "+nbJours+"\n");

        }
}
Nb Annees : 8
Nb Mois : 0
Nb Jours : 17
Etiquettes: 

Décompiler des classes JAVA

Java Decompiler

Java Decompiler est un programme sous Windows / Linux / Mac qui permet de décompiler des classes JAVA.

Java Decompiler

Télécharger la version Windows

Télécharger la version Linux

 

Java: Connaitre la version de java utilisée pour la compilation d'une classe

Pour connaitre la version de java utilisée pour la compilation d'une classe, il suffit d'utiliser la commande javap présente dans le répertoire bin de java.

$ javap -verbose maclasse.class | grep version
  minor version: 0
  major version: 46

La version majeure permet de connaitre la version de java ayant compilé le fichier .class

Java 1.2 uses major version 46
Java 1.3 uses major version 47
Java 1.4 uses major version 48
Java 5 uses major version 49
Java 6 uses major version 50
Java 7 uses major version 51
Java 8 uses major version 52
Java 9 uses major version 53
Java 10 uses major version 54
Java 11 uses major version 55

Etiquettes: 

Remplacer les caractères accentués d'une chaine par des caractères simples

Exemple d'une méthode permettant de remplacer tous les caractères accentués d'une chaine (String) par des caractères simples :

public static String translate(String src) {
        StringBuffer result = new StringBuffer();
        if(src!=null && src.length()!=0) {
            int index = -1;
            char c = (char)0;
            String chars= "àâäéèêëîïôöùûüç";
            String replace= "aaaeeeeiioouuuc";
            for(int i=0; i<src.length(); i++) {
                c = src.charAt(i);
                if( (index=chars.indexOf(c))!=-1 )
                    result.append(replace.charAt(index));
                else
                    result.append(c);
            }
        }
        return result.toString();
    }
Etiquettes: 

Tester si un nombre est un Double

1 - Créer une classe "Char.java" contenant les différentes variables utilisées :

public class Char {

    public static final char SPACE = (char)32;

    public static final char LOWER_N = (char)110;

    public static final char LOWER_U = (char)117;

    public static final char LOWER_L = (char)108;

    public static final char DOT = (char)46;

    public static final char COMMA = (char)44;

    public static final int DIGIT_BEGIN = 48;

    public static final int DIGIT_END = 57;

}
2 - Créer une classe "TestUtil.java" contenant les différentes fonctions utilisées :
public class TestUtil {

    public static boolean isNull(String s) {
        if (s == null) {
            return true;
        }

        int counter = 0;

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == Char.SPACE) {
                continue;
            }
            else if (counter > 3) {
                return false;
            }

            if (counter == 0) {
                if (c != Char.LOWER_N) {
                    return false;
                }
            }
            else if (counter == 1) {
                if (c != Char.LOWER_U) {
                    return false;
                }
            }
            else if ((counter == 2) || (counter == 3)) {
                if (c != Char.LOWER_L) {
                    return false;
                }
            }

            counter++;
        }

        if ((counter == 0) || (counter == 4)) {
            return true;
        }

        return false;
    }
    
    public static boolean isDouble(String number){
        
//        On test si la valeur est nulle
        if (isNull(number)) {
            return false;
        }
        
//        On remplace les virgules par les points (séparateur décimal)
        number = number.replace(Char.COMMA, Char.DOT);
        
        boolean firstDot = true;
        
        
//        On test chaque caractère
//        Si le caractère est un chiffre on test le suivant
//        Si le caractère est un "point" on initialise la variable "firstDot" à "false" et on test le suivant
//        Si le caractère n'est pas un chiffre ou un autre "point" on retourne "false"
//        Sinon, la valeur est un "Double" et on retourne "true"
        for (char c : number.toCharArray()) {
            if (!isDigit(c)) {
                if (c == Char.SPACE) {
                    continue;
                }
                if(c == Char.DOT && firstDot){
                    firstDot = false;
                    continue;
                } else {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    public static boolean isDigit(char c) {
        int x = c;

        if ((x >= Char.DIGIT_BEGIN) && (x <= Char.DIGIT_END)) {
            return true;
        }

        return false;
    }
}

3 - Créer une classe "testDouble.java" afin de tester les différentes fonctions :

public class testDouble {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String s = "12,5689";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
        s = "12.56456456";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
        s = null;
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi false
        
        s = "a56456.5646";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi false
        
        s = "23156.86798,546";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi false
        
        s = "etet.ert47d6t";
            
        System.out.println(TestUtil.isDouble(s));    // Renvoi false
        
        s = "8989797";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
        s = "8989 797";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
        s = "89 897.97";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
        s = "89 897,97";
        
        System.out.println(TestUtil.isDouble(s));    // Renvoi true
        
    }

}
Etiquettes: 

JavaScript

Logo JavaScript

 

 

 

 

 

Tous mes trucs et astuces pour utiliser JavaScript

Mettre automatiquement le focus dans un champ de formulaire

<script type="text/javascript">

    function PMA_focusInput(){
        var objet = document.getElementById('id_element_formulaire');
        objet.focus();
    }
    window.setTimeout('PMA_focusInput()', 500);
</script>
Etiquettes: 

Modifier automatiquement la valeur du paramètre maxlength d'un ou plusieurs éléments textarea

Voici une petite fonction javascript qui permet de modifier la valeur du paramètre "maxlength" d'un élément "textarea".

Dans l'exemple suivant, la fonction modifie la valeur du paramètre "maxlength" à illimité (-1) uniquement si la valeur est inférieur à 1000 caractères.

function updMaxLthTxt () {
    var txts = document.getElementsByTagName('textarea');
    for(var i = 0, l = txts.length; i < l; i++) {
        var len = parseInt(txts[i].getAttribute("maxlength"), 10);
        if(len < 1000) {
            txts[i].setAttribute("maxlength", -1);
        }
    }
}

Pour exécuter cette fonction automatiquement après le chargement de la page html:

<html>
<head>
</head>
<body onload = "updMaxLthTxt();">
.....
</body>
</html>

Modifier le CSS avec JavaScript

Ajouter une classe à une balise en fonction de son contenu :

Ce script javascript parcourt toutes les balises <p> de la page web et si le contenu de chaque balise commence par "$ ", une balise <span> est automatiquement ajoutée avec une classe "code"

<script language=javascript type="text/javascript">
function addCode()
{
var parag = document.getElementsByTagName('p');
var myRegex = /^\$ /;
for (var i=0, c=parag.length; i<c; i++)
{
if(myRegex.test(parag[i].innerHTML))
{
parag[i].innerHTML = '<span class="code">'+(parag[i].innerHTML)+'</span>';
}
}
}
</script>

Pour activer la fonction javascript il suffit simplement de rajouter onload = "addCode();" dans la balise <body> de chaque page web.

<html>
<head>
</head>
<body onload = "addCode();">
.....
</body>
</html>

PHP

PHP: Obtenir le numéro de la dernière semaine de l'année en cours

Voici une petite fonction PHP qui permet de retourner le numéro de la dernière semaine de l'année en cours.

<?php

function lastWeekNumberOfYear(){
    $year = date('Y');
    $week_count = date('W', strtotime($year . '-12-31'));
    if ($week_count == '01'){
        $week_count = date('W', strtotime($year . '-12-24'));
    }
    return intval($week_count);
}

 

Etiquettes: 

PHP: REGEX

Regex

Des exemples de REGEX PCRE avec PHP

 

La fonction preg_match permet d'effectuer une recherche dans une chaine de caractères et renvoie TRUE si le texte cherché est trouvé sinon FALSE.

Cela permet d'effectuer des controles sur des saisies clavier.

Vérifier que la saisie effectuée correspond bien à un nombre de 6 chiffres (123456).

<?php preg_match("#^[0-9]{6}$#","123456"); ?>
// Renvoie TRUE car 123456 est bien un nombre de 6 chiffres.

Explications :
#^[0-9]{6}$#
Le caractère # correspond aux délimiteurs du texte à chercher.
Le caractère ^ indique que la recherche doit s'effectuer à partir du début de la chaine de texte.
Le caractère $ indique que la recherche doit s'effectuer jusqu'à la fin de la chaine de texte.
La classe de caractères [0-9] indique que les caractères recherchés dans la chaine de texte doivent être des chiffres allant de 0 à 9.
Le quantificateur {6} indique le nombre exact de caractères à rechercher dans la chaine de texte.

Autres exemples :

<?php preg_match("#^[0-9]{6}$#","123A56"); ?>
// Renvoie FALSE car il y a un 'A' dans la chaine de caractères.
<?php preg_match("#^[0-9]{6}$#","12345"); ?>
// Renvoie également FALSE car il n'y a que 5 chiffres dans la chaine de caractères '12345'
<?php preg_match("#^[0-9]{6}#","546781A"); ?>
// Renvoie TRUE car la recherche demandée s'effectue uniquement à partir du début de la chaine de caractères (suppression du caractère $) et que celle çi doit donc commencer par 6 chiffres allant de 0 à 9.

Vérifier que la saisie effectuée correspond bien à une adresse mail

<?php preg_match("#^[-.\w]{1,}@[-.\w]{2,}\.[a-zA-Z]{2,4}$#","toto@gmail.com"); ?>
// Renvoie TRUE car le texte 'toto@gmail.com' correspond bien à une adresse mail.

Explications :
#^[-.\w]{1,}@[-.\w]{2,}\.[a-zA-Z]{2,4}$#
Nous retrouvons toujours nos délimiteurs #
Nous retrouvons également nos symboles de dédut ^ et de fin $ de recherche
Notre adresse mail doit être de la forme xxxx@xxxx.xxxx
Le début de l'adresse (à la gauche de l' @) peut contenir des caractères allant de 'A' à 'Z' (minuscule et majuscule), un point '.', un tiret haut '-', un tiret bas '_' et des chiffres allant de 0 à 9 et doit contenir au minimum 1 caractère. Pour indiquer tout cela, nous inscrivons donc :
[-.\w]{1,}
La classe de caractères contient donc le '-' (toujours le placer en première position dans une classe de caractères) suivi du '.' et enfin du raccourci '\w' correspondant à la même chose que [a-zA-Z0-9_], c'est à dire toutes les lettres de l'alphabet minuscule et majuscule, tous les chiffres et le tiret bas '_'. Le tout suivi du quantificateur {1,} indiquant qu'il doit y avoir au minimum 1 caractère.
Il faut ensuite indiquer le caractère @
Ensuite, le nom de domaine doit avoir les mêmes caractéristiques que le début de l'adresse mais doit comporter au minimum 2 caractères, nous inscrivons donc :
[-.\w]{2,}
Nous retrouvons la même classe de caractères que pour le début de l'adresse mais nous modifions le quantificateur {2,} pour indiquer qu'il doit y avoir au minimum 2 caractères.
Nous indiquons ensuite le point '.' mais celui çi doit être échappé car en PCRE, il correspond à un métacaractère indiquant 'n'importe quel caractère'.
\.
Enfin, nous controlons l'extension du nom de domaine. Celui çi ne doit contenir que des lettres et avoir au minimum 2 caractères et au maximum 4. Nous indiquons donc :
[a-zA-Z]{2,4}
Nous retrouvons la classe [a-zA-Z] indiquant toutes les lettres de l'alphabet en minuscule et en majuscule ainsi que le quantificateur {2,4} indiquant un minimum de caractères de 2 et un maximum de 4.

Etiquettes: 

PHP: Requête MySql

Connexion à une base de données MySql

<?php
try
{
     $bdd = new PDO('mysql:host=localhost;dbname=test','user','password');
}
catch(Exception $e)
{
     die('Erreur :'.$e->getMessage());
}
?>

Exécuter une requête simple

<?php
$req = $bdd->query('SELECT id, nom, prenom FROM carnet WHERE id >= 1 AND id <= 10 ORDER BY id') or die (print_r($bdd->errorInfo()));
?>

Préparer et exécuter une requête avec des variables

<?php
$req = $bdd->prepare('SELECT id, nom, prenom FROM carnet WHERE id >= :idMin AND id <= :idMax ORDER BY id') or die (print_r($bdd->errorInfo()));
$req->execute(array(
                     'idMin'=> $_POST['postIdMin'],
                     'idMax' => $_GET['getIdMax']
          ));
?>

Lire le résultat d'une requête

<?php
while($donnees = $req->fetch())
{
     echo $donnees['id'].'<br />';
     echo $donnees['nom'].'<br />';
     echo $donnees['prenom'];
}
?>

Fermer la requête

<?php
$req->closeCursor();
?>
Etiquettes: 

PHP: Utiliser la bibliothèque Monolog dans vos scripts

La bibliothèque Monolog permet de journaliser différentes informations lors de l'exécution de scripts PHP.

Son intégration via un framework de développement tel que Symfony, CakePHP se fait de manière quasi automatique mais s'il s'agit de l'utiliser dans un script fait à la main, c'est un petit peu plus compliqué.

Voici ma méthode (qui peut certainement être améliorée):

Cette bibliothèque pouvant être utilisée dans plusieurs projets, j'ai donc décidé de l'installer dans un dossier commun à tous mes projets web (/var/www/).
Je vais donc l'installer dans le dossier /var/www/commun

$ cd /var/www
$ mkdir commun
$ chown -R www-data:www-data commun
$ cd commun

Cette bibliothèque utilisant les namespaces, il est nécessaire d'installer la bibliothèque ClassLoader qui va nous permettre d'utiliser tout simplement les namespaces dans nos différents scripts.

attention Toutes les installations seront faites à l'aide de la commande git

$ apt-get install git

$ git clone https://github.com/symfony/ClassLoader.git
$ git clone https://github.com/Seldaek/monolog.git
$ git clone https://github.com/php-fig/log.git

Trois projets sont donc installés dans le dossier commun

  • ClassLoader
  • log
  • monolog

Pour protéger l'accès à ce dossier (/var/www/commun):

$ echo "Deny From All" > .htaccess

Pour l'utilisation des namespaces, il est nécessaire de créer un fichier de paramétrage des namespaces (toujours dans le dossier /var/www/commun):

$ cat monolog.php
<?php
 
require_once __DIR__.'/ClassLoader/ClassLoader.php';
 
use Symfony\Component\ClassLoader\ClassLoader;
 
$loader = new ClassLoader();
$loader->register();
 
$loader->addPrefix('Monolog', __DIR__.'/monolog/src');
$loader->addPrefix('Psr', __DIR__.'/log');

Ce fichier intègre donc la classe ClassLoader.php et configure les namespaces Monolog & Psr nécessaire à l'utilisation de la bibliothèque monolog.

L'installation et le paramétrage est terminé, passons à la manière d'utiliser cette bibliothèque.

Je vais créer un projet test ainsi que deux fichiers index.php et init_log.php.

Le fichier index.php contiendra mon projet et le fichier init_log.php la configuration du fichier de log de mon projet.

$ cd /var/www
$ mkdir test
$ chown -R www-data:www-data test
$ cd test

infoPour la documentation de monolog, tout est expliqué sur la page github du projet https://github.com/Seldaek/monolog

Détail de ma configuration:

$ nl init_log.php
     1  <?php
     2      require_once '/var/www/commun/monolog.php';
     3      use Monolog\Logger;
     4      use Monolog\Handler\RotatingFileHandler;
     5      use Monolog\Handler\StreamHandler;
     6      use Monolog\Formatter\LineFormatter;
     7      $dateFormat = "Y-m-d H:i:s";
     8      $output     = "[%datetime%] %channel% %level_name%: %message% %context% %extra%\n";
     9      $formatter  = new LineFormatter($output, $dateFormat);
    10      $stream     = new StreamHandler(__DIR__.'/test.log', Logger::DEBUG); // Pour obtenir un fichier de log global
    11      // $stream     = new RotatingFileHandler(__DIR__.'/test.log', Logger::DEBUG); // Pour obtenir un fichier de log par jour (fichier horodaté)
    12      $stream->setFormatter($formatter);
    13      $logger     = new Logger('test');
    14      $logger->pushHandler($stream);

Ligne 2, j'inclus le fichier monolog.php qui contient toute la configuration de monolog.
Ligne 3 à 6, déclaration des différents use comme indiqué surla page du projet.
Ligne 7 à 9, je redéfini le format des données dans les logs.
Ligne 10 ou 11, permet d'indiquer l'emplacement du fichier de log ainsi que la manière dont il sera nommé et le niveau de log (DEBUG, INFO, WARNING etc etc...). Comme indiqué dans les commentaires, soit un fichier de log global (test.log), soit un fichier de log journalier et horodaté (test-2015-08-14.log).
Ligne 12, affectation du format défini au fichier de log.
Ligne 13 à 14, création d'un nouveau logger nommé test (avec le nom du projet par exemple).

infoIl est possible d'avoir un seul fichier de log commun pour plusieurs projets. Du coup, il sera facile de parser le fichier de log en se basant sur le nom du projet indiqué lors de la création du logger (ligne 13)

Utilisation dans mon fichier index.php:

$ cat index.php
<?php
    require_once __DIR__.'/init_log.php';
    ...
    $logger->addInfo('Connexion', array(
                'User' => $user,
                'Nom' => $nom,
                'Prénom' => $prenom,
            ));

J'inclus mon fichier init_log.php et j'écris tout ce que je veux dans mon fichier de log à l'aide de la commande $logger->addInfo().
Le premier paramètre est une chaine de texte et le second un tableau.

Difficile de faire plus simple.

Etiquettes: 

PHP: igalerie - scan automatique des albums (ftp)

igalerie est une application php qui permet de créer des galeries d'images en ligne.

L'ajout d'images dans la galerie peut se faire via ftp (très pratique) mais il faut obligatoirement exécuter une fonction pour que les images soient affichées dans la galerie.

Cette fonction est disponible via un bouton accessible uniquement dans la section administration du site.

Il est donc nécessaire d'être authentifié pour exécuter cette fonction.

Pour effectuer ce scan automatiquement à intervalle régulière, j'ai donc mis au point le script php suivant avec l'extension curl.

Ce script est disponible ici .

$ nl curl.igalerie.php
     1    <?php
     2    session_start();
       
     3    $site = "https://adresse.de.mon.site.igalerie.fr";
     4    $lien = "/login";
     5    $lien3 = "/admin/?q=ftp";
       
     6    $path_cookie = '/tmp/cookie.'.session_id().'.txt';
     7    if (file_exists(realpath($path_cookie))) unlink($path_cookie);
     8    if (!file_exists(realpath($path_cookie))) touch($path_cookie);
       
     9    $curl = curl_init();
       
    10    $postfields = array();
       
    11    $postfields['auth_login'] = 'mon.user';
    12    $postfields['auth_password'] = 'mon.password';
    13    $postfields['submit'] = 'Valider';
       
    14    $postfields = http_build_query($postfields);
       
    15    curl_setopt($curl, CURLOPT_URL, $site.$lien);
    16    curl_setopt($curl, CURLOPT_COOKIEFILE, realpath($path_cookie));
    17    curl_setopt($curl, CURLOPT_COOKIEJAR, realpath($path_cookie));
    18    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    19    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    20    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    21    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    22    curl_setopt($curl, CURLOPT_HEADER, true);
    23    curl_setopt($curl, CURLOPT_POST, true);
    24    curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
    25    curl_setopt($curl, CURLOPT_COOKIESESSION, true);
       
    26    $return = curl_exec($curl);
    27    $headers = curl_getinfo($curl);
       
    28    if (!$headers['http_code'] == '200'){
    29        echo "Erreur Step 1";
    30        exit(1);
    31    }
       
    32    curl_setopt($curl, CURLOPT_URL, $site.$lien3);
    33    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    34    curl_setopt($curl, CURLOPT_COOKIEFILE, realpath($path_cookie));
    35    curl_setopt($curl, CURLOPT_COOKIEJAR, realpath($path_cookie));
    36    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    37    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    38    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    39    curl_setopt($curl, CURLOPT_HEADER, true);
    40    curl_setopt($curl, CURLOPT_COOKIESESSION, true);
       
    41    $return = curl_exec($curl);
    42    $headers = curl_getinfo($curl);
       
    43    if (!$headers['http_code'] == '200'){
    44        echo "Erreur Step 2";
    45        exit(1);
    46    }
       
    47    $dom = new DOMDocument;
    48    @$dom->loadHTML($return);
    49    $inputs = $dom->getElementsByTagName('input');
    50    foreach ($inputs as $input) {
    51        $cle = $input->getAttribute('name');
    52        $valeur = "";
    53        if($cle=="anticsrf"){
    54            $valeur = $input->getAttribute('value');
    55        }
    56        if(!$valeur=="") break;
    57    }
       
    58    $postfields = array();
       
    59    $postfields['publish_images'] = 'on';
    60    $postfields['anticsrf'] = "$valeur";
    61    $postfields['action'] = 'scan';
       
    62    $postfields = http_build_query($postfields);
       
    63    curl_setopt($curl, CURLOPT_URL, $site.$lien3);
    64    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    65    curl_setopt($curl, CURLOPT_COOKIEFILE, realpath($path_cookie));
    66    curl_setopt($curl, CURLOPT_COOKIEJAR, realpath($path_cookie));
    67    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    68    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    69    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    70    curl_setopt($curl, CURLOPT_HEADER, true);
    71    curl_setopt($curl, CURLOPT_COOKIESESSION, true);
    72    curl_setopt($curl, CURLOPT_POST, true);
    73    curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
       
    74    $return = curl_exec($curl);
    75    $headers = curl_getinfo($curl);
       
    76    if (!$headers['http_code'] == '200'){
    77        echo "Erreur Step 3";
    78        exit(1);
    79    }
       
    80    @$dom->loadHTML($return);
    81    $div = $dom->getElementById('ftp_report');
    82    $ps = $div->getElementsByTagName('p');
       
    83    foreach ($ps as $p => $value) {
    84        echo "$value->nodeValue\n";
    85    }
       
    86    curl_close($curl);
       
    87    exit(0);

Quelques petites explications :

Ligne 4 : adresse http(s) de la galerie.

Ligne 5 : lien qui permet d'accéder à la page d'authentification.

Ligne 6 : lien qui permet d'accéder à la page du scan ftp.

Ligne 8 à 10 : initialisation du cookie de session.

Ligne 12 : initialisation de l'extension curl.

Ligne 14 à 20 : initialisation du formulaire d'authentification.

Ligne 22 à 35 : validation du formulaire d'authentification.

Le formulaire permettant le scan des albums étant protégé par un champ anti-csrf wikipedia, il est nécessaire de récupérer la valeur de ce champ avant de poster le formulaire.

Ligne 42 à 53 : récupération du contenu de la page contenant le formulaire permettant le scan des albums.

Ligne 60 à 70 : on parse le contenu de la page afin de récupérer la valeur du champ "anticsrf".

Ligne 72 à 78 : initialisation du formulaire de scan.

Ligne 80 à 93 : validation du formulaire de scan.

Ligne 100 à 106 : on parse le contenu de la page, après validation du formulaire, afin de récupérer le rapport du scan et on l'affiche sur la sortie standard.

Ligne 108 à 110 : on ferme la connexion curl et on quitte le script.

Pour l'exécuter :

$ php curl.igalerie.php

Pour ne pas afficher le rapport :

$ php curl.igalerie.php >/dev/null

Pour envoyer le rapport par mail :

$ php curl.igalerie.php | mail -s "Rapport Scan Auto Igalerie" moi@domain.com

info Une entrée crontab pour l'automatisation.

PHP: phpSysInfo

phpSysInfo est un script PHP qui permet d'afficher, dans un navigateur, l'état complet du serveur sur lequel il est exécuté.

Une démo est disponible ici http://phpsysinfo.sourceforge.net/phpsysinfo/index.php?disp=bootstrap

Adresse du site officiel http://phpsysinfo.github.io/phpsysinfo/

Pour le téléchargement, les sources sont disponibles sur GitHub https://github.com/phpsysinfo/phpsysinfo

L'installation est ultra simple.
Il suffit de cloner les sources GIT dans un répertoire du serveur accessible en web.
De faire une copie du fichier phpsysinfo.ini.new en phpsysinfo.ini
D'éditer le fichier phpsysinfo.ini afin d'effectuer les réglages désirés
Et enfin, ouvrir son navigateur et ouvrir l'url correspondante

# cd /var/www
# git clone https://github.com/phpsysinfo/phpsysinfo.git
# cd phpsysinfo
# cp -a phpsysinfo.ini.new phpsysinfo.ini

Les données sont également accessible en XML /xml.php?plugin=complete ou en JSON /xml.php?plugin=complete&json

Une application pour Android est également disponible http://rk4an.github.io/psiandroid/

Etiquettes: 

Python

logo python

Etiquettes: 

Python: Liste des paquets et des modules indispensables

Pour éviter tous problèmes lors des installations des modules externes pour Python, il est nécessaire d'installer les paquets suivants:

# apt-get install build-essential python-dev python3-dev

# apt-get install libmysqlclient-dev gcc 

J'essaie de maintenir cette liste le plus à jour possible

Concernant les modules externes:

# pip install bpython httpie mysqlclient lxml requests virtualenv numpy bs4 pandas logger

 

Etiquettes: 

Python: Mettre à jour tous les paquets obsolètes

La commande pip list permet d'afficher la liste complète de tous les paquets python installés avec la version.

# pip list
asn1crypto (0.22.0)
backports.ssl-match-hostname (3.5.0.1)
batinfo (0.4.2)
blessings (1.6)
bottle (0.12.13)
bpython (0.16)
certifi (2017.4.17)
cffi (1.10.0)
chardet (3.0.4)
...
requests (2.18.1)
setuptools (36.2.0)
six (1.10.0)
statsd (3.2.1)
urllib3 (1.21.1)
wcwidth (0.1.7)
websocket-client (0.44.0)
zeroconf (0.19.1)

La commande suivante affiche les principales options disponibles pour la commande pip list:

# pip list -h
Usage:
  pip list [options]

Description:
  List installed packages, including editables.

  Packages are listed in a case-insensitive sorted order.

List Options:
  -o, --outdated              List outdated packages
  -u, --uptodate              List uptodate packages
  -e, --editable              List editable projects.
  -l, --local                 If in a virtualenv that has global access, do not list globally-installed packages.
  --user                      Only output packages installed in user-site.
  --pre                       Include pre-release and development versions. By default, pip only finds stable versions.
  --format <list_format>      Select the output format among: legacy (default), columns, freeze or json.
  --not-required              List packages that are not dependencies of installed packages.

Donc, pour obtenir la liste complète de tous les paquets Python obsolètes, il suffit d'utiliser l'option -o

# pip list -o
Package    Version Latest Type
---------- ------- ------ -----
decorator  4.0.11  4.1.1  wheel
setuptools 36.0.1  36.2.0 wheel

La commande suivante va effectuer la mise à jour complète des paquets obsolètes.

# for x in $(pip list -o --format=columns | sed -n '3,$p' | cut -d' ' -f1); do pip install $x --upgrade; done
Collecting decorator
  Downloading decorator-4.1.1-py2.py3-none-any.whl
Installing collected packages: decorator
  Found existing installation: decorator 4.0.11
    Uninstalling decorator-4.0.11:
      Successfully uninstalled decorator-4.0.11
Successfully installed decorator-4.1.1
Collecting setuptools
  Downloading setuptools-36.2.0-py2.py3-none-any.whl (477kB)
    100% |████████████████████████████████| 481kB 1.1MB/s
Installing collected packages: setuptools
  Found existing installation: setuptools 36.0.1
    Uninstalling setuptools-36.0.1:
      Successfully uninstalled setuptools-36.0.1
Successfully installed setuptools-36.2.0

Attention à la version de pip utilisée.

En général, pip concerne Python2 et pip3 Python3

Python: Ajouter/Mettre à jour facilement des données à un dictionnaire

En Python, l'objet dict est très utile pour indexer du contenu avec une clé.

Pour ajouter des données à un dictionnaire, la méthode est très simple.

>>> d = dict()
>>> d['a'] = 1
>>> d
{'a': 1}

Ajout de la valeur '1' au dictionnaire 'd' avec la lettre 'a' comme clé.

Pour mettre à jour la valeur de la clé 'a':

>>> d['a'] = 2
>>> d
{'a': 2}

Il est également possible d'indexer une liste dans un dictionnaire:

>>> d['l'] = list()
>>> d
{'a': 2, 'l': []}

et pour ajouter des données à ma liste:

>>> type(d['l'])
<class 'list'>
>>> d['l'].append(1)
>>> d
{'a': 2, 'l': [1]}

d['l'] étant une liste, je peux utliser la méthode append de la liste pour y ajouter des données

mais avant de pouvoir ajouter des données à une liste, il faut s'assurer que la clé existe, sinon une erreur est renvoyée

>>> d['ll'].append(1)
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    d['ll'].append(1)
KeyError: 'll'

C'est pour cette raison que j'utilise la fonction suivante pour la gestion de mes dictionnaires.
Je ne me soucie plus de savoir si la clé existe ou pas.
Tout est controlé dans la fonction.

>>> def AddValueToDict(k, d, v, i):
    # k = key - d = dict - v = value - i = type value
    # si le dictionnaire 'd' contient la clé 'k'
    # on récupère la valeur
    if k in d: i = d[k]
    # détermination du type de la valeur
    # si la valeur est de type set()
    if   isinstance(i, set):   i.add(v)
    # si la valeur est de type list()
    elif isinstance(i, list):  i.append(v)
    # si la valeur est de type str()
    elif isinstance(i, str):   i += str(v)
    # si la valeur est de type int()
    elif isinstance(i, int):   i += int(v)
    # si la valeur est de type float()
    elif isinstance(i, float): i += float(v)
    # on met à jour l'objet 'i' pour la clé 'k' dans le dictionnaire 'd'
    d[k] = i
    # on retourne le dictionnaire 'd'
    return d

>>> d
{'a': 2, 'l': [1]}
>>> # Je veux ajouter au dictionnaire 'd'
>>> # la clé 'll' contenant la valeur '33' 
>>> # dans un objet de type list()
>>> d = AddValueToDict('ll', d, '33', list())
>>> d
{'a': 2, 'll': ['33'], 'l': [1]}
>>> # Ajout de la valeur 'aa' dans un objet de type list() pour la clé 'l'
>>> d = AddValueToDict('l', d, 'aa', list())
>>> d
{'a': 2, 'll': ['33'], 'l': [1, 'aa']}
>>> # Ajout de la valeur 'x' dans un objet de type set() pour la clé 's'
>>> d = AddValueToDict('s', d, 'x', set())
>>> d
{'a': 2, 'll': ['33'], 'l': [1, 'aa'], 's': {'x'}}
>>> # Ajout de la valeur 'x' dans un objet de type str() pour la clé 'a'
>>> d = AddValueToDict('a', d, ';x', str())
>>> d
{'a': 2, 'll': ['33'], 'l': [1, 'aa'], 's': {'x'}}
>>> d = AddValueToDict('a', d, 3, int())
>>> d
{'a': 5, 'll': ['33'], 'l': [1, 'aa'], 's': {'x'}}
>>> d = AddValueToDict('b', d, 'bb', str())
>>> d
{'a': 5, 'll': ['33'], 'b': 'bb', 'l': [1, 'aa'], 's': {'x'}}
>>> d = AddValueToDict('b', d, ';cc', str())
>>> d
{'a': 5, 'll': ['33'], 'b': 'bb;cc', 'l': [1, 'aa'], 's': {'x'}}

Dans le cas où la clé est inexistante dans le dictionnaire, elle est automatiquement créée avec la valeur 'v' dans un objet de type 'i'.
Si le type 'i' de la valeur 'v' est un set() ou une list(), la valeur est automatiquement ajoutée.
Si le type 'i' de la valeur 'v' est une chaine de texte str(), elle est concaténée à celle déjà existante.
Si le type 'i' de la valeur 'v' est un entier int() ou un float float(), elle est ajoutée à celle déjà existante.

Qu'en pensez-vous ?
Super simple !

Etiquettes: 

Python: Calculer la somme de contrôle d'un fichier