#1426 Le 03/11/2011, à 22:12
- kamui57
Re : /* Topic des codeurs [6] */
ben beautifulsoup a pas l'air dans les dépôts pour python3
22:09:46 stepharch@toshi:~/charlie 75$ yaourt beautifulsoup
1 community/python-beautifulsoup 3.2.0-1 [installed]
A Python HTML/XML parser designed for quick turnaround projects like
screen-scraping
==> Numéro(s) des paquets à installer (ex: 1 2 3 ou 1-3)
==> ----------------------------------------------------
==>
22:11:07 stepharch@toshi:~/charlie 76$ python3
Python 3.2.2 (default, Sep 5 2011, 04:52:19)
[GCC 4.6.1 20110819 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from BeautifulSoup import BeautifulSoup
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named BeautifulSoup
>>>
Quand le dernier arbre aura été abattu, et le dernier animal exterminé, les hommes se rendront compte que l'argent ne se mange pas (proverbe indien)
Toshiba Satellite L655 4 Go RAM, Archlinux Gnome-shell,LXDE / W7
Toshiba Satellite M30 512 Mo RAM, Archlinux Gnome 3 restreint / Crunchbang LXDE
https://help.ubuntu.com/community/Pastebinit pour poster du texte sur internet en console
Hors ligne
#1427 Le 03/11/2011, à 22:25
- grim7reaper
Re : /* Topic des codeurs [6] */
Ouais je crois qu’il n’a pas encore été porté.
C’est la lose, depuis le temps que Python 3 est sorti…
Hors ligne
#1428 Le 03/11/2011, à 23:15
- tshirtman
Re : /* Topic des codeurs [6] */
Oui, il y a encore beaucoup de modules à porter en python3, il me semble que la fondation python se donne 5ans pour que le marché bascule vraiment à python3.
et puis python3 est sorti lui, contrairement à perl 6 et php 6
Dernière modification par tshirtman (Le 03/11/2011, à 23:16)
Hors ligne
#1429 Le 03/11/2011, à 23:22
- grim7reaper
Re : /* Topic des codeurs [6] */
Ouais enfin Perl 6 quoi… Ce n’est pas la suite de Perl 5, c’est carrément un nouveau langage tellement ils ont modifiés de trucs.
Et puis si Audrey Tang avec pas implémentée Pugs, je crois qu’il serait toujours à l’état de pur spec’ Perl 6
Heureusement qu’elle était là quoi.
Dernière modification par grim7reaper (Le 03/11/2011, à 23:22)
Hors ligne
#1430 Le 03/11/2011, à 23:38
- kamui57
Re : /* Topic des codeurs [6] */
voilà (coloré)
#!/usr/bin/python2
# -*- coding: utf-8 -*-
# finds all pages from charliehebdo.fr indexed by google, for each page writes its cache url in the file cache_urls_file (default cacheurls.txt)
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
import re, urllib2
import mechanize
# query to find all pages from website charliehebdo.fr
address = "http://www.google.com/search?q=site:charliehebdo.fr&hl=en&safe=off&prmd=imvns&filter=0&start="
# begin at result 0
counter = 0
# store cache urls in this file
cache_urls_file = "cacheurls.txt"
# browse google results pages
#10 results per page, so the counter for results beginning increases by 10 for each page
def seek_results(url,count=0):
# empty file
f = open(cache_urls_file, 'w')
f.write("")
cache_links=""
while count < 800 :
print "Analyzing page "+str(count/10)+"..."
seek_page(url,count)
count += 10
# for the page of google results given by url and count (count = begin on which result, 10 per page), extract the results of the page
def seek_page(url,count):
# download page with a firefox user agent because 403 without it
br=mechanize.Browser()
br.set_handle_robots(False)
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
response=br.open(url+str(count))
html=response.read()
page = BeautifulSoup(html, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
# results list
results = page.find('ol',attrs={"id" : "rso"}).findAll('li')
#print("Nombre de résultats pour la page "+str(count/10)+" : "+str(len( results )))
# browse results
cache_links = ""
for result in results :
cache_link = seek_info(result)
#print(type(cache_link).__name__)
if type(cache_link).__name__!='NoneType':
#print "seek links "+cache_link
cache_links += seek_info(result)+"\n"
#print cache_link
f = open(cache_urls_file, 'a')
f.write(cache_links)
#return cache_links
# for this result, extract the link (no google cache) then use it to generate google cache url
def seek_info(li):
h3 = li.find('h3')
if type(h3).__name__!='NoneType':
a = h3.find('a')
if type(a).__name__!='NoneType':
#print type(link1)
link = a['href']
#print link
if type(link).__name__!='NoneType':
cache_link = "http://webcache.googleusercontent.com/search?q=cache:"+link[7:]
#print("seek info "+cache_link)
return cache_link
seek_results(address)
#seek_page(address,0)
Dernière modification par kamui57 (Le 04/11/2011, à 09:02)
Quand le dernier arbre aura été abattu, et le dernier animal exterminé, les hommes se rendront compte que l'argent ne se mange pas (proverbe indien)
Toshiba Satellite L655 4 Go RAM, Archlinux Gnome-shell,LXDE / W7
Toshiba Satellite M30 512 Mo RAM, Archlinux Gnome 3 restreint / Crunchbang LXDE
https://help.ubuntu.com/community/Pastebinit pour poster du texte sur internet en console
Hors ligne
#1431 Le 04/11/2011, à 00:13
- HP
Re : /* Topic des codeurs [6] */
Enfin le nirvana c'est Ruby, évidemment.
i += 1
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#1432 Le 04/11/2011, à 00:49
- tshirtman
Re : /* Topic des codeurs [6] */
@kamui57: en cours sur mon serveur... j'espère que ça marche
edit: ça a l'air
Dernière modification par tshirtman (Le 04/11/2011, à 00:50)
Hors ligne
#1433 Le 04/11/2011, à 01:07
- kamui57
Re : /* Topic des codeurs [6] */
@kamui57: en cours sur mon serveur... j'espère que ça marche
edit: ça a l'air
ça peut être largement amélioré, en isolant le domain.tld à mirrorer dans une autre chaine pour le changer plus facilement, et remplaçant le while count < 800 (déterminé empiriquement) par un while found_links > 0 par ex, 'fin là dodo.
par contre j'ai tenté le wget marqué là et google a pas aimé et au bout d'un moment jme suis pris des 503.
Conversion de ./webcache.googleusercontent.com/search@q=cache%3Awww.charliehebdo.fr%2Fvivisection.html...1-96
Conversion de ./webcache.googleusercontent.com/search@q=cache%3Awww.charliehebdo.fr%2Fvivisection&hl=en&strip=1.html...1-57
Conversion de ./webcache.googleusercontent.com/search@q=cache%3Awww.charliehebdo.fr%2Fvivisection&hl=en&strip=0.html...1-96
3 fichiers convertis en 0,005 secondes.
--2011-11-03 23:35:01-- http://webcache.googleusercontent.com/search?q=cache:www.charliehebdo.fr/corrida
Résolution de webcache.googleusercontent.com... 209.85.227.132
Connexion vers webcache.googleusercontent.com|209.85.227.132|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: non spécifié [text/html]
Sauvegarde en : «./webcache.googleusercontent.com/search@q=cache%3Awww.charliehebdo.fr%2Fcorrida.html»
[ <=> ] 299 221 60,3K/s ds 4,8s
En-tête de dernière modification manquant -- horodatage ignoré.
2011-11-03 23:35:09 (60,6 KB/s) - «./webcache.googleusercontent.com/search@q=cache%3Awww.charliehebdo.fr%2Fcorrida.html» sauvegardé [299221]
--2011-11-03 23:35:11-- http://webcache.googleusercontent.com/search?q=cache:www.charliehebdo.fr/corrida&hl=en&strip=1
Réutilisation de la connexion existante vers webcache.googleusercontent.com:80.
requête HTTP transmise, en attente de la réponse...302 Found
Emplacement: http://www.google.com/sorry/?continue=http://webcache.googleusercontent.com/search%3Fq%3Dcache:www.charliehebdo.fr/corrida%26hl%3Den%26strip%3D1 [suivant]
--2011-11-03 23:35:15-- http://www.google.com/sorry/?continue=http://webcache.googleusercontent.com/search%3Fq%3Dcache:www.charliehebdo.fr/corrida%26hl%3Den%26strip%3D1
Résolution de www.google.com... 173.194.32.17, 173.194.32.18, 173.194.32.19, ...
Connexion vers www.google.com|173.194.32.17|:80...connecté.
requête HTTP transmise, en attente de la réponse...503 Service Unavailable
2011-11-03 23:35:16 ERREUR 503: Service Unavailable.
je vais sur la page avec ff maintenant
Our systems have detected unusual traffic from your computer network. Please try your request again later. Why did this happen?
IP address: XX.XX.XX.XX
Time: 2011-11-04T00:08:30Z
URL: http://webcache.googleusercontent.com/s … fr/censure
Dernière modification par kamui57 (Le 04/11/2011, à 01:09)
Quand le dernier arbre aura été abattu, et le dernier animal exterminé, les hommes se rendront compte que l'argent ne se mange pas (proverbe indien)
Toshiba Satellite L655 4 Go RAM, Archlinux Gnome-shell,LXDE / W7
Toshiba Satellite M30 512 Mo RAM, Archlinux Gnome 3 restreint / Crunchbang LXDE
https://help.ubuntu.com/community/Pastebinit pour poster du texte sur internet en console
Hors ligne
#1434 Le 04/11/2011, à 01:26
- Elzen
Re : /* Topic des codeurs [6] */
Bon, j'suis plutôt content de mon algo, alors je partage.
À l'origine, c'était pour enjoliver un TP de C#, sauf que comme le C#, voilà, quoi, j'ai fait l'algo en Python d'abord pour vérifier que ça marchait avant de le traduire pour le TP. J'n'ai pas gardé la version C#, mais pour le cas où la version Python vous intéresserait…
Il s'agit d'un algo pour afficher plusieurs dates sur un calendrier. Vous lui passez une série de dates au format JJ/MM/AAAA, et lui vous fabrique un joli tableau, avec une colonne par jour de la semaine, et vous place les jours demandés à la bonne position dans le tableau (les doublons sont supprimés, mais on pourrait aussi leur faire un autre traitement en pas beaucoup de modifs), avec le numéro de la semaine dans l'année au début de chaque ligne.
Ça peut aussi permettre d'accéder à quelques infos vaguement intéressantes sur les dates, éventuellement, si on l'importe ailleurs.
Deux formats de sortie sont disponible : texte brut (conçu pour tenir dans un terminal en 80 caractères de large, police monospace) et table HTML (juste la table, sans doctype ni html ni body).
Et même que pour vous faire plaisir, j'ai tenté de commenter en anglais.
#! /usr/bin/python
# coding: Utf-8
import datetime
# Warning: data aren't verified, so it could throw exceptions.
class CalDate:
def __init__(self, year, month, day):
self.year = year ; self.month = month ; self.dayOfMonth = day
self.dayOfWeek = datetime.datetime(year,month,day).weekday()+1
if ((year%4 == 0 and year%100 != 0) or year%400 == 0):
self.mlens = (31,29,31,30,31,30,31,31,30,31,30,31)
else: self.mlens = (31,28,31,30,31,30,31,31,30,31,30,31)
self.dayOfYear = day
for i in range(0, month-1, 1):
self.dayOfYear += self.mlens[i]
# French short format. Just rewrite here: ↓
if (day >= 10): self.shortFormat = str(day)
else: self.shortFormat = "0"+str(day)
if (month >= 10): self.shortFormat += "/"+str(month)
else: self.shortFormat += "/0"+str(month)
self.shortFormat += "/"+str(year)
# Return the number of the week in the year.
def week(self):
if (CalDate(self.year, 1, 1).dayOfWeek > 4):
return self.dayOfYear/7 + 1
else: return self.dayOfYear/7 + 2
# Return a new date which is the same day as self.
def today(self): return CalDate(self.year, self.month, self.dayOfMonth)
# Return a new date which is one day before self.
def yesterday(self):
y, m, d = self.year, self.month, self.dayOfMonth
if (d == 1):
if (m == 1): y -= 1 ; m = 12 ; d = 31
else: m -= 1 ; d = self.mlens[m-1]
else: d -= 1
return CalDate(y, m, d)
# Return a new date which is one day after self.
def tomorrow(self):
y, m, d = self.year, self.month, self.dayOfMonth
if (d == self.mlens[m-1]):
if (m == 12): y += 1 ; m = 1 ; d = 1
else: m += 1 ; d = 1
else: d += 1
return CalDate(y, m, d)
# Return True if self is later than other.
# Return False if other is later than self.
# Return None if self and other are the same day.
def later(self, other):
if (self.year == other.year):
if (self.month == other.month):
if (self.dayOfMonth == other.dayOfMonth):
return None
else: return other.dayOfMonth < self.dayOfMonth
else: return other.month < self.month
else: return other.year < self.year
CalDate.Monday = 1 ; CalDate.Sunday = 7
# Return the list, sorted by dates.
def sort(dates):
slist = []
for date in dates:
toadd = True
for i in range(0, len(slist), 1):
if (slist[i].later(date)):
slist.insert(i, date)
toadd = False
break
if (toadd): slist.append(date)
return slist
# Sort dates and return a text calendar in simple text format.
def writeTextCalendar(dates):
dates = sort(dates)
s = " lundi mardi mercredi jeudi"
s += " vendredi samedi dimanche \n"
c,i = dates[0].today(),0
while (c.dayOfWeek != CalDate.Monday):
c = c.yesterday()
while (i < len(dates)):
while (dates[i].later(c)):
if (c.dayOfWeek == CalDate.Monday):
s += str(c.week())+" "
s += " "
if (c.dayOfWeek == CalDate.Sunday):
s += "\n"
c = c.tomorrow()
if (c.dayOfWeek == CalDate.Monday):
s += str(c.week())+" "
s += dates[i].shortFormat+" "
while (i+1 < len(dates) and dates[i+1].later(dates[i])==None):
i += 1 # Just don't show several times the same day.
if (c.dayOfWeek == CalDate.Sunday):
s += "\n"
c = dates[i].tomorrow()
i += 1
if (c.dayOfWeek != CalDate.Sunday):
while (c.dayOfWeek != CalDate.Sunday):
s += " "
c = c.tomorrow()
s += "\n"
return s
# Sort dates and return a text calendar in html format.
def writeHTMLCalendar(dates):
dates = sort(dates)
s = "\t<table>\n\t<tr>\n\t\t<th />\n\t\t<th>lundi</th>\n"
s += "\t\t<th>mardi</th>\n\t\t<th>mercredi</th>\n"
s += "\t\t<th>jeudi</th>\n\t\t<th>vendredi</th>\n"
s += "\t\t<th>samedi</th>\n\t\t<th>dimanche</th>\n\t</tr>\n"
c,i = dates[0].today(),0
while (c.dayOfWeek != CalDate.Monday):
c = c.yesterday()
while (i < len(dates)):
while (dates[i].later(c)):
if (c.dayOfWeek == CalDate.Monday):
s += "\t<tr>\n\t\t<th>"+str(c.week())+"</th>\n"
s += "\t\t<td />\n"
if (c.dayOfWeek == CalDate.Sunday):
s += "\t</tr>\n"
c = c.tomorrow()
if (c.dayOfWeek == CalDate.Monday):
s += "\t<tr>\n\t\t<th>"+str(c.week())+"</th>\n"
s += "\t\t<td>"+dates[i].shortFormat+"</td>\n"
while (i+1 < len(dates) and dates[i+1].later(dates[i])==None):
i += 1 # Just don't show several times the same day.
if (c.dayOfWeek == CalDate.Sunday):
s += "\t</tr>\n"
c = dates[i].tomorrow()
i += 1
if (c.dayOfWeek != CalDate.Sunday):
while (c.dayOfWeek != CalDate.Sunday):
s += "\t\t<td />\n"
c = c.tomorrow()
s += "\t</tr>\n"
return s+"\t</table>\n"
if (__name__ == "__main__"):
# Sort and show days from program args.
dates,dohtml = [],False
for arg in __import__("sys").argv[1:]:
if (arg == "--text"):
dohtml = False
continue
if (arg == "--html"):
dohtml = True
continue
# French format waited. Just rewrite here: ↓
date = arg.split("/")
dates.append(CalDate(int(date[2]), int(date[1]), int(date[0])))
if (dohtml): print writeHTMLCalendar(dates)
else: print writeTextCalendar(dates)
Si vous avez des remarques, n'hésitez pas…
Dernière modification par ArkSeth (Le 04/11/2011, à 01:31)
Elzen : polisson, polémiste, polymathe ! (ex-ArkSeth)
Un script pour améliorer quelques trucs du forum.
La joie de t'avoir connu surpasse la peine de t'avoir perdu…
timezone[blocklist]
Hors ligne
#1435 Le 04/11/2011, à 01:46
- Kanor
Re : /* Topic des codeurs [6] */
De visu
je pense qu'il y a une bonne partie de ton code qui peut être remplacé par le module calendar
Je pense qu'une librairie de template pour faire l'html aurait été plus sympa et plus facile à débugguer.
par exemple http://www.makotemplates.org//
Hors ligne
#1436 Le 04/11/2011, à 09:01
- kamui57
Re : /* Topic des codeurs [6] */
tshirtman : j'ai mis un mauvais commentaire... en fait le script écrit juste une liste des urls en cache dispo dans un fichier, faut les télécharger et remplacer les liens ensuite.
tshirtman et sweetly ↓ : merci à vous deux pour les explications :-)
Dernière modification par kamui57 (Le 04/11/2011, à 09:06)
Quand le dernier arbre aura été abattu, et le dernier animal exterminé, les hommes se rendront compte que l'argent ne se mange pas (proverbe indien)
Toshiba Satellite L655 4 Go RAM, Archlinux Gnome-shell,LXDE / W7
Toshiba Satellite M30 512 Mo RAM, Archlinux Gnome 3 restreint / Crunchbang LXDE
https://help.ubuntu.com/community/Pastebinit pour poster du texte sur internet en console
Hors ligne
#1437 Le 04/11/2011, à 09:01
- sweetly
Re : /* Topic des codeurs [6] */
en python2, est-ce que c'est normal que j'aie ça ?
print("Nombre de resultats pour la page",compteur/10,":",len( reponses )) # donne ('Nombre de resultats pour la page', 0, ':', 13) et pas Nombre de resultats pour la page 0 : 13
pourtant comme ça ça marche bien
print("Nombre de resultats pour la page "+str(compteur/10)+" : "+str(len( reponses ))) # donne Nombre de resultats pour la page 0 : 13
aussi en mettant résultats (avec accents) la première affiche r\xc3\xa9sultats et la seconde résultats
Pour le problème d'accent, ça vient juste du fait que dans le premier cas, il affiche un tuple (donc méthode pour les tuples) et n'interprète pas l'encodage des éléments de ce tuple de la même manière qu'une chaîne de caractère.
Si tu itères sur les éléments de ton tuple et que tu affiches élément par élément, il affichera donc bien un str, et là, les accents seront correctement représentés.
Exemple :
>>> a = ['à', 'é', 'è']
>>> print(a)
['\xc3\xa0', '\xc3\xa9', '\xc3\xa8']
>>> print(' '.join(a))
à é è
Hors ligne
#1438 Le 04/11/2011, à 09:20
- The Uploader
Re : /* Topic des codeurs [6] */
j'espère que c'est moins tortueux en python 3.
- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10
Hors ligne
#1439 Le 04/11/2011, à 09:31
- sweetly
Re : /* Topic des codeurs [6] */
@ArkSeth : bon vu que c'était un test à destination d'une traduction dans un autre langage, tu n'aurais peut-être pas codé pareil en exclusive python. Néanmoins plusieurs choses me font tiquer (rien de méchant et c'est assez personnel) :
- J'ai horreur des
if cond: blabla; blublu; blibli
- Encore plus des :
if cond:
blabla
else: blibli
- Encore encore plus des :
def func(): return tatayoyo
Je trouve réellement que ça casse le flot visuel de la lecture du code.
Plutôt que de réinventer la roue, pourquoi ne pas utiliser optparse pour parser les arguments (en l'occurrence, dans ton cas, ça t'aurait pris sûrement plus de lignes à écrire, ceci dit, quoique) ?
Quand tu fais ça :
for i in range(0, month-1, 1):
self.dayOfYear += self.mlens[i]
pourquoi ne pas faire plutôt (gain de performance et de lisibilité, amha, surtout que Python est clairement designer dans ce sens):
for m in self.mlens[:month-1]:
self.dayOfYear += m
Et c'est pas le seul exemple où tu boucles sur les indices alors que tu ne fais pas traitement particulier avec que de parcourir la liste linéairement.
Ca, j'aime pas trop :
s = " lundi mardi mercredi jeudi"
s += " vendredi samedi dimanche \n"
Je préfère ça :
s = " lundi mardi mercredi jeudi \
vendredi samedi dimanche \n"
(ou encore un traitement basé sur la liste ['lundi', 'mardi', ...], plus facile pour ajuster par la suite les caractères blancs dans ton formatage)
Ca non plus :
s = " "
Je préfère :
''.rjust(10)
C'est plus safe (par ex, si tu dois répéter cette action plusieurs fois dans ton code, ça évite de compter à chaque fois les espaces), et utiliser les méthodes de built-in types, c'est le bien. Sachant que tu peux ajuster le caractère à répéter pour le rjust (des tabs, des é, des >, bref, ce que tu veux).
Pour les commentaires en anglais, c'est pa smal, mais évite les abréviations orales (aren't). Y'a peut-être d'autres petits trucs, mais je vais pas tout relever.
Sinon, ça fait le boulot
Hors ligne
#1440 Le 04/11/2011, à 09:35
- sweetly
Re : /* Topic des codeurs [6] */
j'espère que c'est moins tortueux en python 3.
Je trouve pas ça spécialement tortueux une fois que tu sais pourquoi il le fait : tu lui demande d'afficher un int, il t'affiche un int, tu lui demandes d'afficher un tuple, il t'affiche un tuple sans interpréter ce qu'il contient, etc.
L'avantage de cette voie-là, c'est que tu peux afficher un tuple avec des objets dont le __str__ n'est pas bien défini. Par défaut, dans du tout objet, je trouve que c'est un bon principe d'affichage (et qui pose le moins d'hypothèses sur ce que tu lui donnes à afficher, ce qui est bien, pour une fonction standard).
Hors ligne
#1441 Le 04/11/2011, à 13:17
- Elzen
Re : /* Topic des codeurs [6] */
Attention, message long.
je pense qu'il y a une bonne partie de ton code qui peut être remplacé par le module calendar
Sans doute, mais le but du jeu était de savoir faire ça moi-même, histoire de pouvoir le porter dans un langage où j'n'aurais éventuellement pas de module calendar (d'autant que celui-là, j'le connaissais pas. Je n'connais pas plein de trucs en python, en fait).
En fait, même l'appel à datetime m'embête, j'l'ai utilisé pour gagner du temps parce que je savais que j'pouvais récupérer ça sans traitement en C#, mais si j'refais ça proprement, j'essayerai de trouver comment le calculer moi-même, au cas où.
L'intérêt n'est pas tant d'avoir un truc qui tourne, que d'avoir un truc dont j'pourrais expliquer pourquoi ça tourne ^^
Je pense qu'une librairie de template pour faire l'html aurait été plus sympa et plus facile à débugguer.
J'n'ai jamais réussi à accrocher à la logique des templates. Ça me paraît toujours plus propre, plus lisible et plus facile à comprendre de générer une chaîne de caractère en prog impérative normale que d'utiliser des machins comme ça.
@ArkSeth : bon vu que c'était un test à destination d'une traduction dans un autre langage, tu n'aurais peut-être pas codé pareil en exclusive python.
À peu de chose près, si, j'pense. Désolé.
- J'ai horreur des
if cond: blabla; blublu; blibli
- Encore plus des :
if cond: blabla else: blibli
- Encore encore plus des :
def func(): return tatayoyo
Je trouve réellement que ça casse le flot visuel de la lecture du code.
Hmm… peux-tu préciser ? Parce que là, t'expliques pas trop ce que tu n'aimes pas au juste.
En l'occurrence, j'ai fait ça en tentant de réduire au maximum le nombre de lignes, juste parce que ça faisait « gros » pour poster sur un forum (je n'me rappelais plus que la balise code gérait du scroll en cas de contenu trop long).
Pour les fonctions+contenu définis entièrement sur la même ligne, en général et en dehors de toute contrainte sur le nombre de lignes, j'évite, à l'exception, de temps en temps, des trucs du genre
import gtk
def mainwin_destroyed(widget): gtk.main_quit()
win = gtk.Window()
win.connect("destroy", mainwin_destroyed)
Mais ç'n'est pas systématique, ça dépend de l'humeur du moment.
Sinon, dès qu'il y a plusieurs instructions je passe à la ligne, mais si le « else: » n'est suivit que d'une seule instruction, ça n'me choque pas du tout de laisser ça en inline, au contraire.
Plutôt que de réinventer la roue, pourquoi ne pas utiliser optparse pour parser les arguments (en l'occurrence, dans ton cas, ça t'aurait pris sûrement plus de lignes à écrire, ceci dit, quoique) ?
Parce qu'à mon avis, optparse n'est clairement pas adapté ici.
Le module optparse sert quand tu acceptes plein d'options différentes, et que tu veux des combinaisons du genre « -xcvf », mais là, il n'y a que deux cas particulier (« --text » et « --html ») (et encore, si j'n'avais pas rajouté la sortie texte parce que c'était plus facile à visualiser dans un terminal, il n'y en aurait même pas eu du tout), le reste n'est que de des valeurs à récupérer. Sortir optparse pour ça, c'est un peu comme sortir un marteau-piqueur pour ouvrir une noix.
(D'autant que j'me doute que ça doit être possible, mais je n'sais pas du tout comment dire à optparse de me garder les arguments autre que des options sans me balancer une exception parce que ce ne sont pas des options prévues. Je connais super mal ce module, en fait).
Quand tu fais ça :
for i in range(0, month-1, 1): self.dayOfYear += self.mlens[i]
pourquoi ne pas faire plutôt (gain de performance et de lisibilité, amha, surtout que Python est clairement designer dans ce sens):
for m in self.mlens[:month-1]: self.dayOfYear += m
Et c'est pas le seul exemple où tu boucles sur les indices alors que tu ne fais pas traitement particulier avec que de parcourir la liste linéairement.
J'fais ça surtout parce que je suis habitué à plein d'autres langages qui ont une vraie boucle for et pas juste un foreach déguisé. D'ailleurs, j'trouve que c'est une lacune de python, l'absence d'une vraie boucle for. On peut bien sûr refaire ça facilement avec une boucle while, mais ça n'a pas du tout le même rendu visuel.
La boucle foreach est bien aussi, mais sémantiquement, c'est un truc que tu n'utilises que quand tu veux parcourir toutes les entrées d'un conteneur, ce qui n'est pas le cas ici (même si on peut effectivement faire en prenant un conteneur plus petit). En l'occurrence, j'trouve beaucoup plus lisible de parcourir le tableau indice par indice.
D'autant que mon objectif n'est pas de me spécialiser dans un langage en particulier, donc j'n'aime pas trop utiliser des subtilités de codage d'un langage particulier quand on peut arriver exactement au même résultat en utilisant une syntaxe plus « commune ».
(ou encore un traitement basé sur la liste ['lundi', 'mardi', ...], plus facile pour ajuster par la suite les caractères blancs dans ton formatage)
Ouaip, ç'eût peut-être été le plus intéressant si j'avais soigné la forme, mais j'ai fait ça en vitesse.
Et sinon, moi, en ce qui me concerne, je préfère largement ma version à la tienne. Pour moi, une chaîne de caractères, soit tu la développes sur plusieurs lignes, mais auquel cas le contenu correspond très exactement au résultat, genre un saut de ligne est là pour remplacer un "\n" et une vraie tabulation pour un "\t", soit tu la contractes.
Mettre des sauts de lignes échappés par des antislashes, je trouve ça largement moins présentable.
C'est plus safe (par ex, si tu dois répéter cette action plusieurs fois dans ton code, ça évite de compter à chaque fois les espaces), et utiliser les méthodes de built-in types, c'est le bien. Sachant que tu peux ajuster le caractère à répéter pour le rjust (des tabs, des é, des >, bref, ce que tu veux).
En l'occurrence, la tab ne l'aurait pas fait, puisque c'est pour aligner des caractères à la colonne près ^^ Mais sinon, j'suis d'accord avec ton raisonnement.
Le truc, c'est d'une part que je ne connaissais pas la fonction rjust (j'ai apprit le python tout seul, alors j'ai loupé plein des trucs intéressants que t'es censé voir dès le début, comme à chaque fois que j'apprends à faire un truc tout seul…), et d'autre part, comme je l'ai dit juste au dessus, que je préfère faire du générique récupérable ailleurs en un minimum de corrections que du spécifiques dont tu vas être perdu et te demander comment faire dès que tu devrais changer de langage.
En C#, par exemple, j'utilise catégoriquement d'utiliser le StringBuilder (mais c'est aussi parce que je trouve ce truc totalement aberrant, alors qu'il aurait été tellement plus simple de mettre les bonnes fonctions directement dans la classe String).
Pour les commentaires en anglais, c'est pa smal, mais évite les abréviations orales (aren't). Y'a peut-être d'autres petits trucs, mais je vais pas tout relever.
Bah pour autant que j'me souvienne, j'ai toujours vu écrit ça comme ça, donc je n'me suis pas posé trop de question. Y a vraiment des gens qui écrivent are not ?
Sinon, ça fait le boulot
Elzen : polisson, polémiste, polymathe ! (ex-ArkSeth)
Un script pour améliorer quelques trucs du forum.
La joie de t'avoir connu surpasse la peine de t'avoir perdu…
timezone[blocklist]
Hors ligne
#1442 Le 04/11/2011, à 13:50
- sweetly
Re : /* Topic des codeurs [6] */
sweetly a écrit :@ArkSeth : bon vu que c'était un test à destination d'une traduction dans un autre langage, tu n'aurais peut-être pas codé pareil en exclusive python.
À peu de chose près, si, j'pense. Désolé.
Tu n'as pas à être désolé, je m'en fiche au fond :p
Hmm… peux-tu préciser ? Parce que là, t'expliques pas trop ce que tu n'aimes pas au juste.
En l'occurrence, j'ai fait ça en tentant de réduire au maximum le nombre de lignes, juste parce que ça faisait « gros » pour poster sur un forum (je n'me rappelais plus que la balise code gérait du scroll en cas de contenu trop long).
Pour les fonctions+contenu définis entièrement sur la même ligne, en général et en dehors de toute contrainte sur le nombre de lignes, j'évite, à l'exception, de temps en temps, des trucs du genre
import gtk def mainwin_destroyed(widget): gtk.main_quit() win = gtk.Window() win.connect("destroy", mainwin_destroyed)
Mais ç'n'est pas systématique, ça dépend de l'humeur du moment.
Sinon, dès qu'il y a plusieurs instructions je passe à la ligne, mais si le « else: » n'est suivit que d'une seule instruction, ça n'me choque pas du tout de laisser ça en inline, au contraire.
Moi, ça me gêne à la lecture du code. Ca me bouffe une demi-seconde de compréhension. Le tout inline, quel qu'il soit ne trouve pas grâce à mes yeux, surtout en python.
sweetly a écrit :Plutôt que de réinventer la roue, pourquoi ne pas utiliser optparse pour parser les arguments (en l'occurrence, dans ton cas, ça t'aurait pris sûrement plus de lignes à écrire, ceci dit, quoique) ?
Parce qu'à mon avis, optparse n'est clairement pas adapté ici.
Le module optparse sert quand tu acceptes plein d'options différentes, et que tu veux des combinaisons du genre « -xcvf », mais là, il n'y a que deux cas particulier (« --text » et « --html ») (et encore, si j'n'avais pas rajouté la sortie texte parce que c'était plus facile à visualiser dans un terminal, il n'y en aurait même pas eu du tout), le reste n'est que de des valeurs à récupérer. Sortir optparse pour ça, c'est un peu comme sortir un marteau-piqueur pour ouvrir une noix.
(D'autant que j'me doute que ça doit être possible, mais je n'sais pas du tout comment dire à optparse de me garder les arguments autre que des options sans me balancer une exception parce que ce ne sont pas des options prévues. Je connais super mal ce module, en fait).
Qui peut le plus, peut le moins, surtout quand c'est pas trop mal fait, et optparse n'est pas trop mal fait. Sinon, depuis 2.7, il vaut mieux utiliser argparse, d'ailleurs.
sweetly a écrit :Quand tu fais ça :
for i in range(0, month-1, 1): self.dayOfYear += self.mlens[i]
pourquoi ne pas faire plutôt (gain de performance et de lisibilité, amha, surtout que Python est clairement designer dans ce sens):
for m in self.mlens[:month-1]: self.dayOfYear += m
Et c'est pas le seul exemple où tu boucles sur les indices alors que tu ne fais pas traitement particulier avec que de parcourir la liste linéairement.
J'fais ça surtout parce que je suis habitué à plein d'autres langages qui ont une vraie boucle for et pas juste un foreach déguisé. D'ailleurs, j'trouve que c'est une lacune de python, l'absence d'une vraie boucle for. On peut bien sûr refaire ça facilement avec une boucle while, mais ça n'a pas du tout le même rendu visuel.
La boucle foreach est bien aussi, mais sémantiquement, c'est un truc que tu n'utilises que quand tu veux parcourir toutes les entrées d'un conteneur, ce qui n'est pas le cas ici (même si on peut effectivement faire en prenant un conteneur plus petit). En l'occurrence, j'trouve beaucoup plus lisible de parcourir le tableau indice par indice.
D'autant que mon objectif n'est pas de me spécialiser dans un langage en particulier, donc j'n'aime pas trop utiliser des subtilités de codage d'un langage particulier quand on peut arriver exactement au même résultat en utilisant une syntaxe plus « commune ».
Là, je ne suis absolument pas d'accord. Tu veux bien parcourir chaque élément d'un conteneur (le conteneur "plus petit" est lui-même un conteneur). Je ne vois pas le problème sémantique du foreach, au contraire, c'est même exactement ce qu'il faut utiliser. Qui plus est quand le langage est designé pour ! Quant à la lisibilité, ben, encore une fois, quand tu sais ce qu'est un foreach, je le trouve beaucoup plus lisible (tu aurais pu juste écrire range(month-1), d'ailleurs).
Enfin, le foreach par défaut n'est pas une spécificité python. Donc, l'argument du "je ne veux pas me spécialiser dans un langage, je veux faire comme en C" (:p), me paraît bizarre.
sweetly a écrit :(ou encore un traitement basé sur la liste ['lundi', 'mardi', ...], plus facile pour ajuster par la suite les caractères blancs dans ton formatage)
Ouaip, ç'eût peut-être été le plus intéressant si j'avais soigné la forme, mais j'ai fait ça en vitesse.
Et sinon, moi, en ce qui me concerne, je préfère largement ma version à la tienne. Pour moi, une chaîne de caractères, soit tu la développes sur plusieurs lignes, mais auquel cas le contenu correspond très exactement au résultat, genre un saut de ligne est là pour remplacer un "\n" et une vraie tabulation pour un "\t", soit tu la contractes.
Mettre des sauts de lignes échappés par des antislashes, je trouve ça largement moins présentable.
L'antislash, c'est pas pour un saut de ligne, c'est juste pour la continuation de ligne. Ce que j'ai écrit reviens très exactement à :
s = " lundi mardi mercredi jeudi vendredi samedi dimanche \n"
C'était juste pour éviter d'avoir une ligne trop longue.
sweetly a écrit :C'est plus safe (par ex, si tu dois répéter cette action plusieurs fois dans ton code, ça évite de compter à chaque fois les espaces), et utiliser les méthodes de built-in types, c'est le bien. Sachant que tu peux ajuster le caractère à répéter pour le rjust (des tabs, des é, des >, bref, ce que tu veux).
En l'occurrence, la tab ne l'aurait pas fait, puisque c'est pour aligner des caractères à la colonne près ^^ Mais sinon, j'suis d'accord avec ton raisonnement.
Le truc, c'est d'une part que je ne connaissais pas la fonction rjust (j'ai apprit le python tout seul, alors j'ai loupé plein des trucs intéressants que t'es censé voir dès le début, comme à chaque fois que j'apprends à faire un truc tout seul…), et d'autre part, comme je l'ai dit juste au dessus, que je préfère faire du générique récupérable ailleurs en un minimum de corrections que du spécifiques dont tu vas être perdu et te demander comment faire dès que tu devrais changer de langage.
Moi aussi, je l'ai appris tout seul, mais à force d'en faire, de faire des fonctions toutes connes à cahque module pour refaire les mêmes choses, tu te dis que ça existe peut-être dans la pyton stl. Et oui, donc je t'en fais profiter :D
Il y avait encore une autre solution, plus simple que le rjust :
s = ' ' * 10
Sinon, je ne comprends pas pourquoi tu fais du python si tu veux pas utiliser le sucre syntaxique qu'il y a dedans.
sweetly a écrit :Pour les commentaires en anglais, c'est pas mal, mais évite les abréviations orales (aren't). Y'a peut-être d'autres petits trucs, mais je vais pas tout relever.
Bah pour autant que j'me souvienne, j'ai toujours vu écrit ça comme ça, donc je n'me suis pas posé trop de question. Y a vraiment des gens qui écrivent are not ? :o
Moi :p
Dernière modification par sweetly (Le 04/11/2011, à 14:02)
Hors ligne
#1443 Le 04/11/2011, à 13:54
- The Uploader
Re : /* Topic des codeurs [6] */
Enfin, le foreach par défaut n'est pas une spécificité python. Donc, l'argument du "je ne veux pas me spécialiser dans un langage, je veux faire comme en C" (:p), me paraît bizarre.
Spareil en ruby : .each et for ne sont que le for each du langage.
Et sinon sur les if/else, j'aime les ternaires et les if/unless en fin de ligne (à la Ruby).
- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10
Hors ligne
#1444 Le 04/11/2011, à 13:58
- Dr Le Rouge
Re : /* Topic des codeurs [6] */
ArkSeth a écrit :Y a vraiment des gens qui écrivent are not ?
Moi
Et moi
C'est deux suites de Cauchy qui veulent aller à la soirée 'no limit'. Hélas, à l'entrée le videur leur dit : "désolé, c'est complet !".
mon site perso (π²/6.fr) et mon blog
Hors ligne
#1445 Le 04/11/2011, à 14:00
- Kanor
Re : /* Topic des codeurs [6] */
Et je trouve que bien coder c'est de prendre en compte les spécificité d'un langage de programmation.
Sinon ArkSeth tu devrais ressayer les templates c'est super pratique quand tu a un petit modification de style à faire.
Dernière modification par Kanor (Le 04/11/2011, à 14:11)
Hors ligne
#1446 Le 04/11/2011, à 14:06
- tshirtman
Re : /* Topic des codeurs [6] */
L'intérêt d'un template selon moi, c'est qu'on sépare la présentation de la logique, et qu'on peut voir la page sans résultat dedans, pour la donner à skinner à un intégrateur, ensuite, on ajoute les boucles et les insertions de données dedans, c'est bien plus clair. Alors qu'a la construction à la php classique, c'est simple à comprendre certes, mais c'est vite une horreur à débugger.
Hors ligne
#1447 Le 04/11/2011, à 14:16
- HP
Re : /* Topic des codeurs [6] */
Et je trouve que bien coder c'est de prendre en compte les spécificité d'un langage de programmation.
Évidemment.
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#1448 Le 04/11/2011, à 14:22
- Rolinh
Re : /* Topic des codeurs [6] */
Y a vraiment des gens qui écrivent are not ?
Moi. En fait, on ne devrait jamais écrire la version abrégée car elle sert pour l'oral. Enfin, c'est surtout valable en littérature quoi. Si t'écris un mail à un pote je pense que tout le monde s'en fiche.
Sinon, je salue ton effort pour l'anglais
Hors ligne
#1449 Le 04/11/2011, à 14:51
- Elzen
Re : /* Topic des codeurs [6] */
Moi, ça me gêne à la lecture du code. Ca me bouffe une demi-seconde de compréhension. Le tout inline, quel qu'il soit ne trouve pas grâce à mes yeux, surtout en python.
Bah je n'le fais pas souvent, c'est sûr (sauf dans le cas du « else: » qui ne fait qu'un truc).
Qui peut le plus, peut le moins, surtout quand c'est pas trop mal fait, et optparse n'est pas trop mal fait. Sinon, depuis 2.7, il vaut mieux utiliser argparse, d'ailleurs.
Ouais, mais quand ç'n'est pas la peine d'utiliser un module externe parce que le traitement est juste trivial et rapide, bah j'n'utilise pas de module externe, même s'il peut faire ça aussi bien
Enfin, le foreach par défaut n'est pas une spécificité python. Donc, l'argument du "je ne veux pas me spécialiser dans un langage, je veux faire comme en C" (:p), me paraît bizarre.
Rien à voir avec le C, que j'ai commencer à savoir vraiment utiliser après Python.
Les langages avec lesquels j'ai apprit à programmer sont Java 1.4 (les foreach sont apparus dans la 1.5, mais c'est vrai qu'ils ont une syntaxe plutôt « pythonesque ») et PHP (dans lequel les foreach ont un mot-clef foreach, ç'plus clair).
Mais en l'occurrence, j'pensais surtout au truc en pseudo-code. Je sais que chacun fait son pseudo-code différemment, mais j'ai toujours, même avant de savoir utiliser un foreach dans quelque langage que ce soit, fait la différence entre tant que condition, pour i de X à Y et pour chaque e de E.
Et « les mois jusqu'à celui en cours », sémantiquement, ça me paraît plus se rapprocher du 2e cas.
L'antislash, c'est pas pour un saut de ligne, c'est juste pour la continuation de ligne.
Je sais, mais c'est de dont visuellement ça a l'air et c'est ça que j'n'aime pas.
Il y avait encore une autre solution, plus simple que le rjust :
s = ' ' * 10
Yep, merci aussi ^^
Sinon, je ne comprends pas pourquoi tu fais du python si tu veux pas utiliser le sucre syntaxique qu'il y a dedans.
J'dirais qu'il n'y a pas que les langages, qui ont leurs spécificités, il y a aussi les développeurs. J'fais selon ce qui me paraît naturel à moi.
Et je trouve que bien coder c'est de prendre en compte les spécificité d'un langage de programmation.
Ça dépend ce qu'il s'agit de coder. Quand c'est pour un truc dont le langage est fixé, ouais, bien sûr. Quand il s'agit, comme là, d'un algo pour savoir ce qu'il faut faire dans ce genre de situation, non. Ça rejoint un peu ce que disait sweetly au début de son post, en fait. Ç'vrai que j'ai codé ça plus comme du pseudo-code que comme du python.
Sinon ArkSeth tu devrais ressayer les templates c'est super pratique quand tu a un petit modification de style à faire.
J'ai essayé, j'ai jamais accroché.
L'intérêt d'un template selon moi, c'est qu'on sépare la présentation de la logique, et qu'on peut voir la page sans résultat dedans, pour la donner à skinner à un intégrateur, ensuite, on ajoute les boucles et les insertions de données dedans, c'est bien plus clair. Alors qu'a la construction à la php classique, c'est simple à comprendre certes, mais c'est vite une horreur à débugger.
J'n'ai jamais eu de soucis côté débuggage. Au contraire, je « sais mieux » à quelle partie du code correspond quelle partie du résultat.
Après, quand il s'agit de trucs vraiment propres, j'me faits des trucs genre ça :
def generate_header(title, favicon, styles, scripts):
header = """≤?xml version="1.0" encoding="utf-8" ?≥
≤!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"≥
≤html xmlns="http://www.w3.org/1999/xhtml"≥
≤head≥
≤title≥"""+title+"""≤/title≥
≤meta http-equiv="Content-Type" content="text/html; charset=utf-8" /≥
≤link rel="Shortcut Icon" type="image/x-icon" href=\""""+favicon+'" /≥'
for style in styles:
header += '\n\t≤link rel="Stylesheet" type="text/CSS" href="'+style+'" /≥'
for script in scripts:
header += '\n\t≤script type="text/JavaScript" src="'+script+'"≥≤/script≥'
return header+"""
≤/head≥
≤body≥"""
HTML_FOOTER = "\n≤/body≥\n≤/html≥"
def generate_checkbox(id, label, checked, action):
input = '≤input type="checkbox" name="'+id+'" id="'+id
if (action != None):
input += ' onchange="return '+action+'();"'
if (checked):
input += ' checked="checked"'
return input +'" /≥≤label for="'+id+'"≥'+label+'≤/label≥'
(Exemple codé totalement à l'arrache, sans relecture ni réflexion, et balises massacrées pour que le forum les accepte), donc j'ai bien la partie traitement séparée de la partie construction du rendu, mais là, en l'occurrence, ma fonction de création de calendrier en HTML est une partie rendu et pas une partie traitement, selon moi.
Dernière modification par ArkSeth (Le 04/11/2011, à 14:56)
Elzen : polisson, polémiste, polymathe ! (ex-ArkSeth)
Un script pour améliorer quelques trucs du forum.
La joie de t'avoir connu surpasse la peine de t'avoir perdu…
timezone[blocklist]
Hors ligne
#1450 Le 04/11/2011, à 15:05
- tshirtman
Re : /* Topic des codeurs [6] */
ben les templates, c'est exactement ça, mais séparé dans un autre fichier, ou tu as ta coloration syntaxique pour le html, et quelques mots clés en plus pour simplifier la vie.
(c'est normal les ≤ et ≥ au lien de < et > ? ^^ edit, j'ai rien dit, c'est pour le forum)
Dernière modification par tshirtman (Le 04/11/2011, à 15:06)
Hors ligne