O'Reilly Forums: Chapter 9, Page 344 - O'Reilly Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Chapter 9, Page 344 got stuck

#1 User is offline   d_j_h_17728 

  • New Member
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 24-February 12

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
0

#2 User is offline   d_j_h_17728 

  • New Member
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 24-February 12

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
0

#3 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

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.
0

#4 User is offline   d_j_h_17728 

  • New Member
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 24-February 12

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
0

#5 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

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.
0

#6 User is offline   d_j_h_17728 

  • New Member
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 24-February 12

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
0

#7 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

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.
0

#8 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

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
0

#9 User is offline   d_j_h_17728 

  • New Member
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 24-February 12

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

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users