MakeMake The Dwarf Planet is a feed agregator.

Sur Lyon − Meetup le 13 février

by grewn0uille from AFPy discuss

Hello tout le monde,

On se retrouve le jeudi 13 février à 19h où David nous parlera des difficultés rencontrées par les personnes qui débutent en Python !

Pour ce meetup, nous serons accueillis par OVHcloud (métro Garibaldi).

Père Castor 🐻, raconte-nous une histoire (de Python) 🐍

2025-02-13 19:00 (Europe/Paris) → 2025-02-13 21:30 (Europe/Paris)

1 message - 1 participant(e)

Lire le sujet en entier

Lire la suite…

Migration Hackinscience → Genepy

by mdk from AFPy discuss

Certains ont suivi de très près (le design est de Marie-Ange, qui a fait le design de la PyConFR 2023, l’intégration de @grewn0uille et @liZe), d’autres moins.

En tout cas ça y est la migration de https://hackinscience.org vers https://genepy.org est bien lancée !

Faites-moi remonter les bugs, je vois qu’il y a des gens (dans les logs), mais je ne vois pas trop si ça se passe bien pour eux :smiley:

J’ai crée :

je vais essayer d’y publier un peu la progression du projet.

Et ça serait cool de faire remonter l’équipe AFPy en 1ère place :smiley:

23 messages - 9 participant(e)s

Lire le sujet en entier

Lire la suite…

Première publication libre de Multigit

by Philippe F,bobble bubble,Benoît Sibaud from Linuxfr.org

Multigit est un outil graphique conçu pour simplifier la gestion de projets composés de beaucoup de dépôts git.

Une image et une vidéo valant mieux qu'un long discours, voici à quoi ça ressemble:

Screenshot

Je l'ai développé dans le cadre de mon travail chez IDEMIA où nous sommes souvent confrontés à plus de trente (voire plus de soixante) dépôts à gérer conjointement sur un projet. Dans ce contexte, la moindre opération git devient un mini-défi qu'il fallait relever quotidiennement.

Multigit est abouti et stable, il est utilisé au quotidien par plus d'une centaine de personnes (sous Windows), depuis plusieurs années. Mon employeur m'a aimablement autorisé à le publier en Open Source, ce dont je lui sais gré. Il est publié sous licence Apache 2.0

La problématique de gestion de plusieurs dépôts git conjoints pour un projet est assez peu répandue dans le monde du logiciel libre. Mais beaucoup plus dans le monde de l'entreprise. En effet, git ne gère pas la notion de droit d'accès à une partie d'un dépôt. La seule façon de restreindre l'accès à certains parties d'un projet est donc de créer un dépôt spécifique pour les y stocker, avec des droits d'accès au niveau du dépôt. Ajoutons à cela beaucoup de personnes, beaucoup de projets parfois complexes, beaucoup de sous-projets, beaucoup d'historique et on se retrouve avec une gestion des sources particulièrement complexe. Complexe … avant l'arrivée de Multigit en tout cas.

Installation

Sous Linux, la seule option d'installation disponible à l'heure actuelle est Python + pip, ou encore mieux avec pipx:

    $ sudo apt install python-pipx
    $ pipx install multigit_gx
    $ multigit

Sous Windows, un installeur graphique click-and-play vous permettra d'arriver au même résultat.

J'ai bien tenté de fournir un snap pour Linux mais snap est conçu pour empêcher à peu près tout ce que veut faire Multigit: accèder à tous vos fichiers et lancer des programmes de votre distribution (git, gitk, …)

Je ferai mieux dans la prochaine version. D'ailleurs, si vous avez des recommandations pour un packaging moderne, simple, facile à maintenir et couvrant toutes les distributions Linux, je suis preneur.

Contribution

Le projet est géré sous GitHub, les contributions ou les retours sont les bienvenus.

Télécharger ce contenu au format EPUB

Commentaires : voir le flux Atom ouvrir dans le navigateur

Lire la suite…

Demande pour que mon code python aille 1 million de fois plus vite car j'ai au moins 4 millions de f

by Lilie3887 from Linuxfr.org

Bonjour,
j'aurais besoin d'aide pour que le code ci-dessous aille beaucoup beaucoup plus vite, car j'ai plus de 4 millions de fichier à exécuter avec ce code et si je le laisse tel qu'il est j'en aurais pour au moins une à 2 semaines d'exécution. Alors que je dois l'utiliser toutes les semaines. Le code fais une recherchev par rapport à mon 1er tableau et met les valeurs dans mes fichiers, fais la somme de ma recherchev, supprime les valeurs de ma recherchev et place la ligne ou il y a la somme où il doit être placé.
Ensuite il fait la même chose pour un 2ème tableau et idem pour un 3ème tableau, et pour un 4ème tableau, ça va jusqu'à 10 tableau.
S'il vous plaît, c'est complexe pour moi donc si vous pouvez m'aider. Voici le code:
import os

|| || || |import pandas as pd| |from openpyxl import load_workbook| || |# ???? Définition des chemins| |dossier_source = "D:/PYTHON/VALEUR REMPLACER ZIP"| |fichier_rebase = "D:/PYTHON/REBASE.xlsx"| || |# ???? Chargement des valeurs de REBASE.xlsx| |wb_rebase = load_workbook(fichier_rebase, data_only=True)| |ws_rebase = wb_rebase.active| || |# ???? Extraction des valeurs des Tableaux 1 (A:B), 2 (D:E), 3 (G:H) et 4 (J:K)| |tableau_1 = pd.DataFrame(ws_rebase.iter_rows(min_row=1, max_row=273, min_col=1, max_col=2, values_only=True), columns=["Clé", "Valeur"])| |tableau_2 = pd.DataFrame(ws_rebase.iter_rows(min_row=1, max_row=273, min_col=4, max_col=5, values_only=True), columns=["Clé", "Valeur"])| |tableau_3 = pd.DataFrame(ws_rebase.iter_rows(min_row=1, max_row=273, min_col=7, max_col=8, values_only=True), columns=["Clé", "Valeur"])| |tableau_4 = pd.DataFrame(ws_rebase.iter_rows(min_row=1, max_row=273, min_col=10, max_col=11, values_only=True), columns=["Clé", "Valeur"])| || |# ???? Traitement des fichiers dans le dossier source| |for fichier in os.listdir(dossier_source):| |if fichier.endswith(".xlsx"):| |chemin_fichier = os.path.join(dossier_source, fichier)| || |# ???? Charger le fichier Excel| |wb = load_workbook(chemin_fichier)| |ws = wb.active| || |# ???? Identifier la dernière ligne contenant des données (entre 1 et 19)| |last_data_row = max([i for i in range(1, 20) if any(ws.cell(row=i, column=j).value for j in range(2, ws.max_column + 1))], default=1)| || |### ✅ Étape 1 : Remplacement avec le Tableau 1 (A:B)| |ligne_depart = 21| |if any(ws.cell(row=21, column=j).value for j in range(2, ws.max_column + 1)):| |ligne_depart = max([i for i in range(21, ws.max_row + 1) if any(ws.cell(row=i, column=j).value for j in range(2, ws.max_column + 1))], default=20) + 2 | || |ligne_debut_bloc_1 = ligne_depart| || |# ???? Ajout des valeurs du Tableau 1| |for col in range(2, ws.max_column + 1):| |for row in range(1, last_data_row + 1):| |valeur_originale = ws.cell(row=row, column=col).value| |if valeur_originale:| |valeur_remplacee = tableau_1.loc[tableau_1["Clé"] == valeur_originale, "Valeur"]| |if not valeur_remplacee.empty:| |ws.cell(row=ligne_depart + row - 1, column=col, value=valeur_remplacee.values[0])| || |# ???? Calcul de la somme du Tableau 1| |ligne_somme_1 = ligne_depart + last_data_row + 1| |somme_bloc_1 = [sum(ws.cell(row=row, column=col).value or 0 for row in range(ligne_debut_bloc_1, ligne_somme_1) if isinstance(ws.cell(row=row, column=col).value, (int, float))) for col in range(2, ws.max_column + 1)]| || |# ???? Suppression du bloc 1 et insertion des sommes à la ligne 21| |for row in range(ligne_debut_bloc_1, ligne_somme_1):| |for col in range(2, ws.max_column + 1):| |ws.cell(row=row, column=col, value=None)| |ws.delete_rows(ligne_debut_bloc_1, ligne_somme_1 - ligne_debut_bloc_1)| |ws.insert_rows(21)| |for col_idx, somme in enumerate(somme_bloc_1, start=2):| |ws.cell(row=21, column=col_idx, value=somme)| || |### ✅ Étape 4 : Remplacement avec le Tableau 4 (J:K)| |ligne_depart = max([i for i in range(21, ws.max_row + 1) if any(ws.cell(row=i, column=j).value for j in range(2, ws.max_column + 1))], default=20) + 2 | |ligne_debut_bloc_4 = ligne_depart| || |# ???? Ajout des valeurs du Tableau 4| |for col in range(2, ws.max_column + 1):| |for row in range(1, last_data_row + 1):| |valeur_originale = ws.cell(row=row, column=col).value| |if valeur_originale:| |valeur_remplacee = tableau_4.loc[tableau_4["Clé"] == valeur_originale, "Valeur"]| |if not valeur_remplacee.empty:| |ws.cell(row=ligne_depart + row - 1, column=col, value=valeur_remplacee.values[0])| || |# ???? Calcul de la somme du Tableau 4| |ligne_somme_4 = ligne_depart + last_data_row + 1| |somme_bloc_4 = [sum(ws.cell(row=row, column=col).value or 0 for row in range(ligne_debut_bloc_4, ligne_somme_4) if isinstance(ws.cell(row=row, column=col).value, (int, float))) for col in range(2, ws.max_column + 1)]| || |# ???? Suppression du bloc 4 et insertion des sommes à la ligne 24| |for row in range(ligne_debut_bloc_4, ligne_somme_4):| |for col in range(2, ws.max_column + 1):| |ws.cell(row=row, column=col, value=None)| |ws.delete_rows(ligne_debut_bloc_4, ligne_somme_4 - ligne_debut_bloc_4)| |ws.insert_rows(24)| |for col_idx, somme in enumerate(somme_bloc_4, start=2):| |ws.cell(row=24, column=col_idx, value=somme)| || |wb.save(chemin_fichier)| |print(f"✅ {fichier} mis à jour avec succès.")| || |print("✔ Tous les fichiers ont été traités correctement.")|

Télécharger ce contenu au format EPUB

Commentaires : voir le flux Atom ouvrir dans le navigateur

Lire la suite…

Inline C dans une fonction Python

by mdk from AFPy discuss

Parce que, je voulais voir où ça mènerai, bah ça mène là (pour Linux uniquement) :

import shlex
import tempfile
from ctypes import CDLL, py_object
from functools import wraps
from inspect import signature
from subprocess import PIPE, run


def compile(c_str) -> CDLL:
    with tempfile.TemporaryDirectory() as tmpdir:
        with open(f"{tmpdir}/tmp.c", "w", encoding="UTF-8") as f:
            f.write(c_str)
        flags = shlex.split(run(["python3-config", "--cflags", "--ldflags"], encoding="UTF-8", stdout=PIPE).stdout)
        run(["cc", "-shared", "-fPIC", "-xc"] + flags + [f"-o{tmpdir}/tmp.so", f"{tmpdir}/tmp.c"], check=True)
        return CDLL(f"{tmpdir}/tmp.so")


def c(fct):
    parameters = signature(fct).parameters
    c_args = ", ".join([f"PyObject *{name}" for name in parameters.keys()])
    lib = compile(FR"""
#include <stdio.h>
#include <Python.h>

PyObject *the_function({c_args}) {{
    {fct.__doc__}
}}
""")
    lib.the_function.argtypes = [py_object] * len(parameters)
    lib.the_function.restype = py_object
    @wraps(fct)
    def call_c(*args):
        return lib.the_function(*args)
    return call_c


@c
def cprint(pyobject):
    r"""
    Py_ssize_t size;
    const char *str;

    PyGILState_STATE state = PyGILState_Ensure();
    if (PyUnicode_CheckExact(pyobject)) {
        str = PyUnicode_AsUTF8AndSize(pyobject, &size);
        write(1, str, size);
        write(1, "\n", 1);
    }
    else {
        PyObject *repr = PyObject_Repr(pyobject);
        printf("%s\n", PyUnicode_AsUTF8(repr));
    }
    PyGILState_Release(state);
    return Py_None;
    """


@c
def fib(n):
    """
    long m = PyLong_AsLong(n);
    long a = 1;
    long b = 1;

    PyGILState_STATE state = PyGILState_Ensure();
    for (int i = 0; i < m; i++) {
        b = a + b;
        a = b - a;
    }
    n = PyLong_FromLong(a);
    PyGILState_Release(state);
    return n;
    """


def main():
    cprint([fib(i) for i in range(40)])


if __name__ == "__main__":
    main()

Bon ça marche, ça m’amuse, c’est tout.

OK pour ceux qui veulent vraiment parler perfs, même si c’était pas mon but (promis) :

$ pyperf timeit -s 'import inline_c' 'inline_c.py_fib(40)'
.....................
Mean +- std dev: 993 ns +- 70 ns

$ pyperf timeit -s 'import inline_c' 'inline_c.c_fib(40)'
.....................
Mean +- std dev: 257 ns +- 6 ns

mais on perd la magie des int de Python, très vite le long ne suffira pas a contenir le résultat de fib, les deux implèms ne sont donc pas comparables, l’une est rapide, l’autre est juste, meh, arrêtons de parler perfs.

Qui pour implémenter @asm ?

1 message - 1 participant(e)

Lire le sujet en entier

Lire la suite…

wrapper python pour une lib en C

by Mindiell from AFPy discuss

Bonjour ici,

j’ai un petit souci avec une lib en C que j’ai produite avec une seule fonction.

Le code C de toto.c :

#include <stdio.h>

char * titi(void) {
	return "Hello world!";
}

qui donne toto.so.

Le wrapper python toto.py :

from ctypes import CDLL, c_char_p

# Load the shared library
toto = CDLL("./toto.so")
toto.titi.restype = c_char_p

Et le code de test test_toto.py :

import toto

print(toto.titi())

Voilà, un truc assez basique, j’ai jeté un oeil à pas mal de tutos, et j’obtiens toujours la même erreur quand j’utilise le dernier script :

Traceback (most recent call last):
  File "test_toto.py", line 1, in <module>
    import toto
ImportError: dynamic module does not define module export function (PyInit_toto)

Si j’exécute la fonction titi depuis le fichier toto.py, elle est bien appelée sans souci. Mais il semble que je ne puisse pas l’appeler depuis un import.

Sur les internets ça parle de version de compilateur,… Si vous avez une idée, je suis preneur !

4 messages - 3 participant(e)s

Lire le sujet en entier

Lire la suite…

Bonne année 2025 !

by grewn0uille from AFPy discuss

Bonjour tout le monde,

L’AFPy vous souhaite une bonne année 2025 et vous présente ses meilleurs vœux pour cette nouvelle année !

En ce début d’année, nous avons lancé notre campagne d’adhésions 2025 sur HelloAsso : https://www.helloasso.com/associations/afpy/adhesions/adhesion-2025-a-l-afpy :sparkles:

Être membre de l’AFPy vous permet de prendre part à la vie de l’association en votant lors de l’Assemblée Générale et vous permettez à l’APFy de financer ses frais de fonctionnement, d’engager les dépenses pour l’organisation de la PyConFR et d’assurer la promotion du langage Python en francophonie :snake:

Concernant les vidéos de la PyConFR 2024, une bonne partie est disponible sur IndyMotion : PyConFR2024 - IndyMotion
D’autres nécessitent plus de travail et sont encore en cours de traitement. Elles arriveront au fur et à mesure !

Pour ne manquer aucune nouvelle sur l’AFPy, les meetups locaux et la PyConFR, vous pouvez nous suivre sur nos différents réseaux (AFPy (@AFPy@mamot.fr) - Mamot - Le Mastodon de La Quadrature du Net et Association Francophone Python (AFPy) | LinkedIn), participer sur le forum (https://discuss.afpy.org/) ou le salon Discord (AFPy) :blush:

Merci pour votre soutien :sparkling_heart:


L’équipe de l’AFPy (Association Francophone Python)

3 messages - 2 participant(e)s

Lire le sujet en entier

Lire la suite…

Bras robotisé MKX3D

by phroy from AFPy discuss

Bonjour à tous, je vous présente le bras robotisé MKX3D open source.

  • Il est réellement open source en effet les fichiers CAO (SolidWorks) sont sous CC BY-NC-SA et l’interface de prog en GNU GPL.
  • Il est programmable en Python.
  • Le bras est complétement imprimable son coût est autour des 400 € (l’équivalent dans le commerce est à 4000 € et bien évidement en closed)
  • La plateforme de dev est Blender/UPBGE + Python + Arduino

Le dépôt est sur la Forge (gitlab de l’Education Nationale) : Bras MKX3D / Jumeau numérique · GitLab

Une présentation plus longue (20 min) est ici : Bras MKX3D : Présentation longue - Sciences & Technologies

1 message - 1 participant(e)

Lire le sujet en entier

Lire la suite…