Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/01/2007, à 04:15

Francinou

[script python] chansons au hasard pour le mpio hd300 (et les autres)

Bonjour!
Je débute en python et pour me faire les dents j'ai écrit ce petit script. Comme le dit le proverbe, on gratte là où ça démange!

Il y a deux mois, j'ai acheté un lecteur mp3 (et surtout ogg) mpio hd300. Très bien, un dd de 20Go etc... mais après quelques temps, je me rends compte qu'il est limité:
- seulement 250 fichiers par répertoire
-si une liste de lecture pique dans plusieurs répertoires et que la somme des répertoires contient plus que 250 fichiers, ça foire
-pas de lecture aléatoire entre différents répertoires.
-la lecture aléatoire revient souvent sur les mêmes morceaux

J'ai 1200 fichiers classée en répertoires et sous-répertoires et l'astuce que j'ai trouvé pour lire ma musique au hasard est la suivante:
Copier 250 morceaux au hasard dans un répertoire (avec 20Go j'ai largement la place) et faire précéder le nom du fichier de son numéro d'arrivée dans le répertoire, ainsi une lecture continue dans le répertoire équivaut à  une lecture aléatoire à travers tout le dossier musique/.

J'ai donc écrit un script python qui réalise tout ça, en faisant gaffe à ne pas prendre deux fois le même morceau.

J'aimerais votre avis sur ce code et savoir si vous avez des idées d'amélioration.

[Edit]J'ai mis à jour le script avec toutes les améliorations[/Edit]

#!/usr/bin/python
# -*- coding:Utf-8 -*-

# Licence GPLv2

try:    import psyco; psyco.full() 
except:    pass

from os import walk, mkdir, environ
from re import compile
from string import upper
from random import randint
from shutil import copyfile
from os.path import exists

#Fonction qui demande à l'utilisateur de choisir un répertoire en tapant son chemin, et qui propose un répertoire par défaut (defaut).
def choisir_repertoire(defaut):
    repertoire = defaut
    ok = "rien"
    while not exists(repertoire):
        repertoire = raw_input("Le répertoire "+repertoire+" n'existe pas.\nIndiquez le chemin vers le répertoire:\n")
        ok = "p"
    while ok not in ("O", "OUI", "Y", "YES", "N", "NON", "NO", "p"):
        ok = upper(raw_input("Le répertoire actuel est "+repertoire+" voulez-vous le changer? (O/N)\n"))
        if ok in ("O", "OUI", "Y", "YES"):
            repertoire = raw_input("Indiquez le chemin vers le répertoire:\n")
            while not exists(repertoire):
                repertoire = raw_input("Le répertoire "+repertoire+" n'existe pas\nIndiquez le chemin vers le répertoire:\n")
        elif ok not in ("N", "NON", "NO"):
            print("Répondez par oui ou non\n")
    return repertoire

#Selection du répertoire contenant la musique
print "Choisissez un répertoire à scanner\n"
repertoire_musique = choisir_repertoire("/home/partage/musique")

#Selection du répertoire ou placer le répertoire hasard
print "Choisissez un répertoire où sauver le répertoire hasard\n"
home = choisir_repertoire(environ["HOME"])
repertoire_hasard = home + "/hasard"               #Le répertoire hasard

#Définition d'un fichier musical
ogg = ".+\.[oO][gG][gG]$"
mp3 = ".+\.[mM][pP]3$"
wma = ".+\.[wW][mM][aA]$"
wav = ".+\.[wW][aA][vV]$"
aac = ".+\.[mM][pP]4$|.+\.[mM]4[aA]$|.+\.[mM]4[pP]$"
flac = ".+\.[fF][lL][aA][cC]$"

choix_possible = compile('^[0-6]$')
formats=["Ogg", "Mp3", "Wma", "Wav", "Aac", "Flac"]
formats1=[ogg, mp3, wma, wav, aac, flac]
print ("Choisissez un format de fichier à rechercher :")
i=0
while i<6:
    print ("\n"+str(i+1)+". "+formats[i]),
    i+=1
choix=raw_input()
while not choix_possible.match(choix):
    print ("choisissez un nombre de 1 à 7")
    choix=raw_input()
choix = int(choix)
fichier_musical = ""
fichier_musical = fichier_musical+"|"+formats1[choix-1]
choisis = []
choisis.append(formats[choix-1])
ok = "rien"
while ok not in ("O", "OUI", "Y", "YES", "N", "NON", "NO"):
    print("Choisis :")
    for item in choisis:
        print item,
    ok = upper(raw_input("\n\nVoulez-vous ajouter un format? (O/N)"))
    if ok in ("O", "OUI", "Y", "YES"):
        print ("Choisissez un format de fichier à rechercher.")
        i=0
        while i<6:
            print ("\n"+str(i+1)+". "+formats[i]),
            i+=1
        choix=raw_input()
        while not choix_possible.match(choix):
            print ("choisissez un nombre de 1 à 6")
            choix=raw_input()
        choix = int(choix)
        fichier_musical = fichier_musical+"|"+formats1[choix-1]
        choisis.append(formats[choix-1])
    elif ok not in ("N", "NON", "NO"):
        print("Répondez par oui ou non\n")
        
fichier_musical = compile(fichier_musical)

#expression régulière d'un fichier musical
listing=[]                                        #Le listing des fichiers musicaux
listing2=[]                                        #le nom des fichiers

#nombre de morceaux à tirer au sort
entier=compile('^[0-9]+$')
nombre_a_selectionner=raw_input("Indiquez un nombre de morceaux à tirer au sort:\n")
while not entier.match(nombre_a_selectionner):
    print("La valeur entrée n'est pas un nombre entier.\n")
    nombre_a_selectionner=raw_input("Indiquez un nombre de morceaux à tirer au sort:\n")
nombre_a_selectionner=int(nombre_a_selectionner)

# création du répertoire hasard1 s'il n'existe pas, sinon hasard2, sinon.. hasardn
rep=1
while exists(repertoire_hasard+str(rep)):
    rep+=1
repertoire_hasard=repertoire_hasard+str(rep)
mkdir(repertoire_hasard)

#liste récursivement tous les fichiers musicaux de repertoire_musique dans linsting
for (chemin,reps,fichiers) in walk(repertoire_musique):            #parcourt le répertoire musique
     for fichier in fichiers:                                        #parcourt les fichiers pour chaque répertoire
         if fichier_musical.match(fichier):                            #si le fichier est un fichier musical
             listing.append(chemin+"/"+fichier)                      #ajoute le fichier au listing
             listing2.append(fichier)                              #ajoute le nom du fichier au listing2

#affiche tous les fichiers musicaux et les compte
for item in listing:                            #parcourt le listing de fichiers musicaux
    print item                                    #affiche  le fichier
nombre_fichiers_musicaux = len(listing)        #compte le nombre de fichiers musicaux
print "Il y a", nombre_fichiers_musicaux, "fichiers musicaux dans", repertoire_musique     #affiche le nombre de fichiers musicaux

nombres_hasard=[]            #un tableau de nombres au hasard

#On tire un nombre au hasard, et on le place dans le tableau pour autant qu'il ne s'y trouve pas déjà                            
while len(nombres_hasard) < nombre_a_selectionner:
    h=randint(0, nombre_fichiers_musicaux-1)
    if h not in nombres_hasard:
        nombres_hasard.append(h)

#grâce au tableau de nombres au hasard, on copie les fichiers musicaux correspondants dans le répertoire hasardn       
ordre=0
for hasard in nombres_hasard:
    ordre+=1
    print "copie "+repertoire_hasard+"/"+str("%.3i" %ordre)+" "+listing2[hasard]
    copyfile(listing[hasard],repertoire_hasard+"/"+str("%.3i" %ordre)+" "+listing2[hasard])

#on annonce à l'utilisateur que le programme est terminé
print "Terminé"

Dernière modification par Francinou (Le 28/06/2007, à 13:57)

Hors ligne

#2 Le 17/01/2007, à 18:58

Francinou

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

j'ai un problème en améliorant le script j'essaye de demander combien de fichiers tirer au sort, et je veux vérifier ensuite que le nombre donné correspond bien à un int. Le problème est que lorsqu'on entre un string, plutôt que de demander de recommencer, le programme plante, alors qu'il fonctionne très bien pour un float.

nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
while not isinstance(nombre_a_selectionner,int):
    print(str(nombre_a_selectionner)+" n'est pas un nombre entier.\n")
    nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")

Message d'erreur:

Indiquez un nombre de morceaux à tirer au sort:
2.5
2.5 n'est pas un nombre entier.

Indiquez un nombre de morceaux à tirer au sort:
dfs
Traceback (most recent call last):
  File "/home/fbastien/workspace/chansons_hasard/src/main.py", line 53, in ?
    nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
  File "<string>", line 0, in ?
NameError: name 'dfs' is not defined

Hors ligne

#3 Le 17/01/2007, à 19:40

snigit

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Coucou, pour ton probleme avec ta boucle while et ton entier, c'est normal qu'il fasse une erreur
il cherche la variable qui s'appelle "dfs", or celle-ci n'existe pas.
Pour passer du texte a une fonction "input" il faut le mettre entre guillemets.

Je te conseillerais d'inserer un "try / except" dans ta boucle
genre :

while type(nombre_a_selectionner)!=int : (là c'est ma modif perso :-p)
    print(str(nombre_a_selectionner)+" n'est pas un nombre entier.\n")
    try:
        nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
    except NameError:  (là tu peux juste mettre "except")
        nombre_a_selectionner = "La valeur entrée"  (là on réinitialise la variable avec un type différent de int, j'ai pas trouvé mieux)

Le problème qu'il reste, c'est si on rentre une suite de lettres des le premier "input" (avant de rentrer dans la boucle). Mais en bidouillant, ya moyen de se débrouiller

Dernière modification par snigit (Le 17/01/2007, à 20:00)

Hors ligne

#4 Le 17/01/2007, à 19:59

snigit

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Pour :

nombre_fichiers_musicaux=0                                              #compteur
for item in listing:                            #parcourt le listing de fichiers musicaux
    print item                                    #affiche  le fichier
    nombre_fichiers_musicaux+=1

Tu peux mettre :

for item in listing:                            #parcourt le listing de fichiers musicaux
    print item                                    #affiche  le fichier
nombre_fichiers_musicaux = len(listing)

Ensuite :

while len(nombres_hasard) < nombre_a_selectionner:
    h=randint(0, nombre_fichiers_musicaux-1)
    dejavu=0
    for hasard in nombres_hasard:
        if h == hasard:
            dejavu=1
            break
    if dejavu==0:
        nombres_hasard.append(h)

Tu peux mettre :

while len(nombres_hasard) < nombre_a_selectionner:
    h=randint(0, nombre_fichiers_musicaux-1)
    if h not in nombres_hasard:
        nombres_hasard.append(h)

Hors ligne

#5 Le 17/01/2007, à 20:47

Francinou

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Merci beaucoup ça fonctionne très bien! J'ai mis

#nombre de morceaux à tirer au sort
try:
    nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
except:
    nombre_a_selectionner = "pas un entier"
while type(nombre_a_selectionner)!=int :
    print("La valeur entrée n'est pas un nombre entier.\n")
    try:
        nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
    except:
        nombre_a_selectionner = "pas un entier"

et ça fonctionne à merveille!

Merci aussi pour les autres modifs, ça m'aide beaucoup dans mon apprentissage.

Hors ligne

#6 Le 17/01/2007, à 21:09

aleph

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Petite remaque

Pous comparer les types de variable, prendre l'habitude d'utiliser isinstance() et non type() == int.

Exemple
>>> a = 1
>>> isinstance(a, int)
True

#7 Le 17/01/2007, à 21:13

aleph

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Petit envoi accidentel, je continue

dans l'ancien style, la comparaison de type correcte eut été

>>> type(a) is type(1)
True

voir http://www.python.org/dev/peps/pep-0008/

#8 Le 17/01/2007, à 21:21

Francinou

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Donc

try:
    nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
except:
    nombre_a_selectionner = "pas un entier"
while not isinstance(nombre_a_selectionner, int):
    print("La valeur entrée n'est pas un nombre entier.\n")
    try:
        nombre_a_selectionner=input("Indiquez un nombre de morceaux à tirer au sort:\n")
    except:
        nombre_a_selectionner = "pas un entier"

C'est bien ça?

[Edit] :

Pour finir, j'ai changé parce que si on tape le nom d'une variable, ça prend la valeur de la variable si c'est un entier. J'ai une autre méthode à base de regex, et en plus c'est plus clair :

entier=compile('[0-9]+$')
nombre_a_selectionner=raw_input("Indiquez un nombre de morceaux à tirer au sort:\n")
while not entier.match(nombre_a_selectionner):
    print("La valeur entrée n'est pas un nombre entier.\n")
    nombre_a_selectionner=raw_input("Indiquez un nombre de morceaux à tirer au sort:\n")
nombre_a_selectionner=int(nombre_a_selectionner)

Dernière modification par Francinou (Le 17/01/2007, à 23:35)

Hors ligne

#9 Le 17/01/2007, à 23:28

snigit

Re : [script python] chansons au hasard pour le mpio hd300 (et les autres)

Wahou ! Belle progression, je me coucherai moins con ! big_smile

Hors ligne