Nom de l’auteur/autrice :yvonh

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 :

javascript

Test de nullité en Javascrip : Cas où l’ordre a une importance

    const handleAccountCreation = async () => {
        const exist = await userExistCheck(result.email)
        console.warn('social login', exist)

        if (exist.exist !== null) {
            socialLogin(result.email)
            console.warn('social login')
        }
        else {
            createAccount(result.email)
            console.warn('social create account')
        }
    }

La condition dans le if échoue si exist est null, car exist.exist reverra une erreur undefined.

Il faut mettre une condition autrement

    const handleAccountCreation = async () => {
        const exist = await userExistCheck(result.email)
        console.warn('social login', exist)

        if (exist == null) {
             createAccount(result.email)
             console.warn('social login')
        }
        else {
            socialLogin(result.email)
            console.warn('social create account')
        }
    }

javascript

Opérateur point d’interrogation ?. en Javascript (Null propagation operator)

A ne pas confondre avec le null coalesce operator en Javascript ?? . Cet opérateur est encore appelé optional chaining operator.

        if (data.error?.message) {
          Alert.alert('Erreur carte',
            `Votre transaction ne s\'est pas terminée correctement Message de Stripe.com : ${data.error.message}`)
        } else {
          return data.id
        }

Si error n’existe pas alors data.error?.message évaluera en undefined

https://ponyfoo.com/articles/null-propagation-operator

Linux

Compresser une dossier avec la commande tar (tarball)

Cette commande est rapide et puissante. Vous pouvez archiver une dossier complet, et avoir la possibilité d’excluer certains répertoire. Vous pouvez aussi à la volée compresser l’archive.

Archive simple

tar -cvf archive.tar /folder

Archiver en excluant des répertoires

$ tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .
react native

Configurer Apple Pay sur React Native (Part 1)

Tuto React Native Apple Pay avec Laravel en backend

C’est quoi Apple Pay?

Pour pouvoir payer avec Apple Pay, vous devez ouvrir l’application Wallet, scanner votre carte bancaire, un process de validation va suivre et si c’est OK vous pourrez utiliser votre Iphone pour payer. C’est en fait une dématérialisation de votre carte bancaire, qui ne fera qu’un avec votre téléphone, vous n’avez plus besoin d’utiliser votre carte bancaire. Apple Pay agit comme un proxy de votre carte bancaire. Vous avez un portefeuille numérique (Digital Wallet)

Ce qu’Apple Pay n’est pas

Apple Pay n’est pas un moyen de paiement au sens Payment Gateway (comme l’est Stripe, Briaintree,, ça n’encaisse pas d’argent sur un compte Apple, ce n’est pas le In App purchase sur lequel Apple prélève 30%. Apple Pay n e peut donc être utilisé pour l’In App purchase. C’est pour ça qu’une fois Apple Pay est intégré sur une application mobile, si vous utilisez Strip epour encaisser, il faudra utiliser le tuto de Stripe pour intégrer Apple Pay, car votre code Apple Pay va faire une requête vers Stripe.

Procédure de configuration sur le site d’Apple

  • créer un CSR depuis le trousseau de clé Application > Utilitaire
  • Aller dans le compte développeur Apple, créer un Id Merchant
  • Aller dans Certificate créer un certificat cochez Apple Pay Payment Processing Certificate
  • Uploadez le CSR généré, attention pour générer un certificat pour Apple Pay, c’est différent il faut associer une clé spéciale
  • Vous serez invité à téléchargé le certificat
  • Allez dans Certificat,Identifier & Profile, cliquez sur l’application sur laquelle vous voulez utiliser Apple Pay, Apple Pay Payment Processing, choisissez le Merchant ID cochez, un nouveau provisioning profile sera créé (à chaque fois que vous ajoutez ou enlevez une Capabilities
  • Ouvrez Xcode, choisissez onglet Signing&Capabilities, cliquez sur le bouton « +Capabilities« , une liste apparait, double cliquez sur Apple Pay
  • Apple Pay apparait maintenant dans l’onglet, cochez la case « MerchantID »

https://medium.com/enappd/implement-apple-pay-in-react-native-apps-dec9cd5c6808, pour ce lien ne suivez pas l’utilisation de la librairie mais seulement la configuration côté Apple developper Account, elle n’est plus maintenue, et préférer ces deux liens, IOS et Android.

Génération du certificat Procédure

Générer le CSR pour Apple Pay : https://docs.skillz.com/docs/v23.2.1/apple-pay/

On your Mac, open Keychain Access
In the menu bar go to Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority....
Input your preferred email address
Select Saved to Disk
Check Let me specify key pair information
Press Continue
Choose a location to save the .certSigningRequest file, and give it a name.
Select Algorithm ECC
Select Key Size 256 Bits ** NOTE: You MUST select ECC before the 256 Bits option becomes available
Press Continue

https://docs.skillz.com/docs/v23.2.1/apple-pay/

Créer un Sandbox tester Account

Pour éviter d’utiliser votre vraie carte, il vous faut ce type de compte. Allez dans AppStore Connect, dans Utilisateurs et Accès, barre latérale gauche, dans Sandbox, cliquez sur Testeurs, ajoutez un testeur, entrez les informations et validez le compte via email.

Attention la procédure suivante nécessite de vous déconnecter de votre Iphone et de vous connecter avec le compte de test.

Une fois connecté, allez dans vos paramètres > wallet and apple Pay ou en cliquant sur l’icône Wallet, il vous faut entrer manuellement votre carte de test. Vérifiez que la région de votre compte est bien dans un pays supporté par Apple Pay. Cette page officielle contient des numéro sde carte, mais je n’ai pu réussir qu’avec le numéro sur cette page.(je n’ai pas tout essayé non plus)

react native

Ajouter Facebook Login dans une application React Native

https://enappd.com/blog/facebook-login-in-react-native-apps/89/

https://developers.facebook.com/docs/react-native/login/

Résumé des étapes pour intégrer le Facebook Login

  • créer une ap dans Facebook developer Console, récuper l’Id de l’app
  • Installer le package pour React Native
  • Implémenter le code 2 composants sont nécessaire LoginButton, LoginManager

Bien suivre les instructions de cette videos, j’ai suivi le tuto, j’ai pu faire marcher sur Android, mais pas sur IOS qui refuse de builder malgré le paramétrage, la solution a été proposée sur Stackoverflow, solution non intuitive si on n’est pa développeur natif.

https://www.youtube.com/watch?v=J-VIu_i0NRM

Ce lien propose une solution quand le projet ne veut lus builder après l’installation de fbsdk sur IOS.

https://stackoverflow.com/questions/50096025/it-gives-errors-when-using-swift-static-library-with-objective-c-project/56187043#56187043

Facebook Login et le système existant de connexion à votre application

Si vous faites coexister votre système de login et celui de Facebook Login, des questions intéressantes peuvent se poser. A la première connexion, l’utilisateur n’a pas de compte sur votre application, il peut choisir soit de recourir à votre système, soit à celui de Facebook. Je suppose que l’ backend de l’appli est un serveur sous PHP (ex Laravel ou Symfony), et que l’application React Native communique par Rest API, donc authentification par JWT.

Votre système de création de compte et de connexion

  • Création de compte : l’utilisateur entre email et mot de passe et valide la création
  • l’utilisateur se connecte en entrant email et mot de passe
  • le serveur envoit un token d’authentification qui sera stocké sur l’application, et envoyé à chaque requête Ajax

Création avec Facebook Login

  • L’utilisateur clique sur le bouton Facebook Login, s’authentifie, et Facebook envoit un Access Token

Mais voilà à ce stade il a le choix de créer son compte ou non. S’il crée un compte sur l’application, on doit pouvoir recueillir son email automatiquement (c’est possible avec Facebook Login de demander l’email, nom et prénom), envoyer vers le serveur (s’assurer que le compte n’existe pas déjà en comparant l’email), la création de compte étant fini, il faut pouvoir renvoyer un token d’authentification vers l’application qui stockera le token.

Obtenir l’email avec le facebook login

import React, { Component } from 'react';
import { View } from 'react-native';
import { LoginButton, AccessToken, LoginManager, GraphRequestManager, GraphRequest } from 'react-native-fbsdk';

export default class Login extends Component {
    render() {
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <LoginButton
                    onLoginFinished={
                        (error, result) => {
                            LoginManager.logInWithPermissions(['public_profile', 'email']).then(
                                function (result) {
                                    if (result.isCancelled) {
                                        console.log("Login cancelled");
                                    } else {
                                        console.log(
                                            "Login success with permissions: " +
                                            result.grantedPermissions.toString()
                                        );

                                        AccessToken.getCurrentAccessToken().then(
                                            (data) => {
                                                console.log(data)
                                                let accessToken = data.accessToken;

                                                const responseInfoCallback = (error, result) => {
                                                    if (error) {
                                                        console.log(error)
                                                        alert('Error fetching data: ' + error.toString());
                                                    } else {
                                                        console.log(result)
                                                        alert('Success fetching data: ' + result.toString());
                                                    }
                                                }


                                                const infoRequest = new GraphRequest(
                                                    '/me',
                                                    {
                                                        accessToken: accessToken,
                                                        parameters: {
                                                            fields: {
                                                                string: 'email,name,first_name,middle_name,last_name'
                                                            }
                                                        }
                                                    },
                                                    responseInfoCallback
                                                );

                                                // Start the graph request.
                                                new GraphRequestManager().addRequest(infoRequest).start();


                                            }
                                        )
                                    }
                                },
                                function (error) {
                                    console.log("Login fail with error: " + error);
                                }
                            );
                        }
                    }
                    onLogoutFinished={() => console.log("logout.")} />
            </View>
        );
    }
};

Anoter que la section

LoginManager.logInWithPermissions(['public_profile', 'email']).then(
                                function (result) {
                                    if (result.isCancelled) {
                                        console.log("Login cancelled");
                                    } else {
                                        console.log(

la façon dont est géré la promesse ne permet pas de lire le bon mot clé this, donc si on passait une props, elle ne sera pas récupérable on aura un undefined, la bonne technique est:

LoginManager.logInWithPermissions(['public_profile', 'email']).then( (result) => {
if(!result){
    console.log("Login cancelled");
}
else {
// le code quand tout est bon
}

https://github.com/lakshmantgld/react-native-fbsdk-example

https://developers.facebook.com/docs/facebook-login/multiple-providers/

Voir aussi Intégrer Google SignIn

Retour en haut