Overblog
Suivre ce blog Administration + Créer mon blog
Articles récents

Créer une usine à résumer des fichiers pdf en Python avec openai

27 Janvier 2023 , Rédigé par Hugues MEUNIER Publié dans #IA

Comme chacun le sait, Openai fournit des moteurs d'IA parmi les plus avancés du monde. Les capacités de ces IA sont nombreuses. Je trouve impressionnante la capacité de réaliser des résumés à partir de texte.

Ici j'ai fait un petit programme en python qui va chercher un fichier pdf à partir d'une url, qui stocke le fichier en local, qui lit le fichier et demande un résumé de chaque page.

Dans l'exemple, j'utilise le document 

http://www.tsu.edu/academics/colleges-and-schools/jesse-h-jones-school-of-business/pdf/fin-financial-statement-analysis.pdf

qui parle d'analyse financière (en anglais). Je vous laisse lire le document.

Le résumé créé par DaVinci est :

"Financial analysis involves the examination of both financial statements and financial
ratios to assess a firm's performance and make investment decisions. The common methods
of benchmarking include trend analysis and common-size statements. Financial ratios are
used to compare a company over time and with competitors; these include liquidity ratios,
leverage ratios, asset management ratios, profitability ratios, and market value ratios. The
Du Pont Analysis is also a valuable tool in understanding return on equity.

Profitability ratios measure a firm's effectiveness in turning sales or assets into profits. Market value ratios are used to gauge how attractive a firm's current price is relative to its earnings, growth rate, and book value. The DuPont analysis involves breaking down returns on equity into three components. Liquidity ratios show a company's short-term cash obligations and solvency ratios demonstrate the ability to meet debt obligations for extended periods of time. The most important ratio for 
a banker considering a debt loan would be the times interest earned.

Asset management ratios are used to evaluate how management is using assets to generate profits. The P/E ratio is a measure of growth, with higher P/E ratios indicating growth firms. The DuPont identity analyzes return on equity. Comparing a company to others in different industries can show what areas the company and its industry are falling behind in.
 The current ratio is a measure of a business's ability to meet its current liabilities with its current assets. It is calculated by dividing current assets by current liabilities. A higher current ratio is usually better, but may also indicate idle or underutilized resources in the company. The quick ratio is a stricter measure of 
liquidity and is most useful when the proportion of illiquid current assets to total current assets is high. It is calculated by taking the sum of cash, marketable securities, and receivables, and then dividing it by current liabilities. Another approach involves subtracting all illiquid current assets from total current assets and 
dividing the result by total current liabilities.
 Quick ratio is useful for assessing liquidity in times of distress and is best used in relation to other ratios like the current ratio and cash ratio. The debt ratio 
is used to measure a business's financial risk, and the times interest earned ratio determines a company's ability to pay off interest expenses with available earnings.
 Debt ratio measures total debt exposure relative to total assets, and Times Interest Earned (TIE) ratio assesses if the company is earning enough to pay off the associated interest expense. Net Profit Margin measures the percentage of net income of the entity to net sales, and Return on Equity (ROE) ratio is a measure of profitability of stockholders' investments. Earnings per Share (EPS) is an indicator of the dollars of net income earned by the company per share of its common stock.
 Earnings Per Share (EPS) and Price/Earnings (P/E) Ratio measure the value of a company's share price to its earnings. The Dividend Payout Ratio tells investors whether a company is reinvesting earned profits or distributing dividends. The Inventory Turnover Ratio tells if a business is efficiently managing its inventories.
 Inventory Turnover Ratio measures how quickly a business is able to sell its inventory. Days' Sales Outstanding (DSO) Ratio measures the average number of days it takes for a business to collect its credit sales. Total Assets Turnover Ratio measures how successfully a company is utilizing its assets in generating revenue."

L'exemple de code est :

 

import openai
import wget
import pathlib
import pdfplumber
import numpy as np
 
def getDocument(paper_url, filename="random_paper.pdf"):
    """
    Telecharger un document et le stocker en local
    """
    downloadedPaper = wget.download(paper_url, filename)    
    downloadedPaperFilePath = pathlib.Path(downloadedPaper)
 
    return downloadedPaperFilePath
 
def CreeResume(paperContent):
    tldr_tag = "\n tl;dr:"
    openai.organization = "org-dFD5cXv0LtW9kQ5smiaXQKse"
    openai.api_key = "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"
    engine_list = openai.Engine.list()
   
    for page in paperContent:    
        text = page.extract_text() + tldr_tag
        ptext = text
        response = openai.Completion.create(model="text-davinci-003",prompt=ptext,temperature=1,
            max_tokens=1024,
            top_p=1,
            frequency_penalty=0,
            presence_penalty=0
        )
        print(response["choices"][0]["text"])
 
paperFilePath = getDocument("http://www.tsu.edu/academics/colleges-and-schools/jesse-h-jones-school-of-business/pdf/fin-financial-statement-analysis.pdf")
paperContent = pdfplumber.open(paperFilePath).pages
CreeResume(paperContent)
Lire la suite

Ajouter un header à un ensemble de fichier fits avec le module astropy

23 Décembre 2022 , Rédigé par Hugues MEUNIER Publié dans #Astronomie

SI vous devez ajouter ou modifier un header dans un fichier fits, procédez comme suit (ici j'ajoute le header FILTER = 'NA') :

import os
from astropy.io import fits
 
# Définissez le chemin du répertoire contenant les fichiers FITS
directory_path = 'C:/VotreRepertoire'
 
# Obtenez la liste de tous les fichiers FITS dans le répertoire
fits_files = [f for f in os.listdir(directory_path) if f.endswith('.fit')]
 
# Pour chaque fichier FITS dans la liste
for fits_file in fits_files:
    # Ouvrez le fichier FITS
    hdulist = fits.open(os.path.join(directory_path, fits_file), mode='update')
    # Récupérez le header du premier segment du fichier
    header = hdulist[0].header
    # Ajoutez l'en-tête "FILTER='na'"
    header['FILTER'] = 'NA'
    # Enregistrez les modifications
    hdulist.flush()
    # Fermez le fichier FITS
    hdulist.close()
Lire la suite

Solutions de sécurisation de Microsoft Teams

13 Juillet 2022 , Rédigé par Hugues MEUNIER Publié dans #Microsoft

Analyse des solutions de sécurisation de Microsoft Teams

Un article de fond sur la sécurité de Microsoft Teams avec des solutions basées sur les outils Azure et M365.

 

 

Lire la suite

Plein d'annonces à la conference build 2022 de Microsoft

27 Mai 2022 , Rédigé par Hugues MEUNIER Publié dans #Microsoft

Beaucoup d'annonces à cette conférence. Microsoft les synthétise dans le book of news :

https://news.microsoft.com/build-2022-book-of-news/fr/

J'ai noté beaucoup de nouvelles sur l'intelligence artificielle et notamment l'intelligence artificielle responsable avec la mise à disposition de OpenAI et de Azure Cognitive services for language avec notamment des capacités d'analyse syntaxique supplémentaire (résumé automatique, analyse de texte...)

Sur le workplace, Teams va pouvoir partager des applications (live sharing) donc nous allons pouvoir collaborer directement sur nos applications avec la mise à disposition d'un sdk Teams qui permet d'incorporer directement Teams dans nos applications.

Microsoft accélère aussi sur l'ouverture du service d'exécution des applications Android sur Windows 11.

Le métaverse est à l'honneur avec une collaboration forte avec Meta sur le sujet.

Sur Azure, j'ai noté la mise à disposition d'Azure Spring Apps pour les applications Spring, résultat d'une collaboration Ms et Vmware.

Azure Synapse Analytics est un outil puissant d'analyse du big data.

Pas mal de nouveautés sont annoncées sur Azure ARC et le pilotage des environnements multi-cloud hybrides.

 

 

Lire la suite

Voilà mon premier programme python qui s'exécute sur un ordinateur quantique IBM

23 Novembre 2020 , Rédigé par Hugues MEUNIER

Enfin c'est un simulateur mais on peut changer qasm_simulator par un vrai ordinateur quantique (ibmq_ourense par exemple) et le programme fonctionne également.

Avant de tenter l'exécution dans Jupyter, il faut créer son compte sur quantum-computing.ibm.com (c'est gratuit) et générer sa clé qu'il faut déclarer dans qiskit.

 

Donc le programme ne fait pas grand chose mais c'est la base du calcul en informatique quantique, le Hello World quantique en quelque sorte :

- déclaration des librairies

- déclaration d'un qbit

- déclaration d'un bit classique pour stocker les résultats

- Mise à l'état 0 du Qbit au démarrage

- application d'une porte de Hadamard

- mesure et copie de la valeur de le bit classique

- affichage des 1000 résultats

- représentation graphique des résultats

 

%matplotlib inline
# Importing standard Qiskit libraries and configuring account
from qiskit import QuantumCircuit, execute, Aer, IBMQ
from qiskit.compiler import transpile, assemble
from qiskit.tools.jupyter import *
from qiskit.visualization import *
# Loading your IBM Q account(s)
provider = IBMQ.load_account()

circuit = QuantumCircuit(1, 1)

circuit.h(0)
circuit.measure([0], [0])

simulator = Aer.get_backend('qasm_simulator')
job = execute(circuit, simulator, shots=1000)
result = job.result()
counts = result.get_counts(circuit)
print("\nTotal count for 0 and 1 are:",counts)

circuit.draw()

plot_histogram(counts)

Lire la suite

Une découverte très importante en physique

27 Octobre 2020 , Rédigé par Hugues MEUNIER

Selon la théorie de la relativité d'Einstein, le temps s'écoule différemment et est fonction de la vitesse de l'objet considéré.

Un objet quantique a des états superposés avec des vitesses différentes donc le temps peut s'écouler différemment dans les états superposés!

C'est très simple mais personne n'y avait pensé avant et cette découverte va permettre de faire avancer la théorie de la gravitation quantique qui pédalait un peu dans le vide depuis quelques mois.

 

Lire la suite

Premiers pas avec l'informatique quantique, Azure Quantum et Q#

9 Juin 2020 , Rédigé par Hugues MEUNIER

Microsoft a publié, il y a quelques temps, un SDK  pour exécuter/simuler un ordinateur quantique. Ce SDK manipule des qbits, des états superposés et des mesures de propriétés.

SI vous ne connaissez rien à la physique quantique, c'est peut être mieux de suivre ce cours qui est abordable sans bagage mathématique : Quantum mechanics for everyone .

Un qbit est l'élément constituant d'un ordinateur quantique. Lorsqu'il est dans l'état superposé (avant la mesure), la propriété peut prendre la valeur 0 ou 1 (50% de chance d'obtenir 1 et 50% de chances d'obtenir 0).

Si je veux écrire une fonction qui retourne un nombre aléatoire, j'écris une fonction pour obtenir l'état superposé de la propriété. En Q# cela donne :

namespace Qrng {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Measurement;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;
    

   //operation qui retourne l'état d'un qbit
    operation SampleQuantumRandomNumberGenerator() : Result {
        using (q = Qubit())  {  // Alloue un qubit.
            H(q);               // Positionne le qbit dans les états superposés. Il y a donc 50% de probabilité pour |0> et 50% pour |1>. Cette fonction H est une porte de Hadamard!
            return MResetZ(q);  // On réalise la mesure.
        }
    }

//Operation qui retourne un nombre aleatoire

operation SampleRandomNumberInRange(max : Int) : Int {
    mutable bits = new Result[0];
    for (idxBit in 1..BitSizeI(max)) {
        set bits += [SampleQuantumRandomNumberGenerator()];
    }
    let sample = ResultArrayAsInt(bits);
    return sample > max
           ? SampleRandomNumberInRange(max)
           | sample;
}

//Point d'entrée de programme quantique

@EntryPoint()
operation SampleRandomNumber() : Int {
    let max = 50;
    Message($"Sampling a random number between 0 and {max}: ");
    return SampleRandomNumberInRange(max);
}

}

Tout ceci peut être consulté sur le site de Microsoft et testé sur Azure Quantum !

https://docs.microsoft.com/en-us/quantum/

N'hésitez pas aussi à vous plonger dans la physique quantique qui est une merveilleuse théorie jamais mise à défaut pour le moment et à son formalisme mathématique qui vaut le détour (la Ket et Bra notation). 

 

Lire la suite

Modèle probabiliste de propagation d'un épidémie : impact du confinement déconfinement

12 Mai 2020 , Rédigé par Hugues MEUNIER

Le confinement est une excellente mesure pour contrer une épidémie car il permet de limiter les contacts donc les contagions de l'épidémie.

Les simulations ci-dessous ont été générées avec un programme Python qui simule la propagation d'une épidémie via un algorithme de type "jeu de la vie". Les règles de ce "jeu" sont les suivantes :

- population initiale : 10 000 personnes

- cas infectés initiaux : 5 personnes

- taux de décès : 0,005

- durée de la simulation : 200 jours

- la durée d'infection est de 24 jours

- la maladie est létale entre le 10ème jours et le 24 ème

- l'immunité est acquise pour tous les jours restants après le 24ème d'infection.

- trois phases sont définies : la phase 1 de 40 jours qui correspond à la phase de contagion initiale, la phase 2 de confinement qui dure 57 jours et la phase de déconfinement qui dure jusqu'au 200ème jour.

 

1er cas: pas de confinement, une forte épidémie de 200 jours

Sur la simulation, on obtient environ 500 décès soit 5% de la population ce qui est très important (ramené à 67 millions cela ferait plus de 3 millions de décès. On obtient une courbe typique du modèle SIR en cloche mais au bout de 200 jours, nous ne sommes pas encore passés dans la partie décroissante et nous stagnons dans une partie plate.

2ème cas : confinement du 41ème jour à la fin de la simulation (200 jours)

La simulation comprend 2 phases :

- une phase initiale de propagation rapide pendant 40 jours

- et 160 jours de confinement pour ralentir la propagation avec un taux de contagion trois fois plus faible

Sur la simulation, on obtient environ 50 décès soit 0,5% de la population. On obtient une courbe typique du modèle SIR amorti et la propagation du virus s'éteint progressivement compte tenu du manque de contact.

3ème cas : phase initiale de propagation de 40 jours puis confinement de 57 jourspuis déconfinement du 98ème jour à la fin de la simulation (200 jours)

 

On obtiendrait donc un nombre de décès plus important que le cas précédent (2 à 3 fois plus de décès soit un taux de 1 à 1,5%). La dynamique est intéressante car on voit bien l'impact du confinement sur la courbe des cas infectés et le rebond (la "deuxième vague") dû au déconfinement au bout de 97 jours.

Conclusion:

Un confinement est une solution efficace de lutte contre les épidémies car il permet de faire baisser drastiquement le taux de contagion. Un modèle simple du type "jeu de la vie" permet de le démontrer. Un déconfinement entraîne toujours une augmentation du taux de contagion (car les contacts sont plus nombreux). Les modèles montrent que ce déconfinement entraîne une relance de l'épidémie du type de la "deuxième vague". 

Lire la suite

Installation et utilisation de Cryptomator sous Windows 10

5 Mai 2020 , Rédigé par Hugues MEUNIER

Créer un coffre-fort dans Onedrive (ou Dropbox ou autre chemin accessible depuis un poste W10)

 

Introduction

 

Cryptomator est un outil entièrement Opensource et gratuit qui permet de créer des coffres-forts sécurisés en local ou sur des dossiers Cloud. Il est disponible pour Windows 10, MACOS ou linux.

 

Installation

 

Télécharger le programme d’installation ici : www.cryptomator.org/downloads/

 

Valider les clauses de la licence.

 

Sélectionner l’emplacement de l’installation.

 

Sélectionner les composants à installer.

 

Attendre la fin de la copie…

 

Cliquer sur NEXT pour installer la librairie Dokan.

 

Sélectionner les composants à installer (laisser par défaut)

 

Cliquer sur « Install ».

 

Attendre la fin de la copie.

 

Cliquer 2 fois sur « Finish » pour fermer les boîtes de dialogue et ouvrir Cryptmator.

 

 

Ajouter un coffre dans OneDrive pour stocker vos documents sensibles

 

 

 

Le mot de passe (la clé) saisi devra être stockée dans un endroit sécurisé (Keepass ou autre).

 

Continuer en affichant  la clé de récupération et cliquer sur suivant. Pensez à stocker votre clé de récupération dans un autre coffre (Keepass ou Digiposte).

 

Déverrouiller le coffre

 

 

Affichage d’un lecteur D : dans l’explorateur qui contient les fichiers protégés. Vous pouvez l’utiliser comme n’importe quel dossier.

 

Cette vue est une vue logicielle affichée par l’outil Cryptomator. La vue physique dans Onedrive contient un ensemble de fichiers chiffrés et ne peut pas être exploitée sans avoir la clé ou la clé de secours.

 

 

 

Lire la suite

Jeu de la vie épidémique en Python

4 Mai 2020 , Rédigé par Hugues MEUNIER

Les algorithmes du type "jeu de la vie" sont utilisés depuis bien longtemps dans de nombreux domaines. Ils permettent également de simuler la propagation d'un virus dans une population donnée et ils offrent des effets visuels intéressants au niveau de la représentation graphique des résultats. Ils permettent de rendre compte de l'évolution d'un modèle SIR(M) probabilistes.

Le programme ci-dessous a été construit avec les hypothèses suivantes :

- l'immunité acquise ou initiale est permanente

- une personne infectée infecte ses "voisins" avec un taux de contagion probaContag

- la maladie est létale à partir du 8ème jour avec une probabilité de décès de probaDec

- les états possibles sont Sains, Infectés, Immunisés (Remis) ou Morts

Si j'exécute le programme avec les paramètres suivants :

- probaContag = 0.055

- probaDec = 0,005

- NbJours infection = 14

j'obtiens ce genre de simulation (la couleur représente l'état : blanc=sain, rouge=infecté, vert=immunisé, noir=décédé).

Simulation vidéo 1

et la dynamique du modèle est la suivante (l'échelle est logarithmique!) :

 

Cette simulation représente une épidémie très contagieuse; elle se propage très vite et la totalité de la population considérée devient soit immunisée ou soit décédée au bout de 120 jours.

 

Maintenant si j'exécute le programme avec les paramètres suivants :

- probaContag = 0.015

- probaDec = 0,005

- NbJours infection = 14

j'obtiens la simulation suivante:

Simulation vidéo 2

et la dynamique du modèle est la suivante (l'échelle est logarithmique!) :

Le programme python est le suivant :

#
# Simulation de la propagation d'une épidémie
# via un algorithme probabiliste du type jeu de la vie
# Hugues MEUNIER
# avril 2020
#

import numpy as np
from tkinter import Tk, Canvas, Button, RIGHT, LEFT
from random import random
import time
from matplotlib import pyplot as plt
from matplotlib.figure import Figure


# Par défaut le monde est créé en 2 dimensions et de taille NbL*NbC
NbL = 100  # hauteur du tableau
NbC = 100  # largeur du tableau
# NbJours est la durée de l'inefection avant d'être immunisé (l'immunité est supposée acquise)
NbJours = 14 #Nb de jours d'infection (incubation+ maladie) avant d'être remis
a = 7    # taille d'une cellule
NbBoucle = 200 #Nombre de jours pour la simulation

# Définitions des matrices de la simulation
cell = np.zeros((NbL,NbC),dtype=int)
etat = np.zeros((NbL,NbC),dtype=int)
NbGen = 0 # le jour courant

# Définition du dictionnaire des états possibles SAIN, MALADEx, IMMUN, DECES
# il y a x états MALADEx fonction du NbJours pendant lesquels la personne est infectée
state = {"SAIN":0}
bou = 1
# Boucle pour les NbJours d'infection
while bou <= NbJours:
    cle = 'MALADE'+str(bou)
    state[cle] = bou
    bou+=1
state["IMMUN"] = NbJours+1
state["DECES"] = NbJours+2

# Une couleur égale un état
CoulSain = "white"
CoulImmun = "green"
CoulMal = "red"
CoulDec = "black"

# Paramètre de la simulation
DensiteImmun = 0.0    # densité d'individus immunisés dans la population au temps zéro (vaccination ...)
ProbaContag = 0.015     # taux de contagion 0.055 signifie une probabilité de 5,5% de contaminer une personne à chaque contact
ProbaDec = 0.005        # taux de mortalité 0.005 signifie 0,5% de probabilité de décès par jour malade

#Initialisation des tableaux permettant de stocker les statistiques de l'épidémie
D = np.zeros(NbBoucle) # Tableau des personnes décédées
I = np.zeros(NbBoucle)# Tableau des personnes infectées ou malades
R = np.zeros(NbBoucle) #Tableau des personnes rétablies et immunisées
S = np.zeros(NbBoucle) # Tableau des personnes saines
t = np.linspace(0, NbBoucle, NbBoucle) # Tableau qui contient les jours

# Conditions initiales pour le démarrage de la simulation
D[0] = 0
I[0] = 0
R[0] = NbL*NbC*DensiteImmun
S[0] = NbL*NbC -D[0]-I[0]-R[0] 


# Fonction appelée à chaque itération (jour) pour calculer l'état du monde
def iterer(p, tau):
    appliquer_regles(p, tau)
    dessiner()

# Fonction d'initialisation
def initialiser_monde(p):
    # on répartit aléatoirement les personnes immunisées dans le monde
    etat[0:NbL,0:NbC] = state["SAIN"]    
    for x in range(NbL):
        for y in range(NbC):
            if random() < p:
                etat[x,y] = state["IMMUN"]
                R[NbGen]+=1
    # création de la grille d'affichage
    for x in range(NbL):
        for y in range(NbC):
            if etat[x,y]==state["SAIN"]:
                coul = CoulSain
            if etat[x,y]==state["IMMUN"]:
                coul = CoulImmun
            cell[x,y] = canvas.create_rectangle((x*a, y*a, (x+1)*a, \
                         (y+1)*a), outline="gray", fill=coul)
    S[0] = NbL*NbC -D[0]-I[0]-R[0]
    canvas.itemconfig(canvas_txt_NbS, text="Nb sains: "+str(S[NbGen]))
    canvas.itemconfig(canvas_txt_NbI, text="Nb infectés: "+str(I[NbGen]))
    canvas.itemconfig(canvas_txt_NbR, text="Nb remis: "+str(R[NbGen]))
    canvas.itemconfig(canvas_txt_NbD, text="Nb décès: "+str(D[NbGen]))
    

# Fonction qui calcule l'état du monde à chaque itération en fonction des règles du jeu suivantes:
# Si un individu est infecté, il infecte tous ses voisins au sens de Von Neumann avec une probabilité égale au taux de contagion
# Si un individu est au NbJours de l'infection soit il décède avec la probabilité égale au taux de décès ou soit il est immunisé
# L'infection est létale uniquement à partir du 8eme jour de l'infection
def appliquer_regles(p,tau):
    global etat
    temp = etat.copy()  # sauvegarde de l'état courant
    for x in range(NbL):
        for y in range(NbC):
            if etat[x,y] >=1 and etat[x,y]<=NbJours:
                if etat[(x-1)%NbL,(y+1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[(x-1)%NbL,(y+1)%NbC] = state["MALADE1"]                                
                if etat[x,(y+1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[x,(y+1)%NbC] = state["MALADE1"] 
                if etat[(x+1)%NbL,(y+1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[(x+1)%NbL,(y+1)%NbC] = state["MALADE1"] 
                if etat[(x-1)%NbL,y] == state["SAIN"]:
                    if random() < p:
                        temp[(x-1)%NbL,y] = state["MALADE1"] 
                if etat[(x+1)%NbL,y] == state["SAIN"]:
                    if random() < p:
                        temp[(x+1)%NbL,y] = state["MALADE1"] 
                if etat[(x-1)%NbL,(y-1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[(x-1)%NbL,(y-1)%NbC] = state["MALADE1"] 
                if etat[x,(y-1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[x,(y-1)%NbC] = state["MALADE1"] 
                if etat[(x+1)%NbL,(y-1)%NbC] == state["SAIN"]:
                    if random() < p:
                        temp[(x+1)%NbL,(y-1)%NbC] = state["MALADE1"] 
                if etat[x,y] == NbJours:
                    if random() < tau:  
                        temp[x,y] = state["DECES"]
                    else:
                        temp[x,y] = state["IMMUN"]
                else:
                    if etat[x,y] >= 7:
                        if random() < tau:  
                            temp[x,y] = state["DECES"]
                        else:
                            temp[x,y] = etat[x,y]+1
                    else:
                        temp[x,y] = etat[x,y]+1            
                
    etat = temp.copy()  # maj de l'état courant


# Dessiner toutes les cellules
def dessiner():
    for x in range(NbL):
        for y in range(NbC):
            if etat[x,y]==state["SAIN"]:
                couleur = CoulSain
            if etat[x,y]==state["IMMUN"]:
                couleur = CoulImmun
            if etat[x,y]==state["DECES"]:
                couleur = CoulDec
            if etat[x,y]>=1 and etat[x,y]<=NbJours:
                couleur = CoulMal
            canvas.itemconfig(cell[x][y], fill=couleur)
            
# Animation 
def pasapas():
    global NbGen
    i = 0
    while i < NbBoucle-1:
        NbGen += 1
        canvas.itemconfig(canvas_txt_NbJours, text="NbJours: "+str(NbGen))
        iterer(ProbaContag, ProbaDec)
        Compte()
        canvas.itemconfig(canvas_txt_NbS, text="Nb sains: "+str(S[NbGen]))
        canvas.itemconfig(canvas_txt_NbI, text="Nb infectés: "+str(I[NbGen]))
        canvas.itemconfig(canvas_txt_NbR, text="Nb remis: "+str(R[NbGen]))
        canvas.itemconfig(canvas_txt_NbD, text="Nb décès: "+str(D[NbGen]))
        if I[NbGen] == 0:
            print("Epidémie terminée!")
            Sortie()
            break
        #time.sleep(1)
        i+=1
        canvas.update()
    Sortie()

# Fonction de traitement du clic gauche de la souris
def  Infecter(event):
    x, y = event.x//a, event.y//a
    # on ne peut pas infecter un individu immunisé
    if etat[x,y] != state["IMMUN"]:
        etat[x,y] = state["MALADE1"]
        I[0]+=1 #on ajoute une personne infectée à chaque clic gauche de la souris
        S[0] = NbL*NbC -D[0]-I[0]-R[0]
        canvas.itemconfig(cell[x][y], fill=CoulMal) #on dessine en rouge la cellule infectée
        canvas.itemconfig(canvas_txt_NbS, text="Nb sains: "+str(S[NbGen]))
        canvas.itemconfig(canvas_txt_NbI, text="Nb infectés: "+str(I[NbGen]))
        canvas.itemconfig(canvas_txt_NbR, text="Nb remis: "+str(R[NbGen]))
        canvas.itemconfig(canvas_txt_NbD, text="Nb décès: "+str(D[NbGen]))

# Fonction de comptage des polupations saines, infectées, décèdées et remises
def Compte():
    nbS = 0
    nbI = 0
    nbR = 0
    nbD = 0
    x=0
    y=0
    while x < NbL:
        while y < NbC:
            if etat[x,y] == state["IMMUN"]:
                nbR+=1
            if etat[x,y] == state["DECES"]:
                nbD+=1
            if etat[x,y] == state["SAIN"]:
                nbS+=1
            if etat[x,y]>=1 and etat[x,y]<=NbJours:
                nbI+=1
            y+=1
        y=0
        x+=1
    I[NbGen] = nbI
    R[NbGen] = nbR
    D[NbGen] = nbD
    S[NbGen] = nbS

# Fonction de sortie de la simulation avec affichage de la courbe d'évolution des populations S, I, R, D
def Sortie():
    fenetre.destroy()
    # Trace les courbes
    fig = plt.figure(facecolor='w')
    fig_size = plt.rcParams["figure.figsize"]
    print("Sortie...")
    fig_size[0] = 36
    fig_size[1] = 24
    plt.rcParams["figure.figsize"] = fig_size
    I2 = np.trim_zeros(I,trim = 'b')
    NbElem = np.size(I2)
    
    
    plt.title('Evolution de l\'épidémie')
    plt.plot(t[0:NbElem], S[0:NbElem], color='blue', label='Sains')
    plt.plot(t[0:NbElem], I[0:NbElem], color='red', label='Infectés')
    plt.plot(t[0:NbElem], R[0:NbElem], color='green', label='Remis')
    plt.plot(t[0:NbElem], D[0:NbElem], color='black', label='Décédés')
    #plt.plot(t, R, color='green', label='Remis')
    plt.xlabel('Nb de jours')
    plt.ylabel('Nb de personnes (log)')
    leg = plt.legend();
    plt.grid()
    plt.yscale('log')
    plt.show()
    # on ne profite pour sauver le graphe au format png
    fig.savefig("simul-ep.png", format='png', bbox_inches='tight')

# Définition de l'interface graphique
fenetre = Tk()
fenetre.title("Le jeu de la vie épidémique")
canvas = Canvas(fenetre, width=a*NbC+150, height=a*NbL+1, highlightthickness=0)
fenetre.wm_attributes("-topmost", True)
# Allocation de la fonction Infecter sur click gauche
canvas.bind("<Button-1>", Infecter)
canvas.pack()

# Définition des boutons de commande
bou1 = Button(fenetre,text='Sortie', width=8, command=Sortie)
bou1.pack(side=RIGHT)
bou2 = Button(fenetre, text='Go!', width=8, command=pasapas)
bou2.pack(side=LEFT)

#Définition des zones de texte pour afficher les compteurs pendant la simulation
canvas_txt_NbJours = canvas.create_text(NbC*a+20,20, anchor="nw")
canvas.itemconfig(canvas_txt_NbJours, text="NbJours: "+str(NbGen))
canvas_txt_NbS = canvas.create_text(NbC*a+20,40, anchor="nw")
canvas.itemconfig(canvas_txt_NbS, text="Nb sains: "+str(S[NbGen]))
canvas_txt_NbI = canvas.create_text(NbC*a+20,60, anchor="nw")
canvas.itemconfig(canvas_txt_NbI, text="Nb infectés: "+str(I[NbGen]))
canvas_txt_NbR = canvas.create_text(NbC*a+20,80, anchor="nw")
canvas.itemconfig(canvas_txt_NbR, text="Nb remis: "+str(R[NbGen]))
canvas_txt_NbD = canvas.create_text(NbC*a+20,100, anchor="nw")
canvas.itemconfig(canvas_txt_NbD, text="Nb décès: "+str(D[NbGen]))

# lancement de l'automate
initialiser_monde(DensiteImmun)
fenetre.mainloop()

Lire la suite
1 2 3 4 5 6 7 8 9 10 20 > >>