Bonjour,
Voilà dans mon apprentissage de python, j'ai pondu ce code
import datetime
from tkinter import Entry, Button, Scrollbar
from tkinter import Listbox, StringVar, Tk
from tkinter import Label, LabelFrame, Menu, ANCHOR, E, N, S
from tkinter.colorchooser import askcolor
from tkinter.messagebox import showinfo
import os
import sys
import math
import pytz
###VARIABLES
obj = dict()
listtz = list(pytz.all_timezones)
BINPATH = os.path.dirname(os.path.realpath(__file__))
with open("{}/tz.conf".format(BINPATH), "r") as conffile:
TIMEZONES = conffile.readlines()
TIMEZONES = list(map(lambda s: s.strip(), TIMEZONES))
citytable = []
for element in TIMEZONES:
tmpelement = element.split("/")
try:
citytable.append(tmpelement[::-1])
except:
pass
TIMEZONES = []
citytable.sort()
for element in citytable:
element.reverse()
TIMEZONES.append("/".join(element))
listtz = [x for x in listtz if x not in TIMEZONES]
print("Timezones initialization....OK")
colorsdic = dict()
try:
with open("{}/colors.conf".format(BINPATH), "r") as CONFFILE:
COLORS = CONFFILE.readlines()
COLORS = list(map(lambda s: s.strip(), COLORS))
for i in COLORS:
j = i.split(":")
colorsdic[str(j[0])] = (j[1])
except:
with open("{}/colors.conf".format(BINPATH), "w") as f:
f.write('bgcolor:bisque\nfgcolor:maroon\nbgclock:black\nfgclock:yellow\nbgday:white\nfgday:black\n')
with open("{}/colors.conf".format(BINPATH), "r") as conffile:
COLORS = conffile.readlines()
COLORS = list(map(lambda s: s.strip(), COLORS))
for i in COLORS:
j = i.split(":")
colorsdic[j[0]] = (j[1])
COLORDAY = [colorsdic['bgday'],colorsdic['fgday']]
COLORCLOCK = [colorsdic['bgclock'],colorsdic['fgclock']]
COLORFRAME = [colorsdic['bgcolor'],colorsdic['fgcolor']]
print("Colors initialization ...OK")
framewidth = 0
for element in listtz:
lenframe = len(element)
if lenframe > framewidth:
framewidth = lenframe
i = 0
column = 1
row = 0
rowmax = 7
relief = 'sunken'
city = 'localtime'
bgcolor = '#AA0000'
fgcolor = 'yellow'
############CLASS
class clock:
"""
Defines displays of the CLOCKS
"""
def __init__(self,city,bgcol,fgcol,bgclock,fgclock,bgday,fgday,fontsize,column,row,relief):
if city == 'localtime':
pass
else:
self.timezone = pytz.timezone(city)
self.bgcol = bgcol
self.fgcol = fgcol
self.bgclock = bgclock
self.fgclock = fgclock
self.bgday = bgday
self.fgday = fgday
self.column = column
self.row = row
self.tz = city
self.bgcol = bgcol
self.fgcol = fgcol
self.fontsize = fontsize
if city == 'localtime':
self.date = datetime.datetime.now()
else:
self.date = datetime.datetime.now(self.timezone)
self.daybefore = int(self.date.day)
self.monthbefore = int(self.date.month)
self.yearbefore = int(self.date.year)
self.Frame = LabelFrame(root,bg=self.bgcol,fg=self.fgcol,highlightbackground="yellow", highlightcolor="green", highlightthickness=2)
self.temptable = []
self.labeltext = StringVar()
self.entrydatetext = StringVar()
self.entryhourtext = StringVar()
self.labelsecondtext = StringVar()
self.display_cal()
self.update_window()
def display_cal(self):
self.label = Label(self.Frame,textvariable=self.labeltext,width=15,height=int(framewidth/5),bg=self.bgcol,fg=self.fgcol)
self.label.config(font=("URW Gothic", self.fontsize+2,"bold"))
self.temptable = self.tz.split("/")
if len(self.temptable) == 1:
self.labeltext.set('Localtime')
self.labeltext.set(self.temptable[-1].upper())
self.entryhour = Entry(self.Frame,textvariable=self.entryhourtext,width=5,bg=self.bgclock,fg=self.fgclock,relief=relief)
self.entrydate = Entry(self.Frame,textvariable=self.entrydatetext,width=10,bg=self.bgday,fg=self.fgday,relief=relief)
self.labelsecond = Label(self.Frame,textvariable=self.labelsecondtext,bg=self.bgcol,fg=self.fgcol)
self.entrydate.config(font=("Swiss 721",14))
self.entryhour.config(font=("Serto Kharput",28,"bold"))
self.labelsecond.config(font=("Console",8))
self.label.grid(column=0,row=0,rowspan=2)
self.entryhour.grid(column=1,row=0)
self.entrydate.grid(column=1,row=1)
def update_window(self):
if self.tz == 'localtime':
self.date = datetime.datetime.now()
else:
self.date = datetime.datetime.now(self.timezone)
self.place = self.tz.upper()
self.year = str(self.date.year)
if int(self.year) > self.yearbefore:
showinfo("HAPPY","Happy new year {}".format(self.place))
self.yearbefore = int(self.date.year)
self.month = str(self.date.month).zfill(2)
if int(self.month) > self.monthbefore:
showinfo("WARNING","The month has changed in {}".format(self.place))
self.monthbefore = int(self.date.month)
self.day = str(self.date.day).zfill(2)
if int(self.day) > self.daybefore:
showinfo("WARNING","The day has changed in {}".format(self.place))
self.daybefore = int(self.date.day)
self.hour = str(self.date.hour).zfill(2)
self.minute = str(self.date.minute).zfill(2)
self.second = str(self.date.second).zfill(2)
self.calendar = "{}/{}/{}".format(self.day,self.month,self.year)
self.time = "{}:{}".format(self.hour,self.minute)
self.entrydatetext.set(self.calendar)
self.entryhourtext.set(self.time)
self.labelsecondtext.set(self.second)
self.label.grid(column=0,row=0,rowspan=2)
self.entryhour.grid(column=1,row=0)
self.entrydate.grid(column=1,row=1)
self.labelsecond.grid(column=2,row=0)
self.Frame.grid(column=self.column,row=self.row)
root.after(1000,self.update_window)
def removeinstance(self):
with open("{}/tz.conf".format(BINPATH), 'r') as f1:
lines = f1.readlines()
with open("{}/tz.conf".format(BINPATH), 'w') as f:
for line in lines:
if self.tz not in line:
f.write(line)
f.truncate()
os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
def __str__(self):
return(self)
#DEF
def addtz(str,column,row):
locallisttz = []
str=str+'/'
OptionFrame.grid_forget()
for widget in OptionFrame.winfo_children():
widget.grid_forget()
SetTzList.delete(0, 'end')
LabelText.set('Add timezone')
def CurSelet(evt):
global row
global column
global COLORDAY
global COLORFRAME
global COLORCLOCK
global relief
if (row + column) %2 == 0:
(bgday, fgday)=COLORDAY
(bgcolor,fgcolor)=COLORFRAME
(bgclock,fgclock)=COLORCLOCK
relief='sunken'
else:
(fgday, bgday)=COLORDAY
(fgcolor,bgcolor)=COLORFRAME
(fgclock,bgclock)=COLORCLOCK
relief='ridge'
value = (SetTzList.get(ANCHOR))
with open("{}/tz.conf".format(BINPATH), 'a') as f1:
f1.write("{}{}\n".format(str,value))
obj[value]=clock("{}{}".format(str,value),bgcolor,fgcolor,bgclock,fgclock,bgday,fgday,10,column,row,relief)
DelTZ.add_command(label=value, command=obj[value].removeinstance)
if row < rowmax:
row += 1
else:
row = 0
column += 1
for element in listtz:
locallisttz=[x for x in listtz if str in x]
LabelTitle.grid(column=0, row=1)
SetTzList.grid(column=0, row=2)
table=[]
for entries in locallisttz:
table=entries.split('/')
if len(table) > 2:
SetTzList.insert("end", "{}/{}".format(table[1],table[2]))
else:
SetTzList.insert("end", table[1])
value=SetTzList.get(ANCHOR)
value=SetTzList.bind('<<ListboxSelect>>', CurSelet)
scrollbar.grid(column=1,row=2,sticky=E+N+S)
scrollbar.config( command = SetTzList.yview )
SetTzList.config(yscrollcommand=scrollbar.set)
ButtonCancel.grid(column=0,row=4,columnspan=2)
OptionFrame.grid(column=0,row=0,rowspan=rowmax+2)
def SetColors():
OptionFrame.grid_forget()
for widget in OptionFrame.winfo_children():
widget.grid_forget()
SetTzList.delete(0, 'end')
LabelText.set('Setcolors')
OptionFrame.grid(column=0,row=0,rowspan=rowmax+1)
def changecolor(key):
newlist=[]
(a, newcolor) = askcolor(color=colorsdic[key],title='Choose...')
if newcolor:
for oldkey, oldvalues in colorsdic.items():
if oldkey == key:
oldvalues=newcolor
newlist.append("{}:{}\n".format(oldkey,str(oldvalues)))
with open("{}/colors.conf".format(BINPATH), 'w') as f1:
f1.writelines(newlist)
os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
Buttonbg=Button(OptionFrame,text=colorsdic['bgcolor'],bg=colorsdic['bgcolor'],width=7,command=lambda: changecolor('bgcolor'))
Buttonbg.grid(column=0,row=0)
Buttonfg=Button(OptionFrame,text=colorsdic['fgcolor'],bg=colorsdic['fgcolor'],width=7,command=lambda: changecolor('fgcolor'))
Buttonfg.grid(column=0,row=1)
Buttonbgclock=Button(OptionFrame,text=colorsdic['bgclock'],bg=colorsdic['bgclock'],width=7,command=lambda: changecolor('bgclock'))
Buttonbgclock.grid(column=1,row=0)
Buttonfgclock=Button(OptionFrame,text=colorsdic['fgclock'],bg=colorsdic['fgclock'],width=7,command=lambda: changecolor('fgclock'))
Buttonfgclock.grid(column=1,row=1)
Buttonbgday=Button(OptionFrame,text=colorsdic['bgday'],bg=colorsdic['bgday'],width=7,command=lambda: changecolor('bgday'))
Buttonbgday.grid(column=2,row=0)
Buttonfgday=Button(OptionFrame,text=colorsdic['fgday'],bg=colorsdic['fgday'],width=7,command=lambda: changecolor('fgday'))
Buttonfgday.grid(column=2,row=1)
ButtonCancel.grid(column=0,row=2,columnspan=3)
def info():
OptionFrame.grid_forget()
for widget in OptionFrame.winfo_children():
widget.grid_forget()
SetTzList.grid_forget()
SetTzList.delete(0, 'end')
LabelText.set('Developped...')
OptionFrame.config(text="?")
LabelTitle.grid(column=0, row=0)
labelGPL=Label(OptionFrame,text="under GPL",bg=fgcolor,fg=bgcolor,width=16)
labelname=Label(OptionFrame,text="by David LUCAS",bg=bgcolor,fg=fgcolor,width=16)
labelmail=Label(OptionFrame,text="davlucas@gmail.com",bg=bgcolor,fg=fgcolor,width=16)
labelthanks=Label(OptionFrame,text="thanks:",bg=fgcolor,fg=bgcolor,width=16)
labelfunmooc=Label(OptionFrame,text="INRIA and fun-mooc",bg=bgcolor,fg=fgcolor,width=16)
labelryoko=Label(OptionFrame,text="Ryoko SHINOHARA",bg=bgcolor,fg=fgcolor,width=16)
labelGPL.grid(column=0, row=1)
labelname.grid(column=0, row=2)
labelmail.grid(column=0,row=3)
labelthanks.grid(column=0, row=4)
labelfunmooc.grid(column=0, row=5)
labelryoko.grid(column=0, row=6)
OptionFrame.grid(column=0,row=0,rowspan=rowmax+1)
ButtonCancel.grid(column=0,row=7)
def refresh():
os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
############MAIN
root=Tk()
root.title("Clock ")
menubar = Menu(root)
LabelText=StringVar()
OptionFrame = LabelFrame(root, text='SETTINGS',width=int(framewidth/1.5))
SetTzList = Listbox(OptionFrame,width=int(framewidth/1.5),bg='white',fg='black')
scrollbar = Scrollbar(OptionFrame,width=5,borderwidth=1)
LabelTitle = Label(OptionFrame, textvariable=LabelText)
ButtonCancel = Button(OptionFrame,text='CANCEL',width=6,command=OptionFrame.grid_forget)
obj_localtime=clock(city,'green','black','black','yellow','green','black',8,column,row,relief)
row+=1
for city in TIMEZONES:
if (row + column) %2 == 0:
(bgday, fgday)=COLORDAY
(bgcolor,fgcolor)=COLORFRAME
(bgclock,fgclock)=COLORCLOCK
relief='sunken'
else:
(fgday, bgday)=COLORDAY
(fgcolor,bgcolor)=COLORFRAME
(fgclock,bgclock)=COLORCLOCK
relief='ridge'
obj[city]=clock(city,bgcolor,fgcolor,bgclock,fgclock,bgday,fgday,10,column,row,relief)
if row < (rowmax):
row += 1
else:
row = 0
column += 1
tzmenu = Menu(menubar, tearoff=0)
AddTZ= Menu (tzmenu,tearoff=0)
AddTZ.add_command(label='Africa',command= lambda: addtz('Africa',column,row))
AddTZ.add_command(label='America',command= lambda: addtz('America',column,row))
AddTZ.add_command(label='Antarctica',command= lambda: addtz('Antarctica',column,row))
AddTZ.add_command(label='Asia',command= lambda: addtz('Asia',column,row))
AddTZ.add_command(label='Australia',command= lambda: addtz('Australia',column,row))
AddTZ.add_command(label='Canada',command= lambda: addtz('Canada',column,row))
AddTZ.add_command(label='Europa',command= lambda: addtz('Europe',column,row))
AddTZ.add_command(label='Indian',command= lambda: addtz('Indian',column,row))
AddTZ.add_command(label='Pacific',command= lambda:addtz('Pacific',column,row))
AddTZ.add_command(label='USA',command= lambda:addtz('US',column,row))
AddTZ.add_command(label='Etc',command= lambda:addtz('Etc',column,row))
tzmenu.add_cascade(label="Add timezone",menu=AddTZ)
DelTZ= Menu (tzmenu,tearoff=0)
for element in TIMEZONES:
DelTZ.add_command(label=element, command=obj[element].removeinstance)
tzmenu.add_cascade(label="Remove timezone",menu=DelTZ)
color=Menu(menubar,tearoff=0)
color.add_command(label='change colors settings',command=SetColors)
menubar.add_cascade(label="Timezones Operations", menu=tzmenu)
menubar.add_cascade(label="Set Colors", menu=color)
menubar.add_separator()
About=Menu(menubar,tearoff=0)
About.add_command(label='?',command=info)
About.add_command(label='Refresh display',command=refresh)
About.add_command(label='Quit',command=root.destroy)
menubar.add_cascade(label='About and Refresh',menu=About)
root.config(menu=menubar)
root.mainloop()
Donc, comme vous pouvez le voir, je suis parti d'un timer et puis j'ai rajouté des horloges selon différentes timezones, au début sans classe, j(ai vite vu l'avantage de programmé en objet.
Même si ce code doit vous faire rire (pylint le note -6 quelque chose, c'est que c'est pas terrible) , j'en suis content et ravi.
Néanmoins, persiste un problème, que je pense de design mais je préfère avoir confirmation:
Chaque horloge est donc une classe qui actualise son affichage toutes les secondes.
Donc, si je détruit la frame lors de la supression d'une TZ, cela n'a aucune conséquence: l'objet est bloqué dans la func update_clock. Ma question est donc : est il possible de supprimer subitement une instance de classe et de la forcer à s'arrêter de tourner ?
# Ça fait mal aux yeux
Posté par GaMa (site web personnel) . Évalué à 3.
Non, il fait pas rire.
pylint est la pour rendre le code lisible. Et justement ton code est très compliqué à lire.
Et j'ai vraiment pas envie de me creuser la tête pour t'aider alors que ton code me faire mal à la tête juste à le regarder (sans parler de lire).
Ceci doit expliquer en parti que tu n'aies pas de réponse.
Matthieu Gautier|irc:starmad
[^] # Re: Ça fait mal aux yeux
Posté par Eh_Dis_Mwan . Évalué à 1.
Pas de soucis, merci de tes remarques, je reposterai un code plus propre… j'espère
# Pas beau du tout...
Posté par François GUÉRIN (Mastodon) . Évalué à 3. Dernière modification le 23 janvier 2019 à 18:11.
Salut,
Je fais du python au quotidien… et là je suis séché : je n'ai jamais rien lu de si moche !
Pour commencer, python dispose d'un mécanisme de namespace qui permet de séparer les trucs dans des distincts:
__init__.py
, importables.Ces 2 trucs permettent de séparer les choses dans des espaces distincts, et éviter les scripts à ralonge.
Les fonctions et méthodes ne doivent pas dépasser 50 lignes, sinon tu dois découper.
En plus, tu mélanges des aspects "objet" avec du code procédural : la seule fonction doit être
main(*args)
, protégée :Ça permet de rendre un script importable, sans qu'il soit executé directement.
Le
main
doit retourner un entier, 0 si tout va bien, un autre entier sinon.Ensuite, les règles de nommage:
truc_machin = "bidule"
_
Tu noteras que plutôt que de mettre 20 args à mon
__init__
, j'utilise l'opérateursplat
qui permet de passer un**kwargs
, qui est le dictionnaire de tous les paramètres passée, nommés.Pour ta question concernant la suppression d'instance, tu as une méthode spéciale
__del__(self)
qui permet de gérer la suppression d'instance.Il faut garder en mémoire qu'une classe permet de fabriquer des instances, et qu'elle peut avoir des méthodes qui permettent de manipuler ces instances…
Bon courage !
[^] # Re: Pas beau du tout...
Posté par Eh_Dis_Mwan . Évalué à 3.
Merci, je me doute bien mis c'est en forgeant qu'on devient forgerons.
Merci pour splat, j'ignorais, j'ai un peu modifier, le pylint est positif désormais
Your code has been rated at 6.96/10 (previous run: 6.92/10, +0.03)
Donc en résumé: couper les fonctions pour qu'elle ne depassent pas 50 lignes, et utilisation de splat/kwargs
et rajouter la func main
Bon, grand merci pour tes conseils
Autre avis, sur un premier truc que j'ai fait pour manipuler les tableau, c'est fournir un tirage du loto , vaut il mieux :
full_list = [str(x) for x in range(1, 29)]
random.shuffle(full_list)
LABELTIRAGE.config(text='Numéros Bleus:\n{}\nNumérosBonus:\n{}'.format(' '.join(full_list[0:7]), ' '.join(full_list[7:12])))
ou découper par des variables temporaires ?
[^] # Re: Pas beau du tout...
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 3.
Je ne suis pas certain de ce que tu envisages de mettre dans des variables temporaires…
Une manière de formatter ton code pourrait être la suivante :
Si tu utilises l'outil black qui est en train de se faire une place croissante, tu aurais alors un formation similaire à ça :
Passer par des variables intermédiaires ? Si c'est pour la lisibilité, ça peut éventuellement (mais pas dans ce contexte-là), si c'est pour permettre de débuguer plus facilement éventuellement (et encore…), et sinon je ne vois pas de raison.
Si tu parles et lis en Anglais, un bon test est de lire ton code et de voir si tu comprends "en Anglais" ce que ça fait. Si tu ne comprends pas, c'est que le nommage, le découpage, bref le code n'est pas bien structuré.
#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo
[^] # Re: Pas beau du tout...
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 6.
Je fais du python au quotidien aussi, depuis dix ans, et du code moche on en trouve… et parfois même quand ce n'est pas le premier code écrit (dans le cas du premier jet d'un dév, c'est normal d'avoir du code moche).
D'ailleurs, ça m'arrive encore d'en écrire du code moche : quand tu prototypes rapidement un truc, tu fais pas du code propre (même si tu appliques tes règles de codage dans une certaine mesure)
Je vais me faire l'avocat du diable, mais parfois les scripts à rallonge se justifient. Si tu écrits des scripts, justement, l'intérêt d'avoir un script à rallonge c'est d'avoir un outil indépendant. Tout comme Go génère un binaire qui contient tout. A déployer, c'est de la rigolade par rapport à un logiciel qui est bien structuré.
Ce dont tu parles, c'est une bonne pratique, pas une obligation. Il est conseillé d'éviter d'écrire des fonctions et des méthodes de plus de 50 lignes, mais ça n'est pas une règle absolue.
C'est un truc que j'ai trouvé dans quasiment tous les projets sur lesquels je suis intervenu. C'est pas forcément une bonne chose, mais c'est la réalité.
A utiliser avec parcimonie, sinon l'utilisateur de ton code va passer son temps à remonter dans la hierachie de classe pour découvrir la véritable signature du constructeur ou de la fonction.
C'est pratique d'écrire du code qui manipule un kwargs, c'est la plaie à maintenir et faire évoluer et à comprendre. C'est l'équivalent de l'utilisation des dictionnaires en PHP, et c'est souvent compliqué de monter en compétence sur du code qui en fait une utilisation forte. (je sais, les pythonistes vont me jeter des cailloux, mais plus de 15 ans de développement dont 10 à faire du python, ça fait voir du pays, et ça permet d'avoir un regard critique sur les "bonnes" pratiques)
Je réagis un peu fort, peut-être, mais els introductions du type "Je fais du python au quotidien… et là je suis séché : je n'ai jamais rien lu de si moche !" ça fait un peu trop le mec qui s'y connait et qui prend le débutant pour un nase.
Tout le monde a été débutant à un moment ou à un autre ; y'a pas besoin de prendre les débutants de haut pour leur expliquer des trucs. Ca me fait penser aux développeurs qui font passer des entretiens et qui trouvent que les candidats sont nuls parce qu'ils n'ont pas réussi à répondre à tous les problèmes spécifiques qui font leur quotidien. Bah oui : si le mec qui bosse ailleurs sait faire exactement tout ce que tu vois comme problème au quotidien, c'est soit qu'il est vraiment plus fort que toi (parce que lui, il ne sait pas ce que tu as en tête et il n'est pas dans ton contexte), soit que tu es nase… soit les deux.
Par rapport aux remarques de François, deux remarques complémentaires :
Il faut bien avoir en tête que les variables privées ou attributs de classe commencent par un
_
par conventionEt aussi un point sur les commentaires. L'intérêt d'un commentaire n'est pas d'expliquer ce que fait le code mais pourquoi il le fait. Par exemple dans le code suivant :
Le commentaire est inutile : il décrit simplement le comportement de la méthode
get()
Dernier point : si tu aimes coder, persévère. Tu vas écrire du code et 1 mois plus tard tu le trouveras dégueu. Ca va continuer comme ça pendant longtemps… au fur et à mesure tu vas passer de 1 mois à 2, puis 3, puis 6, puis 12… mais tu ne seras probablement jamais satisfait de ce que tu as écrit, car ton expérience change, ta maîtrise du sujet que tu essaies de résoudre va se préciser et donc la manière de concevoir ou de modéliser évolue.
Je rejoins François dans ce qu'il ne dit pas explicitement mais qui ressort de sa réponse : il faut essayer d'appliquer les bonnes pratiques. Ca rend ton code plus standard, plus propre en général, et ça permet plus facilement de travailler à plusieurs. Choisi également une approche principale : tu fais de la programmation objet ou tu préfères faire du procédural ? Formatte ton code et standardise-le, il y a pas mal d'outils pour cela : flake, pylint, black, par exemple, et pas mal de bonnes pratiques "standards" que tu peux retrouver dans les pep - dont la fameuse pep8
#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo
[^] # Re: Pas beau du tout...
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 4.
Autre point : évite d'utiliser des
global
. C'est comme utiliser dans variables globales dans tout autre langage : ça rend le code fragile et ça réduit l'évolutivité.#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo
[^] # Re: Pas beau du tout...
Posté par Eh_Dis_Mwan . Évalué à 1.
J'ai recommencer, et je me rends compte qu'en effet. Les espaces de nommage, j'ai pas encore super compris. Une classe pour le menu, une classe pour les horloges. Ensuite, je créerai les modules à partir des classes.
Le splat, ça change la vie.
[^] # Re: Pas beau du tout...
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 4.
Si tu te dis dès maintenant que c'est super et que tu vas l'utiliser partout, je te dis : "attention"… ça complique la maintenance de ton code : tu perds la description de ta signature.
#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo
[^] # Re: Pas beau du tout...
Posté par Eh_Dis_Mwan . Évalué à 2. Dernière modification le 24 janvier 2019 à 20:10.
oui , j'ai bien compris, mais c'est pratique lorsque ton instance (comme dans mon exemple) a besoin d'une palanquée de variable.
[^] # Re: Pas beau du tout...
Posté par flan (site web personnel) . Évalué à 5. Dernière modification le 25 janvier 2019 à 23:36.
Et ça perd les IDE, qui ne peuvent plus t’aider.
Je préfère conserver la signature, voire ajouter le type attendu et avoir un IDE qui me prévient dès que je fais une erreur de type.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.