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.
So ich habe jetzt eine Klasse geschrieben die für dich warscheinlich keinen sinn ergibt und total blöd ist xD ich habe das jetzt einfach so versucht wie ich denke dass es funktionieren könnte und wollte fragen ob du mir sagen kannst ob es fehler gibt die man beheben kann oder ob der code an sich schrott ist ^^
@ZedsWhatSheSaid: Programmentwicklung funktioniert nicht in dem man irgendetwas hin schreibt und hoffst, dass das dann funktioniert. Die ”Klasse” ist in der Tat völlig sinnlos.
Am besten schreibt man Programme, insbesondere Anfänger, „bottom up”. Also mit den Grundlegenden Datentypen und Funktionen zuerst. So kann man jede einzelne Funktion, Klasse, und Methode testen und erst mit der nächsten weiter machen wenn das bis dahin geschriebene Funktioniert. So baut man ein Programm aus bereits getesteten Bausteinen zusammen. Dafür zerlegt man das Problem in Teilprobleme bis die so klein/einfach sind, dass man sie einfach in Code lösen kann.
An Datentypen gibt es `Company` und `Companies`. Der grundlegendere von beiden ist `Company` denn man kann `Companies` nicht programmieren ohne das man `Company` bereits als Datentyp hat, denn man braucht `Company`-Objekte um sie in `Companies` zu verwalten. Jetzt musst Du Dir überlegen welche Daten ein `Company`-Objekt braucht, und dann kannst Du eine `__init__()`-Methode dafür schreiben, mit der man so ein Objekt erstellen kann. Wenn man es erstellen kann, kann man sich überlegen wie die Ausgabe als Zeichenkette aussehen soll und kann die `__str__()`-Methode entsprechend umsetzen. Jetzt kann man schon mal testen ob das Erstellen eines `Company`-Objekts mit festen Argumenten und die anschliessende Ausgabe mit ``print`` so funktionieren wie man sich das gedacht hat.
Als nächstes möchte man ein `Company`-Objekt nicht aus einzelnen Argumenten erstellen, sondern aus einer Zeile, also Zeichenkette aus der Eingabedatei. Dafür kann man sich eine Funktion schreiben, die so eine Zeile als Argument bekommt, die in ihre Bestandteile zerlegt, die Datentypen umwandelt, und damit dann ein `Company`-Objekt erstellt und das zurück gibt. Das kann man mit einer festen Zeichenkette testen, oder schon mit einer Schleife über die Datei in dem man einfach jede Zeile nimmt, damit die Funktion aufruft, und das zurückgegebene `Company`-Objekt ausgibt.
Wenn das alles bis dahin funktioniert kann man anfangen die `Companies`-Klasse zu entwerfen und dann ebenfalls Stück für Stück zu implementieren und bei jeder Operation zu testen ob das soweit funktioniert wie man das geplant hat.
Ich habe das mal in Clojure umgesetzt, weil ich mir die Sprache gerade anschaue. `Companies` ist dabei eine Abbildung (`hash-map`) geblieben, also das was in Python ein Wörterbuch (`dict()`) wäre, weil das sonst IMHO zu viel unnötiger Aufwand wäre das in eine Klasse (Record) zu stecken.
(ns companies
(:require [clojure.string :as string]
:require [clojure.data.json :as json]))
(defn input [prompt] (print prompt) (flush) (read-line))
(defrecord Company [name founding-year employee-count]
Object
(toString [_] (str name " exists since " founding-year " and has "
employee-count " employees.")))
(defn parse-company [line]
(let [[name year count]
(string/split (subs line (inc (.indexOf line ")"))) #",")]
(->Company name (read-string year) (read-string count))))
(def ->Companies hash-map)
(defn add-company [companies company] (assoc companies (:name company) company))
(def get-company get)
(defn load-companies [filename]
(with-open [reader (clojure.java.io/reader filename)]
(reduce
add-company (->Companies) (map parse-company (line-seq reader)))))
(defn companies-as-json [companies] (json/write-str (vals companies)))
(defn -main []
(let [companies (load-companies "test.txt")
company (get-company companies (input "Enter company name: "))]
(println (if company (str company) "No company by that name."))
(newline)
(println (companies-as-json companies))))
Wenn ich das richtig verstanden habe dann braucht man in Clojure für Klassen zwingend ein Protokoll für die Methoden‽ In Java-sprech also zu jeder Klasse zwingend ein Interface‽ Das fänd ich ja mal krass nervend.
BlackJack hat geschrieben:Wenn ich das richtig verstanden habe dann braucht man in Clojure für Klassen zwingend ein Protokoll für die Methoden‽ In Java-sprech also zu jeder Klasse zwingend ein Interface‽ Das fänd ich ja mal krass nervend.
In Clojure nutzt man auch Klassen kaum und du kannst dir ja problemlos ein Makro schreiben dass das zusammenfasst, nicht so wie in Java.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
@Leonidas: Heisst das man benutzt eine Mischung aus `defrecord` und Methoden darauf um dem zum Beispiel eine Zeichenkettendarstellung beizubringen oder eine Vergleichsfunktion zu definieren und Funktionen auf der anderen Seite oder nutzt man auch `defrecord` schon nicht, und hat damit kein polymorphes `.toString` was mit `str` verwendbar ist. `defrecord` erstellt ja letztlich eine Klasse.
Das man sich ja ein Makro schreiben kann finde ich oft ein schwaches Argument für Sachen die „selbstverständlich” sind, weil sich dann jeder Programmierer Makros für die gleichen Sachen schreibt, aber alle unterschiedlich heissen und geringfügig anders funktionieren. Dabei könnte man das leicht lösen wenn man zusätzlich zu den Protokollen und Klassen auch `nil` erlauben würde wo man dann Methoden schreiben kann, die ausschliesslich zu dem Objekt gehören. Oder man erlaubt auch ein Keyword, damit es lesbarer und erweiterbar bleibt.