1

Objective:

I am writing an application (using Tkinter, Python 3.0 - ubuntu). The event trigger is user input a float, user presses a button; then 'calculate' function compares a column from a pandas dataframe (made from a .csv) to the user's input.

It should return the five rows.

Those rows are determined by the proximity (closeness) of the user's number compared with all floats in a particular column of the dataframe the function created using pandas. Next, it should return summary stats for (one 0f the columns) from those 5 returned rows. (Note: pandas' df.column.describe() will suffice for now).

(I have a pressing deadline, so any thoughtful suggestions will be met with immediate good karma and instant upvoting). :-)

Error1:

   **TypeError: unsupported operand type(s) for -: 'float' and 'instance'**

Note1:

I know they are missed typed -- are there convenient hacks around this?

The compiler considers the floats from dataframe and 'instance' my declared es_in=DoubleVar().

Modification: Tkinter has no 'FloatVar()'. I cast float(es_in). It gives:

Error2:

  AttributeError: DoubleVar instance has no attribute '__float__'




import pandas as pd
from Tkinter import *
import ttk

def calculate(*args):
    try:
        df=pd.read_csv('master_pl.csv')

Note2:

The following line gives me the five 'closest' rows. The error is generated from this line: where I compare a column of my dataframe: df["ES"], to the user-defined input called es_in.

        df.ix[(df["ES"][:]-es_in).abs().argsort()[:5]]

     except ValueError:
       pass


  <___calculate_function_ends_here___>
   # GUI code continues...


root = Tk()
root.title("Cluster Program")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

The user defined input is here:

es_in = DoubleVar()

es_entry = ttk.Entry(mainframe, width=7)
es_entry.grid(column=2, row=1, sticky=(W, E))


ttk.Button(mainframe, text="Calculate", command=calculate).grid(column=3, row=3, sticky=W)

 ttk.Label(mainframe, text="ES").grid(column=3, row=1, sticky=W)
 ttk.Label(mainframe, text="output_fiveclosestrows").grid(column=3, row=2, sticky=W)



es_entry.focus()
root.bind('<Return>', calculate) 


<end>
Michele Reilly
  • 643
  • 2
  • 9
  • 19
  • @user1827356 Interesting. I made your change. Takes an awfully long time to run. I don't see any errors OR output (of the row results) to the box. Should I be adding additional features, allocating a specific space for this output? – Michele Reilly Jul 29 '13 at 17:08
  • es_in is a tkinter object and not a python 'float'. Hence your error. Processing time should not be related to this specific question. You will want to convert your df result to a string and display in the label (assuming that's your goal). It should be easy to find examples showing how that's done. – user1827356 Jul 29 '13 at 17:12
  • @user1827356 I cannot simply convert it to a string b/c it need to return the *closest* 5 numbers in the df's column to the user's number. I do that by differencing - can't difference strings. – Michele Reilly Jul 29 '13 at 17:15
  • I meant making the result a string. Assuming, you want to display the result in a label, assign your 'processed result' as follows - df.ix[(df["ES"][:]-es_in.get()).abs().argsort()[:5]]['your column name'].to_str() – user1827356 Jul 29 '13 at 17:30
  • @user1827356 I don't think it is possible to convert a series into a string. Series has no attribute to_str(). – Michele Reilly Jul 29 '13 at 17:45
  • My bad, it should've been this pd.Series.to_string – user1827356 Jul 29 '13 at 17:46
  • @user1827356 This does not seem to be working: Still NO errors and NO output. – Michele Reilly Jul 29 '13 at 17:54
  • Are you able to display anything in the label? I would try to accomplish that first. Also if you try to print the result of to_string you should be able to see it on the terminal – user1827356 Jul 29 '13 at 18:42
  • @user1827356 thanks but the labeling and text on the buttons are fine. It's just not producing any output. – Michele Reilly Jul 29 '13 at 19:36
  • Those work because of initialized values. Updating is different. This might help - http://stackoverflow.com/questions/1918005/making-python-tkinter-label-widget-update – user1827356 Jul 29 '13 at 19:38
  • +1 for offering karma. – John Jul 30 '13 at 01:22

1 Answers1

0

If I understand you correctly, the error is produced by this bit of code: df["ES"][:]-es_in, correct?

es_in is an instance of DoubleVar, which means you can't use the value of that variable directly since the value is an instance rather than a value -- exactly what the error message is telling you.

So, how do you get the value from a DoubleVar? With the get method. Change the code to this, and see if it works any better:

df.ix[(df["ES"][:]-es_in.get()).abs().argsort()[:5]]

Notice where it uses es_in.get() rather than es_in

Of course, another problem seems to be that you're subtracting a floating point value from a sequence, which makes no sense. Are you wanting to subtract it from each value in the sequence?

It would help if you broke your code up into multiple lines. It would make the code easier to understand, and easier for you to debug. For example, if I break your code into multiple lines, I end up with something like this:

diff = df["ES"][:]-es_in.get()
delta = diff.abs()
sorted = delta.argsort()
index = sorted[:5]
df.ix[index]

That looks wrong to me, but I don't know numpy or pandas, so maybe it makes sense in that context. Regardless, breaking a complex statement into multiple statements is a good first step in trying to debug code that isn't working the way you behave. After breaking it apart you'll have a better idea of what part of the code is failing, and you can use a debugger or print statements to display intermediate values to validate your assumptions.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • if you read the chain, you would have noticed that the get() method was already suggested above -- and addressed. Also there is nothing wrong with that line, I have used it in multiple contents. Although, for other people reading this and posterity -- your breakdown might be useful. – Michele Reilly Jul 29 '13 at 22:12
  • @user1374969: there is no other answer that I can see that mentions `.get(0)`. There's a comment, but no answer. Comments are for clarification, answers are for answers. Your question is specifically asking about why you're getting the error `**TypeError: unsupported operand type(s) for -: 'float' and 'instance'**`, and this answer addresses that. – Bryan Oakley Jul 29 '13 at 22:18
  • @user1374969: I don't understand your comment about there being nothing wrong with the line. Using `x-y` where `y` is an instance of DoubleVar will absolutely give you an error every time. – Bryan Oakley Jul 29 '13 at 22:21
  • No. Re-read. I understand the problem. My question asks for any hacks around this, given those types. (I see you edited you comment). Despite your ambiguous "answers are for answers" --- we still don't seem to have one, now do we? The *very first* remark by the anonymous user is precisely the suggestion you seem to be giving. The rest of your response is you telling me to compile something which is NOT what I asked (b/c this line works)-- if you don't believe it, simply import pandas and run that line for yourself. – Michele Reilly Jul 30 '13 at 00:52
  • @user1374969: Why do you need a hack to get around this? What would a hack get you that calling `.get()` doesn't? – Bryan Oakley Jul 30 '13 at 01:33
  • Bryan, as I said above, that removes all errors yet I still don't SEE any output to the box. Happy to post what I figure out later. – Michele Reilly Jul 30 '13 at 01:38
  • Ok, so you're saying this answer explains the question that you asked, but now you have another question? If you do, ask another question. As for why you don't see anything, I don't see anywhere in your code where you're even _trying_ to see anything. There are no print statements, no places where you're setting the value of a label, etc., so it's hard for us to guess why no information is showing up. – Bryan Oakley Jul 30 '13 at 01:52
  • Why did it take you so long to figure out that the first guy made your so-called "answer" irrelevant? Reading comprehension. Furthermore, user1827356 pointed to a relevant link, you're just wasting time, presumably hoping for an upvote. – Michele Reilly Jul 30 '13 at 02:02
  • @user1374969: I don't understand how a correct answer is irrelevant. And, hey, what happened to the good karma you promised? I don't care about the vote (heck, vote me down if it makes you feel good!), but you're coming across as pretty angry for someone who promised "immediate good karma". This site is for questions and answers. You asked a question, this is a correct answer to that question. It's not an answer to some other question, it's an answer to the specific question that you asked, about a specific error message. Why get angry about that? – Bryan Oakley Jul 30 '13 at 02:13
  • Maybe if we put a price on it, it would be easier to see. Suppose this were a competition to win $1000 for who can give the answer to the integral of a Gaussian the quickest, (or pick your favorite integral); someone goes to the board with the answer. One hour later, another guy, walks by and sees his answer (or figures it out himself) then screams out to the judges what it is. Does he deserve the money? For something other then what was just said -- I'll def upvote it, man! – Michele Reilly Jul 30 '13 at 02:26