|
|
|
|
Klammern ausmultiplizieren, Terme mit a^2, a und en Rest zusammenfassen, fertig.
|
|
|
|
|
|
|
| Zitat von Flitzpiepe42
Munteres Raten? Bin ich bei!
Spoiler - markieren, um zu lesen:
Krass wie man so Zeug vergisst, oder?
Ich wuerde einfach die Klammern ausmultiplizieren. Das gibt ne quadratische Gleichung, die kannst du dann ggf mit p/q-Formel oder sonstwie aufloesen afair
bei mir kam auf die Schnelle a^2 - (387/252)a + 174/252 raus - das ist echt zu lange her ...
| |
Eine Gleichung ist da nirgends. Das was Xerxes sagt, evtl. kann man das Ergebnis dann noch als binmoische Formel zusammenfassen.
|
|
|
|
|
|
|
Ok ok, ich liefere mal ein Beipiel an.
Also, folgendes XML soll zur Tabelle werden:
|
Code: |
<root>
<trade>
<ID>A1</ID>
<some>
<path>
<info>001</info>
<name>Bart</name>
</path>
</some>
<somewhere>
<else>
<list1>
<detail>El Barto</detail>
</list1>
<list2>
<detail>Bort</detail>
</list2>
</else>
</somewhere>
<detail>DO NOT SELECT ME</detail>
</trade>
<trade>
<ID>A2</ID>
<some>
<path>
<info>002</info>
<name>Lisa</name>
</path>
</some>
<somewhere>
<else>
<detail>Middle Child</detail>
</else>
</somewhere>
</trade>
</root>
|
|
Mein gewünschter Output ist
ID | somewhere/else/detail(1) | somewhere/else/detail(2) | some/path/info | some/path/name | A1 | El Barto | Bort | 001 | Bart | A2 | Middle Child | | 002 | Lisa |
Was ich für einen Output will, erfahre ich über ein Textfile mit dem Inhalt
|
Code: |
trade/ID
trade/somewhere/else/detail
trade/some/path/info
trade/some/path/name
|
|
(Es ist jetzt dem Beispiel geschuldet, dass wir fast alle Informationen in der Tabelle wollen. Tatsächlich hat das xml tausende Einträge, von denen uns wenige interessieren.)
An die gewünschten Elemente komme ich jetzt per prekompilierten XPaths, die ich einfach nach und nach auf jedes Trade Element anwende. Das muss iteriert laufen, weil ich teilweise mehrere Gigabytes an trades habe.
Meine Auswahl liegt also schon auf der "trade" node und ich wähle aus
|
Code: |
"ID | somewhere/else//child::detail | some/path/info | some/path/name" |
|
(Ich weiß vorab, wo ich mehrere Einträge erwarten kann (hier in "detail", entsprechend die angepasste Syntax.)
Zurück bekomme ich eine Liste mit den entsprechenden Nodes für diesen trade. Meine Frage ist jetzt, in welchem Datentyp ich diese sinnvollerweise ablege, bevor ich zum nächsten Node gehe.
In unserem Beispiel bekäme ich ja vom ersten Trade eine Liste von Länge 4, vom zweiten Trade aber eine Liste von Länge 3 zurück. Diese kann ich nicht einfach untereinanderpacken, weil ich ja noch die Info brauche, wo in der kürzeren Liste eine Leerstelle einzufügen ist.
Das kann ich jetzt sicherlich manuell tracken, indem ich für jeden Filter ein eigenes XPath vorbereite und mir jeweils die Anzahl der Ergebnisse zusätzlich merke. Aber gibt es da nichts besseres? Ich würde meine Auswahl gerne ähnlich einem Dictionary so ablegen, dass ich hinterher leicht die Tabelle bauen kann.
Und ja, es muss leider eine Tabelle sein, für die Excelschnittstelle der Software zur weiteren Verarbeitung. Langfristig will ich hier auf xml input umstellen (da ich so meine Rohdaten bekomme und es für die dünn besiedelten Tabellen eben auch sinnvoller ist), aber die weitere Verarbeitung für diese Saison läuft leider schon und verlangt weitere Tabellen.
|
|
|
|
|
|
|
1. Wenn ID, some/path/info und some/path/name immer vorhanden ist, wieso dann nicht alle details einfach dahinter ranpacken? Dann kann es dir egal sein, wie viele Details dazukommen.
2. Gibt es eine vordefinierte Maximalanzahl an Details? Sprich, es können z.B. maximal 10 sein? Wenn ja, dann halt in der Tabelle immer 10 Detailspalten, wobei die, für die Daten vorhanden sind, ausgefüllt werden.
3. Vielleicht meinst du aber auch, dass dein detail-Query immer nur einen Wert zurück gibt. Das stimmt so nicht. Der Query kann auch so geschrieben werden, dass einfach alle detail-Nodes eines Parent-Nodes zurückgegeben werden. Da kann man dann wieder drüberiterieren, und für jeden Node eine Spalte erstellen.
|
[Dieser Beitrag wurde 3 mal editiert; zum letzten Mal von derSenner am 04.01.2019 12:06]
|
|
|
|
|
|
Es gibt leider mehrere Kategorien mit variabler Ergebniszahl, ans Ende packen klappt also leider nicht. Die Maximalanzahl ist auch jeweils unbekannt. Mein Detail-Query (somewhere/else//detail) gibt mir wie gewünscht alle Nodes "detail" unter "else" zurück, ich weiß halt nur vorher nicht, wieviele das sind.
Um die angedeutete Lösung auszuführen: ich würde für jeden Filter ein zweidimensionales Array (d.h. geschachtelte Listen, ist ja Python) zu erstellen. Also nach Durchlauf aller trades sowas bekomme wie
|
Code: |
somewhere_else_detail = [ [El Barto, Bort], [Middle Child] ]
some_path_info = [ [001], [002] ]
|
|
und daraus die Tabelle baue. Muss man halt aufpassen, dass man selbst im Falle einer Leerauswahl einen (leeren) Eintrag hinzufügt, damit am Ende die Zeilenzahl mit der Anzahl Trades übereinstimmt.
|
|
|
|
|
|
|
| Zitat von Irdorath
Und ja, es muss leider eine Tabelle sein, für die Excelschnittstelle der Software zur weiteren Verarbeitung. Langfristig will ich hier auf xml input umstellen (da ich so meine Rohdaten bekomme und es für die dünn besiedelten Tabellen eben auch sinnvoller ist), aber die weitere Verarbeitung für diese Saison läuft leider schon und verlangt weitere Tabellen.
| |
Dann tu dir selbst einen gefallen und parse die Daten sinnvoll, persistiere sie sinnvoll und dann erzeuge die Tabellen in einem extra Schritt. Wenn du dann mal auf eine andere Pipeline umstellst musst du nicht die ganzen Hacks um eine Tabelle zu bekommen mühsam wieder entfernen.
Wenn es nur um ein paar Gigabyte geht, dann solltest du einfach Python Bordmittel verwenden können, das sollte schon schnell genug sein. Daraus baust du entweder neues XML wenn du Struktur erhalten willst oder "molten data" (ich verweise hier nochmal auf das tidy data paper) und das persistierst du. Und dann hast du eine brauchbare Basis mit der du später was auch immer erzeugen kannst, sogar die Excel-Tabellen, das ist recht einfach.
Ich gebe mal ein Beispiel für den "molten data"-Weg. Hier ist eine repräsentation deiner Beispieldaten als CSV. Ich habe das jetzt einfach abgetippt, aber ich denke es ist ersichtlich, dass diese Daten recht einfach zu erzeugen sind.
|
Code: |
id,path,value
A1,some/path/name,Bart
A1,somewhere/else/detail,El Barto
A1,somewhere/else/detail,Bort
A1,some/path/info,001
A2,some/path/name,Lisa
A2,somewhere/else/detail,Middle Child
A2,some/path/info,002
|
|
Das ist nicht ganz tidy data weil wir eine Spalte haben die die Spaltennamen beinhaltet, aber das ist den Wiederholungen geschuldet. Ab hier können wir pandas verwenden um zu bekommen was du willst, zum Beispiel:
|
Code: |
In [40]: df = pd.read_csv('bla.csv')
In [41]: df
Out[41]:
id path value
0 A1 some/path/name Bart
1 A1 somewhere/else/detail El Barto
2 A1 somewhere/else/detail Bort
3 A1 some/path/info 001
4 A2 some/path/name Lisa
5 A2 somewhere/else/detail Middle Child
6 A2 some/path/info 002
In [42]: repetition = df.groupby(['id', 'path']).cumcount()
In [43]: repetition
Out[43]:
0 0
1 0
2 1
3 0
4 0
5 0
6 0
dtype: int64
In [44]: unique_path = df['path'].str.cat(map(str, repetition))
In [45]: unique_path
Out[45]:
0 some/path/name0
1 somewhere/else/detail0
2 somewhere/else/detail1
3 some/path/info0
4 some/path/name0
5 somewhere/else/detail0
6 some/path/info0
Name: path, dtype: object
In [46]: df['unique_path'] = unique_path
In [47]: df.pivot(index='id', columns='unique_path', values='value')
Out[47]:
unique_path some/path/info0 some/path/name0 somewhere/else/detail0 somewhere/else/detail1
id
A1 001 Bart El Barto Bort
A2 002 Lisa Middle Child NaN
|
|
Schönheitsreparaturen wie die Vermeidung von Umbenennungen von eindeutigen Pfaden bleiben dir als Übung überlassen. Das kann man dann wiederum einfach mit pandas-Bordmitteln als csv (ich glaube sogar als xls?) ausgeben.
Solang bla.csv in den RAM passt ist das aus meiner Sicht ein guter Tradeoff aus Effizienz und geringer Menge Code, denn schnell sollte das durchaus sein. Wenn es viel größer wird dann muss man sich halt was pberlegen, beispielweise die groupby-Operation in Chunks zu machen. Aber ich glaube dass zuerst Excel schlapp macht .
e/ Ein Satz sei mir noch erlaubt: Hier zeigt sich schön, warum so ein flaches Dateiformat keine gute Idee ist: Statt die Struktur der Daten in einer Datenstruktur zu haben haben wir sie jetzt in den Strings der Spaltennamen. Viel Spaß beim zurückparsen!
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von B0rG* am 04.01.2019 13:48]
|
|
|
|
|
|
Pandas ist so geil.
Wollt ich nur mal eingeworfen haben.
|
|
|
|
|
|
|
|
|
|
|
cumsum ist Bukkake, ja?
|
|
|
|
|
|
|
| Zitat von Irdorath Aber gibt es da nichts besseres?
| |
B0rG* delivers. Sowas hab ich mir erhofft, vielen Dank!
|
|
|
|
|
|
|
Was ist denn so der go-to-way, um ein VirtualEnv aus dem Code heraus zu aktivieren? Das Problem ist, dass wir unfassbar viele Shell-Skripte rumfahren haben. Dass dann ein Shell-Skript eine anderes Shell-Skript aufruft, welches z.B. eine Spark-Applikation mit X Parametern startet, ist dabei keine Seltenheit.
Ich will jetzt also besonders radikal sein und nur einmal ein Python-Skript aufrufen, in welchem ich alle Parameter einfach schön in einer yaml einstellen kann.
Ich habe von mehreren Wegen gelesen, z.B. über OS, Subprocess oder exec/execfile (wobei ich Python 3.3+ verwenden will). So etwa:
|
Code: |
if __name__ == '__main__':
exec(open("/opt/venv3.6.4/bin/activate_this.py").read(), dict(__file__=activate_this_file)) # hier ist der Knackpunkt?
with open('src/configs/product_ranking.yml') as file:
config = yaml.load(file)
spark_config = SparkRunConfig(config['spark_run'])
subprocess.call(["spark2-submit",
"--executor-memory", spark_config.executor_memory,
"--driver-memory", spark_config.driver_memory,
"--conf", f"spark.yarn.am.memory={spark_config.yarn_am_memory}",
spark_config.filename],
env={"PYSPARK_PYTHON": spark_config.pyspark_python,
"PYSPARK_DRIVER_PYTHON": spark_config.pyspark_driver_python
})
|
|
Habe ich da eine Möglichkeit, an einem Bash-Skript vorbeizukommen, um das venv zu aktivieren? Oder ist das überhaupt ne ganz schlechte Art, das zu lösen?
|
|
|
|
|
|
|
#!/virtualenv/bin/python
Irgendwo am Ende einer Datei im __main__-Block am sys.path rumfummeln klingt nach einem super Weg um mismatched imports zu bekommen, und funktioniert nicht, wenn deine aktuelle Python-Version != venv-Python-Version.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von csde_rats am 04.01.2019 21:35]
|
|
|
|
|
|
Ok. So einen shebang übersieht man halt auch mal leicht. Aber eigentlich ist die Lösung ziemlich schick. Und bezüglich der Seiteneffekte liegst du sicherlich auch richtig. Danke.
|
|
|
|
|
|
|
Ne Frage zu Pandas, wieso klappt meine Spaltensortierung nicht?
Ich hab den obigen Workflow von Borg* übernommen, wobei ich die unique_path Sache nicht brauche, da meine Pfade aus lxml schon bei Vielfachheit so Namen haben wie
Path/to/Event[1]/Value
Path/to/Event[1]/Name
Path/to/Event[2]/Value
Path/to/Event[2]/Name
etc.
Ich erzeuge also meine Pivot Tabelle
|
Code: |
df = pd.read_csv(file_to_open)
output = df.pivot(index='TradeId', columns='Path', values='Value') |
|
und jetzt will ich sortieren, denn nativ bekomme ich Event[100] vor Event[10] vor Event[1]:
|
Code: |
from natsort import natsorted
output.columns=natsorted(output.columns) |
|
Jetzt gibt es aber fehlerhafte Einträge, also beispielsweise stehen in manchen Spalten "Path/to/Event[*]/Value" Einträge vom Typ Name. Hat jemand ne Idee, was hier schiefläut?
|
|
|
|
|
|
|
Wenn du columns neu zuweist benennst du die Spalten nur um und änderst nicht ihre Ordnung. Probier mal
df = df[natsorted(df.columns)]
Falls bei natsorted ein Generator rauskommt musst du vermutlich daraus noch eine Liste machen.
Mehr editieren! Juchuu!
|
[Dieser Beitrag wurde 3 mal editiert; zum letzten Mal von B0rG* am 10.01.2019 16:49]
|
|
|
|
|
|
Danke. Irgendwo bin ich da gestern falsch abgebogen, wenn ich heute nach "pandas rearrange columns" suche, werde ich auch wesentlich fündiger.
|
|
|
|
|
|
|
Fun Fact:
|
|
|
|
|
|
|
Hmkaaay, folgendes Problem.
Ich habe eine Klasse, welche einen Haufen Parameter aus einer Datei (Format X) liest, per IPC mit anderen Prozessen kommuniziert, und in Datei (Format Y) schreibt.
Im Moment sieht das so aus:
|
Code: |
class Params {
public:
unsigned int getParam1() const {
return _param1;
}
float getParam1() const {
return _param2;
}
...
void readFromFormatA() {
SomeFormatAApi.read("param1", _param1);
SomeFormatAApi.read("param2", _param2);
...
}
void readFromFormatB() {
SomeFormatBApi.read("param1", _param1);
SomeFormatBApi.read("param2", _param2);
...
}
void writeToFormatA() {
SomeFormatAApi.write("param1", _param1);
SomeFormatAApi.write("param2", _param2);
...
}
void writeToFormatB() {
SomeFormatBApi.write("param1", _param1);
SomeFormatBApi.write("param2", _param2);
...
}
void MPIbroadcast() {
SomeMPIWrapper.broadcast(_param1);
SomeMPIWrapper.broadcast(_param2);
...
}
private:
unsigned int _param1{0};
float _param2{1};
...
} |
|
Ihr könnt euch vorstellen, dass es sehr nervig ist, Parameter hinzuzufügen und die Übersicht zu behalten (Ich habe so ca. 20+ von denen). Dauernd vergesse ich irgendwas.
Am liebsten hätte ich folgendes:
|
Code: |
class Params {
public:
Params() {
_params.push_back(Param<unsigned int>("param1"));
_params.push_back(Param<float>("param2"));
...
}
unsigned int get(std::string name) const {
// irgendeine smarte Implementierung
}
void readFromFormatA() {
for(auto & p: _params)
SomeFormatAApi.read(..);
}
void readFromFormatB() {
for(auto & p: _params)
SomeFormatBApi.read(..);
}
void writeToFormatA() {
for(auto & p: _params)
SomeFormatAApi.write(..);
}
void writeToFormatB() {
for(auto & p: _params)
SomeFormatBApi.write(..);
}
void MPIbroadcast() {
for(auto & p: _params)
SomeMPIWrapper.broadcast(..);
}
private:
std::vector<Param<>> _params; // oder eine Map oder wasweißich
} |
|
So muss ich meine Parameter und deren Typen nur an einer einzigen Stelle verwalten. Frage: Wie löse ich das ohne std::variant bzw. boost::variant ohne irgendwelche größeren externen Bibliotheken?
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Oli am 16.01.2019 17:05]
|
|
|
|
|
|
Oida, jetzt will ich aber auch die Lösung sehen
|
|
|
|
|
|
|
In Code-Schnipsel 2 versuchst du die Meta-Ebene in konkrete Typen zu wrappen (std::vector<$MetaDinge>. Ich vermute mal, dass die "korrekte" Lösung entweder Runtime-Polymorphismus statt Templates oder ein Template über die Parameter an sich ist, ala
Params<Param<unsigned int>("param1"), Param<float>("param2"), ...> params;
Außerdem könnte man noch anmerken, dass writeToFormatA und writeToFormatB, ..., so aussehen, als ob hier zwei separierbare Concerns vorliegen (Welche Parameter gibt es? und Wie werden Datensätze (bestehend aus Parametern) von/zu Bytes umgewandelt?)
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von csde_rats am 16.01.2019 17:14]
|
|
|
|
|
|
Hab sowas mal in etwa so gelöst:
struct formatAWriter {
void rw(std::string name, int& val) {
//something
}
void rw(std::string name, float& val) {
//something
}
}
struct formatAReader {
void rw(std::string name, int& val) {
val = blah;
}
void rw(std::string name, float& val) {
val = blub;
}
}
struct Params {
int a;
float b;
template <typename T>
void rw(T& w) {
w.rw("a", a);
w.rw("b", b);
}
void readFromFormatA() {
formatAReader reader;
rw(reader);
}
void writeToFormatA() {
formatAWriter writer;
rw(writer);
}
}
(man muss parameter dann nur noch einmal "registrieren")
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von Krypt0n am 16.01.2019 17:19]
|
|
|
|
|
|
Der Aspekt des dynamischen Zugriffs [1] ist mit dem Ansatz allerdings schwierig. Wenn der nicht benötigt wird, ist das m.E. der einfachste Ansatz, was bei C++ immer gut ist. (Es ist irgendwie krass wie sehr sich da manche verrennen).
unsigned int(Param<>?) get(std::string name) const {
// irgendeine smarte Implementierung
}
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von csde_rats am 16.01.2019 17:22]
|
|
|
|
|
|
Naja, irgendwie geht das
template <typename T>
struct paramWithNameGetter {
paramWithNameGetter(std::string name) : name(name) {}
std::string name;
T result;
void rw(std::string name, int& val) {
if (this->name == name) {
result = val;
}
}
}
int getInt(std::string name) {
paramWithNameGetter<int> w = paramWithNameGetter<int>(name);
rw(w);
return w.result;
}
/e
Das ist ein bisschen so wie cereal das macht.
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von Krypt0n am 16.01.2019 17:33]
|
|
|
|
|
|
Der Channel ist toll!
|
|
|
|
|
|
|
Danke @ rats & Krypt0n.
Krypt0ns erster Ansatz ist vielleicht ein Kompromiss; die Parameter sind zwar immer noch einfache Klassenmember, aber immerhin muss ich sie nur zweimal schreiben.
Was mich ein wenig nervt, ist, dass ich entweder getter/setter für jeden einzelnen implementieren muss, oder halt alles public mache. Hätte ich einen Container, käme ich mit einer get/set Funktion zurecht, und könnte darin auch irgendwelche Logik implementieren.
cereal habe ich sowieso schon als dependency... Ob man da einfach irgendein feature nutzen kann?
Am geilsten wäre ein std::map<std::variant<...>>, welches auch noch compile time evaluiert würde. Meine Parameter sind ja alle bei der Kompilierung schon bekannt.
Ich könnte natürlich auch einfach Macros zum Code generieren nutzen.
|
|
|
|
|
|
|
Ich glaube ich gehe mich erstmal waschen.
|
Code: |
#include <map>
#include <string>
#include <iostream>
#define MEMBERDEF(type, typename) \
std::map<std::string, type> typename##_params; \
std::map<std::string, std::tuple<type, type>> typename##_tuple_params; \
#define FUNCTIONDEF(type, typename) \
template<> \
type ParamContainer::get(const std::string & name) const { \
return typename##_params.at(name); \
} \
\
template<> \
void ParamContainer::set(const std::string & name, type val) { \
typename##_params[name] = val; \
} \
\
template<> \
void ParamContainer::reg(const std::string & name, type default_val) { \
typename##_params[name] = default_val; \
} \
struct ParamContainer {
public:
template<typename T>
T get(const std::string & name) const {
//fehler?
}
template<typename T>
void set(const std::string & name, T val) {
//fehler?
}
template<typename T>
void reg(const std::string & name, T val) {
//fehler?
}
private:
MEMBERDEF(int, int)
MEMBERDEF(float, float)
MEMBERDEF(double, double)
MEMBERDEF(bool, bool)
MEMBERDEF(unsigned int, uint)
};
FUNCTIONDEF(int, int)
FUNCTIONDEF(float, float)
FUNCTIONDEF(double, double)
FUNCTIONDEF(bool, bool)
FUNCTIONDEF(unsigned int, uint)
class B {
public:
B() {
c.reg<int>("test", 5);
c.reg<float>("floattest", 10.);
c.reg<std::tuple<float, float>>("tupletest", std::make_tuple<>(2., 15.));
std::cout << c.get<int>("test") << std::endl;
std::cout << c.get<float>("floattest") << std::endl;
std::cout << std::get<0>(c.get<std::tuple<float, float>>("tupletest")) << std::endl;
}
ParamContainer c;
};
int main(int argc, char const *argv[])
{
B b;
return 0;
} |
|
|
|
|
|
|
|
|
Oder halt sowas:
|
Code: |
#include <iostream>
#include <map>
class Parameters {
private:
class Parameter {
public:
virtual ~Parameter() {};
};
template<typename T>
class Param : public Parameter {
public:
Param(const T val) : p(val) {
}
T get() const {
return p;
}
private:
T p;
};
public:
Parameters() {
parameters["double"] = new Param<double>(0.25);
parameters["float"] = new Param<float>(0.125);
parameters["int"] = new Param<int>(25);
parameters["pair"] = new Param<std::pair<unsigned int, std::string>>(std::make_pair(25, "afsasf"));
}
~Parameters() {
for(auto p : parameters)
delete p.second;
}
template<typename T>
bool get(const std::string& name, T& val) const {
const std::map<std::string, Parameter*>::const_iterator it = parameters.find(name);
if (it == parameters.end())
return false;
const Param<T>* p = dynamic_cast<Param<T>*>(it->second);
if (not p)
return false;
val = p->get();
return true;
}
private:
std::map<std::string, Parameter*> parameters;
};
int main(int argc, char* argv[]) {
Parameters p;
double a;
float b;
int c;
std::pair<unsigned int, std::string> d;
std::cout << p.get("double", a) << " " << p.get("float", a) << " " << p.get("int", a) << std::endl;
std::cout << p.get("double", b) << " " << p.get("float", b) << " " << p.get("int", b) << std::endl;
std::cout << p.get("double", c) << " " << p.get("float", c) << " " << p.get("int", c) << std::endl;
std::cout << p.get("pair", d) << " " << d.second << std::endl;
}
|
|
Könnte man jetzt auch einfach auf get<type> umbauen, dann müsste man halt einen anderen Weg finden, inkompatible Typen zu signalisieren.
|
|
|
|
|
|
|
Hoff bin hier richtig
Hab mittlerweile zwei Raspberry 3b+ am laufen (osmc & pihole) sowie einen orange pi zero mit Home Assistant.
Nun würd ich gerne einen Raspberry zero dazu packen mit einem LCD & Case um die uptimes etc. (per python) anzuzeigen. So drei Textzeilen dürften genügen - aber nach was such ich da auf den Chinaseiten? Hab nichts zum löten hier und auch kein 3D Drucker. Displays find ich ja noch (HAT dürfte mein Stichwort sein..?) aber ein dazugehöriges Case?
|
|
|
|
|
|
|
Ich setze meine Doktorarbeit aufs ArXiV. Keine 24h später: Ein Crackpot, der mir zwei E-Mails schickt - eine, weil er den Anhang in der ersten verpeilte, der aus einem absolut grotest schlechten Versuch, die Schreibe des Fachgebiets zu kopieren, ist. Und ein Forscher, der bettelt, dass die nächste Fassung (einer Doktorarbeit...) doch bitte sein Werk zitiert. Ich zitiere es bereits.
Are you fucking kidding me?
You got to belong to someone, even if he kicks you once in a while.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Wraith of Seth am 18.01.2019 15:14]
|
|
|
|
|
|
| Zitat von BuddelWilli3
Hoff bin hier richtig
Hab mittlerweile zwei Raspberry 3b+ am laufen (osmc & pihole) sowie einen orange pi zero mit Home Assistant.
Nun würd ich gerne einen Raspberry zero dazu packen mit einem LCD & Case um die uptimes etc. (per python) anzuzeigen. So drei Textzeilen dürften genügen - aber nach was such ich da auf den Chinaseiten? Hab nichts zum löten hier und auch kein 3D Drucker. Displays find ich ja noch (HAT dürfte mein Stichwort sein..?) aber ein dazugehöriges Case?
| |
Hier sind die Experten diesbezüglich.
|
|
|
|
|
|
Thema: pOT-lnformatik, Mathematik, Physik XXII ( Jetzt nehmen uns Computer schon die Memes weg! ) |
|