Python : nombre d’argument arbitraire avec **kwargs et *args

En python il est possible de construire des fonctions qui acceptent un nombre indéfini de paramètres, aussi bien en positionnel qu’en nommé.

*args

def mafonction(*args):
   for a in args:
        print(a)

mafonction(1)
# 1
mafonction(1,2,3)
# 1
# 2
# 3

le *args est interprété comme un tuple

**kwargs

def mafonction(param,*args,**kwargs):
    for a in kwargs:
        print(a,kwargs[a])

mafonction(nom="Dupont",age=27)
#nom Dupont
#age 27

Notez qu’il n’est pas nécessaire de les appeler *args et **kwargs, on peut utiliser d’autres noms.

On peut mixer ces deux types de paramètre avec des paramètres classiques

def mafonction(param1,*args,**kwargs):
    

Unpack argument list

Cette technique consiste à préfixer le paramètre d’un astérisque, pas lors de la déclaration de la fonction, mais lors de l’appel de la fonction.

def mafonction(a,b,c):
    print(a,b,c)

obj = {"nom":"Dupont","age":27}
mafonction(100,**obj)
# 100,Dupont 27

def mafonction(a,b):
    print(a,b)

l = [1,2]
mafonction(*l)
# 1 2

Pour les listes et tuple on utilisera *args, pour les dictionnaire on utilisera **

mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3

>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3

>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3

Extended iterable unpacking

Une façon de faire de l’unpacking puissante

first, *rest = [1,2,3,4]
first,*l,last = [1,2,3,4]

Enfin un esyntaxe propre à Python 3 :

def mafonction(arg1,arg2,*,kwarg1,kwarg2):
    pass

La syntaxe ci-dessus impose que les deux premiers paramètres soient positionnel, et les paramètre après l’astérisque soient nommés.

https://stackoverflow.com/questions/36901/what-does-double-star-asterisk-and-star-asterisk-do-for-parameters

Python : tester si une variable est un nombre avec isdigit ()

Le problème de conversion d’une chaine en nombre entier

Lorsqu’on a une chaine de caractères qu’on cherche à convertir en nombre, il faut se poser la question de si c’est faisable.

Imaginons qu’on ait une variable à tester dont le type est un string :

ns = "125"
n = int(ns)

Mais si on a une chaine de caractère qui ne contient pas purement des chiffres (voire une chaine vide):

nm1 = "12.3"
nm2 = "z123"
nm3 = ""

Tenter de convertir ces chaines en entier déclenchera une erreur de type ValueError.

Tester si une chaine est un nombre entier avec isdigit()

En Python tout est objet, un nombre entier est un objet, un booléen est un objet, un float est un objet,(vous pouvez le voir en utilisant la notation pointée). Ces objets ont des méthodes (c’est le nom en OOP pour une fonction). Et dans le cas des chaines de caractères, uen de ces méthode est isdigit().

n = "123"
print(n.isdigit())  # True 
n = ""
print(n.isdigit())   # False
#on peut encore écrire
print("123".isdigit())  #True

Ainsi avant de convertir en entier, testez la chaine avec isdigit() avant d’utiliser int()

if("123".isdigit()):
    n = int("123")

Connexion à MySQL en Python

Installez au préalable Mysql, le plus rapide (avec zéro configuration ) étant d’installer la solution de développement PHP Laragon si vous êtes sous windows.

Ensuite il faudra redéfinir le mot de passe root, allez dans Laragon click droit sur le bouton Database > Mysql > Change root password.

Connexion à Mysql en Python

from mysql.connector import MySQLConnection, Error

def connect():
    """ Connect to MySQL database """
    conn = None
    try:
        conn = mysql.connector.connect(host='localhost',
                                       database='boutique',
                                       user='root',
                                       password='root')
        if conn.is_connected():
            print('Connected to MySQL database')

    except Error as e:
        print(e)

    finally:
        if conn is not None and conn.is_connected():
            conn.close()

if __name__ == '__main__':
    connect()

Exécuter une requête SQL en Python

from mysql.connector import MySQLConnection, Error

def query_with_fetchone():
    try:

        conn = MySQLConnection(host='localhost',
                                         database='boutique',
                                         user='root',
                                         password='root')
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM staffs")

        row = cursor.fetchone()

        while row is not None:
            print(row)
            row = cursor.fetchone()

    except Error as e:
        print(e)

    finally:
        cursor.close()
        conn.close()


query_with_fetchone()

Connexion à Sqlite en Python

Sqlite est une base de donnée un peu spéciale, puisque la base tient dans un fichier binaire, avec extension .db, c’est donc quelque chose de très simple, et Sqlite est destiné à être utilisé sur des systèmes embarqués.

Donc pas besoin d’installer un programme, c’est la librairie Python qui va s’ocuper de cela. De plus c’est dans la librairie standard, ce qui veut dire que l’on n’ pas besoin de faire un pip install.

La librairie Python sqlite3

Il suffit tout simplement d’importer la librairie sqlite3, de créer une connexion pour créer le fichier binaire de la base de données

import sqlite3
from sqlite3 import Error


def create_connection(db_file):
    """ crée une connexion SQLite si lea DB n'existe pas elle sera créée"""
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()


if __name__ == '__main__':
    create_connection(r"C:\db\pythonsqlite.db")

Sivous exécutez pour la première fois ce script, le fichier pythonslqite.db sera créé, par contre il vous faudra avoir le répertoire déjà créé, sinon vous aurez une erreur. Vous pouvez aussi créer une base de données avec DB Browser, un browser de base sqlite.

Requêter dans Sqlite en Python

Voici la recette pour faire une requête SQL en Python dans Sqlite. On acréé la base de données test.db, et il y a une table items. Vous pouvez importer dans DBBrowser le fichier contenant les données ci-dessous ou exécuter le SQL suivant :

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "items" (
	"id"	INTEGER,
	"nom"	TEXT,
	"prix"	INTEGER
);
INSERT INTO "items" VALUES (1,'Pomme',5);
INSERT INTO "items" VALUES (1,'Poire',3);
INSERT INTO "items" VALUES (1,'raisin',13);
COMMIT;
import sqlite3
from sqlite3 import Error

def create_connection(db_file):
    conn = None
    try:
        conn = sqlite3.connect(db_file)
    except Error as e:
        print(e)

    return conn

def select_items(conn):
    """
    Query all rows in the tasks table
    :param conn: the Connection object
    :return:
    """
    cur = conn.cursor()
    cur.execute("SELECT * FROM items")

    rows = cur.fetchall()

    for row in rows:
        print(row)

db_file = "c:\\Users\\admin\\Documents\\test.db"
conn = create_connection(db_file)
select_items(conn)

Compréhension de liste en Python

Base de compréhension de liste

list = [i for i in range(5)]
print(list)  # [0,1,2,3,4]
list2 = [ i * i for i in range(10)]
print(list2) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

If dans compréhension de liste

list3 = [ n for n in range(10) if n % 2 == 0]
print(list3) # [0, 2, 4, 6, 8]

If imbriqués
list4 = [ n for n in range(10) if n % 2 == 0 if n >= 5]
print(list4) # [6, 8]

If…Else dans compréhension de liste

list5 = ["Even" if i%2==0 else "Odd" for i in range(10)]
print(list5) #

list6 = [str(i) + ":Pair" if i%2==0 else str(i) + ":Impair" for i in range(10)]
print(list6) 
# ['0:Pair', '1:Impair', '2:Pair', '3:Impair', '4:Pair', '5:Impair', '6:Pair', '7:Impair', '8:Pair', '9:Impair']

csharp green logo

Conversion entre les bases

conversion HEX en décimal

Formule pour convertir un HEX en décimal:

C = 12 x 16^0

AB = 10 x 16^1 + 11 x 16^0 = 10 x 16 + 11 x 1 = 160 + 11 = 171

Comme A est en seconde position son poids est de 16^1, B ayant un poids de 16^0 qui équivaut à 1. La valeur de A est 10 en décimal, B vaut 11 en décimal.

Conversion décimal en HEX

Pour convertir un nombre décimal en HEX, il faut diviser par 16 plusieurs fois. Par exemple pour convertir 199 décimal en HEX:

Calcul de 199 modulo 16 = 7 (le reste de la division entière), le diviseur étant 12. 12 en HEX s’écrit C. Donc 119 en HEX s’écrit C7.

1ère étape : Calcul de 3999 modulo 16 = 15 soit F en HEX, le diviseur étant 249

2ème étape : Calcul de 249 moduleo 16 = 9 soit 9 en HEX, le diviseur étant 15 soit F en HEX.

conversion binaire en décimal

On regarde le poids n de chaque bit (position) on élève 2 à la puissance n, puis on multiplie par la valeur de la position, on somme les sous résultats obtenus pour avoir la valeur en décimal.

Ici on a 1 x 2^7 = 128, 1 x 2^5 = 32, 1 x 2^1 = 2

On somme le chiffres en gras et on obtient la valeur décimale correspondante.

Conversion décimal en binaire

C’est comme la manipulation pour convertir HEX en décimal, sauf qu’ici on divise par 2 au lieu de 16 et on regarde le reste.

Conversion de 112 en binaire

112 % 2 = 0 reste 56, 56 % 2 = 0 reste 28, 28 % 2 = 0 reste 14, 14 % 2 = 0 reste 7, 7 % 2 = 1 reste 3, 3 % 2 = 1 reste 1

En prenant les chiffres en gras de la fin vers le début, on obtient 1110000.

Lien vers un convertisseurs en ligne :

https://www.rapidtables.com/convert/number/decimal-to-binary.html

Attribut de classe et d’instance en Python

Attribut de classe

class Dog:
    leg_number = 4
    def __init__(self,name):
        self.name = name

chien1 = Dog("Médor")
print(chien1.leg_number)  # 4
print(Dog.leg_number)     # 4

Dans l’exemple ci-dessus leg_number est un attribut de classe. Pyton va chercher d’abord dans les attribut d’instance pour voir si leg_number existe, sinon va aller chercher dans les attributs de classe.

Attribut d’instance

name est un attribut d’instance car rattaché à self.

class Dog:
    leg_number = 4
    def __init__(self,name):
        self.name = name

chien1 = Dog("Médor")
print(chien1.name)  # Médor
print(Dog.name)     # AttributeError: type object 'Dog' has no attribute 'name'

Python ne trouvera pas name en attribut de classe. Par contre on peut surcharger name en attribut de classe.

class Dog:
    leg_number = 4
    name = "toto"
    def __init__(self,name):
        self.name = name

chien1 = Dog('médor')
print(chien1.name)   # médor
print(Dog.name)      # toto

Un attribut de classe est commun à tous les objets qui en dérivent.

class Dog:
    leg_number = 4
    def __init__(self,name):
        self.name = name

chien1 = Dog('médor')
chien2 = Dog('Lassie')
print(chien1.leg_number)
print(chien2.leg_number)
Dog.leg_number = 5
print(chien1.leg_number)
print(chien2.leg_number)

https://www.toptal.com/python/python-class-attributes-an-overly-thorough-guide

Héritage de classe dans Python

A première vue, les notions d’orienté objet sont simple en Python par rapport à Java, mais même si l’encapsulation ,n’existe pas en tant que tel (voir le mangling en Python), il y a beaucoup de choses à apprendre en héritage dans Python.

Il y a les fonctions magiques (avec le dunder) pour faire du polymorphisme et l’héritage multiple comme en C++ !

Classe et héritage simple

class Kite:
    def __init__(self,max_altitude):
        self.max_altitude = max_altitude
    def do(self):
        return "I fly"
    def getMaxAltitude(self):
        return self.max_altitude


class BigKite(Kite):
    def __init__(self,max_altitude,weight):
        self.max_altitude = max_altitude
        self.weight = weight
    def getWeight(self):
        return self.weight

Ici BigKite hérite de Kite, et la méthode de constructeur __init__ est surchargée. Si nous voulons utiliser le constructeur de la classe parente :

class Kite:
    def __init__(self,max_altitude):
        self.max_altitude = max_altitude
    def do(self):
        return "I fly"
    def getMaxAltitude(self):
        return self.max_altitude


class BigKite(Kite):
    def __init__(self,max_altitude,weight):
        super().__init__(max_altitude) #appel classe parente
        self.weight = weight
    def getWeight(self):
        return self.weight

On aurait pu écrire aussi :

super(Kite,self).__init__(max_altitude)

Héritage multiple

Ici KiteSurf hérite de la classe Kite et de la classe Surf, qui elles-même héritent de Object, on est ici en présence de diamond problem

class Object:
    def __init__(self):
        pass
    def do(self):
        return "I exist"


class Kite(Object):
    def __init__(self,max_altitude):
        self.max_altitude = max_altitude
    def do(self):
        return "I fly"
    def getMaxAltitude(self):
        return self.max_altitude


class Surf(Object):
    def __init__(self,matter):
        self.matter = matter
    def do(self):
        return "I surf"
    def getMaxAltitude(self):
        return self.max_altitude

class KiteSurf(Surf,Kite):
    def __init__(self):
        pass

ks = KiteSurf()
print(ks.do())

L’affichage de ks.do() méthode existant dans Kite et dans Surf dépend de l’ordre dans lequel est passé en paramètre les classes parentes.

https://he-arc.github.io/livre-python/super/index.html

Encapsulation dans les classes Python

Il n’existe pas de private ni de protected dans Python, la philosophie de Python est que le développeur est un être responsable.

Cependant Python supporte ce que l’on appelle le mangling.

class Dog:
    __init__(self):
        self.name = "Médor"
        self.__tatoo = "X312B13"

chien1 = Dog()
print(chien1.name) # Médor
print(chien1.__tatoo) # AttributeError: 'Dog' object has no attribute '__tatoo'

__tatoo a été substitué par un autre nom en vertu des deux underscores, on ne connait pas le nouveau nom, ce qui reproduit le process d’encapsulation.

javascript

Ecouter un événement de réponse AJAX

C’est quoi un événement en Javascript?

Un événement est par exemple un click de souris, une touche de clavier enfoncée, mais ça peut être purement logiciel, par exemple lorsque la page HTML a fini de se charger, il se produit un événement de type onload.

Un événement de requête AJAX

Ce type d’événement permet de détecter lorsqu’une requête AJAX est émise.

(function() {
    var origOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        console.log('request started!');
        this.addEventListener('load', function() {
            console.log('request completed!');
            console.log(this.readyState); //will always be 4 (ajax is completed successfully)
            var text = this.responseText
            toto = document.querySelector('#toto')
            toto.innerHTML = toto.innerHTML + text

        });
        origOpen.apply(this, arguments);
    };
})();
php

Débugger sous VSCode en PHP

Il vous faut installer le plugin PHP Debugger de Felix Becker

Configurez XDebug dans le php.ini comme d’habitude (PHPstorm)

Cliquez sur Listen for XDebug

Mettez un breakpoint où vous voulez et lancez la page web.

Pour Débugger avec le serveur interne de PHP

zend_extension = C:\laragon\bin\php\php-7.2.19-Win32-VC15-x64\ext\php_xdebug-2.6.1-7.2-vc15-x86_64.dll
[xdebug]
xdebug.remote_enable = 1
xdebug.profiler_enable = off
xdebug.profiler_enable_trigger = 1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.profiler_output_name = "cachegrind.out.%u.%H.%R"
xdebug.profiler_output_dir = "c:/laragon/tmp"
xdebug.show_local_vars=0
xdebug.remote_autostart=1

Il faut mettre dans le php.ini la configuration suivante pour Xdebug en plus :

xdebug.remote_autostart=1
javascript

Javascript import et symbole @

Vous avez sans doute souvent vu dans un script javascript moderne ceci:

import Component from '@/components/component'

Normalement si on veut importer un module Javascript, il faut utiliser les / et les .. soit pour remonter d’un niveau soit pour descendre d’un niveau, comme on le ferait dans n’importe quel langage de programmation.

Cette notation n’est pas du Javascript natif, elle est rendue possible par l’utilisation d’un plugin de type module loader ou module bundler.

Un plugin comme babel plugin root import, quel root? le root du projet javascript en question. Ainsi quelquesoit l’emplacement du plugin et de la page qui demande le plugin, on utilisera l’arobase pour atteindre un plugin comme si on le demandait depuis la racine du projet.

Cela permet d’éviter que la syntaxe suivante :

import Component from 'components/component'

Dans ce cas ça va chercher dans /node_modules.

Mécanisme de session de Django

Similaire aux sessions en PHP, dans Django il faut importer deux lignes pour pouvoir travailler avec les sessions:

#settings
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions', // le module Session
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'products.apps.ProductsConfig'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware', // le middleware
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Avec Django par défaut les sessions sont sauvées dans la base de données.

Les formulaires dans Django

Les formulaires sont un vaste chapitre comme dans tout framework web quelque soit le langage. Mais Django permet de les manipuler plus facilement que Symfony par exemple.

cleaned_data qu’est ce que c’est?

Il y a deux types de formulaire dans Django, les formulaires classiques qui héritent de forms.Form, et mes formulaires liés à des entités, qui héritent de forms.ModelForm.

Avec les modelForm, inutile de s’inquiéter du cleaned_data.

Dans un form classique on doit utiliser les données validée:
if form.is_valid():
    ex = Example()
    ex.username = form.cleaned_data['username']
    ex.save()

Alors que dans un modelForm, cette étape est automatique.

if form.is_valid():
    form.save()

https://stackoverflow.com/questions/53594745/what-is-the-use-of-cleaned-data-in-django

Upload de fichiers dans Django

Pour uploader un fichier dans un formulaire, il faut modifier le model,

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.FloatField()
    stock = models.IntegerField()
    image = models.CharfieldField(max_length=1000)

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.FloatField()
    stock = models.IntegerField()
    image = models.FileField()

Après avoir changé la propriété dans le model, il faut faire une migration

python manage.py makemigrations products  #le nom de l'app
python manage.py migrate

Ensuite il faut faire quelques modification de code, dans le settings.py de votre projet :

#monprojet\settings.py
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'

#monprojet\urls.py
from django.contrib import admin
from django.urls import path, include

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('products/', include('products.urls'))
]

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

php

Doctrine et ses 4 façons de requêter la base de données

DQL Doctrine Query Langage

$query = $this->em->createQuery(
    "
    SELECT p
    FROM AppBundle\Entity\RedditPost p
    WHERE p.id > :id
    "
)->setParameter('id', 50);

$data = $query->getResult();

Mais on ne peut splitter la requête simplement, alors qu’avec le query builder c’est possible:

// it is still DQL, but now it is painful

var $someConditional = false;

if ($someConditional === true) {
    $query = $this->em->createQuery(
        "
        SELECT p
        FROM AppBundle\Entity\RedditPost p
        WHERE p.id > :id
        "
    )->setParameter('id', 50);
} else {
    $query = $this->em->createQuery(
    "
        SELECT p
        FROM AppBundle\Entity\RedditPost p
    "
    );
}

$data = $query->getResult();

Query Builder

C’est mieux avec le query builder, plus facile de paramétrer sa requête, tout est à base de méthode objet.

// using Doctrine's Query Builder

var $someConditional = false;

$query = $this->getDoctrine()->getRepository('AppBundle:RedditPost')->createQueryBuilder('p');

if ($someConditional === true) {
    $query
        ->where('p.id > :id')
        ->setParameter('id', 50)
    ;
} 

$data = $query->getQuery()->getResult();

https://codereviewvideos.com/course/doctrine-databasics/video/dql-vs-doctrine-query-builder

$query = $this->getDoctrine()
    ->getRepository('AppBundle:RedditPost')
    ->createQueryBuilder('p')

createQueryBuilder('p') implicitly creates the equivalent:

    SELECT p
    FROM AppBundle\Entity\RedditPost p

C’est la raison pour laquelle on n’a pas besoin de SELECT et FROM explicite

Native Query

Ressemble beaucoup au SQL, la notion de resultSetMapping est centrale.

use Doctrine\ORM\Query\ResultSetMapping;

$rsm = new ResultSetMapping();
// build rsm here

$query = $entityManager->createNativeQuery('SELECT id, name, discr FROM users WHERE name = ?', $rsm);
$query->setParameter(1, 'romanb');

$users = $query->getResult();

https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/native-sql.html

On peut utiliser le resultSetMappingBuilder pour construire des requêtes Native Query

use Doctrine\ORM\Query\ResultSetMappingBuilder;

$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " . 
       "FROM users u INNER JOIN address a ON u.address_id = a.id";

$rsm = new ResultSetMappingBuilder($entityManager);
$rsm->addRootEntityFromClassMetadata('MyProject\User', 'u');
$rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', 'u', 'address', array('id' => 'address_id'));

Raw SQL

On met du pur SQL dans un repository Doctrine

    public function getEvoplusStatusCountByMonthByCommercial(int $idUser, $start, $end)
    {
        $conn = $this->getEntityManager()->getConnection();

        $sql = "select count(*) as count, M.ID_ETAT_MATRICE, EM.LIBELLE_ETAT_MATRICE from MATRICE M 
inner join ETAT_MATRICE EM on 
M.ID_ETAT_MATRICE = EM.ID_ETAT_MATRICE 
where 
CONTRAT_DATE_SIGNATURE BETWEEN '$start' AND '$end'
AND USR_ID = $idUser GROUP by M.ID_ETAT_MATRICE; ";

        $stmt = $conn->prepare($sql);
        $stmt->execute();
        $res = $stmt->fetchAll();

        return $res;
    }

Cette méthode est ma préférée, vou sl’aurez compris je ne suis pas un fan des ORM, c’est tellement plus facile de faire des requêtes SQL, et tant pis si on n’a pas d’objet en résultat, manipuler des tableaux associatifs n’est pas si difficile.

Introduction à Jupyter Notebook

Jupyter Notebook est une interface web pour faire de la datascience, vous exécutez vos scnippet Python dans ce qu’on appelle des cells, des unités d’exécution.

Pour l’installer, voici la procédure :

Installation des librairies

pip install pandas
pip install numpy
pip install matplotlib
pip install xlrd

Installation de Jupyter Notebook

pip install notebook

#démarrer notebook
jupyter notebook

Vous pouvez installer d’abord Jupyter Notebook et installer les librairies depuis Jupyter Notebook

!pip install pandas 

le ! permet d'accéder au shell.

Afficher les log server dans Python Django

Il est pratique de logger en mode développement les requêtes servies par le serveur de Python

dans le fichier settings.py de votre projet mettez ce code juste après le DEBUG = true

if DEBUG:
    # will output to your console
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
    )
else:
    # will output to logging file
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
        filename = '/my_log_file.log',
        filemode = 'a'
    )

https://stackoverflow.com/questions/4558879/python-django-log-to-console-under-runserver-log-to-file-under-apache

Comprendre le mot clé with en Python

La syntaxe en Python de with est assez étrange, quel problème essait-il de résoudre?

with est utilisé lorsqu’on travaille avec des ressources non managées, notamment ouverture d’une fichier. Avant on utilisait try...catch,

    set things up
    try:
        do something
    finally:
        tear things down

Syntaxe basique de with

with expression [as variable]:
    with-block

L’expression est évaluée, et retourne un objet qui implémente le context management protocol, c’est à dire qui possède les méthodes __enter__() et __exit__()

with open('text.txt','w') as fichier
    fichier.write('Hello')

Avec cette syntaxe pas besoin de fermer explicitement le fichier, c’est automatique.

javascript

L’Event Loop dans Javascript

setTimeout n’appartient pas à V8

Javascript est single threaded

Blocking

Async callback and call stack @ 11:25

console.log('hi'); // A

setTimeout(function(){  // B
    console.log('there');
},5000);

console.log('Hello');  // C

Ordre d’appel dans le callstack A, B, C mais le ‘there’ est affiché 5 secondes après. Javascript ne fait qu’une seule chose à la fois

Event Loop

L’event loop regarde s’il reste encore des opérations à faire dans le stack, si le stack est vide, l’Event loop va regarder dans le task queue.

Liens :

JS Async

Latentflip Loupe

Javascript engine talk

Introduction à Numpy

Numpy est une librairie Python qui introduit une nouvelle structure de données l’Array, qui est comme une liste, mais en beaucoup plus rapide.

Installation de Numpy

pip install numpy
#test.py
import numpy
arr = numpy.array([1,2,3,4,5])
print(arr)

Importation de Numpy avec un alias

import numpy as np
arr = np.array([1,2,3,4,5])
print(np.__version__)

Array scalaire 0 dimension

import numpy as np
arr = np.array(42)
print(arr) 

Array unidimensionnel

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr) 

Array 2D

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr) 

Dans le cas particuliers des matrices Numpy a une librairie dédiée numpy.mat

Array 3D utilisé pour représenter les tenseurs.

Checker la dimension d’un array avec ndim

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim) 

Index des array c’est comme les listes

Le notation est différente ce ce qu’on peut voir en Javascript

import numpy as np
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print('2nd element on 1st dim: ', arr[0, 1]) 

Index négatif

pour accéder depuis la fin

import numpy as np
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print('Last element from 2nd dim: ', arr[1, -1]) 

Array slicing

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[1:5]) 
print(arr[4:]) 
print(arr[:4]) 
print(arr[:]) 
print(arr[-3:-1]) #Array slicing négatif
print(arr[1:5:2]) #step slicing !cette notation exclut le dernier (tem index 5 n'est pas pris en compte)

Slicing 2D array

import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[1, 1:4])  # sur un array
print(arr[0:2, 2]) # sur deux array
print(arr[0:2, 1:4]) # sur deux array de 1 à 4

Les datatype de Numpy


		
logo windows

Clonez votre SSD avec Macrium gratuit pour avoir une sauvegarde

J’ai un SSD qui est une sauvegarde exacte de mon disque principal (un clone), si ce dernier plante, je replugge direct le SSD de sauvegarde, ça fait gagner une journée !

Sélectionnez le disque à cloner, si vous en avez plusieurs, faites attention au choix de votre disque.

Sélectionnez le disque qui sera le clone (disque cible)

Effacez les partitions du disque cible

Sélectionnez les partitions à cloner, dans l’idéal, le disque cible doit être au moins aussi gros que le disque source, si ce n’est pas le cas, il existe des moyens de contourner à chercher sur le Net.

Faire le backup, dans la version gratuite ne cochez pas la seconde case, qui ordonnance une sauvegarde régulière.

Message d’avertissement, vérifiez que tout est bien en ordre et clonez !

Update:

Vidéo clonage de disque SSD avec Macrium

AVERTISSEMENT : Je ne suis pas responsable de la perte de vos données ! Cette vidéo est à titre informative, soyez prudent avec les disque que vous écrasez, conseil : débrancher les disques non sollicité dans le processus de clonage (il doit en rester deux connectés).

Vérifiez à deux fois avant de cloner.

Insérer un modèle dans la base avec Django

De la même façon qu’on peut générer un formulaire facilement avec le modèle, on peut facilement insérer dans la base de données une entité provenant d’un formulaire HTML généré de cette façon, ou en le construisant from scratch depuis une méthode de view

#models.py
class Foo(models.Model):
    name = models.CharField(max_length=100)

#view.py
def add(request):
    foo_instance = Foo.objects.create(name='test')
    return render(request, 'some_name.html.html')

Ou l’on peut se servir du model directement

from django.http import HttpResponse
from django.template import loader

from .models import Article


def index(request):
    article = Article()
    article.title = 'This is the title'
    article.contents = 'This is the content'
    article.save()

    template = loader.get_template('articles/index.html')
    context = {
        'new_article_id': article.pk,
    }
    return HttpResponse(template.render(context, request))

En utilisant les model form c’et plus simple

# views.py
def monform(request):
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = MyProductForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/products/thanks')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = MyProductForm()

    return render(request, 'myproductform.html', {'form': form})

#form.py
class MyProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'price', 'stock', 'image']  #or use tuple
#models.py
class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.FloatField()
    stock = models.IntegerField()
    image = models.CharField(max_length=2000)
xcode

Problème rencontré avec XCode

SI vous passez à XCode 12 depusi une version antérieure (la 11.x dans mon cas) et vous compilez votre projet (React Native) dans mon cas, vous aurez sans doute un problème de compatibilité avec les modules

Module compiled with Swift 5.3.1 cannot be imported by the Swift 5.2.4 compiler

Il faut aller dans les paramètres de XCode, puis Location et sélectionnez la version du CLI

xcode

Mise à jour de React Native suite à la version IOS 14

C’est un casse-tête cette màj de IOS.

J’étais en RN 0.61.5 et après avoir mis à jour la version de XCode vers la version 12, le déploiement sur device IOS marche mais il manque les images. Ce qui est conseillé est de mettre à jour React Native vers la dernière version qui corrige ce problème. Il est conseillé de mettre régulièrement à jour React Native, ça va tellement vite. J’ai lu que si vous ne le faites pas sur une durée de 18 mois, c’est un peu la catastrophe de mettre à jour, car le programme qui met à jour peut changer et d’autres joyeusetés.

Pour mettre à jour suivez ce lien sur Stackoverflow,

Cocoapod refus de s’exécuter, si vous avez le message :

[!] CocoaPods could not find compatible versions for pod "ReactCommon/callinvoker":
  In Podfile:
    ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`)

None of your spec sources contain a spec satisfying the dependency: `ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`)`.

You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Solution à ce problème :

Retour en haut