Seit Update auf Anaconda-Spyder 5.5.1 Fehler in Python-Script stock.py

Probleme bei der Installation?
Antworten
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!
Hier mein Code:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name:        stock.py
# Purpose:     historical share prices are downloaded from the Internet
#
# Author:      Thomas Graeber
#
# Created:     11/11/2020
# License:     n/a
#-------------------------------------------------------------------------------
"""
    historical share prices are downloaded from the Internet
    individual values are saved in a pandas dataframe
    
    1 main class that, beside constructor, contains 5 functions:
        
        constructor (__init__)
            - querys table with the Ariva Security Number
              and gets Securitynumber from it
            - builds the ariva-URL
            - calls the private functions:
                _request_site
                _create_dataframe
                _edit_dataframe                
        
        3 private functions:
            _request_site
            makes request
            In: url
            Out: request_result
            
            _create_dataframe
            creates dataframe containing result
            In: request_result
            Out: stock_data
            
            _edit_dataframe
            does 5 operations on the dataframe            
            In: stock_data
            Out: stock_data_finished
         
        2 public functions:
            print_dataframe
            In: stock_data_finished
            
            to_excel
            In: stock_data_finished
"""
import pandas as pd
import requests
import io
import datetime

# main class
class Stock():
    def __init__(self, start_date, end_date, isin):
        """
        constructor (__init__) - builds the ariva-URL
                
        In:
        security-number, start-date, end-date
        
        Out:
        URL
        """
        # create pandas dataframe from Excel-file
        isin_table = pd.read_excel('data/AllMArkets.xls')
        # query dataframe
        result = isin_table.query('ISIN == @isin')
        # get secu from query-result
        secu = result.iloc[0]['Ariva Security Number']
        
        self.url = 'http://www.ariva.de/quote/historic/historic.csv?secu=%d&boerse_id=6&clean_split=1&clean_payout=0&clean_bezug=1&min_time=%s&max_time=%s&trenner=%s3B&go=Download' % (secu, start_date, end_date, chr(37))
        self._request_site()
        self._create_dataframe()
        self._edit_dataframe()
    
    # private functions
    def _request_site(self):
        """
        makes the http-request
           
        In:
        URL
        
        Out:
        request-result
        """
        self.request_result = requests.get(self.url)
    
    def _create_dataframe(self):
        """
        creates a pandas-dataframe containing the request-result
        
        In:
        request_result
        
        Out:
        stock-data (dataframe)
        """
        urlData = self.request_result.content
        self.stock_data = pd.read_csv(io.StringIO(urlData.decode('utf-8')),
                                      sep=";", thousands='.')
        
    def _edit_dataframe(self):
        """
        does 5 operations on the dataframe
            + removes the column 'Volumen'
            + translates the column names into English
            + inverts the rows
            + resets the index
            + removes the old index
           
        In:
        stock-data
        
        Out:
        stock-data finished
        """
        # remove column 'Volumen' (the special value 'Volumen' isn't necessary, the number/quantity is
        # called 'volume' from now on)
        stock_data = self.stock_data.drop(columns=['Volumen'])
        # translate column names
        stock_data.columns = ['date', 'open', 'high', 'low', 'close', 'volume']
        # invert rows
        stock_data = stock_data.iloc[::-1]
        # reset index
        stock_data = stock_data.reset_index()
        # remove old index
        self.stock_data_finished = stock_data.drop(columns=['index'])
        
    # public functions
    def print_dataframe(self):
        print(self.stock_data_finished)
    
    def to_excel(self):
        """
        writes the requested data to a csv-file
           
        In:
        stock_data_finished
        """
        self.stock_data_finished.to_excel('results/stock.xlsx')

def main():
    start_date = datetime.date(2016, 1, 14)
    end_date = datetime.date(2017, 1, 14)
    apple = Stock(start_date, end_date, isin='US0378331005')
    apple.print_dataframe()
    apple.to_excel()
       
if __name__ == "__main__":
    main()
Siehe nun bitte Betreff.
Ich habe versucht, das Modul pandas upzudaten, erhielt dabei jedoch:
ERROR: Could not install packages due to an OSError: [WinError 5] Zugriff verweigert: 'C:\\Users\\User\\anaconda3\\Lib\\site-packages\\~andas\\_libs\\algos.cp311-win_amd64.pyd'
Consider using the `--user` option or check the permissions.

Erbitte Hilfe!
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
grubenfox
User
Beiträge: 433
Registriert: Freitag 2. Dezember 2022, 15:49

Was nun? Fehler in Python-Script (welche Fehlermeldung?) wie es im Betreff steht oder geht es um die Fehlermeldung beim Update von Pandas?
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Es geht um die Fehlermeldung, die auch dann entsteht, wenn man stock.py im Interpreter laufen lässt:
TypeError: read_excel() missing 1 required keyword-only argument: 'engine_kwargs'
Also unabhängig von Spyder, jedoch bestehend seit Spyder-Update.
:-)

Hinzuzufügen ist noch, dass die Fehlermeldung unter/im Interpreter (ohne Spyder) anders lautet, nämlich:
pandas.errors.ParserError: Error tokenizing data. C error: Expected 1 fields in line 5, saw 2
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17763
Registriert: Sonntag 21. Oktober 2012, 17:20

Welche Pandas-Versionen hast Du denn in Deinen unterschiedlichen Environments installiert?
Bitte die vollständige Fehlermeldung posten.

Variablennamen werden immer komplett klein geschrieben und sollten aussagekäftig sein.
Die Klasse ist ziemlich umständlich. Methoden haben normalerweise einen Rückgabewert und setzen nicht nur ein Attribut, denn die sollten alle in __init__ initalisiert werden.
Ein `request_result` ist ein `response`, macht hier aber wenig Sinn, das als Attribut zu speichern. Der response sollte auf Fehler geprüft werden. Das Encoding sollte vom http-Server kommen, so dass das händische Dekodieren nicht nötig sein sollte.
read_csv kann aber auch direkt URLs verarbeiten.
% als chr(37) zu scheiben, ist unnötig kompliziert, und das als Parameter anzugeben auch, weil man einfach '%%' im String benutzen könnte, oder man steigt gleich auf f-Strings um, die man eh bevorzugen sollte.
Der Doc-String von __init__ sagt ja eigentlich schon, dass Du eher Funktionen schreiben wolltest.

Code: Alles auswählen

def generate_url(start_date, end_date, isin):
    """builds the ariva-URL
            
    In:
    security-number, start-date, end-date
    
    Out:
    URL
    """
    all_markets = pd.read_excel('data/AllMArkets.xls')
    result = all_markets.query('ISIN == @isin')
    security_number = result.iloc[0]['Ariva Security Number']
    return ('http://www.ariva.de/quote/historic/historic.csv?'
        f'secu={security_number}'
        '&boerse_id=6'
        '&clean_split=1'
        '&clean_payout=0'
        '&clean_bezug=1'
        f'&min_time={start_date}'
        f'&max_time={end_date}'
        '&trenner=%3B'
        '&go=Download')

def create_dataframe(url):
    return pd.read_csv(url, sep=";", thousands='.')

def cleanup_dataframe(sock_data):
    """
    does 5 operations on the dataframe
        + removes the column 'Volumen'
        + translates the column names into English
        + inverts the rows
        + resets the index
        + removes the old index
       
    In:
    stock-data
    
    Out:
    stock-data finished
    """
    stock_data = stock_data.drop(columns=['Volumen'])
    stock_data.columns = ['date', 'open', 'high', 'low', 'close', 'volume']
    stock_data = stock_data.iloc[::-1]
    stock_data = stock_data.reset_index()
    return stock_data.drop(columns=['index'])
Zuletzt geändert von Sirius3 am Mittwoch 17. April 2024, 20:35, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13126
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Strawk: Das sind mehrere Fragen die man vielleicht besser in jeweils einem eigenen Thema abhandeln sollte.

Anmerkungen zum Quelltext: Diese ”Klasse” ist extrem gruselig und keine Klasse. Das sollten Funktionen sein und das was da an „In“ und „Out“ dokumentiert ist, wo steht welche ”Ein”- und ”Ausgaben” die ”Methoden” haben, sollten tatsächliche Eingabeparameter und Rückgabewerte von den Funktionen sein.

Es macht grundsätzlich auch nicht so viel Sinn in einer `__init__()` lauter kleine Methoden aufzurufen die jeweils ein oder zwei Attribute definieren.

Parameter selbst in eine URL formatieren ist unübersichtlich und gegebenfalls auch fehleranfällig weil man bestimmte Zeichen escapen muss. Das sollte man dem `requests` überlassen.

``%`` zur Zeichenkettenformatierung hätte man aber auch schon in Python 2 nicht mehr gemacht. Es gibt die `format()`-Methode auf Zeichenketten beziehungsweise f-Zeichenkettenliterale.

``chr(37)`` statt "%"? Warum so kryptisch?

Eine HTTP-Antwort kann auch eine Fehlermeldung sein. Darauf sollte man prüfen.

Code: Alles auswählen

import io
from datetime import date as Date

import pandas as pd
import requests


def get_stock_data(start_date, end_date, isin):
    separator = ";"
    response = requests.get(
        "http://www.ariva.de/quote/historic/historic.csv",
        params={
            "secu": (
                pd.read_excel("data/AllMArkets.xls")
                .query("ISIN == @isin")
                .iloc[0]["Ariva Security Number"]
            ),
            "boerse_id": "6",
            "clean_split": "1",
            "clean_payout": "0",
            "clean_bezug": "1",
            "min_time": str(start_date),
            "max_time": str(end_date),
            "trenner": separator,
            "go": "Download",
        },
        timeout=None,
    )
    response.raise_for_status()
    stock_data = pd.read_csv(
        io.StringIO(response.content.decode("utf-8")),
        sep=separator,
        thousands=".",
    ).drop(columns=["Volumen"])
    stock_data.columns = ["date", "open", "high", "low", "close", "volume"]
    return stock_data.iloc[::-1].reset_index().drop(columns=["index"])


def main():
    apple = get_stock_data(
        Date(2016, 1, 14), Date(2017, 1, 14), "US0378331005"
    )
    print(apple)
    apple.to_excel("results/stock.xlsx")


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten