Attribute Error

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.
Antworten
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Hi,

ich brauche mal Hilfe von erfahreneren Leuten. Ich programmiere Momentan ein Skript, um via Python und der Erweiterung "PyZDDE" für das Optiksimulationsprogramm Zemax OpticStudio Werte aus einer .csv zu lesen, mit diesen dann zu simulieren, um die Ergebnisse wieder in einer .csv auszugeben. Den Großteil des Codes habe ich mir aus Beispielen zusammengesucht, deswegen ist das Verständnis noch nicht so gegeben. Schonmal Vorweg: der Code funktionierte bisher - erst seitdem ich Zeile 48 bis 59 eingefügt habe hakt es.

Den Quelltext der PyZDDE-Erweiterung findet ihr hier: https://github.com/indranilsinharoy/PyZ ... de/zdde.py

Ich möchte die Funktion in Zeile 5461 "zSetNSCProperty" benutzen, habe aber die Syntax nicht ganz verstanden. Bisher habe ich die die Funktion ganz Stumpf wie im Quelltext aufgebaut:

Code: Alles auswählen

import sys
PyZDDEPath = 'C:\PyZDDE'  # Assuming PyZDDE was unzipped here!
  
if PyZDDEPath not in sys.path:
    sys.path.append(PyZDDEPath)

import os as os
import pyzdde.arraytrace as at  
import pyzdde.zdde as pyz
import csv


ln = pyz.createLink()
ln.zGetRefresh()
zmxfile = os.path.split(ln.zGetFile())[1]

# Get maximum number of segments
maxSeg = ln.zGetNSCSettings().maxSeg

# limit the number maximum number of segments to 50
nMaxSeg = maxSeg if maxSeg < 50 else 50

# read Phosphor Data
dateihandler = open('Phosphor_Kennwerte.csv')

inhalt = dateihandler.read()

werte = []

zeilen = inhalt.split('\n')

for i in range(len(zeilen)):
    spalten = zeilen[i].split(';')
    werte.append(spalten)

density = werte[3][2]
particleindex = werte[4][2]
size = werte[5][2]
minthresh = werte[6][2]
bluemin = werte[7][2]
bluemax = werte[8][2]
fluorescenttrans = werte[9][2]
scattertrans = werte[10][2]
power = werte[11][2]

# set NSC Property

setscattermode = at.zSetNSCProperty(surfNum=1, objNum=2, code=81, value=2)
setmeanpath = at.zSetNSCProperty(surfNum=1, objNum=2, code=82, value=2)
setdllname = at.zSetNSCProperty(surfNum=1, objNum=2, code=84, value=Phosphor.dll)
setparticleindex = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=1 , code=85, value=particleindex)
setsize = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=2, code=85, value=size)
setdensity = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=3, code=85, value=density)
setmintresh = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=4, code=85, value=minthresh)
setbluemin = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=5, code=85, value=bluemin)
setmax = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=6, code=85, value=bluemax)
setfluorescenttrans = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=7, code=85, value=fluorescenttrans)
setscattertrans = at.zSetNSCProperty(surfNum=1, objNum=2, faceNum=8, code=85, value=scattertrans)
setwaveshift = at.zSetNSCProperty(surfNum=1, objNum=2, code=86, value=1,2,1)

# Trace a single in NSC mode with polarization and splitting, but no scattering.
rayData = at.zGetNSCTraceArray(n=1, Eyr=1.0, intensity=1, surf=1, usePolar=1,
                               split=1, nMaxSegments=50)



outputfile = "H:\\Listing of Array trace data.csv"


with open(outputfile, 'w') as f:
        f.write("Listing of Array trace data\n")
        f.write("{:^4}; {:^4}; {:^4}; {:^6}; {:^4}; {:^14}; {:^14}; {:^14}; {:^12}\n"
        .format('seg#', 'Prnt', 'Levl', 'In', 'Hit', 'X', 'Y', 'Z', 'Intensity'))
        

        for i, seg in enumerate(rayData):
            segLevel = seg.segment_level
            segParent = seg.segment_parent
            insideOf = seg.inside_of
            hitObj = seg.hit_object
            x, y, z, l, m, n = seg.x, seg.y, seg.z, seg.l, seg.m, seg.n
            intensity = seg.intensity
            opl = seg.opl

            line = ("{:4d}; {:4d}; {:4d}; {:4d}; {:4d}; {:15.6E}; {:15.6E}; {:15.6E}; {:8.4f}\n"
                .format(i+1, segParent, segLevel, insideOf, hitObj, x, y, z, intensity))

            f.write(line)

ln.close()
Nun bekomme ich aber folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "H:\Testordner\test.py", line 48, in <module>
    setscattermode = at.zSetNSCProperty(surfNum=1, objNum=2, code=81, value=2)
AttributeError: 'module' object has no attribute 'zSetNSCProperty'
Das heißt doch, dass die Funktion "zSetNSCProperty" bisher kein Teil der PyZDDE-Erweiterung ist. Zumindest wurde die Funktion nicht mit ihr importiert, oder? Wieso steht die Funktion aber im Quelltext? Oder habe ich einen offensichtlichen Fehler gemacht?

Vielleicht kann mir ja jemand helfen... :K :?: :D
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na es gibt die Attribute halt nicht. Wenn man das Repository durchsucht findet man da genau eine Erwaehnung, und die ist eine leere Testimplementation. Woher hast du denn diesen Code?
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Den Code habe ich mir selber überlegt/zusammengesucht. In dieser Form funktioniert er auch mehr oder weniger:

Code: Alles auswählen

import sys
PyZDDEPath = 'C:\PyZDDE'  # Assuming PyZDDE was unzipped here!
  
if PyZDDEPath not in sys.path:
    sys.path.append(PyZDDEPath)

import os as os
import pyzdde.arraytrace as at  
import pyzdde.zdde as pyz
import csv


ln = pyz.createLink()
ln.zGetRefresh()
zmxfile = os.path.split(ln.zGetFile())[1]

# Get maximum number of segments
maxSeg = ln.zGetNSCSettings().maxSeg

# limit the number maximum number of segments to 50
nMaxSeg = maxSeg if maxSeg < 50 else 50


# Trace a single in NSC mode with polarization and splitting, but no scattering.
rayData = at.zGetNSCTraceArray(n=1, Eyr=1.0, intensity=1, surf=1, usePolar=1,
                               split=1, nMaxSegments=50)



outputfile = "H:\\Listing of Array trace data.csv"


with open(outputfile, 'w') as f:
        f.write("Listing of Array trace data\n")
        f.write("{:^4}; {:^4}; {:^4}; {:^6}; {:^4}; {:^14}; {:^14}; {:^14}; {:^12}\n"
        .format('seg#', 'Prnt', 'Levl', 'In', 'Hit', 'X', 'Y', 'Z', 'Intensity'))
        

        for i, seg in enumerate(rayData):
            segLevel = seg.segment_level
            segParent = seg.segment_parent
            insideOf = seg.inside_of
            hitObj = seg.hit_object
            x, y, z, l, m, n = seg.x, seg.y, seg.z, seg.l, seg.m, seg.n
            intensity = seg.intensity
            opl = seg.opl

            line = ("{:4d}; {:4d}; {:4d}; {:4d}; {:4d}; {:15.6E}; {:15.6E}; {:15.6E}; {:8.4f}\n"
                .format(i+1, segParent, segLevel, insideOf, hitObj, x, y, z, intensity))

            f.write(line)

ln.close()
Einen ziemlich ähnlichen Code gibt es auf dieser GitHub-Seite (siehe "Example 3" etwas weiter unten): https://github.com/indranilsinharoy/PyZ ... n-article)
Nur das dort nicht in eine .csv geschrieben wird. Das habe ich angepasst.

In beiden Links die ich genannt habe, wird die SetNSCProperty-Funktion ja auch angegeben. Irgendwie muss man damit ja arbeiten können... :K Ich kenne mich nicht wirklich aus, aber kann mir jemand sagen wie ich Funktionen der PyZDDE finden kann? Zum Beispiele die Funktion "zGetNSCTraceArray" ist nirgends zu finden, wird aber in dem Code benutzt und funktioniert auch.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also ich finde keine Referenzen auf SetNSC*. Hingegen durchaus fuer zGetNSCTraceArray: https://github.com/indranilsinharoy/PyZ ... rray&type=

Insofern weiss ich immer noch nicht, woher du glaubst, dass es das gibt. Spaetestens irgendwo im Code muss es eine Implementierung dafuer geben, Dokumentation hin oder her. Und wenn es das nicht gibt, dann gibt es eben einen AttributeError wenn man trotzdem probiert die zu verwenden.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Erstmal vielen Dank für deine Hilfe! Ich weiß wie nervig das sein kann... Dein Link hat mir an anderer Stelle schon geholfen. :D

Ich glaube ich weiß was du mir sagen möchtest. Aber im Grund hat der zweite Treffer aus deinem Link doch genau die Struktur aus meinem Link (Zeile 5461)
https://github.com/indranilsinharoy/PyZ ... de/zdde.py. GetNSCTracearray ist Teil der PyZDDE und SetNSCProperty nicht, obwohl es, so sieht es mit meinem amateurhaften Blick zumindest aus, "ähnlich" aufgebaut und vorgestellt wird. Ist das die Message die du mir versuchst mitzuteilen?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na, ich finde es halt nirgendwo, vor allem nicht im Code. Ist also nicht da :K Da ich nicht den Hauch einer Ahnung habe, was da inhaltlich passieren soll, kann ich auch keine Alternative vorschlagen.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Ich sehe das hier:

Code: Alles auswählen

 def zSetNSCProperty(self, surfNum, objNum, faceNum, code, value):
        """Sets a numeric or string value to the property pages of objects
        defined in the NSC editor. It mimics the ZPL function NPRO.
        Parameters
        ----------
        surfNum : integer
            surface number of the NSC group. Use 1 if for pure NSC mode
        objNum : integer
            the NSC ojbect number
        faceNum : integer
            face number. Use 0 for "All Faces"
        code : integer
            for the specific code
        value : string/integer/float
            value to set NSC property
        Returns
        -------
        nscPropData : string/float/integer
            the returned data (same as returned by ``zGetNSCProperty()``)
            depends on the ``code``. If the command fails, it returns
            ``-1``. Refer table nsc-property-codes_.
Aber ich habe keine Ahnung wie ich damit umgehen soll...
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Woher kommt denn das? Und das ist im uebrigen auch eine Methode, die funktioniert auf einem Objekt. Du probierst aber eine Funktion auf einem Modul aufzurufen ("this module has no attribute...")
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Wie gesagt, das kommt hier her: https://github.com/indranilsinharoy/PyZ ... de/zdde.py (Zeile 5461)
__deets__ hat geschrieben:Und das ist im uebrigen auch eine Methode, die funktioniert auf einem Objekt.
Sorry für die ganz doofe Frage, aber was bedeutet das? ...Gerade in meinem speziellen Fall...?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ok, also erstmal ist es komisch das ich das nicht gefunden habe - die github Suche ist da offensichtlich fehlerhaft, denn da habe ich es probiert mit zu finden.

Und das ist eine Methode auf dem Objekt vom Typ PyZDDE. Das scheint in deinem Fall das (sehr bescheiden benannte...) ln-Ding zu sein. Nicht das Modul at.

Ob du auf Dauer weiter kommst, ohne wenigstens das kleine Python 1x1 zu beherrschen, kann ich mir nicht so recht vorstellen. Was ein Modul ist, und was ein Objekt sind schon ziemlich fundamentale Grundlagen.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

__deets__ hat geschrieben:Und das ist eine Methode auf dem Objekt vom Typ PyZDDE.
Ist PyZDDE jetzt das Objekt oder die Methode? Das wird für mich aus dem Satzbau nicht klar, sorry. :| Ich tippe darauf, dass PyZDDE das Objekt ist und ln. die Methode, mit der ich einen Link zum Objekt herstelle?!
__deets__ hat geschrieben:Das scheint in deinem Fall das (sehr bescheiden benannte...) ln-Ding zu sein.
Du meinst bestimmt die Zeile "ln = pyz.createlink()", oder?


Wieso funktioniert dann GetNSCTraceArray mit dem Modul at.?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil es etwas andres ist? Ich weiß nicht was das tut, aber wenn du dich in dein Auto setzt erwartest du doch auch nicht, dass du die Wäschetrommel öffnen kannst. Genauso wenig können irgendwelche Funktionen und Methoden an beliebigen Orten auftauchen und nutzbringend verwandt werden.

Und ln ist dein Objekt. Es ist vom Typ PyZDDE. Statt Typ kann man auch klasse sagen. Frau Erna Pasulke ist das Objekt von der Klasse “deine Tante”.

Was ein Modul, ein Objekt, eine Methode, eine Klasse und eine Funktion sind, und wie sich das alles zueinander verhält, steht alles im gRundlagentutorial. Das möchte ich hier ehrlich gesagt nicht noch mal vorkauen.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Ok, ok. Ich gucke mir das ganze erstmal gründlich an. Danke für die Hinweise! Diese bildlichen Beschreibungen sind für mich als absoluter Nicht-Informatiker viel einfacher zu verstehen.

Eine Frage würde ich aber gerne noch stellen. Kann man irgendwie sehen was SetNSCProperty ist? Anscheinend ja nicht, oder? Das heißt ich kann aus dem GitHub-Zeugs absolut nicht ahnen wie ich die Befehle einbauen muss?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du versuchst schon wieder durch raten weiter zu kommen :K

Dieses Tool ist sehr spezifisch. Was es tut, und warum, und wie man das beeinflusst- keine Ahnung. Du selbst hast ja die Dokumentation hier zitiert. Wenn dir die nix sagt - ICH hab’s erst recht nicht geblickt. “Code for the specific code” ist so klar wie Betonbrühe für mich.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

`SetNSCProperty` wird in der Klasse `PyZDDE` definiert, also hat auch jedes Exemplar dieser Klasse diese Methode. Eigentlich sollte es Dir klar sein, wenn Du weißt, was die Methode macht und für was die Objekte da sind, die Du erzeugst.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

Nein, damit wollte ich abschätzen wie groß das Problem ist. Wenn du mir jetzt sagst, es sei auch für dich unmöglich zu wissen wie man die speziellen Befehle einbindet, wird es für mich um ein vielfaches schwieriger.
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

__deets__ hat geschrieben:“Code for the specific code” ist so klar wie Betonbrühe für mich.
Darüber bin ich gerade nochmal gestolpert. Was das bedeutet ist mir mehr oder weniger klar. Das sind alles Einstellungen, die ich in dem Optik-Programm vornehmen möchte. Der Teil in der Klammer hinter dem Befehl ist (hoffentlich) nicht das Problem denke ich.

Viel mehr stehe ich vor der Aufgabe, die Funktion zum laufen zu bekommen. "rayData = at.zGetNSCTraceArray()" funktioniert. So wie ich __deets__ abr auch verstanden habe, kann hier niemand sagen was "at.z..." macht, sodass auch niemand sagen kann wie ich NSCProperty einbinde, richtig?

Ich hab Schiss hier euren Geduldsfaden zu überspannen. :|
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich hab' schon gesagt, wie du das machst - du musst deine gewuenschte Methode auf dem Objekt ln aufrufen. IN DIESEM FALL.

Code: Alles auswählen

ln.zSetNSCProperty(...)
Hans-Uwe
User
Beiträge: 56
Registriert: Dienstag 16. Januar 2018, 16:26

:wink: Genau das habe ich heute morgen ausprobiert und (ich glaube) es funktioniert.

Danke für deine Hilfe!
Antworten