Cet article utilise uniquement le script de Je veux empêcher le haut-parleur connecté à Raspberry Pi (jessie) de devenir bon lorsque le système d'exploitation est redémarré (script Perl) en Python. Le contenu est que je l'ai écrit. Par conséquent, sachez qu'il n'y a rien de nouveau à part le script.
Veuillez cocher Je veux empêcher le haut-parleur connecté au Raspberry Pi (jessie) de devenir bon au redémarrage du système d'exploitation (script Perl).
Allons-y maintenant.
Je vais le coller pour le moment. Je vais l'expliquer ci-dessous.
get_dac_port_num.py
#!/usr/bin/python
# coding: utf-8
import sys
import re
HUB = {}
reBUS = re.compile(r'Bus (\d*)\.Port')
reHUB = re.compile(r'^(\s*)\|__.*Port (\d*): .*Class=Hub')
rePort = re.compile(r'^(\s*)\|__.*Port (\d*): .*Driver=snd-usb-audio')
for line in sys.stdin:
tmp = reHUB.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2))) + "."
continue
tmp = rePort.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2)))
for v in range(0,len(tmp.group(1))+1):
if HUB.has_key(v):
sys.stdout.write(HUB.get(v))
exit()
tmp = reBUS.search( line )
if tmp:
HUB[0] = str(int(tmp.group(1))) + "-"
continue
Regardons de plus près.
J'ai importé sys et j'utilise des entrées standard et des expressions régulières.
import sys
import re
Définissez un dictionnaire pour contenir chaque numéro. Il n'est pas nécessaire que le nom soit HUB, mais c'est arrivé.
HUB = {}
Ce qui suit est pré-compilé sous forme de sort pour transformer les expressions régulières plus rapidement. De haut en bas, expressions régulières pour les numéros de bus, les numéros de hub et les numéros de port. L'expression régulière elle-même est [quand Perl](http://qiita.com/kouichirou/items/76dadc7cab6ef694fe18#%E5%AD%90%E3%82%B9%E3%82%AF%E3%83%AA%E3 C'est exactement la même chose que% 83% 97% E3% 83% 88).
reBUS = re.compile(r'Bus (\d*)\.Port')
reHUB = re.compile(r'^(\s*)\|__.*Port (\d*): .*Class=Hub')
rePort = re.compile(r'^(\s*)\|__.*Port (\d*): .*Driver=snd-usb-audio')
Je n'expliquerai pas les détails, mais chaque groupe (entre parenthèses) pour référence arrière est inclus. Pour plus de détails, veuillez consulter ici.
Cela signifie qu'il traitera ligne par ligne à partir de l'entrée standard.
for line in sys.stdin:
Pour le moment, [ici](http://webdev.bulkitem.com/python%E3%81%A7%E6%A8%99%E6%BA%96%E5%85%A5%E5%8A%9B%E3% 82% 92% E8% AA% AD% E3% 82% 80) J'ai également considéré la méthode de lecture du tout en premier comme buffer = sys.stdin.readline.splitlines ()
Cependant, il semble que la vitesse était lente, alors je me suis arrêté. (Même si le résultat du remplissage des données de test à environ 200000 lignes (ce qui est peu probable avec lsusb -t) a montré une différence d'environ 10%, donc l'un ou l'autre convient pour une utilisation pratique.)
Commencez par vérifier la valeur de HUB.
Trouvez la ligne de lecture dans l'objet précompilé reHUB
.
tmp
est l'objet qui contient les résultats de la recherche. Il est utilisé pour référencer en arrière la valeur acquise en tant que groupe au moment de la recherche en tant que tmp.group (1)
.
S'il y a un objet dans le résultat de la recherche (= si l'expression régulière correspond), une valeur est ajoutée au dictionnaire HUB. Comme dans l'exemple, la clé est le nombre de caractères vides au début de la ligne et la valeur est le nombre suivant Port, qui est acquis sous forme de chaîne de caractères, converti en type int, puis ajouté à nouveau sous forme de chaîne de caractères avec "." (Point).
tmp = reHUB.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2))) + "."
continue
Par exemple, la chaîne de caractères d'entrée est la suivante
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
Si c'est le cas, il y a 4 chiffres d'espace.
HUB[len(" ")] = str(int("1")) + "."
Autrement dit, HUB [4] =" 1 "+". "
.
À propos, la raison pour laquelle le nombre est défini sur int et str est que si la partie du nombre est «01», le résultat souhaité pour finalement passer pour délier sera étrange, par exemple, «01-01.01». Donc je suis en difficulté: grave:.
Par conséquent, même s'il s'agit de la chaîne de caractères «01», si vous la saisissez, elle deviendra «1», ce qui est pratique plus tard.
Après avoir attribué la valeur, continuez et revenez à la tête de pour.
continue
Si vous ne l'incluez pas, cela sera très inutile car il recherchera les rapports et reBUS suivants. Le traitement total sera presque doublé. Même ainsi, cela prend environ 1,2 seconde ou 0,6 seconde pour environ 200000 lignes, donc ... (Omis ci-dessous)
Le contenu du traitement est presque le même que celui du Hub ci-dessus, mais la différence est qu'il y a un traitement de sortie.
tmp = rePort.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2)))
for v in range(0,len(tmp.group(1))+1):
if HUB.has_key(v):
sys.stdout.write(HUB.get(v))
exit()
Correspondance dans la recherche de port = BUS et HUB doivent déjà avoir des valeurs. Par conséquent, la valeur entrée dans le dictionnaire HUB est sortie autant que nécessaire. (Autant que vous en avez besoin, car s'il y a une longue branche avec de nombreux HUB suspendus au milieu, le HUB sera aussi profond que le nombre de HUB.
Par exemple, supposons qu'il y ait une longue branche au milieu et que le dictionnaire HUB soit dans l'état suivant. (Les clés du dictionnaire ne doivent pas être triées par nature, mais par souci de simplicité.)
['0':'1-' , '4':'2.' , '8':'1.' , '12':'3.' , '16':'2.' , '20':'1.' ]
#Évaluer-Est attaché à BUS,.HUB est attaché.
Alors fais quelques pas
['0':'1-' , '4':'3.' , '8':'3' , '12':'3.' , '16':'2.' , '20':'1.' ]
#Évaluer-Est attaché à BUS,.HUB est attaché à, et Port est uniquement le numéro sans rien.
Dans un tel état, il est correct de sortir "1-3.3", mais si tous sont sortis, cela n'aura pas de sens comme "1-3.33.2.1.".
Donc, pour la clé du dictionnaire HUB, faites la valeur de 0 au nombre de chiffres requis (jusqu'à 8 dans le cas ci-dessus) avec range, mais comme la plage de Python semble commencer à 0, vous devez +1.
for v in range(0,len(tmp.group(1))+1):
if HUB.has_key(v):
sys.stdout.write(HUB.get(v))
De plus, comme la clé prend des valeurs discrètes, elle est vérifiée avec has_key
pour éviter les erreurs lorsqu'il n'y a pas de valeurs.
Enfin, c'est BUS. Cependant, c'est presque la même chose que HUB. La différence est que la clé est 0, ce qui est un point défini. BUS est le niveau le plus élevé, vous n'avez donc pas à le calculer un par un.
tmp = reBUS.search( line )
if tmp:
HUB[0] = str(int(tmp.group(1))) + "-"
continue
Le résultat de lsusb -t est au plus une douzaine de lignes, donc en pratique, peu importe celle que vous utilisez vraiment: sueur_smile:, je me demande à quel point les performances sont différentes, comme mentionné ci-dessus, le nombre de lignes cibles est gaspillé. Je l'ai testé sur le même Linux avec l'augmentation des cas. Il a été gonflé à environ 200 000 lignes, mais il ne sert à rien de mentionner le nombre de lignes qui restent, alors préoccupons-nous simplement de la différence qu'il y a avec le même nombre de lignes.
Quand j'ai mesuré le temps du script Perl (version extrait du processus correspondant uniquement) plusieurs fois avec le temps, c'était à peu près
Perl
real 0m0.450s
user 0m0.433s
sys 0m0.031s
C'est un sentiment de chiffres. Par contre, avec Python,
Python
real 0m0.720s
user 0m0.710s
sys 0m0.019s
Se sentir comme. Quant à la valeur de l'utilisateur, Python est environ 1,6 fois. Il y a une différence considérable.
Lorsque le nombre de lignes cibles est d'environ quelques lignes réelles
Perl
real 0m0.011s
user 0m0.004s
sys 0m0.006s
Python
real 0m0.021s
user 0m0.012s
sys 0m0.009s
J'avais envie de dire. Hmm. Je pensais que Perl était assez lourd, mais est-ce un peu plus rapide que Python? (Dans ce processus, cependant.)
Pour le moment, j'étais préoccupé par la vitesse, j'ai donc pensé à divers algorithmes Python en tant que tels.
Comme je l'ai déjà expliqué ci-dessus, il sera plus rapide de penser normalement. Après avoir traité quelque chose, je passerai à la ligne suivante sans aucun traitement supplémentaire. Au fait, je pense qu'il vaudrait mieux faire ça pour la version Perl aussi, mais je ne voulais pas changer ce que je pourrais écrire court, alors j'ai arrêté d'y penser.
J'ai aussi essayé diverses choses, mais
――Le nombre de BUS est absolument petit, donc le dernier convient. ――En ce qui concerne HUB, je pense qu'il était préférable de le mettre en premier car de nombreux HUB ont été intentionnellement inclus dans les données de test gonflées cette fois. ――Le port est donc au milieu. Il peut être préférable de changer l'ordre du HUB et du Port s'il y a peu de HUB et beaucoup de Ports.
Alors je me suis calmé. S'il s'agit d'une classe d'algorithme universitaire, elle serait évaluée en comptant le nombre, mais bon, elle est omise: stuck_out_tongue:.
Comme le traitement de for est similaire pour BUS, HUB et Port, je voulais juste en faire une fonction. Cependant, j'ai dû changer l'expression régulière de reBUS pour en faire une fonction, et il semblait que le nouveau reBUS était un frein, et il était environ 10% plus lent. (De plus, la partie sortie est incomplète car elle a été omise dans la source suivante, et il est mignon qu'il n'y ait pas de "-" ou "." Lors de la substitution dans le dictionnaire HUB. Cela n'affecte pas tellement.)
reBUS = re.compile(r'^\S*(\s*)Bus (\d*)\.Port')
#reBUS = re.compile(r'Bus (\d*)\.Port')
reHUB = re.compile(r'^(\s*)\|__.*Port (\d*): .*Class=Hub')
rePort = re.compile(r'^(\s*)\|__.*Port (\d*): .*Driver=snd-usb-audio')
def calc(re,line):
tmp = re.search( line )
if tmp:
HUB[len(tmp.group(1))] = int(tmp.group(2))
return True
else:
return False
for line in sys.stdin:
if calc(reHUB,line):
continue
if calc(rePort,line):
print HUB
exit()
if calc(reBUS,line):
continue
J'ai mis l'objet pré-compilé dans un dictionnaire appelé reS et pour cela.
Ça a l'air magnifique, ça ne ressemble pas à ça. ..
La vitesse a presque doublé. Il serait superflu de vérifier RE == rePort
à chaque fois après l'affectation aux nouveaux reBUS et reS et au dictionnaire HUB.
reS = [reBUS , rePort , reHUB ]
for line in sys.stdin:
for RE in reS:
tmp = RE.search( line )
if tmp:
HUB[len(tmp.group(1))] = int(tmp.group(2))
if RE == rePort:
print HUB
exit()
continue
Donc, j'ai essayé divers essais et erreurs, et c'est à nouveau la source suivante. (Identique au premier)
get_dac_port_num.py
#!/usr/bin/python
# coding: utf-8
import sys
import re
HUB = {}
reBUS = re.compile(r'Bus (\d*)\.Port')
reHUB = re.compile(r'^(\s*)\|__.*Port (\d*): .*Class=Hub')
rePort = re.compile(r'^(\s*)\|__.*Port (\d*): .*Driver=snd-usb-audio')
for line in sys.stdin:
tmp = reHUB.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2))) + "."
continue
tmp = rePort.search( line )
if tmp:
HUB[len(tmp.group(1))] = str(int(tmp.group(2)))
for v in range(0,len(tmp.group(1))+1):
if HUB.has_key(v):
sys.stdout.write(HUB.get(v))
exit()
tmp = reBUS.search( line )
if tmp:
HUB[0] = str(int(tmp.group(1))) + "-"
continue
Récemment, j'écrivais du code uniquement dans des langages tels que PHP, Shell et Perl, donc j'étais un peu ennuyé par la politesse de Python selon la rumeur. Cependant, d'un autre côté, il y avait une prise de conscience récente que je devais faire une conversion de type correctement, et que si je l'abrégeais tellement en maniaque, je ne le comprendrais pas pour les débutants. J'ai pu travailler dessus avec le feeling (?)
Je pense que je n'utilise encore que les fonctionnalités très basiques de Python, alors j'écrirai à nouveau à ce sujet si j'ai quelque chose d'intéressant à étudier à l'avenir.
Ce script Python est [Child Script at Perl](http://qiita.com/kouichirou/items/76dadc7cab6ef694fe18#%E5%AD%90%E3%82%B9%E3%82%AF%E3%83] % AA% E3% 83% 97% E3% 83% 88) ne frappe pas lsusb -t en interne, donc si vous voulez l'implémenter, chmod ugo + x [chemin d'accès complet du script Python]
Garde le
/usb/bin/lsusb -t | [Chemin complet du script Python] > $UNBIND
Veuillez décrire dans le script parent comme.
Puis.