TypeError: 'str' object is not callable

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.
Antworten
topy
User
Beiträge: 7
Registriert: Freitag 3. Mai 2019, 22:51

Hey, ich fange gerade an Python zu lernen und komme schon nicht weiter. Wenn ich folgenden Code ausführe

Code: Alles auswählen

[
regr = linear_model.LinearRegression()
regr.fit(size2,house_price)

def graph(formular, data):
    x = np.array(data)
    y = eval(formular)
    plt.plot(x,y)
    

graph('regr.coef_*x + regr.intercept_',range(1000,2700))
plt.scatter(size2,house_price,color = 'black')
plt.ylabel('house_price')
plt.xlabel('size')
plt.show()][code]
bekomme ich die Fehlermeldung

Code: Alles auswählen

[TypeError                                 Traceback (most recent call last)
<ipython-input-46-009f91ee2c72> in <module>
      7 graph('regr.coef_*x + regr.intercept_',range(1000,2700))
      8 plt.scatter(size2,house_price,color = 'black')
----> 9 plt.ylabel('house_price')
     10 plt.xlabel('size')
     11 plt.show()

TypeError: 'str' object is not callable][code]
Wie gesagt bin recht neu und habe keine Ahnung was hier falsch ist.
Schonmal Danke im voraus
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@topy: Wenn man das versucht auszuführen wird man gleich in der ersten Zeile einen `NameError` für `linear_model` bekommen, weil das nirgends definiert ist. Du musst schon den gesamten Code zeigen, denn wenn man mal davon ausgeht, das `plt` das `matplotlib.pyplot`-Modul ist, dann muss davor irgendwo Code stehen der die `ylabel()`-Funktion durch eine Zeichenkette ersetzt hat. Das ist der Fehler. Denn Zeichenketten kann man nicht aufrufen, wie die Ausnahme ja deutlich sagt.

Code: Alles auswählen

In [14]: 'some string'('house_price')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-997a33391817> in <module>()
----> 1 'some string'('house_price')

TypeError: 'str' object is not callable
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
topy
User
Beiträge: 7
Registriert: Freitag 3. Mai 2019, 22:51

Sry, hier einmal der ganze Code

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model

house_price = [245, 312, 279,308, 199, 219 ,405, 324, 319, 255];
size = [1400,1600,1700,1875,1100,1550,2350,2450,1425,1700];

regr = linear_model.LinearRegression()
regr.fit(size2,house_price)

def graph(formular, data):
    x = np.array(data)
    y = eval(formular)
    plt.plot(x,y)
    

graph('regr.coef_*x + regr.intercept_',range(1000,2700))
plt.scatter(size2,house_price,color = 'black')
plt.ylabel('house_price')
plt.xlabel('size')
plt.show()
hier wurde die ylabel() Funktion doch nirgends durch eine Zeichenkette ersetzt oder ?
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@topy: Da bekommt man offensichtlich eine `NameError`-Ausnahme weil `size2` nicht definiert ist. Du solltest Code den Du zeigst auch laufen lassen und sicherstellen, das tatsächlich die Fehlermeldung kommt, die Du behauptet hast.

Das `size` in dem Code geht nicht für `size2` weil das kein zweidimensionales Array ist. Also wo kommt `size2` her?

Anmerkungen zum Quelltext: `datasets` wird importiert, aber nicht verwendet.

Das Semikolon ist in Python zum trennen von zwei Anweisungen in der selben Zeile da, also überflüssig wenn die zweite Anwendung die leere Anweisung ist.

Containertypen bekommen normalerweise einen Namen in Mehrzahl. Den `house_size` steht ja nicht für *eine* Hausgrösse, sondern für *mehrere* Hausgrössen.

Es ist ungünstig, weil fehleranfällig, parallele Listen zu führen. Wenn Hauspreis und Grösse jeweils pro Index zusammen gehören, sollten die Werte nicht in verschiedenen Listen stehen. Für die weitere Verarbeitung braucht man die getrennt, aber bei der Eingabe ist das fehleranfällig wenn zusammengehörende Daten vom Programmierer in zwei getrennten Listen gepflegt werden müssen.

`regression` könnte man auch ausschreiben. Abkürzungen sollte man vermeiden.

`graph` währe eher ein Name für einen Graphen statt für eine Funktion. Da sollte man etwas wählen was mehr nach einer Tätigkeit klingt.

`formular` heisst auf Deutsch „Vordruck“ oder „Formular“. Ich denke das sollte `formula` – „Formel“ heissen.

Beziehungsweise sollte das eigentlich so gar nicht existieren, denn es macht keinen Sinn hier einen Ausdruck als Zeichenkette zu übergeben und per `eval()` auszuwerten. `eval()` ist fast immer das falsche Werkzeug. Man würde hier eher eine Funktion übergeben, die `x` als Argument bekommt.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model


def plot(function, data):
    x = np.array(data)
    plt.plot(x, function(x))
    

def main():
    houses_data = [
        (245, 1400),
        (312, 1600),
        (279, 1700),
        (308, 1875),
        (199, 1100),
        (219, 1550),
        (405, 2350),
        (324, 2450),
        (319, 1425),
        (255, 1700),
    ]

    house_prices = [price for price, _ in houses_data]
    sizes = [size for _, size in houses_data]

    regression = linear_model.LinearRegression()
    regression.fit(size2, house_prices)

    plot(
        lambda x: regression.coef_ * x + regression.intercept_,
        range(1000, 2700)
    )
    plt.scatter(size2, house_prices, color='black')
    plt.ylabel('house_price')
    plt.xlabel('size')
    plt.show()


if __name__ == '__main__':
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
topy
User
Beiträge: 7
Registriert: Freitag 3. Mai 2019, 22:51

Erstmal viele Dank für die Tipps.
size2 hatte ich vergessen mit in den Code zu packen, nutze jupyter und habe die Zelle vergessen.

Code: Alles auswählen

size2 = np.array(size).reshape((-1,1))
Wenn ich nun deinen oder auch meinen Code durchlaufen lassen bekomme ich aber immer noch dieselbe Fehlermeldung.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@topy: Ich bekomme dann einen Plot. Wenn Du Zelle vergessen kannst, kannst Du ja auch sonstwas irgendwann vorher in dem Interpreter mal ausgeführt haben. Wenn Du sicher sein willst, das ein Jupyter-Notebook tatsächlich funktioniert, muss das komplette Notebook in einem frischen Kernel ausgeführt werden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

@blackjack in deinem Code ist aber 2x ein undefiniertes size2
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
topy
User
Beiträge: 7
Registriert: Freitag 3. Mai 2019, 22:51

@blackjack Vielen Dank.
Ich habe Jupyter neu gestartet und dann haben beide Varianten funktioniert.
Es lag also daran, dass ich vorher etwas im Interpreter ausgeführt habe, was mein Problem beeinflusst hat ?
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ThomasL: Naja, die sind auch im Original vorhanden und dort nicht definiert, das habe ich doch gleich als erstes geschrieben, dass das zu einem `NameError` führt. Ich wollte da jetzt nicht weiter drüber nachdenken was das denn sein könnte, denn das musste es im Original ja irgendwo geben, sonst wäre der Code nicht bis zum Label setzen gekommen.

@topy: Ja, so ein Notebook verwendet den gleichen Interpreter solange es läuft und man den nicht explizit neu startet. Alles was man da so drin macht, kann den Zustand verändern, auch wenn Code den man mal hat laufen lassen, so gar nicht mehr im Notebook steht. Darum sollte man spätestens wenn man ein Notebook fertig gestellt hat, oder einen Teilabschnitt fertig hat, das ganze neu starten und die Zellen abarbeiten lassen, um sicher zu stellen, das man alles notwendige da auch tatsächlich (noch) drin stehen hat, und das es auch in der Reihenfolge wie es im Notebook steht, ausgeführt werden kann.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
topy
User
Beiträge: 7
Registriert: Freitag 3. Mai 2019, 22:51

Vielen Dank für die Hilfe. Hoffentlich kann ich mir durch den letzten Tipp ein paar Fragen später ersparen. :D
Antworten