Systeminfos mit sys.argv auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

@BlackJack

Wie würdest du es dann machen?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@MrAeon: BlackJack hat doch schon beschrieben, wie er es machen würde. Allerdings hat er Dir nicht die Implementierung geliefert — schließlich ist es ja Deine Hausaufgabe. Und er tut Dir damit auch einen Gefallen, denn nur wenn Du es selbst umsetzt, hast Du anschließend auch was gelernt — sowohl über die Implementierung als auch zur Recherche der Lösung.

Was Du bisher hast ist ein Skript, welches Informationen über das System liefert (zwar nicht robust, aber immerhin für Deine Plattform).

Was Du nun brauchst ist beispielsweise eine Funktion, die aus diesen Informationen einen bestimmten Wert zurück liefert:

Code: Alles auswählen

def get_info('cpu'):
    # gibt gewünschte Information zurück
Mit 'sys.argv' hast Du Zugriff auf die Kommandozeilenparameter (oder etwas aufwendiger aber dafür professioneller mit 'argparse'). Nun brauchst Du Dein Skript nur noch so zu erweitern, dass die gewünschte Information (oder auch mehrere) ausgegeben wird.

Das wäre jedenfalls ein möglicher Lösungsansatz, den ich Dir zur Übung vorschlagen würde.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Das ist doch sowas in der Art, oder?
MrAeon hat geschrieben:

Code: Alles auswählen

#!/usr/bin/python3.2
# Skript: M122_Scripts/python/listmemoryinfo.py
def getmemoryinfo():
  memoryinfo = open('/proc/meminfo', 'r')
  liste = memoryinfo.readlines()
  return liste
Ich hatte auch schon bereits ein Script geschrieben, welches die Kommandozeilenparameter wieder ausgibt, was ja aber nicht der sinn der Sache ist.
Kann ich eigentlich die Abfrage und "Ausgabe" von sys.argv in einem Print machen oder wäre es schlauer noch ein bis zwei weiter Code-Zeilen zu schreiben?
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Ich bin schon ein bischen weiter gekommen:

Bild

nur sollte eben stat den lauter 1en die besagten infos vom CPU kommen...
Ich bin immer noch der meinung das mit dem print noch etwas nicht Stimmt und nicht mit dem herausgesuchten Informationen...
Wie schon einmal erwähnt ist dieser Code schon fast über meinem Wissensstand von Python, da ich bis jetzt erst ca 14h Python in der Schule habe.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo MrAeon,
Du solltest dringend mal ein »print(sys.argv)« vor und eines nach Deiner for-Schleife einfügen und Dich dann fragen, was Du mit »sys.argv« gerade angestellt hast.

Code: Alles auswählen

>>> cpu = ["processor       : 0", "cpu family      : 1", "model           : 5"]
>>> for info in cpu:
...     print(info, info in cpu)
... 
processor       : 0 True
cpu family      : 1 True
model           : 5 True
>>> 
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

vielen vielen Dank @Sirius3 für deinen Tipp!!

Demnach muss nun wahrscheinlich die for schleife falsch sei, oder liege ich da Falsch?

Bild
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

ja die for-Schleife ist falsch.
Was passiert mit der Variable vor dem »in« und was mit der nach dem »in«?
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

So ich habe jetzt beschlossen alles in ein Script zu packen!
Was heisst, das ich den Code hier:

Code: Alles auswählen

def getmemoryinfo():
  memoryinfo = open('/proc/meminfo', 'r')
  liste = memoryinfo.readlines()
  return liste
in meinen anderen nehme.

Weiter habe ich gemerkt, das es mit der for schleife höchst wahrscheinlich nicht klappen wird, da diese, soweit ich gelesen habe, nur Zahlenmäßig Sachen übergibt.
Stimmt das von eurer Seite aus?
BlackJack

@MrAeon: Da sicher niemand mit der Formulierung „nur Zahlenmäßig Sachen übergibt“ etwas anfangen kann, kann man schlecht etwas dazu sagen. Mit einer ``for``-Schleife kann man den Code im Schleifenkörper für jedes Element eines iterierbaren Objekts ausführen. Also zum Beispiel für jedes Element in einer Liste, jede Zeile in einer Datei, und so weiter.

Die `getmemoryinfo()`-Funktion ist so übrigens ein wenig unsauber, weil man Dateien die man öffnet, auch wieder schliessen sollte, damit das Betriebsystem die dadurch belegten Ressourcen auch zeitnah wieder freigeben kann. Entweder kann man Dateien mit einem expliziten Aufruf der `close()`-Methode schliessen, oder man verwendet die ``with``-Anweisung, die beim verlassen des Blocks, egal aus welchem Grund, die Datei schliesst.

Man muss das Zwischenergebnis vom Lesen der Datei auch nicht unbedingt an einen Namen binden. Das liefe dann auf diese drei Zeilen hinaus (mit einer etwas lesbarer benannten Funktion):

Code: Alles auswählen

def get_memory_info():
    with open('/proc/meminfo', 'r') as memory_info_file:
        return memory_info_file.readlines()
Aber das wird letztendlich nicht ausreichen. Du müsstest beide Dateien nicht einfach als Listen von Zeilen einlesen, sondern die Informationen in diesen Dateien zeilenweise verarbeiten und in eine Datenstruktur überführen, die man dann auch sinnvoll abfragen kann. Ich wiederhole es noch einmal: Du brauchst hier ein Wörterbuch, also den Datentyp `dict` in Python. Die Informationen in den einzelnen Zeilen der beiden Dateien müssen in Schlüssel und Wert zerlegt werden. Und wenn Du dann die eingelesenen Daten in einem Wörterbuch (oder eventuell auch zwei — eines pro Datei) hast, kannst Du den nächsten Schritt in Angriff nehmen und für jedes Argument von der Kommandozeile nachschlagen ob und welche Information dort hinterlegt ist.

Wenn Du Dir die beiden Funktionen zum Einlesen und Verarbeiten der Dateien mit den Systeminformationen anschaust, wird Dir auch auffallen, dass die beide sehr viel, sehr ähnlichen Quelltext enthalten. Man also eine Funktion heraus ziehen kann, die allgemein, Dateien in diesem Format einlesen kann.

Edit: Bei den Problemen die Du mit den grundlegenden Datenstrukturen und Konstrollstrukturen wie ``for``-Schleifen hast, solltest Du vielleicht auch noch mal ein Tutorial durcharbeiten und Deine Unterlagen aus der Schule. Ein für Anfänger oft empfohlenes Tutorial ist Learn Python The Hard Way.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Hallo Zusammen
kleines Update:

Hab den Code jetzt soweit Fertig bis auf eine Kleinigkeit, das man bei der Eingabe der gewollten Information auf die Gross- und Kleinschreibung achten muss.

Hier wäre der Code:

Code: Alles auswählen

#!/usr/bin/python3.2
# Skript: M122_Scripts/python/systeminfo.py

import sys     
meminfo = open('/proc/meminfo','r')
mem = meminfo.readlines()
cpuinfo = open('/proc/cpuinfo','r')
cpu = cpuinfo.readlines()
for a in sys.argv:
  for b in mem:
    if b.find(a) != -1:
      print('++++++++++++++++++++++++')
      print('Basic Memory information:')
      print('++++++++++++++++++++++++')
      print(b)
  for c in cpu:
    if c.find(a) != -1:
      print('++++++++++++++++++++++++')
      print('Basic CPU information:')
      print('++++++++++++++++++++++++')
      print(c)
 
Er funktioniert bis auf das oben erwähnte Problem Fehlerfrei.


MFG MrAeon
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

- Die bewährte Einrückungstiefe in Python sind vier Spaces - nicht zwei!

- Deine Namen sind schlecht! Was bedeuten denn ``a``, ``b`` und ``c``? Wähle Namen so, dass sie Dir sagen, was sich dahinter verbirgt.

- Dateien sollte man mit dem ``with open() as handler``-Idiom öffnen; BlackJack zeigte Dir ja schon, wie das geht.

- Du hast zu viel Copy-and-Paste-Programmierung in Deinem Code. Schau ihn Dir genau an... im Grunde genommen kommt alles doppelt vor, nur die *Daten* unterscheiden sich (mit Ausnahme der ``for``-Schleife). Verpacke die gemeinsam genutzte Funktionalität in *separate* Funktionen und rufe diese dann mit den Datenwerten auf.

Ich sehe da eine Funktion fürs Öffnen der Dateien, eine fürs Auffinden der Informationen, eine für die Ausgabe der Infos und schließlich noch die ``main``-Funktion, die sich ums Command Line Parsing und die Aufrufe der Funktionen kümmert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten