f"{self.label}" utilise le mécanisme d’interpolation de chaînes de caractères de Python qui peut être légèrement plus rapide parce qu’il est optimisé pour concaténer des littéraux de chaîne et des variables ;
str(self.label) appelle explicitement le constructeur de la classe str, ce est un peu plus lent en raison de l’appel de fonction.
Numpy et Pandas n’ont pas exactement les mêmes objectifs.
Dans la plupart des cas, NumPy peut être légèrement plus rapide que pandas, car NumPy est plus bas niveau et a moins de surcharge. Cependant, pandas offre des structures de données et des fonctionnalités plus avancées, ce qui peut faciliter le travail avec des ensembles de données complexes. Les performances relatives de NumPy et pandas dépendent également des opérations spécifiques effectuées sur les données, de sorte que les différences de performances peuvent varier en fonction des tâches spécifiques. Certaines fonctions n’existent qu’avec pandas, et qui n’ont pas d’équivalents NumPy sont : read_csv, read_excel, groupby, pivot_table, merge, concat, melt, crosstab, cut, qcut, get_dummies et applymap.
Résultats
Résultat : image générée : notez bien que j’ai appelé des fonctions « bas niveau » pour qu’on voie ce que NumPy a dans le ventre et des fonctions qui n’existent que dans pandas, que ré-implémentées en Python pur + NumPy.
Code source
Voici le code source que j’ai fait, qui appelle quelques fonctions connues de NumPy et de pandas.
Il faut aller chercher le code source qui vous intéresse.
Exemple, faire tourner un « vieux » Python 3.6, aller dans les versions ici et prendre celle qui nous intéresse.
Puis récupérer le code source et le compiler :
mkdir ~/source ; cd ~/source
wget https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tar.xz
tar xvf Python-3.6.13.tar.xz
cd ~/source/Python-3.6.13
./configure && make
sudo make altinstall
Et voilà :
~/source/Python-3.6.13$ python3.6
Python 3.6.13 (default, May 21 2021, 17:12:12)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Deux exemples très courts pour vous mettre sur les rails, qui envoient et reçoivent du binaire « pur » = très peu de bande passante, avec une connexion persistante.
Je vous donne deux envois-réception qui devraient vous permettre de faire tous vos envois binaires :
C# : le client envoie un octet, qui correspond à un booléen, pour dire s’il est en big ou little endian ;
C# : le client envoie un message encodé en UTF-8 (oui j’ai trouve la solution qui fonctionne !) ;
Python : le serveur lit ce booléen ;
Python : le serveur lit le message et le dit à voix haute (sous Windows) ;
Python : le serveur envoie un entier non signé, puis deux float ;
C# : le client lit l’entier non signé puis deux floats.
Avec ça, vous avez de quoi comprendre et faire tous les échanges que vous voulez !
using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;
public class Connexion : MonoBehaviour
{
public string server;
public string message;
public ushort port;
private void Start()
{
// working sample to send text:
byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
byte isLittleEndian = BitConverter.IsLittleEndian ? (byte)1 : (byte)0;
TcpClient client = new TcpClient(server, port);
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.WriteByte(isLittleEndian);
stream.Write(data, 0, data.Length);
Debug.Log($"Sent: {message}");
// read sample
BinaryReader reader = new BinaryReader(stream);
uint len = reader.ReadUInt16();
var x = reader.ReadSingle();
var y = reader.ReadSingle();
Debug.Log("len=" + len);
Debug.Log($"x={x}, y={y}");
}
}
Pour la note, ces deux exemples paraissent simples, mais ils m’ont pris un temps fou, et je n’ai eu aucune réponse au bout de 3 semaines sur stackoverflow…
Pourquoi cela ? Explication : l’opposé de EAFP, c’est LBYL.
EAFP : Easier to ask for forgiveness than permission
Plus facile de demander pardon que la permission. Ce style de codage très utilisé en Python suppose l’existence de clés ou d’attributs valides et intercepte les exceptions si l’hypothèse s’avère fausse. Ce style propre et rapide se caractérise par la présence de nombreuses déclarations try and except. La technique contraste avec le style LBYL commun à de nombreux autres langages tels que C.
LBYL : Look before you leap
Réfléchir avant d’agir.
Ce style de codage teste explicitement les conditions préalables avant d’effectuer des appels ou des recherches. Ce style contraste avec l’approche EAFP et se caractérise par la présence de nombreuses déclarations if.
Dans un environnement multi-thread, l’approche LBYL peut risquer d’introduire une condition de concurrence entre « la vérification » et « la validation ». Par exemple, le code : if key in mapping: return mapping [key] peut échouer si un autre thread supprime la clé du mappage après le test, mais avant la recherche. Ce problème peut être résolu avec des verrous ou en utilisant l’approche EAFP.
Lorsque vous voulez faire des pages d’erreur sur mesure, c’est très simple… une fois que vous savez !
En effet, la documentation n’est pas très claire…
Voici un résumé de mon expérience, pour faire des pages d’erreur sur mesure (404, 500, etc.).
Il faut d’abord savoir que les erreurs sont des fonctions appelées (= vous ne pouvez pas le faire via les vues génériques).
Ensuite, la documentation donne un exemple, mais ce n’est pas assez.
Grâce aux raccourcis de Django, vous avez la fonction render() à laquelle vous pouvez passer un template et un contexte (= donc des variables).
Je me suis servi de cela pour créer un dictionnaire qui contient les erreurs, et les passer dans dans le contexte avec la clé title et content.
Voici le code des vues qui affiche une erreur « proprement » :
Une fois les vues faites, il faut aller dans la déclaration principale de vos vues. Donc le fichier urls.py qui est la racine de votre projet. Si vous mettez le code ailleurs, il sera ignoré.
Dedans, déclarez vos fonctions qui gèrent les erreurs :
Et enfin, dans vos templates, créez un fichier errors.html dans lequel vous pouvez construire votre page HTML qui gère l’erreur « proprement », avec, en plus dans le contexte, les variables {{ title }} et {{ content }} qui affichent respectivement le titre et le détail de l’erreur.
Maintenant, comment, en mode « développement », tester ces pages ? Dans la pratique vous ne pouvez pas, car en mode développement, une erreur affiche les informations de déboguage, et pas vos pages !
La solution : faire une URL qui « simule » l’erreur. Exemple avec 404 : vous ajouter dans vos urls : path('404/', error_404_view_handler), et puis d’afficher votre URL adéquate, soit http://localhost:8000/404/ et vous verrez l’erreur !
Comment faire simplement une interface d’administration pour le projet entier
Sur les versions de Django < 2.1, il était impossible de surcharger « correctement » l’administration.
Créez un fichier admin.py à la racine de votre projet (« à la racine », parce qu’il est « global » à tout le projet)
Mettez-y ce code: from django.contrib import admin
class MyProjectAdminSite(admin.AdminSite):
title_header = 'My project Admin'
site_header = 'My project administration'
Bien sûr, changez « MyProject » par le nom de votre projet…
Dans settings.py, remplacez 'django.contrib.admin' par 'my_app.apps.MyAppAdminConfig',
Dans le fichier apps.py de votre projet, soit my_project/my_app/apps.py, déclarez l’administration comme suit :
from django.apps import AppConfig
from django.contrib.admin.apps import AdminConfig
class MyAppConfig(AppConfig):
name = 'my_app'
class MyAppAdminConfig(AdminConfig):
default_site = 'admin.MyProjectAdminSite'
Vidéo sur les expressions régulières en Python : liste Youtube de 15+ videos, de débutant jusqu’à niveau avancé (regardez la playlist sur la droite pour voir les 15) !