Jump to content


Photo

Chapter 9, Page 344


  • Please log in to reply
8 replies to this topic

#1 d_j_h_17728

d_j_h_17728

    New Member

  • Members
  • Pip
  • 7 posts

Posted 01 April 2012 - 06:03 AM

Hi all,

I finally got thru to ch. 9 and everything worked out so far, but now I'm stuck. Where does the

athlete_names = [ath[0]for ath in athletes]

bit go? I tried this and that but now I'm getting a NameError: name 'athletes' is not defined.

Plus the additional code for the Add Time button: does that replace some of the previous code or is this additional?

Could someone maybe post the complete amended code to coachapp.py in the version for ch. 9? (That's not in the code-solution download - there's only the older version.) I would greatly appreciate that - thanks a lot in advance.

(Since I can't work through the book all in one go I keep losing track of some of the implications, coming back to the project only now & then. I guess once I'm finished I'll have to go over the whole thing from the middle onward. But it's fun though.)

Best greetings,
Dirk

#2 d_j_h_17728

d_j_h_17728

    New Member

  • Members
  • Pip
  • 7 posts

Posted 01 April 2012 - 10:00 AM

Hi again,

and pls disregard above message: I think I finagled it out in a way. Just the add_timing_data doesn't seem to be called: There's no message on the console indicating the added time, just the 'CGI-script exited ok'.

My code:
import android
import json
import time

from urllib import urlencode
from urllib2 import urlopen

hello_msg 	  = "Welcome to NUAC's Timing App"
list_title 	  = 'Here is your list of athletes: '
quit_msg 	  = "Quitting Coach Kelly's App"

web_server 	  = 'http://192.168.178.58:8080'

get_names_cgi = '/cgi-bin/generate_names.py'
get_data_cgi  = '/cgi-bin/generate_data.py'

def send_to_server(url, post_data=None):
	if post_data:
		page = urlopen(url, urlencode(post_data))
	else:
		page = urlopen(url)
	return(page.read().decode("utf8"))
	
app = android.Android()

def status_update(msg, how_long=2):
	app.makeToast(msg)
	time.sleep(how_long)

status_update(hello_msg)

athletes = sorted(json.loads(send_to_server(web_server + get_names_cgi)))
athlete_names = [ath[0] for ath in athletes]

app.dialogCreateAlert(list_title)
app.dialogSetSingleChoiceItems(athlete_names)
app.dialogSetPositiveButtonText('Select')
app.dialogSetNegativeButtonText('Quit')
app.dialogShow()
resp = app.dialogGetResponse().result

if resp['which'] in ('positive'):
    selected_athlete = app.dialogGetSelectedItems().result[0]
    which_athlete = athletes[selected_athlete][1]
    athlete = json.loads(send_to_server(web_server + get_data_cgi,{'which_athlete': which_athlete}))
    athlete_title = athlete['Name'] + ' (' + athlete['DOB'] + '), top 3 times:'
    app.dialogCreateAlert(athlete_title)
    app.dialogSetItems(athlete['top3'])
    app.dialogSetPositiveButtonText('OK')
    
    app.dialogSetNegativeButtonText('Add Time') # new button
    if resp['which'] in ('positive'):
        pass
    elif resp['which'] in ('negative'):
        timing_title = 'Enter a new time:'
        timing_msg = 'Provide a new timing value ' + athlete['Name'] + ': '
        add_time_cgi = '/cgi-bin/add_timing_data.py'
        
        resp = app.dialogGetInput(timing_title, timing_msg).result

        if resp is not None:
            new_time = resp
            send_to_server(web_server + add_time_cgi,{'Time': new_time, 'athlete': which_athlete})


    app.dialogShow()
    resp = app.dialogGetResponse().result

status_update(quit_msg)

Any help appreciated, have a nice one
Dirk

#3 paulbarry

paulbarry

    Advanced Member

  • O'Reilly Author
  • PipPipPipPipPipPipPipPip
  • 306 posts

Posted 08 April 2012 - 06:58 AM

Hi Dirk.

I'm not totally sure what is not working here, as the code you show comes from later in the chapter and the 'add_timing_data' code is early in the chapter. It might help to cast your eye over the errata (here: http://oreilly.com/c...n=0636920003434) which has - embarrassingly - a number of reported issues with the code in this chapter.

Regards.

--Paul.

#4 d_j_h_17728

d_j_h_17728

    New Member

  • Members
  • Pip
  • 7 posts

Posted 10 April 2012 - 09:29 AM

Hi Paul,

thanks for your reply! The problem is this: I get to the dialog where I see a selected athlete's top3 times. When I push the button "Add time" the application quits - without asking for the new time. I even copied the line

add_time_cgi = '/cgi-bin/add_timing_data.py'


to the beginning of the code (just under the other cgi-definitions): didn't help either. That's why I think the add_timing_data.py module doesn't get called at all. I checked the code with your errata-list but it seems alright. I must have messed it up somewhere in the above code - that piece does not get too clear from the book. :(

Here's the console-output:
192.168.178.65 - - [10/Apr/2012 19:16:12] "POST /cgi-bin/generate_data.py HTTP/1.1" 200 -
192.168.178.65 - - [10/Apr/2012 19:16:17] command: C:\Python32\python.exe -u C:\Users\Dirk\Documents\python_scripts\HeadFirst
_Python\chapter9\webapp\cgi-bin\generate_data.py ""
192.168.178.65 - - [10/Apr/2012 19:16:21] CGI script exited OK

Here's my add_timing_data.py:
import cgi
import sqlite3

import yate

print(yate.start_response('text/plain'))

form_data = cgi.FieldStorage() # might be a cause of the problem as well?
the_id = form_data['Athlete'].value
the_time = form_data['Time'].value

connection = sqlite3.connect('coachdata.sqlite')
cursor = connection.cursor()
cursor.execute("INSERT INTO timing_data (athlete_id, value) VALUES (?, ?)",
                       (the_id, the_time))
connection.commit()
connection.close()

print('OK.')

Does anyone see where I messed it up? Thanks again - any help welcome

best wishes,

Dirk

#5 paulbarry

paulbarry

    Advanced Member

  • O'Reilly Author
  • PipPipPipPipPipPipPipPip
  • 306 posts

Posted 17 April 2012 - 04:37 AM

Can you post the code that's running on the phone (or have you not got to that part yet?).

Thanks.

--Paul.

#6 d_j_h_17728

d_j_h_17728

    New Member

  • Members
  • Pip
  • 7 posts

Posted 17 April 2012 - 11:00 AM

Hi Paul,

above is my coachapp.py which is running on the phone. As I said - I do get the welcome message, I do get to see the selected athlete's top3 times and when I select an athlete I do have an "Add Time" button. Just when I press it all I see is the quitting message and the application stops. :huh:?

That's why I think I messed up somewhere against the end of coachapp.py.

Greetings, Dirk

#7 paulbarry

paulbarry

    Advanced Member

  • O'Reilly Author
  • PipPipPipPipPipPipPipPip
  • 306 posts

Posted 17 April 2012 - 11:24 AM

Sorry, Dirk. I wasn't paying attention earlier. I'll give your Android code a go on my emulator and see what transpires.

Regards.

--Paul.

#8 paulbarry

paulbarry

    Advanced Member

  • O'Reilly Author
  • PipPipPipPipPipPipPipPip
  • 306 posts

Posted 18 April 2012 - 11:22 AM

Hi Dirk.

You have all the lines of code that you need, you just have them in the wrong order/place. The end of your code should look like this:

        ...
    app.dialogSetItems(athlete['top3'])
    app.dialogSetPositiveButtonText('OK')
    app.dialogSetNegativeButtonText('Add Time') # new button
    app.dialogShow()
    resp = app.dialogGetResponse().result
    
    if resp['which'] in ('positive'):
        pass
    elif resp['which'] in ('negative'):
        timing_title = 'Enter a new time:'
        timing_msg = 'Provide a new timing value ' + athlete['Name'] + ': '
        add_time_cgi = '/cgi-bin/add_timing_data.py'
        
        resp = app.dialogGetInput(timing_title, timing_msg).result

        if resp is not None:
            new_time = resp
            send_to_server(web_server + add_time_cgi,{'Time': new_time, 'athlete': which_athlete})
            ...

Check this against what you have and you'll see where you went wrong - you were not showing the dialog in the correct order, so the result (in "resp") was being processed incorrectly.

I've confirmed that this new code works as shown in the book (compare it to the page346.py included in the chapter9 download).

Hope this work for you. Good luck with the rest of the book.

--Paul

#9 d_j_h_17728

d_j_h_17728

    New Member

  • Members
  • Pip
  • 7 posts

Posted 22 April 2012 - 07:52 AM

Hello Paul,

thank you very much for your reply! I saw now where I messed up and corrected it according to your hints. Now the coachapp.py runs and lets me proceed to the add-time dialogue. :)

Unfortunately there is another mistake somewhere, because the new time does not get added. Here is what the server-log says:
192.168.178.65 - - [22/Apr/2012 17:30:02] command: C:\Python32\python.exe -u C:\Users\Dirk\Documents\python_scripts\HeadFirst
_Python\chapter9\webapp\cgi-bin\add_timing_data.py ""
192.168.178.65 - - [22/Apr/2012 17:30:07] b'Traceback (most recent call last):\n  File "C:\\Users\\Dirk\\Documents\\python_sc
ripts\\HeadFirst_Python\\chapter9\\webapp\\cgi-bin\\add_timing_data.py", line 9, in <module>\n    the_id = form_data[\'Athlet
e\'].value\n  File "C:\\Python32\\lib\\cgi.py", line 575, in __getitem__\n    raise KeyError(key)\nKeyError: \'Athlete\'\n'
192.168.178.65 - - [22/Apr/2012 17:30:11] CGI script exit status 0x1

I checked the code vs. the errata-list, but see no faults: I do use form_data and I do have FieldStorage in upper case (see complete code above). Now why is the key-error raised? What's wrong with the cgi.FieldStorage()? It doesn't seem to deliver the right contents?

Best greetings,
Dirk




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users