#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 22 15:58:54 2026

@author: matthieu



"""


#%%
##Oral 1 2025
import numpy as np
import numpy.linalg as la

def matriceA(n):
    A=np.zeros([n,n])
    for j in range(n):
        for i in range(n):
            if i!=j:
                A[i,j]=j+1# décalage, tableau numpy 
    return A 

for i in [2,3,4,10]:
    print(la.eigvals(matriceA(i)))


# tracé de f_n (non demandé)
import matplotlib.pyplot as plt
def f(n,x):
    s=0
    for k in range(1,n+1):
        s+=k/(k+x)
    return s

n=10
X=np.arange(-(n+2),2,0.001)
Y=f(n,X)
plt.ylim(-100,100)
plt.plot(X,Y)

## Oral 1 2025 sans préparation

#avec dictionnaire

def election1_dico(L):
    d={}
    for x in L:
        if x in d:
            d[x]+=1 
        else:
            d[x]=1 
    score_max=0
    gagnant=None
    for k in d: #décrit les clefs du dico
        if d[k]>score_max:
            score_max=d[k]
            gagnant=k
        elif d[k]==score_max:
            gagnant=None
    return gagnant

#sans dictionnaire
def election1_liste(L):
    liste_nom=[]
    liste_score=[]
    for x in L:
        if x not in liste_nom:
            liste_nom.append(x)
            liste_score.append(1)
        else:
            i=liste_nom.index(x)#position de x dans liste_nom 
            liste_score[i]+=1 
    if liste_score[0]==liste_score[1]:
        return None
    else:
        return liste_nom[liste_score.index(max(liste_score))]
    
        
    
#avec dictionnaire

def election2_dico(L):
    d={}
    for x in L:
        if x in d:
            d[x]+=1 
        else:
            d[x]=1 
    score_max=0
    gagnants=[]
    
    for k in d: #décrit les clefs du dico
        if d[k]>score_max:
            score_max=d[k]
            gagnants=[k]
        elif d[k]==score_max:
            gagnants.append(k)
    return gagnants

#sans dictionnaire
def election2_liste(L):
    liste_nom=[]
    liste_score=[]
    for x in L:
        if x not in liste_nom:
            liste_nom.append(x)
            liste_score.append(1)
        else:
            i=liste_nom.index(x)#position de x dans liste_nom 
            liste_score[i]+=1 
    score_max=max(liste_score)
    gagnants=[]
    for x in range(len(liste_nom)):
        if liste_score[x]==score_max:
            gagnants.append(liste_nom[x])
    return gagnants

##
#%% Oral 2 2025
import random as rd
def nb_analyseA(L):
    nb_True=0
    for x in L:
        if x:## équivalent à if x == True
            nb_True+=1 
    if nb_True==0:
        return 1 
    else:
        return len(L)+1 
    

def echantillon(n,q):
    """renvoie un echantillon de longeur n"""
    L=[]
    for i in range(n):
        if rd.random()<q:
            L.append(False)
        else:
            L.append(True)
    return L
    
n=10
q=0.9

N=10**5 # nb expériences
S=0#somme
for i in range(N):
    S+=nb_analyseA(echantillon(n, q))
print(S/N)
##
#%% Oral 2 2025 sans préparation

def s(n):
    S=0
    for i in range(1,n):
        if n%i==0:
            S+=i
    return S

def prop_parf(N):
    nb_succes=0
    for i in range(1,N+1):
        if s(i)==i:
            nb_succes+=1 
    return nb_succes/N

##
#%% Oral 3 2025

import numpy as np
import random as rd


def f(M):
    n,p=np.shape(M)
    X=np.zeros(n)
    for i in range(n):
        X[i]=rd.random()
    return(np.dot(np.transpose(X),np.dot(M,X)))

A=np.array([[2,1,1],[1,2,1],[1,1,2]])
M=A-3*np.eye(3)
    
nb_succes=0
for i in range(100):
    if f(M)>0:
        nb_succes+=1 
print(nb_succes)
##
#%% Oral 3 2025 sans préparation
import random as rd

def alea(k):
    if rd.random()<(k+1)/(k+2):
        return 1 
    else:
        return 0
    
def simulX(n):
    X=0
    for i  in range(n):
        if alea(X)==1:
            X+=1 
        else:
            X=0
    return X 

def attend():
    X=alea(0)
    n=1
    while X!=0:
        if alea(X)==1:
            X+=1 
        else:
            X=0
        n+=1
    return n
    
        
##
#%% Oral 4  2025 
import math as m  #fonction cos et exp

def intC(x,nb_pas):
    def f(t):
        return m.exp(2*t)*m.cos(t)
    pas =x/nb_pas
    t=0
    S=0
    for i in range(nb_pas+1):
        S+=f(t)
        t+=pas
    return S*pas

#non demandé
import matplotlib.pyplot as plt
import numpy as np
X=np.linspace(-2,2.2,10**4)
Y= [ intC(x,10**2) for x in X]

plt.plot(X,Y,color="teal",linewidth=3)

plt.plot()
##
#%% Oral 4 2025 sans préparation

def coder(L):
    Liste_indice=[]
    Liste_valeur=[]
    n=len(L)
    for i in range(n):
        if L[i]!=0:
            Liste_indice.append(i)
            Liste_valeur.append(L[i])
    return [Liste_valeur,Liste_indice,n]

def decoder(L):
    Lv=L[0] #liste valeurs
    Li=L[1] #liste indice
    n=L[2] #longueur
    LR=[0]*n
    
    for k in range(len(Li)):
        LR[Li[k]]=Lv[k]
    return LR 

def prod_scal(V1,V2):
    PS=0
    Lv1,Li1,n1=V1[0],V1[1],V1[2]
    Lv2,Li2,n2=V2[0],V2[1],V2[2]
    for k in range(len(Li1)):
        if Li1[k] in Li2:
            j=Li2.index(Li1[k])
            PS+=Lv1[k]*Lv2[j]
    return PS

def prod_scal2(V1,V2):
    PS=0
    Lv1,Li1,n1=V1[0],V1[1],V1[2]
    Lv2,Li2,n2=V2[0],V2[1],V2[2]
    i=0
    j=0
    while i<len(Li1) and j<len(Li2):
        if Li1[i]<Li2[j]:
            i+=1 
        elif Li1[i]>Li2[j]:
            j+=1
        else:
            PS+=Lv1[i]*Lv2[j]
            i+=1 
            j+=1 
    return PS
        

##
#%% Oral  5 2025

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 600

def f(x):
    if x!=0:
        return x*np.log(np.abs(x))
    else: 
        return 0

def g(x):
    return x*f(x)

X=np.linspace(-2,2,10**5)
Yf=[f(x) for x in X]
Yg=[g(x) for x in X]
plt.plot(X,Yf)
plt.plot(X,Yg)
plt.show()

##
#%% Oral 5 2025 sans préparation


##
#%% version numpy
import numpy as np
def somme_ligne(M,i):
    n,p=np.shape(M)
    S=0
    for j in range(p):
        S+=M[i,j]
    return S

def somme_colonne(M,j):
    n,p=np.shape(M)
    S=0
    for i in range(n):
        S+=M[i,j]
    return S

M=np.array([[1,20],[1,-1],[1,2]])
print(somme_colonne(M, 1))
print(somme_ligne(M, 2))


##
#%% version liste
def somme_ligne(M,i):
    n=len(M)
    p=len(M[0])
    S=0
    for j in range(p):
        S+=M[i][j]
    return S

def somme_colonne(M,j):
    n=len(M)
    p=len(M[0])
    S=0
    for i in range(n):
        S+=M[i][j] #syntaxe !
    return S

M=[[1,20],[1,-1],[1,2]]
print(somme_colonne(M, 1))
print(somme_ligne(M, 2))    
    
##
#%% version numpy

import numpy as np
def est_magique(M):
    n,p=np.shape(M)
    S=somme_colonne(M, 0)
    for j in range(1,p):
        if S!=somme_colonne(M, j):
            return False
    for i in range(n):
        if S!=somme_ligne(M, i):
            return False
        
    return True

M=np.array([[11,15,19],[21,7,17],[13,23,9]])
N=np.array([[7,1,6],[1,15,9]])

print(est_magique(M),est_magique(N))

##
#% version listes
import numpy as np
def est_magique(M):
    n=len(M)
    p=len(M[0])
    S=somme_colonne(M, 0)
    for j in range(1,p):
        if S!=somme_colonne(M, j):
            return False
    for i in range(n):
        if S!=somme_ligne(M, i):
            return False
        
    return True

M=[[11,15,19],[21,7,17],[13,23,9]]
N=[[7,1,6],[1,15,9]]

print(est_magique(M),est_magique(N))
        
