dynamisch Variablen generieren in C

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
hypnoticum
User
Beiträge: 132
Registriert: Dienstag 15. März 2011, 15:43

Hallo,
ich will in einer Schleife eine erst zur Laufzeit bekannte Anzahl von Listen als PyObject anlegen und deren Elementen später Werte zuweisen.
wie mache ich das?
statisch sieht es so aus:

Code: Alles auswählen

	int i;
	char title[100];
	PCLCnt = 1;
	TChCnt = 30;


	PyGraphList = PyList_New((int)2*PCLCnt);

	PyObject	*PyGraph1 = PyDict_New();
	PyObject	*PyAbscissaList1 = PyList_New((int)TChCnt);
	PyObject	*PyOrdinateList1 = PyList_New((int)TChCnt);

	for (i = 0; i < TChCnt; i++) {
		PyNumber = PyInt_FromLong((long)i);
		PyList_SET_ITEM(PyAbscissaList1, i, PyNumber);
		PyNumber = PyFloat_FromDouble((double)i);
		PyList_SET_ITEM(PyOrdinateList1, i, PyNumber);
	}

	sprintf(title, "Title_1, PCL: %ld", (long)PCLCnt);
	PyDict_SetItemString(PyGraph1, "title", PyString_FromString("hallo_1"));
	PyDict_SetItemString(PyGraph1, "legend", PyString_FromString("-+-+-"));

	PyDict_SetItemString(PyGraph1, "abscissa", PyAbscissaList1);
	PyDict_SetItemString(PyGraph1, "abscissaUnits", PyString_FromString("TxCh"));

	PyDict_SetItemString(PyGraph1, "ordinate", PyOrdinateList1);
	PyDict_SetItemString(PyGraph1, "ordinateUnits", PyString_FromString("P[dBm]"));
	PyList_SetItem(PyGraphList, 0, PyGraph1);

	PyObject	*PyGraph2 = PyDict_New();
	PyObject	*PyAbscissaList2 = PyList_New((int)TChCnt);
	PyObject	*PyOrdinateList2 = PyList_New((int)TChCnt);

	int OffSet = 30;
	for (i = OffSet; i < OffSet + TChCnt; i++) {
		PyNumber = PyInt_FromLong((long)i);
		PyList_SET_ITEM(PyAbscissaList2, i - OffSet, PyNumber);
		PyNumber = PyFloat_FromDouble((double)i);
		PyList_SET_ITEM(PyOrdinateList2, i - OffSet, PyNumber);
	}

	sprintf(title, "Title_2, PCL: %ld", (long)PCLCnt);
	PyDict_SetItemString(PyGraph2, "title", PyString_FromString("hallo_2"));
	PyDict_SetItemString(PyGraph2, "legend", PyString_FromString("-+-+-"));

	PyDict_SetItemString(PyGraph2, "abscissa", PyAbscissaList2);
	PyDict_SetItemString(PyGraph2, "abscissaUnits", PyString_FromString("TxCh"));

	PyDict_SetItemString(PyGraph2, "ordinate", PyOrdinateList2);
	PyDict_SetItemString(PyGraph2, "ordinateUnits", PyString_FromString("P[dBm]"));
	PyList_SetItem(PyGraphList, 1, PyGraph2);
BlackJack

@hypnoticum: Was soll denn nun genau an diesem statischen Code dynamisch werden? Und was ist dabei das Problem? Und warum hast Du die zweite Schleife so umständlich geschrieben? Denn da kommt an Werten ja wieder das gleiche heraus wie bei der ersten.

Muss das in C? Das ganze statisch in Python würde so aussehen:

Code: Alles auswählen

    pcl_count = 1
    tch_count = 30
    
    abscissa = range(tch_count)
    ordinate = map(float, abscissa)
    graphs = [
        {
            'title': 'Title_1, PCL: %d' % pcl_count,
            'legend': '-+-+-',
            'abscissa': abscissa,
            'abscissaUnits': 'TxCh',
            'ordinate': ordinate,
            'ordinateUnits': 'P[dBm]',
        },
        {
            'title': 'Title_2, PCL: %d' % pcl_count,
            'legend': '-+-+-',
            'abscissa': abscissa,
            'abscissaUnits': 'TxCh',
            'ordinate': ordinate,
            'ordinateUnits': 'P[dBm]',
        },
    ]
Etwas kompakter — und hier ist auch gleich Fehlerbehandlung enthalten, die Du Dir wieder mal komplett gespart hast.
hypnoticum
User
Beiträge: 132
Registriert: Dienstag 15. März 2011, 15:43

"dynamisch" sollen die PyObjects erzeugt werden, da erst zur Laufzeit bekannt wird wieviele und mit mit welche Größe diese angelegt werden sollen.
Zur Zeit wiederholt sich die erzeugung der benötigten Variablen mit fester Größe "statisch" zwei mal.
Es muss in C sein. Am Ende der Funktion werden alle Listen gesammelt in einem Dictionary an Python übergeben.
hypnoticum
User
Beiträge: 132
Registriert: Dienstag 15. März 2011, 15:43

Gibt es vielleicht eine Möglichkeit nach jeder Zuweisung eine Kopie zu erstellen, die dann im Dictionary abgelegt wird?
BlackJack

@hypnoticum: Was bedeutet denn nun "dynamisch" in Anführungszeichen? Python-Objekte werden grundsätzlich dynamisch erzeugt, auch in Deinem statischen C-Quelltext. Welche von den statischen Grössen dort soll sich zur Laufzeit ändern? Die Anzahl der Wörterbücher, die in die Liste gesteckt werden? Was sind "alle Listen" die am Ende der Funktion in ein Wörterbuch gesteckt werden sollen? Jetzt ist es ja genau umgekehrt — es werden Wörterbücher in eine Liste gesteckt.

Wenn Du statt zwei Wörterbücher in der Liste beliebig viele haben willst und dort die Werte für 'abscissa' und 'ordinate' unterschiedliche Längen haben sollen, dann setz das doch einfach um. Was Schleifen sind, weisst Du ja ganz offensichtlich. Da würde ich jetzt das Problem nicht sehen!? Aus Gründen der Les- und Überschaubarkeit würde ich das erzeugen *eines* Wörterbuchs mit Plotdaten in eine eigene Funktion auslagern.

Warum muss es C sein? Du kümmerst Dich ja nicht nur nicht um Fehler, ich bin mir auch nicht sicher ob die Speicherverwaltung so hinhaut. Das sind alles Sachen die man in Python hat, ohne dass man sich explizit darum kümmern muss. Kürzer und lesbarer ist der Quelltext dann auch.
0x1cedd1ce
User
Beiträge: 31
Registriert: Sonntag 3. Oktober 2010, 12:21

Nimm doch einfach ein Array mit PyObject. Mithilfe einer For-Schleife kannst du dann die Werte eintragen.
Antworten