Hallo, ich bin gerade dabei ein projekt von mir in eine Library zu stopfen, aber irgend wie schaffe ich es nicht.
Ich kann die Library builden und installieren ohne probleme oder Fehlermeldungen zu bekommen, aber wenn ich sie im code verwenden will, geht nix.
Hier der Link zum Github: https://github.com/Mallo321123/Investspiel_library
Ich habe das projekt mit "python3 -m build" gebaut, und mit "pip install Investspiel_library/dist/investspielapi-0.1.0-py3-none-any.whl" installiert.
Selbst erstellte Library lässt sich nicht importieren
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
Hier ist die Fehlermeldung wenn ich die Library in einem Programm verwenden will:
Code: Alles auswählen
Traceback (most recent call last):
File "/**/test/test.py", line 1, in <module>
import investspielapi
ModuleNotFoundError: No module named 'investspielapi'
- __blackjack__
- User
- Beiträge: 13937
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@mallo321123: Dann gehört das ``pip`` wohl zu einem anderen Python als dem mit dem das Programm dann ausgeführt wird. Dazu gehört auch ob das in ein venv installiert wird und ob *das* dann auch aktiv ist bei der Programmausführung.
Das `venv` hat in dem Github-Repository nichts zu suchen. Das ``dist/``-Verzeichnis mit dem Wheel und dem Quelltext-Archiv auch nicht. In ein Repository gehören keine generierten Sachen, sondern nur Quelltext.
Pro Klasse ein Modul macht keinen Sinn, und man steckt auch nichts in eine Klasse das einfach eine Funktion sein könnte. Und schon gar nicht hat man ”Klassen” die *nur* aus solchen Funktionen bestehen. Das ist nicht Java sondern Python!
Das `venv` hat in dem Github-Repository nichts zu suchen. Das ``dist/``-Verzeichnis mit dem Wheel und dem Quelltext-Archiv auch nicht. In ein Repository gehören keine generierten Sachen, sondern nur Quelltext.
Pro Klasse ein Modul macht keinen Sinn, und man steckt auch nichts in eine Klasse das einfach eine Funktion sein könnte. Und schon gar nicht hat man ”Klassen” die *nur* aus solchen Funktionen bestehen. Das ist nicht Java sondern Python!
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
@mallo321123: Wenn Du das mit den Pfaden korrigiert hast, kommen die nächsten Probleme.
In Python gibt es eine Namenskonvention, dass Klassen mit Großen Anfangsbuchstaben geschrieben werden, Funktionen und Variablen aber komplett klein. Da Du Dich nicht an diese Konvention hältst, macht es das Lesen des Codes sehr schwierig.
buy, read und sell sind zum Großteil identisch. Du solltest nicht in jeder Klasse nochmal das Lesen Deiner Config-Dateien implementieren, sondern die Konfiguration sollte einmal gelesen werden und dann eventuell an die einzelnen Klassen als Argument übergeben werden.
Du importierst Module, die gar nicht existieren. read, calc, ... sind Submodule von investspielapi, müssen deshalb auch als Submodule importiert werden.
Du benutzt print und return für das Fehlerhandling, statt Exceptions. In `read` sind z.B. im Fehlerfall Variablen nicht definiert, was dann zu einem kryptischen Folgefehler führt. `return` ist keine Funktion, sollte also nicht wie eine solche geschrieben werden.
Die Funktion chart sollte also eher so aussehen:
In `price` stückelst Du dann eine URL zusammen, die eigentlich Parameter enthält:
Buy und Sell sind so ähnlich, dass man sie am besten in eine Klasse packt:
wobei hier auch noch die Methoden der `read`-Klasse und die calc-Funktioen dazugehören, weil ohne eine konkrete Instanz funktionieren die sowieso nicht.
In Python gibt es eine Namenskonvention, dass Klassen mit Großen Anfangsbuchstaben geschrieben werden, Funktionen und Variablen aber komplett klein. Da Du Dich nicht an diese Konvention hältst, macht es das Lesen des Codes sehr schwierig.
buy, read und sell sind zum Großteil identisch. Du solltest nicht in jeder Klasse nochmal das Lesen Deiner Config-Dateien implementieren, sondern die Konfiguration sollte einmal gelesen werden und dann eventuell an die einzelnen Klassen als Argument übergeben werden.
Du importierst Module, die gar nicht existieren. read, calc, ... sind Submodule von investspielapi, müssen deshalb auch als Submodule importiert werden.
Du benutzt print und return für das Fehlerhandling, statt Exceptions. In `read` sind z.B. im Fehlerfall Variablen nicht definiert, was dann zu einem kryptischen Folgefehler führt. `return` ist keine Funktion, sollte also nicht wie eine solche geschrieben werden.
Die Funktion chart sollte also eher so aussehen:
Code: Alles auswählen
def chart(self, name, time_range):
url = self.stock_config[name][time_range]
response = requests.get(url)
response.raise_for_status()
return response.json()
Code: Alles auswählen
def price(self, name):
url = self.generall_config["get"]["url"]
parameters = {
"portfolio_id": self.portfolioid,
"exchange": self.trade_config[name]["type"],
"ticker": self.trade_config[name]["ticker"],
}
response = requests.get(url, cookies=self.cookie, params=parameters)
response.raise_for_status()
return response.json()["StockRateInGameCurrency"]
Code: Alles auswählen
class Sell:
def __init__(self, config, trade_config, stock_config, generall_config):
self.trade_config = trade_config
self.stock_config = stock_config
self.generall_config = generall_config
self.portfolioid = config.portfolioid
self.cookie = config.cookie_full
def _buy_or_sell(self, name, parameters)
url = self.generall_config["post"]["url"]
headers = {
"Cookie": str(self.cookie)
}
exchange = self.trade_config[name]["type"]
parameters.update({
'PortfolioId': int(self.portfolioid),
'Exchange': exchange,
'Ticker': self.trade_config[name]["ticker"],
'DoEnqueue': False
})
value = {
'rq': json.dumps(parameters)
}
response = requests.post(url, headers=headers, data=value)
response.raise_for_status()
return response
def sell_count(self, amount, name):
if amount > self.quant(name):
raise RuntimeError("not enouth in stock")
return self._buy_or_sell(name, {
'SellQuantity': amount,
})
def sell_price(self, money, name):
amount = self.calc_count(name, money)
return self.count(amount, name)
def sell_all(self, name):
amount = self.quant(name)
return self.count(amount, name)
def buy_price(self, money, name):
if money > self.ballance():
return("not enouth money")
return self._buy_or_sell(name, {
'BuyWithAmount': money,
})
def buy_count(self, count, name):
money = self.calc_price(name, count)
return self.buy_price(money, name)
def buy_all(self, name):
amount = self.quant(name)
return self._buy_or_sell(name, {
'SellQuantity': amount,
})
... # hier noch die Methoden aus read und calc
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
Ok, danke für die Infos, ich werd's mir noch mal anschauen. Ist halt mein erster versuch, und ich hab mich an eine Anleitung im Internet gehalten.__blackjack__ hat geschrieben: ↑Montag 17. Juni 2024, 12:28 @mallo321123: Dann gehört das ``pip`` wohl zu einem anderen Python als dem mit dem das Programm dann ausgeführt wird. Dazu gehört auch ob das in ein venv installiert wird und ob *das* dann auch aktiv ist bei der Programmausführung.
Das `venv` hat in dem Github-Repository nichts zu suchen. Das ``dist/``-Verzeichnis mit dem Wheel und dem Quelltext-Archiv auch nicht. In ein Repository gehören keine generierten Sachen, sondern nur Quelltext.
Pro Klasse ein Modul macht keinen Sinn, und man steckt auch nichts in eine Klasse das einfach eine Funktion sein könnte. Und schon gar nicht hat man ”Klassen” die *nur* aus solchen Funktionen bestehen. Das ist nicht Java sondern Python!![]()
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
@Sirius3
Auch dir, danke für die ganzen tipps. Ich habe jetzt mal versucht so viele und so gut wie ich konnte anzuwenden.
Ich habe jetzt auch herausgefunden, warum ich die Library nicht Importen kann. Ich hatte im VScode den falschen Interpreter ausgewählt. Ich weis nicht wich ich dass geschaft habe, aber jetzt findet er zumindest was er finden soll.
Ich habe jetzt aber ein anderes Problem, wenn ich eine config verwenden will, bekomme ich einen KeyError, obwohl der Key vorhanden ist, übersehe ich da was?
Auch dir, danke für die ganzen tipps. Ich habe jetzt mal versucht so viele und so gut wie ich konnte anzuwenden.
Ich habe jetzt auch herausgefunden, warum ich die Library nicht Importen kann. Ich hatte im VScode den falschen Interpreter ausgewählt. Ich weis nicht wich ich dass geschaft habe, aber jetzt findet er zumindest was er finden soll.
Ich habe jetzt aber ein anderes Problem, wenn ich eine config verwenden will, bekomme ich einen KeyError, obwohl der Key vorhanden ist, übersehe ich da was?
Code: Alles auswählen
Traceback (most recent call last):
File "/***/test/test.py", line 14, in <module>
trade.buy_price(1000, "etherium")
File "/***/.local/lib/python3.10/site-packages/investspielapi/Trade.py", line 59, in buy_price
if money > self.ballance():
File "/***/.local/lib/python3.10/site-packages/investspielapi/Trade.py", line 100, in ballance
name = self.generall_config["get"]["example"]
File "/usr/lib/python3.10/configparser.py", line 965, in __getitem__
raise KeyError(key)
KeyError: 'get'
- __blackjack__
- User
- Beiträge: 13937
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@mallo321123: Wurde die Konfigurationsdatei denn überhaupt geladen? Also ich meine nicht ob Du das glaubst, sondern ob das *tatsächlich* passiert ist. Du hast da *verschiedene* und *relative* Pfadangaben in dem Quelltext und `configparser` löst keine Ausnahme aus wenn eine Datei nicht gefunden wurde, sondern lädt dann einfach nicht.
Das mit den relativen Pfadangaben ist ein Problem.
Das mit den relativen Pfadangaben ist ein Problem.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
https://github.com/Mallo321123/Investspiel_library
Naja, in der Config.py lese ich in der __init__ die config aus, und speichere sie in self.
in meinem test Programm führe ich dann vollgendes aus:
da sollte ja eigentlich die config mitkommen? Oder verstehe ich hier was Falsch?
Naja, in der Config.py lese ich in der __init__ die config aus, und speichere sie in self.
Code: Alles auswählen
class Config:
def __init__(self, cookieconsent, ssid, cookie, portfolioid):
self.portfolioid = portfolioid
self.cookie = {
"CookieConsent": cookieconsent,
"EQSESSID": ssid
}
self.cookie_full = cookie
self.stock_config = configparser.ConfigParser()
self.stock_config.read('config/stock.conf')
self.generall_config = configparser.ConfigParser()
self.generall_config.read('config/generall.conf')
self.trade_config = configparser.ConfigParser()
self.trade_config.read('config/trade.conf')
Code: Alles auswählen
conf = Config(cookieconsent, ssid, cookie, 517566)
trade = Trade(conf)
- __blackjack__
- User
- Beiträge: 13937
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@mallo321123: Da sind `read()`-Aufrufe mit relativen Pfadangaben. Die beziehen sich auf das aktuelle Arbeitsverzeichnis des Prozesses — was immer *das* auch ist! Wir wissen es nicht. Du vielleicht auch nicht. Und die `read()`-Aufrufe machen einfach gar nichts wenn die angegebene Datei nicht existiert. Und genau das scheint ja zu passieren.
Du musst entweder sicherstellen das diese Dateien relativ zum Arbeitsverzeichnis des Prozesses tatsächlich existieren, das heisst das Programm aus dem richtigen Verzeichnis heraus starten. Oder die Angaben der Pfade dort in der Methode entsprechend anpassen.
Du musst entweder sicherstellen das diese Dateien relativ zum Arbeitsverzeichnis des Prozesses tatsächlich existieren, das heisst das Programm aus dem richtigen Verzeichnis heraus starten. Oder die Angaben der Pfade dort in der Methode entsprechend anpassen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
Na, dass erklärt einiges. Kann ich irgend wie die config dateien in die Library hinzufügen?
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
Habs hinbekommen die configs mit einzubauen. Sind jetzt nur noch kleine probleme
-
- User
- Beiträge: 11
- Registriert: Mittwoch 12. April 2023, 14:16
- Wohnort: 127.0.0.1
Jetzt geht alles, vielen dank euch beiden für die Hilfe!!