« Tutorial python » : différence entre les versions

De Wikipast
Aller à la navigation Aller à la recherche
Ligne 2 : Ligne 2 :


Ceci est une introduction simple au language python en vue de programer un bot Wikipast.
Ceci est une introduction simple au language python en vue de programer un bot Wikipast.
Ce tutoriel sera mis à jour au fur et à mesure du cours pour faciliter les exercices.


==Code==
==Code==

Version du 28 mars 2017 à 08:48

Info

Ceci est une introduction simple au language python en vue de programer un bot Wikipast.

Code

# -*- coding: utf-8 -*-
# Cette première ligne indique que le codage de charactères de ce code est utf-8, celà n'est pas
# nécessaire mais c'est particulièrement utile quand on travaille avec des données textuelles.

##################################################
#### 1. Commentaires et chaine de charactères ####
##################################################

# Un commentaire est une ligne de code commençant par le charactère "#", il ne sera pas interprété par python

# Un commentaire sur plusieurs ligne peut être effectué à l'aide de la chaine de caractères ''' avant
# et après le block à commenter. Cependant ce n'est pas le rôle principal de ''' dont le but est plutôt
# de déterminer une longue chaine de caractère

'''
Ceci est un commentaire en bloc
Ce commentaire s'étend
sur trois lignes
'''

x='''
En réalité, cette façon de faire
correspond plutôt à la création
d'une longue chaine de caractère
'''

x
# print est une fonction qui permet de visualiser la variable passée en paramètre (avec formatage)
print(x)

# Une chaine de charactère est généralement déclaré avec simplement le
# charactère ' ou " avant et après la chaine
x='mon prénom est "Vincent"'
print(x)
x="mon prénom est 'Vincent'"
print(x)
x='mon prénom est \'Vincent\''
print(x)

y_2='une chaine de charactère'

# Ces chaines peuvent être concaténée avec l'opérateur +

y_1="\nCeci est un exemple d'"
y_3=' (ou "string") :'

y=y_1+y_2+y_3
print(y)

y=y_1+y_2+'\n'+y_3
print(y)

# l'opérateur * permet de multiplier le "pattern" de la chaine de charactère
print('\n'+'-'*50+'\n')

# Un nombre réel ou entier peut être converti en string via la fonction str
x=1000
y=str(x)

print('voici un nombre converti en string (fonction str) : '+y)

print('\n'+'-'*50+'\n')
###################################
#### 2. Modules et importation ####
###################################

# python permet d'installer facilement divers modules via la console cmd.exe ou un terminal mac
# en tapant directement la commande "pip install XXX" ou XXX est le module désiré.

# Une fois le module XXX installé on utilise "import XXX" dans le script python pour pouvoir utiliser
# les fonctionalités du module.
import urllib2

# certain modules sont déjà pré-installé, d'autres nécessite l'installation via pip install
# d'autres modules plus spécifiques doivent éventuellement être installé manuellement selon
# des instructions particulières. certain modules requier la présence d'autre modules.
import requests

print('\n'+'-'*50+'\n')
############################################################
#### 3. déclaration de variables et opéarations simples ####
############################################################

# Déclaration d'un entier
x=4
print('voici un nombre entier : '+str(x))

# Déclaration d'un réel
y=4.4
print('voici un nombre réel : '+str(y))

#opération simples
z=x+y
print("voici le résultat de l'addition : "+str(z))

# Attention la variable x à été convertie automatiquement en variable réelle
# La conversion "propre" s'obtient à l'aide des fonctions suivantes
x_float=float(x)
y_int=int(y)
print('conversion en float : '+str(x_float))
print('conversion en int : '+str(y_int))

# la fonction type permet d'afficher le type de variable
print(type(x))
print(type(x_float))
print(type(y))
print(type(y_int))

# Attention de mauvaises surprises peuvent subvenir quand on oublie le type de la variable
# et que l'on mélange des variables de type différent
x=4/3
print('4/3 ='+str(x))
x=4/3.0
print('4/3.0 ='+str(x))
x=1.0*4/3
print('1.0*4/3 ='+str(x))
x=(1.0*4)/3
print('(1.0*4)/3 ='+str(x))
x=1.0*(4/3)
print('1.0*(4/3) ='+str(x))
print('\n'+'-'*50+'\n')

# Une astuce rapide consiste en cas de doute à multiplier une variable entière ou réelle
# par le nombre réel 1.0, ce qui rend en sortie une variable réelle de même valeur

# Exposant et modulo
print('Exposant : 4**2 = '+str(4**2))
print('Modulo : 4.4%2 = '+str(4.4%2))
print(int(4.4)+(4.4%2))

# des fonctions mathematiques
import math
x=2*math.pi
x_sqrt=math.sqrt(x)
e_exp_x=math.exp(x)
cos_x=math.cos(x)

print([x,x_sqrt,e_exp_x,cos_x])

print('\n'+'-'*50+'\n')
#######################
#### 4. conditions ####
#######################

x=5
y='5'
z=int(float(x))

x==y
x==z
x==y and x==z
x==y or x==z

condition=x==y
if condition:
	print('yes')
else:
	print('non')

condition=x==z
if condition:
	print('yes')
else:
	print('non')

x=5.5
y=5.55
z=5.45

print(x<y)
print(y<z)

print(x<y<z)
print(z<x<y)

print(x<y and y<z)
print(x<y or y<z)

print(x<=y)
print(x<=x)
print(x<x)

print('\n'+'-'*50+'\n')
#################################
#### 5. boucles for et while ####
#################################

liste=[]
print(liste)

liste.append(5)
liste.append(2.45)
liste.append('un')
liste.append('une')
liste.append('des')
print(liste)

# un élément de la liste (la première position est l'indice 0)
print(liste[0])
print(liste[2])

# la longeur de la liste est données par la fonction "len"
print(len(liste))

# boucle "for"

for i in range(3):
        print(liste[i])

for i in range(len(liste)):
	print(liste[i])

for element in liste:
	print(element)

# boucle "while"
compteur=0
while compteur<len(liste):
	print liste[compteur]
	compteur+=1

print('\n'+'-'*50+'\n')
##############################
#### 6 functions creation ####
##############################

def ma_fonction():
        compteur_max=10
        compteur=1
        while compteur<compteur_max:
                if compteur%2==0:
                        print compteur
                compteur+=1

ma_fonction()
print('\n'+'-'*50+'\n')

def ma_fonction_param(compteur_max=20,modulo=3):
        compteur=1
        while compteur<compteur_max:
                if compteur%modulo==0:
                        print compteur
                compteur+=1

ma_fonction_param()
print('\n'+'-'*50+'\n')

ma_fonction_param(40)
print('\n'+'-'*50+'\n')

ma_fonction_param(40,10)
print('\n'+'-'*50+'\n')


################################
#### 6 read and write files ####
################################

# read
nom_fichier='Lexique381.txt'
#nom_fichier='C:/Users/buntinx/Dropbox/DHBachelor2017/tutorial_python/Lexique381.txt'
fichier=open(nom_fichier,'r')
text=fichier.read().decode('utf-8')
fichier.close()
text=text.split('\n')
for i in range(len(text)):
    text[i]=text[i].split('\t')

text=text[:(len(text)-1)]

for i in range(30,60):
        print(text[i][0]+' / '+text[i][3])

print('\n'+'-'*50+'\n')

for i in range(60,30,-1):
        print(text[i][0]+' / '+text[i][3])

print('\n'+'-'*50+'\n')

for i in range(59,29,-1):
        print(text[i][0]+' / '+text[i][3])

# write
fichier=open('monlexique.txt', "w")
for i in range(len(text)):
        fichier.write(text[i][0].encode('utf-8')+' / '+text[i][3].encode('utf-8')+'\n')
fichier.close()

# exercice: ècrire une fonction qui écrit tous les nombres modulo 5 entre 0 et 100 dans un fichier.
# Ensuite une fonction qui lit une ligne sur deux

print('\n'+'-'*50+'\n')
#############################################
#### 7. Graphiques Tkinter et matplotlib ####
#############################################

# Tkinter
from Tkinter import *
import random

def cercle(x, y, r, coulout='black', coulin='red'):
    "tracé d'un cercle de centre (x,y) et de rayon r"
    can.create_oval(x-r, y-r, x+r, y+r, outline=coulout, fill=coulin)
    
def carre(x, y, r, coulout='black', coulin ='blue'):
    "tracé d'un carré de centre (x,y) et de longueur r"
    can.create_rectangle(x-r, y-r, x+r, y+r, outline=coulout, fill=coulin)
    
def damier(longueur=30):
    "liste de pions possibles"
    global liste_tk
    liste_tk=[]
    for i in range(10):
        for j in range(10):
            new=[longueur*(i+1), longueur*(j+1)]
            liste_tk.append(new)
    "dessiner un damier"
    # Effacer d'abord tout dessin préexistant :
    can.delete(ALL)
    # Création des carrés en boucle en couleur alternée par modulo :
    coul=['white','blue']
    for i in range(10):
        for j in range(10):
            carre(longueur*(i+1), longueur*(j+1), longueur/2, 'black', coul[(i+j) % 2])

def pion(longueur=30):
    global liste_tk
    if len(liste_tk) == 0 :
        print('pas de pion disponible')
    else:
        n=random.randint(0,len(liste_tk)-1)
        cercle(liste_tk[n][0],liste_tk[n][1],0.8*(longueur/2))
        liste_tk.remove(liste_tk[n])

# Programme principal damier #
liste=[]
fen=Tk()
can=Canvas(fen,width=11*30,height=11*30,bg='ivory')
can.pack(side=TOP,padx=5,pady=5)
b1=Button(fen,text='damier',command=damier)
b1.pack(side=LEFT,padx=3,pady=3)
b2=Button(fen,text='pion',command=pion)
b2.pack(side=RIGHT,padx=3,pady=3)
fen.mainloop()

# matplotlib
import matplotlib as plt
from matplotlib.pyplot import figure, show, plot
from numpy import arange, sin, pi

t=arange(0.0, 5.0, 0.01)
plot(t,sin(2*pi*t))

show()

fig=figure()

ax1=fig.add_subplot(211)
ax1.plot(t,sin(2*pi*t))
ax1.grid(True)
ax1.set_ylim((-2, 2))
ax1.set_ylabel('1 Hz')
ax1.set_title('A sine wave or two')

for label in ax1.get_xticklabels():
    label.set_color('r')

ax2=fig.add_subplot(212)
ax2.plot(t, sin(2*2*pi*t))
ax2.grid(True)
ax2.set_ylim((-2, 2))
l=ax2.set_xlabel('Axis x')
l.set_color('g')
l.set_fontsize('large')

show()

###############################
#### 8. scrapping web data ####
###############################

import urllib2
from bs4 import BeautifulSoup

response=urllib2.urlopen("https://fr.wikipedia.org/wiki/Liste_des_capitales_du_monde")
page_source=response.read()
soup=BeautifulSoup(page_source,'html.parser')
capitales_and_countries=[]
for primitive in soup.findAll("table"):
    if primitive.find("th").string=='Capitale':
        for cap_and_count in primitive.findAll("td"):
            for text in cap_and_count.findAll("a"):
                if text.string != None:
                    capitales_and_countries.append(unicode(text.string))
    
for i in range(len(capitales_and_countries)):
    print(capitales_and_countries[i])
print('\n'+str(len(capitales_and_countries))+' capitales and countries listed\n')

# exercice: Scrapper des prénoms sur
# https://fr.wikipedia.org/wiki/Liste_de_pr%C3%A9noms_fran%C3%A7ais_et_de_la_francophonie

##################################
#### 9. Mediawiki bot example ####
##################################

import urllib2
import requests
from bs4 import BeautifulSoup

user='testbot'
passw='dhbot2017'
baseurl='http://wikipast.epfl.ch/wikipast/'
summary='Wikipastbot update'
names=['Madame X','Monsieur Y']

# Login request
payload={'action':'query','format':'json','utf8':'','meta':'tokens','type':'login'}
r1=requests.post(baseurl + 'api.php', data=payload)

#login confirm
login_token=r1.json()['query']['tokens']['logintoken']
payload={'action':'login','format':'json','utf8':'','lgname':user,'lgpassword':passw,'lgtoken':login_token}
r2=requests.post(baseurl + 'api.php', data=payload, cookies=r1.cookies)

#get edit token2
params3='?format=json&action=query&meta=tokens&continue='
r3=requests.get(baseurl + 'api.php' + params3, cookies=r2.cookies)
edit_token=r3.json()['query']['tokens']['csrftoken']

edit_cookie=r2.cookies.copy()
edit_cookie.update(r3.cookies)

# 1. retrouver le contenu et l'imprimer

for name in names:
    result=requests.post(baseurl+'api.php?action=query&titles='+name+'&export&exportnowrap')
    soup=BeautifulSoup(result.text, "lxml")
    #soup=BeautifulSoup(result.text)
    code=''
    for primitive in soup.findAll("text"):
        code+=primitive.string
    print(code)

# 2. changer le contenu

for name in names:
        content='\n'
        content+='==Contenu rajoutté=='
        content+='''
\nLorem ipsum dolor sit amet , consectetur adipiscing elit . Integer at pulvinar tellus . Integer neque lectus , suscipit in lorem et , mollis suscipit neque . Sed commodo orci odio . Cras accumsan id dui ut facilisis . Curabitur vulputate ultricies turpis , eget dapibus lacus tristique non . Quisque vulputate diam nec nulla eleifend , eget sollicitudin dolor dapibus . Pellentesque tristique ultrices lobortis . Sed fringilla placerat odio vel mollis . Fusce eleifend facilisis fringilla . Mauris quam velit , aliquam nec rhoncus ac , efficitur quis leo . Pellentesque lacinia arcu mollis arcu suscipit , vel blandit magna condimentum . Morbi sed elementum nunc . Suspendisse eget quam eget erat tristique fermentum . Vestibulum urna sapien , lobortis sed hendrerit sit amet , blandit et magna . In fermentum , mi quis elementum hendrerit , lacus arcu ullamcorper lectus , a sodales justo diam sed diam .
Maecenas sit amet mi mattis , faucibus lorem eu , tempus sapien . Morbi aliquam commodo ligula nec tincidunt . Integer imperdiet dolor ut enim venenatis , congue gravida sem placerat . Phasellus tempus ipsum eu nisl consequat , et lacinia augue tristique . Integer diam arcu , viverra eleifend leo non , vehicula pretium risus . Donec molestie maximus quam vitae mollis . Nulla congue lacus in augue rutrum scelerisque . Phasellus facilisis neque ultricies nisl bibendum imperdiet . Duis dapibus mauris quis faucibus viverra .
Pellentesque faucibus egestas blandit . Fusce malesuada magna ut sollicitudin mollis . Fusce ut tempus felis . Aliquam eget tempus risus . Nunc et semper tellus . Curabitur imperdiet magna congue est vestibulum , eget tristique justo lacinia . Proin sodales enim dolor , sit amet viverra nibh pellentesque a . Nulla pellentesque sed purus quis viverra . Class aptent taciti sociosqu ad litora torquent per conubia nostra , per inceptos himenaeos . Nam condimentum in leo at molestie . Mauris ullamcorper maximus convallis . Ut cursus consectetur dui , vel pharetra ante ornare eget . Class aptent taciti sociosqu ad litora torquent per conubia nostra , per inceptos himenaeos . Donec dignissim ut magna non scelerisque .
Sed facilisis nulla eget est rhoncus tincidunt . Praesent eu metus non magna ullamcorper tincidunt . Morbi dui velit , aliquet non bibendum sollicitudin , tempus eu purus . Nulla dolor tortor , feugiat ac convallis vitae , rhoncus ultricies tortor . Maecenas bibendum in augue quis aliquet . Fusce at sapien dictum sem luctus malesuada . Cras posuere odio at pellentesque vehicula . Donec consequat neque non dolor varius pulvinar . Integer sit amet porttitor massa . In hac habitasse platea dictumst .
Vivamus pellentesque blandit tellus , eget hendrerit nibh varius ac . Mauris eget cursus justo . Integer at quam sit amet enim tincidunt condimentum . Donec egestas lacinia nisi , ullamcorper imperdiet mauris rutrum eget . Donec viverra luctus efficitur . Suspendisse sed ipsum erat . Sed tincidunt urna interdum arcu sagittis volutpat . Morbi vitae dignissim massa . Ut erat sapien , vulputate vitae nisi vitae , aliquet ullamcorper nunc . Etiam volutpat mi sapien , in pellentesque massa fringilla a . Nunc sed nunc gravida , hendrerit turpis eget , molestie tortor . Vestibulum consectetur nulla at ultricies consectetur . Nam et mattis augue . Pellentesque sed dolor vel ante ultricies tristique a a felis . Etiam a nulla at arcu sodales lacinia in vel elit .\n'''
        payload={'action':'edit','assert':'user','format':'json','utf8':'','appendtext':content,'summary':summary,'title':name,'token':edit_token}
        r4=requests.post(baseurl+'api.php',data=payload,cookies=edit_cookie)
        print(r4.text)

# exercice: Faire un bot qui modifie le contenu de la page "Madame X" et "Monsieur Y" en fonction
# du contenu précédent. Exemple renmplacer les fautes de type "blabla . Blabla" par "blabla. Blabla".
# Astuce: utiliser la fonction "replace"