%%AMC:preprocess_command=/home/luc/github/sujets-AMC/tes/qcm1_tg2/prePythonTex4AMC
%%AMC:jobspecific=1
%%AMC:latex_engine=pdflatex --shell-escape

% Compilation Texmaker : Utilisateur/Commandes utilisateur
%--------------------------
% Shell Python :
% pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|
% python /usr/share/texlive/texmf-dist/scripts/pythontex/pythontex.py %.tex|
% pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|
%------------------------
% Copier-coller la ligne ci-dessous dans Utilisateur/Commandes Utilisateur/Editer Commandes Utilisateur
%------------------------
% pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex | python /usr/share/texlive/texmf-dist/scripts/pythontex/pythontex.py %.tex | pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex
%--------------------------

\documentclass[a4paper]{article}
\RequirePackage{etex}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\selectlanguage{french}
\usepackage[francais,bloc,completemulti]{automultiplechoice}
\usepackage{fancyhdr,amssymb,amsmath}
\usepackage{multicol}
\usepackage[babel=true,kerning=true]{microtype}
\usepackage{graphicx}
\usepackage{float}
\usepackage{wrapfig}
\usepackage{pgfplots}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}

\pgfplotsset{compat = newest}

% ---------- Utilisation de codes Python -----
\usepackage{pythontex}
\usepackage{csvsimple}

%----------------------------------------------


\makeatletter
\renewcommand{\explain}[1]{ %
    \ifAMC@correc%
    \AMCif@env{question}{\par\noindent{\AMC@loc@explain#1}}{\AMC@error@explain}\vspace{1ex}%
    \else%
    \AMCif@env{question}{}{\AMC@error@explain}%
    \fi%
}
\makeatother






\begin{pycode}
import numpy as np
import math
from fractions import Fraction as F
from sympy import *
#from numpy.random import default_rng
rng=np.random.default_rng(12345)



#np.random.seed(12345)
# IMPORTANT : Graine pour la fonction random

from math import*
import numpy as np
import matplotlib.pyplot as plt


def drawgraph(A,B):
    print("\\begin{tikzpicture}[scale=2.5,->,>=stealth',shorten >=1pt,auto,inner sep=2pt,semithick,bend angle=20]")
    print("\\tikzstyle{every state}=[draw=none]")
    print("\\node[state] (A) at (1,1.7321) {$A$};")
    print("\\node[state] (B) at (0,0)      {$B$};")
    print("\\node[state] (C) at (2,0)      {$C$};")
    print("\\path (A) edge [in=115,out=65,loop]       node[swap] {$1$}            (A)")
    print("          edge [bend right,looseness=0.5] node[swap] {$0$}            (B)")
    print("          edge [bend right,looseness=0.5] node[swap] {$0$}            (C)")
    print("      (B) edge [in=250,out=200,loop]      node[swap] {$\\dfrac{"+str(A)+"}{4}$} (B)")
    print("          edge [bend right,looseness=0.5] node[swap] {$\\dfrac{"+str(B)+"}{4}$} (C)")
    print("          edge [bend right,looseness=0.5] node[swap] {$0$}            (A)")
    print("      (C) edge [in=340,out=290,loop]      node[swap] {$\\dfrac{1}{2}$} (C)")
    print("          edge [bend right,looseness=0.5] node[swap] {$\\dfrac{1}{4}$} (B)")
    print("          edge [bend right,looseness=0.5] node[swap] {$\\dfrac{1}{4}$} (A);")
    print("\\end{tikzpicture}")
    return True

def drawplot(a,b,c):
    xs=(a+b)/2
    ys=(xs-a)*(xs-b)
    print("\\begin{center}")
    print("\\begin{tikzpicture}[line cap=round,line join=round,>=triangle 45,x=1cm,y=1cm,scale=0.5]")
    print("\\begin{axis}[")
    print("x=1cm,y=1cm,")
    print("axis lines=middle,")
    print("ymajorgrids=true,")
    print("xmajorgrids=true,")
    print("xmin=-10,")
    print("xmax=10,")
    print("ymin=-10,")
    print("ymax=10,]")
    #print("\\clip ("+str(a-2)+","+str(-ymin+2)+") rectangle ("+str(b+2)+","+str(ymin-2)+")")
    print("\\draw [domain="+str(a)+"-3:"+str(b)+"+3] plot[smooth] (\\x, {(\\x-"+str(a)+")*(\\x-"+str(b)+")});")
    print("\\end{axis}[")
    print("\\end{tikzpicture}")
    print("\\end{center}")
    return True

def non_oriente(Graphe):
    """
    Fonction qui indique si un graphe n'est pas orienté
    """
    for S in Graphe:
        for adj in Graphe[S]:
            if S not in Graphe[adj]: return False
    return True
    
def repr_graphe(Graphe, r_sommets=0.1):
    """
    Fonction qui représente un graphe stocké sous forme d'un dictionnaire
    (la fonction trace des arêtes orientées si le graphe est orienté)
    """
    #couleurs du graphique
    col_p='black' 
    col_t='white' 
    
    #récupération du nombre de sommets
    n_sommets=len(Graphe)
    
    #préparation du graphique: axes masqués
    fig, ax = plt.subplots() ; axes = plt.gca()
    for dir in ['left','right','bottom','top']: ax.spines[dir].set_visible(False)
    aff=1+r_sommets*1.1
    plt.xlim(-aff,aff) ; axes.xaxis.set_ticks_position('none') ; axes.xaxis.set_ticklabels([])
    plt.ylim(-aff,aff) ; axes.yaxis.set_ticks_position('none') ; axes.yaxis.set_ticklabels([])
    
    #calcul des coordonnées des sommets:
    x_sommet={} ; y_sommet={}
    k=0
    for S in Graphe:
        angle=2*pi*k/n_sommets
        x_sommet[S]=cos(angle)
        y_sommet[S]=sin(angle)
        k+=1
    
    #tracé des arêtes
    for S in Graphe:
        for adj in Graphe[S]:
            if non_oriente(Graphe):
                #arête simple si le graphe n'est pas orienté
                plt.plot([x_sommet[S],x_sommet[adj]],[y_sommet[S],y_sommet[adj]],color=col_p)
            else:
                #arête orientée sinon
                x_vect=x_sommet[adj]-x_sommet[S] ; y_vect=y_sommet[adj]-y_sommet[S]
                ax.arrow( x_sommet[S] , y_sommet[S] , x_vect*(1-2*r_sommets/sqrt(x_vect**2+y_vect**2)) , y_vect*(1-2*r_sommets/sqrt(x_vect**2+y_vect**2)) , head_width=r_sommets*2/3, head_length=r_sommets, fc=col_p, ec=col_p)
        
    #tracé des sommets
    k=0
    for S in Graphe:
        ax.add_patch(plt.Circle((x_sommet[S],y_sommet[S]), radius=r_sommets , color=col_p )) #disque représentant le sommet
        plt.text(x_sommet[S]-r_sommets/4,y_sommet[S]-r_sommets/4,S, color=col_t) #nom du sommet
        k+=1        
    
    #affichage général
    plt.savefig('graph.pgf')


def genlinreg():
    n = 20
    a = rng.integers(1,high=8,size=1)[0]
    b = rng.integers(1,high=11,size=1)[0]
    c = a/b

    x = np.arange(0,n,1,dtype=np.float64)

    m = np.random.uniform(a,a+0.05,(n,))
    p = np.random.uniform(b,b+2,(n,))

    y = x*m + p
    return x,y

def hardy(err11,err10,err00):
    if err11 > 5 or err00 > 5 or err10 > 5:
        return "Non","Oui"
    return "Oui","Non"

def virtuons(p,x):
    # Boucle pour générer une population de x individus avec des zygotes
    # générés aléatoirement en suivant les probabilités p et q

    zygotes = []
    i = 0
    while i < x:
        # Génération du gamète 1
        if np.random.rand() < p:
            gamete1 = "A"
        else:
            gamete1 = "a"

        # Génération du gamète 2
        if np.random.rand() < p:
            gamete2 = "A"
        else:
            gamete2 = "a"

        # Formation du zygote et ajout à la population des zygotes
        zygotes.append(gamete1 + gamete2)
        i += 1

    # Dénombrement des allèles A et a
    nbAA = 0
    nbaa = 0
    nbAa = 0
    for i in range(len(zygotes)):
        if zygotes[i] == "AA":
            nbAA += 1
        elif zygotes[i] == "aa":
            nbaa += 1
        else:
            nbAa += 1
    if nbAA == 0:
        nbAA = 1
        nbaa = nbaa -1
    if nbaa == 0:
        nbaa = 1
        nbAA = nbAA - 1
    if nbAa == 0:
        nbAa = 1
        nbAA = nbAA + 1
    return nbAA, nbaa, nbAa

def resistance2(R1):
    R2=rng.integers(1,high=9,size=1)[0]
    if R2 == R1:
        if R1 != 1:
            R2 = R1 - 1
        else:
            R2 = R1 + 1
    return R2

def intensite2(I1max):
    I2max=rng.integers(1,high=9,size=1)[0]
    if I2max == I1max:
        if I1max != 1:
            I2max = I1max - 1
        else:
            I2max = I1max + 1
    c=50+5*rng.integers(1,high=10,size=1)[0]
    I0=(I1max+I2max)*c/100
    if I0 == I1max or I0 == I2max:
        I0 = (I1max+I2max)*(c-5)/100
    return I2max, I0

def optim(R1, R2, I1max, I2max, I0):
    I1=R2*I0/(R1+R2)
    if I1 > I1max :
        I1 = I1max
    I2=I0-I1
    if I2 > I2max :
        I2 = I2max
    delta1 = I1max - I1
    delta2 = I2max - I2
    if I1 + I2 < I0:
        delta0 = I0-I1-I2
        if delta1 >= delta0:
            I1 = I1 + delta0
        else:
            I1 = I1 + delta1
            delta3=delta0-delta1
            if delta2 >= delta3:
                I2 = I2 + delta3
            else:
                I2 = I2 + delta2
    return np.array([I1,I2])
\end{pycode}



%--------
% DOCUMENT
%--------
\begin{document}

\newcommand{\sujet}{
\exemplaire{1}{

\AMCassociation{\id}

\begin{minipage}{.4\linewidth}
\centering\large\bf QCM SNT\\1 réponse correcte par question
\end{minipage}
\champnom{\fbox{
    \begin{minipage}{.5\linewidth}
        \centering\textsc{\nom{} \prenom{}}
        \vspace*{2mm}
    \end{minipage}
    }}


\vspace{2ex}

%%% fin de l'en-tête

\begin{center}
    \hrule\vspace{2mm}
    \bf\Large Graphes
    \vspace{1mm}\hrule
\end{center}

%\pyc{G1 = { 'A':['C','F'] , 'B':['C','D','E','F'] , 'C':['A','B','F'] , 'D':['B','E'] , 'E':['B','D'] , 'F':['A','B','C']  }}


%\pyc{A=rng.integers(1,high=9,size=1)[0]}
%\pyc{B=rng.integers(1,high=9,size=1)[0]}
%\pyc{drawgraph(A,B)}

\pyc{a=rng.integers(-5,high=-1,size=1)[0]}
\pyc{b=rng.integers(1,high=5,size=1)[0]}
\pyc{c=rng.integers(-5,high=5,size=1)[0]}
\pyc{drawplot(a,b,c)}

}}

\csvreader[head to column names]{../liste.csv}{}{\sujet}

\end{document}
