Posts by fabs

    Der Grund ist, dass du in Form2.Form2_Load ein neues Form1-Objekt erzeugst. Dort wurde der Button dann noch nicht geklickt. Wenn du in Form2 auf genau das Form1-Objekt zugreifen möchtest, welches das Form2-Objekt erstellt hat, dann müsstest du das irgendwie übergeben, zum Beispiel im Konstruktor:



    Form2



    Das ist natürlich nur eine unter vielen Möglichkeiten, es hängt im wesentlichen davon ab, was du tun möchtest. Du könntest Form2 auch eine entsprechende Property geben, die Form1 direkt nach dem erzeugen setzt, oder Form1 zu einem Singleton machen bzw. anderweitig statisch zugriff auf eine Form1-Instanz erlauben.


    Eine kleine Nebenbemerkung: Ein besseres Benennungsschema für Properties ist es, Dinge wie Get/Set wegzulassen - das ergibt sich nämlich ohnehin aus der Definition der Property und entspricht der Art des Zugriffs eher als ein Methodenname.

    Ob der Bereich benannt ist oder nicht, ist relativ egal. Zählenwenn sollte jedenfalls funktionieren. Falls du was komplizierteres machen möchtest, gibt es WVERWEIS = SVERWEIS für Zeilen. Die folgende Formel macht dann im Wesentlichen dasselbe wie die Zählenwenn-Formel

    Code
    1. =WENN(ISTNV(WVERWEIS(A1;Tabelle2!$A$1:$Z$1;1;FALSCH));"NEIN";"JA")

    Also in der Vorlesung hat Prof. Knoop den Aufgabenzettel nochmal durchgehen wollen, anscheinend hat er ein paar E-Mails bekommen und war sich nicht sicher, wo die Unklarheiten liegen. Ich hab versucht, ihm das mit den Argumenten bei fsum zu erklären, aber da hat er nur gemeint, das ist eigentlich alles klar, und wenn es wo mehrere Möglichkeiten gibt, dann wird das Abgabeskript das schon zulassen. Im speziellen hat er nur von den Argumenten "von" und "bis", die natürlich schon in dieser Reihenfolge sein sollten. Insgesamt schien er von der Diskussion wenig begeistert zu sein, also hab ichs dann gelassen. Eine genaue Klärung der Argumentreihenfolge gibts also nicht. Tatsache ist aber, dass bei mehreren Interpretationsmöglichkeiten auch in der normalen Funkprog-Übung schon mehrere Varianten zugelassen waren, also wird das schon so sein. Ansonsten wär die Richtigkeit der Lösung ja auch durchaus argumentierbar.
    Insgesamt halte ich die von uns verwendete Konvention deswegen für gut, weil sie in etwa der der Prologübung entspricht, die ebenso wie die Abgabeskripte von Prof. Neumerkel gemacht wird. Eine zweite Sicherheitslinie wäre natürlich, wenn alle (oder zumindest die meisten) dieselbe Interpretation hätten - wobei ich die meine natürlich niemandem aufdrängen will.

    Keine offizielle Information, aber wir sind in der Zwischenzeit mal davon ausgegangen, dass bei den Argumenten nach dem Namen vorzugehen ist, d.h. zuerst kommen die beiden Argumente für fsum und dann das eine Argument für das N bzw. die zwei Argumente für VB. Haben aber vor, Prof. Knoop am Do in der Vorlesung nochmal zu fragen - bis nächsten Dienstag ist da dann genug Zeit, die Argumente umzudrehen.

    Also f ist eine Funktion, die eine Funktion von Int nach Int als Parameter aufnimmt und diese in eine Funktion von Int nach Int abbildet. Du kannst also nicht "f 4" aufrufen (oder "f 4 2"), sondern musst zum Beispiel etwas wie "f (\t -> t+1) 2)" aufrufen. Das ergibt dann 4, weil die Funktion x (+1) 2-Mal angewendet wird, einmal auf y (2) und einmal auf das Ergebnis davon. Was f im wesentlichen macht, ist aus einer Funktion x eine Funktion zu generieren, die diese 2-Mal auf ein Argument anwendet. Dasselbe hättest du mit folgender Definition auch erreicht:

    Code
    1. f :: (Int -> Int) -> (Int -> Int)
    2. f x = x.x



    f' ist demnach eine Funktion, die eine Funktion, welche eine Funktion von Int nach Int auf einen Int abbildet, wieder auf einen Int abbildet. Auf die schnelle fällt mir da kein sehr sinnvolles Beispiel ein, nehmen wir an, du hast eine Liste von solchen Funktionen as, z.B. von (+1) bis (+10), und du hast eine Funktion b, die dir dann zurückgibt, wie viel von der übergebenen Funktion a tatsächlich zu ihrem Argument hinzugefügt wird (also etwas zwischen 1 und 10). b wäre dann das erste Argument von f', und du kannst f' dann irgendwas damit machen lassen, zum Beispiel eins abziehen, um den Index nullbasiert zu machen.
    So, nun ist f' eine Funktion mit einem Argument nach Int. Ein Int kann keine Argumente mehr akzeptieren, also kannst du auch kein zweites Argument angeben wie oben bei f, wo das y dazu diente, die zurückgegebene Funktion zu spezifizieren.

    Zusammenfassend: Hauptfehler ist wohl die Klammerung.

    Also auch ein Fach wie OOP ist von der Praxis gefühlt eher weit weg - einfach, weil das niemand so extrem macht - trotzdem finde ich, dass ich dort sehr viel nützliches auf einer theoretischen Basis gelernt habe. Im Gegensatz zu OOM/SEPM/ASE/SQS, wobei ersteres eine Art Vorspiel zu den anderen ist und die anderen einen sehr großen Praxisanspruch erheben. Tatsache ist, dass dabei jeweils genau eine von unzähligen Methoden gelehrt wird, die in der vielgelobten Praxis verwendet werden, und diese Methoden oft nicht Praxisnah umgesetzt werden können, weil wir zum Beispiel keine 40-Stunden-Woche alle im selben Büro sitzen, womit die Scrum-Meetings schon mal sehr schwer zu machen sind. Man macht halt irgendwas und versucht, es so aussehen zu lassen wie Scrum und nennt das dann "Praxis".
    Also gut, ich finde die theoretischen Fächer interessanter, aber ich denke auch, dass sie allgemein nützlicher sind, als wenn man halt genau die eine Interpretation eines Profs von Praxis lernen muss, wo doch jede Firma ihre eigenen Abläufe hat, in die man am Anfang so oder so eingewiesen werden muss. Selbst wenn ich nicht in der Forschung bleiben wollte: von den theoretischen Fächern könnte ich mir zumindest ein paar Sachen merken und die mitnehmen und dann bei komplizierteren Projekten bessere Ideen haben. Natürlich, wenn man die ganze Zeit nur die üblichen Datenbank+GUI "es gibt Kunden und Produkte und Filialen und Verkäufe + ein paar Spezialdaten"-Programme machen will, dann kann man sich wirklich fragen, wozu das alles? Aber dann ist man auf der Uni mMn wirklich falsch aufgehoben.

    Yay, "HTML/CSS" ist eine Programmiersprache!

    edit: es gibt auch ein paar ernsthafte Kritikpunkte. Die Umfrage nimmt (wie schon weiter oben erwähnt) einfach an, dass man in einem Unternehmen Software entwickelt, und dass Agile Softwareentwicklung ein gutes Konzept ist. Es gibt also bei den Gründen, die die Einführung von Agiler Softwareentwicklung behindern könnten, nicht den Grund: "Es ist einfach kein gutes Konzept". Bei den Gründen, warum man sich für Agile Softwareentwicklung entscheiden sollte, gibts nur die Abstufung zwischen Wichtigkeiten oder weiß nicht, nicht aber: "Ich glaube nicht, dass das besser wird".

    Schon zu den Sicherheitsrichtlinien geschaut? Unter Windows 7 heißt das in der Verwaltung "Lokale Sicherheitsrichtlinie" - ich stell mir vor, dass es auf einem Domänenserver sowas auch für die Domäne gibt. Den AppLocker werdet ihr da bei 2003/XP wohl nicht haben, aber vielleicht die Richtlinien für Softwareeinschränkung. Da kann man die Rechte aufgrund von Pfaden, Hashes, Zertifikaten und Netzwerkzonen setzen.

    Ich verstehe nicht ganz, was Ausgangsparameter ist? Ist Ergebnis einer Methode und Ausgangsparameter irgendwie das Gleiche?


    Von der geforderten Kovarianz her schon (S. 48/49 im Skriptum). Gemeint ist mit Ausgangsparameter aber eher folgendes (C#):

    Code
    1. public bool TryParse(String s, out int value) { ... };
    2. int myint;
    3. if(TryParse("5",out myint)) { ... }


    Der "value" genannte Parameter von TryParse ist ein Ausgangsparameter. Der Rückgabetyp von TryParse ist ein boolean, die Methode kann allerdings auch den Wert von myint ändern. Theoretisch könnte man natürlich alle Methoden so schreiben, dass sie kein "Ergebnis" als solches haben, sondern nur Ausgangsparameter oder Durchgangsparameter (wird auch gemacht, in Ada bei Procedures oder ich glaub auch bei Prozeduren bei vielen SQL-Servern, also dann, wenn explizit zwischen Funktionen und Prozeduren unterschieden wird und nicht einfach alles als Methode bezeichnet wird wie in Java oder C#). Damit dann eben das Ersetzbarkeitsprinzip erfüllt ist, müssen diese dann natürlich Ko- bzw. Invariant (Durchgangsparameter) sein, aus denselben Gründen, die für Rückgabewerte und Variablen gelten.


    Ich glaube auf dieser Hompage ist ganz einfach und klar erklärt,was Invarianz Kovarianz und Kontravarianz ist? Oder ?


    http://www.nils-haldenwang.de/…z-kovarianz-kontravarianz


    Es schaut zumindest richtig aus :)

    A extends B extends C

    Code
    1. List<A> alist=new List<A>();
    2. List<C> clist=new List<C>();
    3. List<? extends B> coblist=clist;
    4. List<? super B> contrablist=alist;


    Auf coblist sind deswegen nur "Lesezugriffe" möglich, weil wir nicht wissen können, wie speziell der Typ dahinter tatsächlich ist. Wir kennen ja nur die Typschranke B. Ein Objekt mit dem speziellsten Typ B ließe sich aber nicht in eine Liste von Cs einfügen. Daher können wir in die Kovariante Liste nicht schreiben. Umgekehrt ist Lesen kein Problem, weil wir ja wissen, dass es "zumindest" Bs sind, die in der Liste vorkommen, und wir können mit ihnen alles machen, was wir mit Bs auch machen können.

    Auf contrablist dürfen wir dagegen nur "schreibend" zugreifen, weil wir ja nur wissen, dass das eine Liste von irgendeinem Obertyp von B ist. Wir können also nicht garantieren, dass alle Elemente in der Liste Untertypen von B sind, wenn wir sie irgendwie durchgehen. Dagegen lässt sich in eine Liste von irgendeinem Obertyp von B jedenfalls ein B einfügen, da eine Instanz von B immer dort verwendet werden kann, wo irgendein Obertyp von B erwartet wird.

    Mit diesen Klassen passiert dasselbe wie mit allen anderen Klassen auch. Bei homogener Übersetzung in Java wird es wahrscheinlich keine Typschranke geben, weil es sonst ja schwer wäre, Integer irgendwie hinein zu bekommen. Daher werden an allen Stellen der Klasse die Typparameter mit object ersetzt, und dort, wo man außerhalb der Klasse einen bestimmten Typparameter erwartet, ein Cast eingefügt. Einfache ints werden automatisch geboxed, d.h. wenn du {List<Integer> mylist=new List<Integer>(); int a=5; mylist.Add(a);} schreibst, wird der int in einen Integer "umgewandelt", und wenn du eine int-Variable hast und dieser einen Wert aus der Liste zuweist, wird der eben wieder unboxed, also vom objekt zurück in den Werttyp umgewandelt. Das ist, wie im Skriptum erwähnt, nicht sonderlich effizient im Vergleich zur heterogenen Übersetzung von int-Listen, bei der diese Umwandlungen nicht stattfinden müssen. Nur: Angenommen es gäbe auch heterogene Übersetzung in Java und der Compiler optimiert dir das nicht weg, dann fallen zwar die casts weg, aber wenn du dort noch immer Integer als generischen Typ angibst, dann muss das boxing und unboxing für die int-Werte noch immer stattfinden. Der Unterschied wäre dann nur, dass mit der homogenen Übersetzung nur eine Klasse gibt, die überall object statt dem Typparameter stehen hat, und dann eben die Casts an den Stellen braucht, wo man einen Wert des Typparameters erwartet, während es bei der heterogenen Übersetzung halt eine eigene Übersetzung für Integer gäbe, wo der Typparameter eben immer mit Integer ersetzt wurde, wodurch die Casts wegfallen. Bei heterogener Übersetzung wäre es halt einfacher, nicht Integer, sondern int zu verwenden und damit das boxing-Zeug einzusparen. In C# wird das dann zum Beispiel so gelöst, dass Generizität mit Werttypen (also int, bool, long, structs etc.) homogen und mit Referenztypen (~ der ganze Rest) heterogen übersetzt wird.

    Sie sind vom Beispiel her zumindest als binäre Methoden beabsichtigt, aber so in Java eben nicht realisierbar. Der gegebene Code _würde_ das Ersetzbarkeitsprinzip verletzen, _falls_ die Methode equal in Point3D die Methode equal in Point2D überschreiben würde (was bei binären Methoden der Fall wäre). Da das in Java nicht der Fall ist, ist der Code zwar grundsätzlich korrekt und verletzt das Ersetzbarkeitsprinzip nicht, weil Instanzen von Point3D eben immer noch überall dort verwendet werden können, wo Instanzen von Point2D erwartet werden. Allerdings ist er für Programmierer hochgefährlich, weil er ein Verhalten (eben binäre Methoden) impliziert, das eben so nicht gegeben ist.

    Um die eigentliche Frage vielleicht in einem Satz zu beantworten: Binäre Methoden verlangen per Defnition kovariante Eingangsparameter (da es ja welche geben muss, die stets gleich der aktuellen Klasse sind), und das verletzt das Ersetzbarkeitsprinzip, das eben kontravariante Eingangsparameter fordert.

    Weil Eingangsparametertypen kontravariant sein müssen, im Fall von binären Methoden aber kovariant sein müssten. Sieht man am Beispiel der equal-Methode von Point2D und Point3D auf derselben Seite: hier würde sich der Eingangsparametertyp kovariant verändern. Damit wird diese Methode in Java aber nur überladen und nicht überschrieben, weil eben Point3D kein Obertyp, sondern ein Untertyp von Point2D ist. Daher wird in folgendem Code:

    Point2D p2=new Point3D(2,4,8);
    Point3D p3=new Point3D(2,4,5);
    p2.equal(p3); <-- also an dieser Stelle

    die Methode Point2D.equal() aufgerufen, womit herauskäme, dass die beiden Punkte gleich sind. Dass das wichtig ist, sieht man daran, dass umgekehrt folgendes nicht gehen würde:

    Point2D p2a=new Point3D(2,4,8);
    Point2D p2b=new Point2D(2,4);
    p2a.equal(p2b);

    Würde Point3D.equal Point2D.equal überschreiben, dann müsste nun eben Point3D.equal aufgerufen werden - das würde aber nicht gehen, weil es eine Instanz von Point3D verlangt, gegeben ist aber nur eine Instanz von Point2D. Point3D ist aber eine Instanz von Point2D, und von einer solchen erwarten wir eben, dass ihre equal-Methode eine Instanz von Point2D akzeptiert - somit wäre das Ersetzbarkeitsprinzip verletzt, wenn Point3D das eben nicht tun würde.

    Es geht mir auch weniger darum, dass ich jetzt soviele Programmiersprachen wie möglich lerne, sondern mehr, dass ich einen Vergleich habe, dass ich - wie man Lehramt-Studenten so schön predigt- "über den Dingen stehen kann"


    Das ist ja auch der Fall. Zumindest die Software Engineers müssen, wenn man nach den Pflichtfächern geht, zumindest Java, C, Prolog und Haskell (in etwa in dieser Reihenfolge; außerdem ein paar kleinere Logiksprachen in EWBS) lernen. Zusätzlich gibt es für Interessierte LVAs, in denen man sich halbwegs aussuchen kann, in welcher Sprache man arbeitet, und LVAs, die speziell darauf ausgelegt sind, einen Vergleich zu bekommen bzw. sich in etwas anderes als Java zu vertiefen: zum Beispiel stackbasierte Sprachen, die jeweils fortgeschrittenen Versionen von objektorientierter, funktionaler und logischer Programmierung und die VL Programmiersprachen.