Advertisement
here2share

PyS60 Tutorial <<< As An HTML Page

May 21st, 2015
520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  2. </head><body bgcolor="#ffffff" vlink="blue" link="blue"><div style="position:relative">
  3.  
  4.  
  5. <!-- AdFender script begin --><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=1&amp;url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=2&amp;url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=3&amp;url=webcache.googleusercontent.com"><link rel="stylesheet" type="text/css" media="screen" href="http://local.adfender.com/adfender/elemhide.css?page=4&amp;url=webcache.googleusercontent.com"><script type="text/javascript" src="http://local.adfender.com/adfender/elemhide.js"></script><!-- AdFender script end -->
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <meta name="Creator" content="LaTeX with hyperref package">
  8. <meta name="Producer" content="pdfTeX-1.40.3">
  9. <meta name="CreationDate" content="D:20080401083512+02'00'">
  10. <meta name="ModDate" content="D:20080401083512+02'00'">
  11. <meta name="Fullbanner" content="This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6">
  12. <title>Yet Another PyS60 Tutorial INCOMPLETE DRAFT VERSION Gunnar Misund</title>
  13.  
  14. <table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="1"><b>Page 1</b></a></font></td></tr></tbody></table><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  15. <div style="position:absolute;top:524;left:319"><nobr>Yet Another PyS60 Tutorial</nobr></div>
  16. <div style="position:absolute;top:573;left:319"><nobr>INCOMPLETE DRAFT VERSION</nobr></div>
  17. <div style="position:absolute;top:907;left:319"><nobr>Gunnar Misund</nobr></div>
  18. </span></font>
  19. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  20. <div style="position:absolute;top:1012;left:319"><nobr>April 1, 2008</nobr></div>
  21. <div style="position:absolute;top:1039;left:319"><nobr>Østfold University College, Halden, Norway</nobr></div>
  22. </span></font>
  23.  
  24. <div style="position:absolute;top:1437;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="2"><b>Page 2</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  25. <div style="position:absolute;top:1553;left:108"><nobr>2</nobr></div>
  26. </span></font>
  27.  
  28. <div style="position:absolute;top:2699;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="3"><b>Page 3</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  29. <div style="position:absolute;top:3144;left:458"><nobr>Abstract</nobr></div>
  30. <div style="position:absolute;top:3183;left:184"><nobr>This PyS60 (Python for Symbian Series 60 mobile phones) tutorial is a byproduct of course in Mobile</nobr></div>
  31. <div style="position:absolute;top:3206;left:162"><nobr>Programming at Østfold University College, Halden, Norway, held in the Spring of 2008. It is meant as a</nobr></div>
  32. <div style="position:absolute;top:3229;left:162"><nobr>supplement to the array of ”traditional” sources for PyS60 documentation. We focus in particular on issues</nobr></div>
  33. <div style="position:absolute;top:3252;left:162"><nobr>that are either poorly documented, or poorly demonstrated, or both. We give numerous bare-bone examples</nobr></div>
  34. <div style="position:absolute;top:3276;left:162"><nobr>to make it easier for the eager programmer to develop the next mobile killer applications.</nobr></div>
  35. </span></font>
  36.  
  37. <div style="position:absolute;top:3961;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="4"><b>Page 4</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  38. <div style="position:absolute;top:4264;left:108"><nobr>Table of Contents</nobr></div>
  39. </span></font>
  40. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  41. <div style="position:absolute;top:4379;left:108"><nobr><a href="#4">Abstract</a></nobr></div>
  42. <div style="position:absolute;top:4379;left:749"><nobr>2</nobr></div>
  43. <div style="position:absolute;top:4418;left:108"><nobr><a href="#8">1 Under The Hood</a></nobr></div>
  44. <div style="position:absolute;top:4418;left:749"><nobr>2</nobr></div>
  45. <div style="position:absolute;top:4443;left:130"><nobr><a href="#8">1.1 3xHelloWorld . . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
  46. <div style="position:absolute;top:4443;left:749"><nobr>2</nobr></div>
  47. <div style="position:absolute;top:4467;left:130"><nobr><a href="#11">1.2 SystemInfo . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
  48. <div style="position:absolute;top:4467;left:749"><nobr>5</nobr></div>
  49. <div style="position:absolute;top:4491;left:130"><nobr><a href="#12">1.3 Filesystem . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
  50. <div style="position:absolute;top:4491;left:749"><nobr>6</nobr></div>
  51. <div style="position:absolute;top:4531;left:108"><nobr><a href="#15">2 Storing Stuff</a></nobr></div>
  52. <div style="position:absolute;top:4531;left:749"><nobr>9</nobr></div>
  53. <div style="position:absolute;top:4555;left:130"><nobr><a href="#15">2.1 Files .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
  54. <div style="position:absolute;top:4555;left:749"><nobr>9</nobr></div>
  55. <div style="position:absolute;top:4579;left:130"><nobr><a href="#15">2.2 Pickling,andhowtoeasilyextendPyS60 . . .</a> . . . . . . . . . . . . . . . . . . . . . . . .</nobr></div>
  56. <div style="position:absolute;top:4579;left:749"><nobr>9</nobr></div>
  57. <div style="position:absolute;top:4603;left:130"><nobr><a href="#17">2.3 Databases . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11</nobr></div>
  58. <div style="position:absolute;top:4628;left:130"><nobr><a href="#18">2.4 PersistentDictionaries .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12</nobr></div>
  59. <div style="position:absolute;top:4652;left:130"><nobr><a href="#19">2.5 Contacts . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13</nobr></div>
  60. <div style="position:absolute;top:4676;left:130"><nobr><a href="#20">2.6 Calendar . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14</nobr></div>
  61. <div style="position:absolute;top:4700;left:130"><nobr><a href="#20">2.7 PhoneLogs . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14</nobr></div>
  62. <div style="position:absolute;top:4724;left:130"><nobr><a href="#21">2.8 Inbox . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15</nobr></div>
  63. <div style="position:absolute;top:4764;left:108"><nobr><a href="#22">3 Applications, user interfaces, daemons</a></nobr></div>
  64. <div style="position:absolute;top:4764;left:741"><nobr>16</nobr></div>
  65. <div style="position:absolute;top:4788;left:130"><nobr><a href="#22">3.1 Application Patterns . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16</nobr></div>
  66. <div style="position:absolute;top:4812;left:130"><nobr><a href="#23">3.2 ActiveObjects . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17</nobr></div>
  67. <div style="position:absolute;top:4836;left:130"><nobr><a href="#23">3.3 Blocking . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17</nobr></div>
  68. <div style="position:absolute;top:4861;left:130"><nobr><a href="#24">3.4 Multitasking . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
  69. <div style="position:absolute;top:4885;left:130"><nobr><a href="#24">3.5 Daemons . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
  70. <div style="position:absolute;top:4909;left:165"><nobr><a href="#24">3.5.1 Simpledaemon . . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18</nobr></div>
  71. <div style="position:absolute;top:4933;left:165"><nobr><a href="#26">3.5.2 Cooperatingthreads . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20</nobr></div>
  72. <div style="position:absolute;top:4957;left:165"><nobr><a href="#27">3.5.3 Server threads . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21</nobr></div>
  73. <div style="position:absolute;top:4981;left:165"><nobr><a href="#28">3.5.4 ThreadsandGUI . . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22</nobr></div>
  74. <div style="position:absolute;top:5006;left:130"><nobr><a href="#29">3.6 Graphics . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23</nobr></div>
  75. <div style="position:absolute;top:5050;left:428"><nobr>2</nobr></div>
  76. </span></font>
  77.  
  78. <div style="position:absolute;top:5223;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="5"><b>Page 5</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  79. <div style="position:absolute;top:5339;left:162"><nobr>TABLE OF CONTENTS</nobr></div>
  80. <div style="position:absolute;top:5339;left:802"><nobr>3</nobr></div>
  81. <div style="position:absolute;top:5408;left:162"><nobr><a href="#37">4 Networking</a></nobr></div>
  82. <div style="position:absolute;top:5408;left:795"><nobr>31</nobr></div>
  83. <div style="position:absolute;top:5431;left:184"><nobr><a href="#37">4.1 Bluetooth . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31</nobr></div>
  84. <div style="position:absolute;top:5454;left:219"><nobr><a href="#37">4.1.1 ExternalGPS . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31</nobr></div>
  85. <div style="position:absolute;top:5492;left:162"><nobr><a href="#41">5 Various</a></nobr></div>
  86. <div style="position:absolute;top:5492;left:795"><nobr>35</nobr></div>
  87. <div style="position:absolute;top:5516;left:184"><nobr><a href="#41">5.1 Debugging . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35</nobr></div>
  88. <div style="position:absolute;top:5554;left:162"><nobr><a href="#42">6 Resources</a></nobr></div>
  89. <div style="position:absolute;top:5554;left:795"><nobr>36</nobr></div>
  90. <div style="position:absolute;top:5578;left:184"><nobr><a href="#42">6.1 Python . </a>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36</nobr></div>
  91. <div style="position:absolute;top:5601;left:184"><nobr><a href="#42">6.2 PyS60 . .</a> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36</nobr></div>
  92. <div style="position:absolute;top:5639;left:162"><nobr><a href="#44">Bibliography</a></nobr></div>
  93. <div style="position:absolute;top:5639;left:795"><nobr>38</nobr></div>
  94. </span></font>
  95.  
  96. <div style="position:absolute;top:6485;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="6"><b>Page 6</b></a></font></td></tr></tbody></table></div>
  97. <div style="position:absolute;top:6485;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="7"><b>Page 7</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  98. <div style="position:absolute;top:6787;left:162"><nobr>Introduction</nobr></div>
  99. </span></font>
  100. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  101. <div style="position:absolute;top:6886;left:162"><nobr>This tutorial is meant a supplement to the the ”standard” PyS60 documentation, as listed in Section<a href="#42"> </a>6. We</nobr></div>
  102. <div style="position:absolute;top:6909;left:162"><nobr>focus in particular on issues that are either poorly documented, poorly demonstrated, or both. We will explain</nobr></div>
  103. <div style="position:absolute;top:6932;left:162"><nobr>some of the more obscure features in detail, and give bare-bone, but functioning, code examples.</nobr></div>
  104. <div style="position:absolute;top:6956;left:184"><nobr>We assume the you have a fairly good idea of what PyS60 is, and is determined to use PyS60 in rapid</nobr></div>
  105. <div style="position:absolute;top:6979;left:162"><nobr>prototyping of your next mobile killer app. You should have browsed the standard intro stuff, see Section <a href="#42">6.</a></nobr></div>
  106. <div style="position:absolute;top:7002;left:162"><nobr>Furthermore, you should have attended introductory courses in programming and object oriented design. A</nobr></div>
  107. <div style="position:absolute;top:7026;left:162"><nobr>modest knowledge of Python is an advantage, however, with the above qualifications, you should be able to</nobr></div>
  108. <div style="position:absolute;top:7049;left:162"><nobr>acquire the nescessary Python fluency on-the-go. Just keep a descent Python tutorial, why not “Diving into</nobr></div>
  109. <div style="position:absolute;top:7072;left:162"><nobr>Python”[], ready at hand.</nobr></div>
  110. <div style="position:absolute;top:7096;left:184"><nobr>We also assume that you have established the necessary developer infrastructure, more precisely:</nobr></div>
  111. <div style="position:absolute;top:7118;left:184"><nobr>• A Series 60 mobile phone with PyS60 installed, including the scripting application</nobr></div>
  112. <div style="position:absolute;top:7141;left:184"><nobr>• A Python development environment on your lap/desktop</nobr></div>
  113. <div style="position:absolute;top:7165;left:184"><nobr>• Cable or bluetooth connection for transferring files between mobile and computer</nobr></div>
  114. <div style="position:absolute;top:7188;left:184"><nobr>• A working bluetooth console, enabling you to run and script stuff in a terminal window on your com-</nobr></div>
  115. <div style="position:absolute;top:7212;left:199"><nobr>puter, and execute on your phone (sort the developer to</nobr></div>
  116. <div style="position:absolute;top:7234;left:184"><nobr>• Optionally (since this requires more than the average hassle for Linux/Mac users), a Series 60 emulator</nobr></div>
  117. <div style="position:absolute;top:7259;left:199"><nobr>(don’t forget to install necessary PyS60 stuff) could come handy.</nobr></div>
  118. <div style="position:absolute;top:7282;left:162"><nobr>If not, consult the appropriate sources, keep your tongue steady, do what a developer sometimes has to do,</nobr></div>
  119. <div style="position:absolute;top:7305;left:162"><nobr>and come back.</nobr></div>
  120. <div style="position:absolute;top:7574;left:482"><nobr>1</nobr></div>
  121. </span></font>
  122.  
  123. <div style="position:absolute;top:7747;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="8"><b>Page 8</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  124. <div style="position:absolute;top:8045;left:108"><nobr>Chapter 1</nobr></div>
  125. </span></font>
  126. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  127. <div style="position:absolute;top:8130;left:108"><nobr>Under The Hood</nobr></div>
  128. </span></font>
  129. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  130. <div style="position:absolute;top:8229;left:108"><nobr>Your encounter of the mobile phone as a programmable device might be unfamiliar and frustrating; how do I</nobr></div>
  131. <div style="position:absolute;top:8252;left:108"><nobr>write the code, what language should I use, how do I compile, how do I test it, how do I deploy it, ...always</nobr></div>
  132. <div style="position:absolute;top:8276;left:108"><nobr>comparing it to the familiar desk/laptop environment.</nobr></div>
  133. <div style="position:absolute;top:8300;left:130"><nobr>So, at least for me, on the first encounter: I wanted to get under the hood (and not only under the battery</nobr></div>
  134. <div style="position:absolute;top:8323;left:108"><nobr>hood) of that toyish looking wanna-be-computer, traverse the filesystem (well, I wasn’t sure if there is such a</nobr></div>
  135. <div style="position:absolute;top:8347;left:108"><nobr>thing at all) , access system functions, you know, getting to know the playpen.</nobr></div>
  136. <div style="position:absolute;top:8371;left:130"><nobr>So that’s how we start our PyS60 exploration, by opening the hood.</nobr></div>
  137. </span></font>
  138. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  139. <div style="position:absolute;top:8430;left:108"><nobr>1.1 3 x Hello World</nobr></div>
  140. </span></font>
  141. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  142. <div style="position:absolute;top:8475;left:108"><nobr>A few rounds of hello-world should be sufficient for warming up for more serious exploration. Basically,</nobr></div>
  143. <div style="position:absolute;top:8499;left:108"><nobr>“Hello World!” on PyS60 involves importing the correct GUI module, appuiwf, and call an appropriate</nobr></div>
  144. <div style="position:absolute;top:8522;left:108"><nobr>GUI function. I’m assuming you’re ready for action, with all of your developer tools all running smoothly.</nobr></div>
  145. <div style="position:absolute;top:8545;left:108"><nobr>We start as simple as possible; fire up the Python application on the phone, and choose “Interactive console”.</nobr></div>
  146. <div style="position:absolute;top:8568;left:108"><nobr>Type in the following:</nobr></div>
  147. </span></font>
  148. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  149. <div style="position:absolute;top:8600;left:116"><nobr>&gt;&gt;&gt; import appuifw</nobr></div>
  150. </span></font>
  151. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  152. <div style="position:absolute;top:8633;left:108"><nobr>HitS “enter”, ah, well, the “fire”-button, the one in the middle, and continue with the GUI function:</nobr></div>
  153. </span></font>
  154. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  155. <div style="position:absolute;top:8664;left:116"><nobr>&gt;&gt;&gt; appuifw . note (u ’ Hello World ! ’ , ’ info ’ )</nobr></div>
  156. </span></font>
  157. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  158. <div style="position:absolute;top:8697;left:108"><nobr>The u in front of the message string performs unicode conversion, every string in the PyS60 GUI is assumed</nobr></div>
  159. <div style="position:absolute;top:8721;left:108"><nobr>to be unicoded. The next parameter tells the system which type of pop-up box to use (more on this in Section</nobr></div>
  160. <div style="position:absolute;top:8744;left:108"><nobr><a href="#22">3</a>. Now the magic should happen, and you should see some thing like Figure 1.1:</nobr></div>
  161. <div style="position:absolute;top:8768;left:130"><nobr>If you really managed to sms-style typing these statements without critically raising your blood pressure</nobr></div>
  162. <div style="position:absolute;top:8792;left:108"><nobr>levels, well, congratulations! Otherwise, you have four options:</nobr></div>
  163. <div style="position:absolute;top:8836;left:428"><nobr>2</nobr></div>
  164. </span></font>
  165.  
  166. <div style="position:absolute;top:9009;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="9"><b>Page 9</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  167. <div style="position:absolute;top:9125;left:162"><nobr>1.1. 3 x Hello World</nobr></div>
  168. <div style="position:absolute;top:9125;left:802"><nobr>3</nobr></div>
  169. </span></font>
  170. <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
  171. <div style="position:absolute;top:9513;left:337"><nobr>Figure 1.1: GUI-style Hello World with two statements</nobr></div>
  172. </span></font>
  173. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  174. <div style="position:absolute;top:9559;left:184"><nobr>• If you want to stay mobile: Dust off your bluetooth collapsible keyboard, ideal for a relaxed coding</nobr></div>
  175. <div style="position:absolute;top:9583;left:199"><nobr>session (Figure<a href="#10"> 1.2</a>). You can also install a dedicated Python editor(!) to make your coding even more</nobr></div>
  176. <div style="position:absolute;top:9606;left:199"><nobr>efficient<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>.</nobr></div>
  177. <div style="position:absolute;top:9628;left:184"><nobr>• If you are close to your computer: Start the bluetooth console, making it possible to run code on the</nobr></div>
  178. <div style="position:absolute;top:9653;left:199"><nobr>device from your computer.</nobr></div>
  179. <div style="position:absolute;top:9675;left:184"><nobr>• Or, if you want to ”cheat”, or do not have access to a device: Use the emulator. However: remember,</nobr></div>
  180. <div style="position:absolute;top:9700;left:199"><nobr>there’s a lot of things the emulator can’t emulate, for instance the camera module, or the messaging</nobr></div>
  181. <div style="position:absolute;top:9723;left:199"><nobr>stuff.</nobr></div>
  182. <div style="position:absolute;top:9745;left:184"><nobr>• Write scripts in your favorite editor, preferably one with python support (e.g., on windows, the IDLE</nobr></div>
  183. <div style="position:absolute;top:9769;left:199"><nobr>that is bundled with the most common python distro). When you have convinced yourself that the code</nobr></div>
  184. <div style="position:absolute;top:9793;left:199"><nobr>will work, transfer it to the phone, either by Bluetooth or cable, then run it to check if it’s working.</nobr></div>
  185. <div style="position:absolute;top:9816;left:184"><nobr>Choose the style that best fits your mood, situation and purpose: the bluetooth console is good for informal</nobr></div>
  186. <div style="position:absolute;top:9839;left:162"><nobr>exploration, emulator + IDE is probably best for larger projects. Anyway, you should try to separate symbian</nobr></div>
  187. <div style="position:absolute;top:9863;left:162"><nobr>specific code (e.g., GUI stuff) from general purpose pieces. Then you could decide in runtime which platform</nobr></div>
  188. <div style="position:absolute;top:9886;left:162"><nobr>you’re running the code on, and choose the appropriate files, methods or snippets accordingly.</nobr></div>
  189. <div style="position:absolute;top:9910;left:184"><nobr>You will soon feel the urge for running larger code segments on the phone, and further, making modules</nobr></div>
  190. <div style="position:absolute;top:9933;left:162"><nobr>that could be reused, all in good modularization tradition. And, in the longer run, you are bound to start start</nobr></div>
  191. <div style="position:absolute;top:9956;left:162"><nobr>using the object-oriented features of Python.</nobr></div>
  192. <div style="position:absolute;top:9980;left:184"><nobr>So, before really opening the hood, in the next section we go through a few templates that can help us</nobr></div>
  193. <div style="position:absolute;top:10003;left:162"><nobr>building those wonderful next generation mobile killer apps. However, to justify your choice of programming</nobr></div>
  194. <div style="position:absolute;top:10026;left:162"><nobr>platform for rapid mobile prototyping, let’s consider “Hello World” in Java and C++, which are the most</nobr></div>
  195. </span></font>
  196. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  197. <div style="position:absolute;top:10053;left:178"><nobr>1<a href="http://homepage.rub.de/Arkadiusz.Wahlig/Ped"></a><font style="font-size:9px"><a href="http://homepage.rub.de/Arkadiusz.Wahlig/Ped">http://homepage.rub.de/Arkadiusz.Wahlig/Ped</a></font></nobr></div>
  198. </span></font>
  199.  
  200. <div style="position:absolute;top:10271;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="10"><b>Page 10</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  201. <div style="position:absolute;top:10387;left:108"><nobr>4</nobr></div>
  202. <div style="position:absolute;top:10387;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
  203. </span></font>
  204. <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
  205. <div style="position:absolute;top:10718;left:350"><nobr>Figure 1.2: Pool programming</nobr></div>
  206. </span></font>
  207. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  208. <div style="position:absolute;top:10763;left:108"><nobr>commonly used alternatives for Symbian developers.</nobr></div>
  209. <div style="position:absolute;top:10786;left:130"><nobr>We start with the Java MIDP (and remember, you have to compile before running it in the emulator or</nobr></div>
  210. <div style="position:absolute;top:10809;left:108"><nobr>deploying it on the device (and there is not any equivalent to bluetooth console):</nobr></div>
  211. </span></font>
  212. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  213. <div style="position:absolute;top:10838;left:120"><nobr>import javax . microedition . midlet . ∗ ;</nobr></div>
  214. <div style="position:absolute;top:10856;left:120"><nobr>import javax . microedition . lcdui . ∗ ;</nobr></div>
  215. <div style="position:absolute;top:10893;left:120"><nobr>public class HelloWorld extends MIDlet implements CommandListener {</nobr></div>
  216. <div style="position:absolute;top:10911;left:149"><nobr>private Command exitCommand ;</nobr></div>
  217. <div style="position:absolute;top:10930;left:149"><nobr>private TextBox tbox ;</nobr></div>
  218. <div style="position:absolute;top:10967;left:149"><nobr>public HelloWorld () {</nobr></div>
  219. <div style="position:absolute;top:10985;left:177"><nobr>exitCommand = new Command ( ” E x i t ” , Command . EXIT , 1 ) ;</nobr></div>
  220. <div style="position:absolute;top:11004;left:178"><nobr>tbox = new TextBox(”Hello world MIDlet”, ”Hello World!”, 25, 0);</nobr></div>
  221. <div style="position:absolute;top:11022;left:178"><nobr>tbox . addCommand ( exitCommand ) ;</nobr></div>
  222. <div style="position:absolute;top:11041;left:178"><nobr>tbox . setCommandListener ( this ) ;</nobr></div>
  223. <div style="position:absolute;top:11058;left:148"><nobr>}</nobr></div>
  224. <div style="position:absolute;top:11096;left:149"><nobr>protected void startApp () {</nobr></div>
  225. <div style="position:absolute;top:11115;left:178"><nobr>Display . getDisplay ( this ). setCurrent ( tbox );</nobr></div>
  226. <div style="position:absolute;top:11132;left:148"><nobr>}</nobr></div>
  227. <div style="position:absolute;top:11170;left:149"><nobr>protected void pauseApp ( ) {}</nobr></div>
  228. <div style="position:absolute;top:11188;left:149"><nobr>protected void destroyApp ( boolean bool ) {}</nobr></div>
  229. <div style="position:absolute;top:11225;left:149"><nobr>public void commandAction(Command cmd, Displayable disp) {</nobr></div>
  230. <div style="position:absolute;top:11244;left:178"><nobr>i f (cmd == exitCommand) {</nobr></div>
  231. <div style="position:absolute;top:11262;left:206"><nobr>destroyApp ( false ) ;</nobr></div>
  232. <div style="position:absolute;top:11281;left:207"><nobr>notifyDestroyed ();</nobr></div>
  233. <div style="position:absolute;top:11298;left:176"><nobr>}</nobr></div>
  234. <div style="position:absolute;top:11317;left:148"><nobr>}</nobr></div>
  235. </span></font>
  236.  
  237. <div style="position:absolute;top:11533;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="11"><b>Page 11</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  238. <div style="position:absolute;top:11649;left:162"><nobr>1.2. System Info</nobr></div>
  239. <div style="position:absolute;top:11649;left:802"><nobr>5</nobr></div>
  240. </span></font>
  241. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  242. <div style="position:absolute;top:11719;left:173"><nobr>}</nobr></div>
  243. </span></font>
  244. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  245. <div style="position:absolute;top:11749;left:162"><nobr>Now, for something completely different; for the Symbian C++ Hello World, the following files are needed</nobr></div>
  246. <div style="position:absolute;top:11773;left:162"><nobr>for building the application:</nobr></div>
  247. <div style="position:absolute;top:11795;left:184"><nobr>• bld.inf</nobr></div>
  248. <div style="position:absolute;top:11818;left:184"><nobr>• helloworld.h</nobr></div>
  249. <div style="position:absolute;top:11842;left:184"><nobr>• helloworld.hrh</nobr></div>
  250. <div style="position:absolute;top:11865;left:184"><nobr>• helloworld.mmp</nobr></div>
  251. <div style="position:absolute;top:11888;left:184"><nobr>• helloworld.rss</nobr></div>
  252. <div style="position:absolute;top:11912;left:184"><nobr>• helloworld application.cpp</nobr></div>
  253. <div style="position:absolute;top:11935;left:184"><nobr>• helloworld appui.cpp</nobr></div>
  254. <div style="position:absolute;top:11958;left:184"><nobr>• helloworld appview.cpp</nobr></div>
  255. <div style="position:absolute;top:11981;left:184"><nobr>• helloworld document.cpp</nobr></div>
  256. <div style="position:absolute;top:12005;left:184"><nobr>• helloworld main.cpp</nobr></div>
  257. <div style="position:absolute;top:12029;left:162"><nobr>Say no more.</nobr></div>
  258. </span></font>
  259. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  260. <div style="position:absolute;top:12083;left:162"><nobr>1.2 System Info</nobr></div>
  261. </span></font>
  262. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  263. <div style="position:absolute;top:12126;left:162"><nobr>The sysinfo module supplies you with a lot of under-the-hood stuff. Now, how much memory is there</nobr></div>
  264. <div style="position:absolute;top:12149;left:162"><nobr>around<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font><a href="#1"></a>?</nobr></div>
  265. </span></font>
  266. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  267. <div style="position:absolute;top:12178;left:170"><nobr>&gt;&gt;&gt; import sysinfo</nobr></div>
  268. <div style="position:absolute;top:12197;left:170"><nobr>&gt;&gt;&gt; sysinfo . total ram ()</nobr></div>
  269. <div style="position:absolute;top:12215;left:174"><nobr>58720256</nobr></div>
  270. </span></font>
  271. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  272. <div style="position:absolute;top:12245;left:162"><nobr>And free memory?</nobr></div>
  273. </span></font>
  274. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  275. <div style="position:absolute;top:12273;left:170"><nobr>&gt;&gt;&gt; sysinfo.free ram()</nobr></div>
  276. <div style="position:absolute;top:12292;left:174"><nobr>21192704</nobr></div>
  277. </span></font>
  278. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  279. <div style="position:absolute;top:12322;left:162"><nobr>We launch the map application, and check the RAM use again:</nobr></div>
  280. </span></font>
  281. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  282. <div style="position:absolute;top:12351;left:174"><nobr>19361792</nobr></div>
  283. </span></font>
  284. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  285. <div style="position:absolute;top:12380;left:162"><nobr>Let’s use python as a calculator and find out how much RAM the map app eats:</nobr></div>
  286. </span></font>
  287. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  288. <div style="position:absolute;top:12409;left:170"><nobr>&gt;&gt;&gt; (2119270419361792)/(10241024.0)</nobr></div>
  289. <div style="position:absolute;top:12427;left:174"><nobr>1.746094</nobr></div>
  290. </span></font>
  291. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  292. <div style="position:absolute;top:12457;left:162"><nobr>OK, 1.7 Mb, not bad (note the decimal, ”.0”, without it, python would do perform integer division).</nobr></div>
  293. <div style="position:absolute;top:12480;left:184"><nobr>Battery capacity is a problem on mobile devices, and it could be handy to check it programmatically (0-7</nobr></div>
  294. <div style="position:absolute;top:12504;left:162"><nobr>on earlier devices, 0-100 on new ones):</nobr></div>
  295. </span></font>
  296. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  297. <div style="position:absolute;top:12532;left:170"><nobr>&gt;&gt;&gt; sysinfo . battery ()</nobr></div>
  298. <div style="position:absolute;top:12551;left:173"><nobr>100</nobr></div>
  299. </span></font>
  300. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  301. <div style="position:absolute;top:12577;left:178"><nobr>2<font style="font-size:9px">Run on a Nokia N95</font></nobr></div>
  302. </span></font>
  303.  
  304. <div style="position:absolute;top:12795;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="12"><b>Page 12</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  305. <div style="position:absolute;top:12911;left:108"><nobr>6</nobr></div>
  306. <div style="position:absolute;top:12911;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
  307. <div style="position:absolute;top:12980;left:108"><nobr>Display size:</nobr></div>
  308. </span></font>
  309. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  310. <div style="position:absolute;top:13008;left:116"><nobr>&gt;&gt;&gt; sysinfo . display pixels ()</nobr></div>
  311. <div style="position:absolute;top:13027;left:120"><nobr>(240 , 320)</nobr></div>
  312. </span></font>
  313. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  314. <div style="position:absolute;top:13056;left:108"><nobr>Signal strength may vary wildly when moving around, in partiular in buildings and rural areas, and it could be</nobr></div>
  315. <div style="position:absolute;top:13080;left:108"><nobr>reasonable to give the user a warning if he is going to start a major network transaction with a bad connection.</nobr></div>
  316. <div style="position:absolute;top:13103;left:108"><nobr>The first function uses the range 1-7, the last one returns signal strenght in dBm. A 3 dBm increase roughly</nobr></div>
  317. <div style="position:absolute;top:13126;left:108"><nobr>doubles the strength.</nobr></div>
  318. </span></font>
  319. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  320. <div style="position:absolute;top:13155;left:116"><nobr>&gt;&gt;&gt; sysinfo . signal bars ()</nobr></div>
  321. <div style="position:absolute;top:13173;left:119"><nobr>7</nobr></div>
  322. <div style="position:absolute;top:13191;left:116"><nobr>&gt;&gt;&gt; sysinfo.signal dbm()</nobr></div>
  323. <div style="position:absolute;top:13210;left:119"><nobr>72</nobr></div>
  324. </span></font>
  325. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  326. <div style="position:absolute;top:13239;left:108"><nobr>Signal strenght is also useful in cell tower stumbling, i.e., when you try to estimate your location from cell</nobr></div>
  327. <div style="position:absolute;top:13263;left:108"><nobr>tower information, which you obtain with the location module<a href="#1"></a><font style="font-size:8px"><a href="#1">3</a></font><a href="#1"></a>:</nobr></div>
  328. </span></font>
  329. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  330. <div style="position:absolute;top:13291;left:116"><nobr>&gt;&gt;&gt; import location</nobr></div>
  331. <div style="position:absolute;top:13310;left:116"><nobr>&gt;&gt;&gt; print location.gsm location()</nobr></div>
  332. <div style="position:absolute;top:13328;left:119"><nobr>None</nobr></div>
  333. </span></font>
  334. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  335. <div style="position:absolute;top:13388;left:108"><nobr>1.3 Filesystem</nobr></div>
  336. </span></font>
  337. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  338. <div style="position:absolute;top:13431;left:108"><nobr>Symbian phones sport several drives. We explore them by using the e32 and os modules:</nobr></div>
  339. </span></font>
  340. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  341. <div style="position:absolute;top:13460;left:116"><nobr>&gt;&gt;&gt; import e32 , os</nobr></div>
  342. <div style="position:absolute;top:13478;left:116"><nobr>&gt;&gt;&gt; drives = e32 . d r i v e l i s t ( )</nobr></div>
  343. <div style="position:absolute;top:13497;left:116"><nobr>&gt;&gt;&gt; print drives</nobr></div>
  344. <div style="position:absolute;top:13515;left:120"><nobr>[u’C: ’ ,u’D: ’ ,u’E: ’ ,u’Z: ’]</nobr></div>
  345. </span></font>
  346. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  347. <div style="position:absolute;top:13545;left:108"><nobr>What are these drives? Let’s check for content:</nobr></div>
  348. </span></font>
  349. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  350. <div style="position:absolute;top:13573;left:120"><nobr>for d in drives :</nobr></div>
  351. <div style="position:absolute;top:13592;left:122"><nobr>...</nobr></div>
  352. <div style="position:absolute;top:13592;left:178"><nobr>print ’DRIVE ’ + d + ’ . . . . . . . . . . . . . . . . . . . : ’</nobr></div>
  353. <div style="position:absolute;top:13610;left:122"><nobr>...</nobr></div>
  354. <div style="position:absolute;top:13610;left:178"><nobr>print os. listdir (d)</nobr></div>
  355. <div style="position:absolute;top:13629;left:122"><nobr>...</nobr></div>
  356. <div style="position:absolute;top:13647;left:119"><nobr>DRIVE C : . . . . . . . . . . . . . . . . . . . :</nobr></div>
  357. <div style="position:absolute;top:13666;left:120"><nobr>[ ’cache ’ , ’Data ’ , ’ feeds view template . html ’ , ’ Predic ’ , ’ Private ’ , ’RESOURCE’ , ’</nobr></div>
  358. <div style="position:absolute;top:13684;left:119"><nobr>SYS’ , ’System ’ , ’ video config ’ ]</nobr></div>
  359. <div style="position:absolute;top:13702;left:119"><nobr>DRIVE D : . . . . . . . . . . . . . . . . . . . :</nobr></div>
  360. <div style="position:absolute;top:13721;left:120"><nobr>[ ’ Private ’]</nobr></div>
  361. <div style="position:absolute;top:13739;left:119"><nobr>DRIVE E : . . . . . . . . . . . . . . . . . . . :</nobr></div>
  362. <div style="position:absolute;top:13758;left:120"><nobr>[ ’ . . Trashes ’ , ’ . Trashes ’ , ’ ActivityMonitor ’ , ’ cities ’ , ’Data ’ , ’Documents ’ ,</nobr></div>
  363. <div style="position:absolute;top:13776;left:121"><nobr>’Images ’ , ’ lifeblog ’ , ’My Videos ’ , ’nmea info . py ’ , ’Others ’ , ’pb ’ , ’ Private ’ ,</nobr></div>
  364. <div style="position:absolute;top:13795;left:121"><nobr>’Python ’ , ’qf ’ , ’ resource ’ , ’Sounds ’ , ’ SportsTracker ’ , ’ sys ’ , ’system ’ , ’Videos ’ ]</nobr></div>
  365. <div style="position:absolute;top:13813;left:119"><nobr>DRIVE Z : . . . . . . . . . . . . . . . . . . . :</nobr></div>
  366. </span></font>
  367. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  368. <div style="position:absolute;top:13839;left:124"><nobr>3<font style="font-size:9px">Requires signing, more on this later!</font></nobr></div>
  369. </span></font>
  370.  
  371. <div style="position:absolute;top:14057;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="13"><b>Page 13</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  372. <div style="position:absolute;top:14173;left:162"><nobr>1.3. Filesystem</nobr></div>
  373. <div style="position:absolute;top:14173;left:802"><nobr>7</nobr></div>
  374. </span></font>
  375. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  376. <div style="position:absolute;top:14244;left:174"><nobr>[ ’ c i t i e s ’ , ’ data ’ , ’DevIcon . f i l ’ , ’DevLogo . f i l ’ , ’epoc32 ’ ,</nobr></div>
  377. <div style="position:absolute;top:14262;left:175"><nobr>’feeds view template.html’, ’private’, ’resource’, ’sys’, ’System’]</nobr></div>
  378. </span></font>
  379. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  380. <div style="position:absolute;top:14290;left:162"><nobr>Let’s have a peek in the Images directory on E:</nobr></div>
  381. </span></font>
  382. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  383. <div style="position:absolute;top:14318;left:170"><nobr>&gt;&gt;&gt; print os. listdir (u’E:\ Images ’ )</nobr></div>
  384. <div style="position:absolute;top:14336;left:174"><nobr>[ ’ PAlbTN ’ , ’200701 ’ , ’200704 ’ , ’200705 ’ , ’200706 ’ , ’200707 ’ , ’200708 ’ , ’200711</nobr></div>
  385. <div style="position:absolute;top:14355;left:175"><nobr>, ’200712 ’ , ’200801 ’ , ’200802 ’ , ’GPS−1182932823. jpg ’ , ’GPS−1182932844. jpg ’ , ’GPS</nobr></div>
  386. <div style="position:absolute;top:14372;left:174"><nobr>1182932855. jpg ’ , ’Halden . jpg ’ , ’ Kart . jpg ’ , ’mapdevices . jpg ’ , ’ opera . jpg ’ , ’ pict</nobr></div>
  387. <div style="position:absolute;top:14392;left:174"><nobr>ure1 . jpg ’ , ’Snap ’ ]</nobr></div>
  388. </span></font>
  389. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  390. <div style="position:absolute;top:14420;left:162"><nobr>And what’s on the Private directory on E:</nobr></div>
  391. </span></font>
  392. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  393. <div style="position:absolute;top:14447;left:170"><nobr>&gt;&gt;&gt; print os. listdir (u’D:\ Private ’)</nobr></div>
  394. <div style="position:absolute;top:14466;left:174"><nobr>Traceback (most recent call last ):</nobr></div>
  395. <div style="position:absolute;top:14484;left:189"><nobr>File ”&lt;console&gt;”, line 1, in ?</nobr></div>
  396. <div style="position:absolute;top:14503;left:174"><nobr>OSError : [ Errno −46] : ’D:\\ Private ’</nobr></div>
  397. </span></font>
  398. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  399. <div style="position:absolute;top:14531;left:184"><nobr>Well, what did you expect, the sign said ”Private”, that usual means stay away!</nobr></div>
  400. <div style="position:absolute;top:14554;left:184"><nobr>So, the common mapping of Symbian drives are</nobr></div>
  401. <div style="position:absolute;top:14576;left:184"><nobr>• C: Main ”disk”, or rather flash memory. No reason to mess around here, leave it to the device, installed</nobr></div>
  402. <div style="position:absolute;top:14601;left:199"><nobr>software and operator related stuff.</nobr></div>
  403. <div style="position:absolute;top:14623;left:184"><nobr>• D: RAM memory (do not tamper!)</nobr></div>
  404. <div style="position:absolute;top:14646;left:184"><nobr>• E: Memory card: This is the ”safe” play pen area, and also by far the area with largest capacity (today</nobr></div>
  405. <div style="position:absolute;top:14671;left:199"><nobr>typically 1 GB)</nobr></div>
  406. <div style="position:absolute;top:14693;left:184"><nobr>• Z: ROM memory: Read only system files, may only be changed by flashing software, e.g., when you</nobr></div>
  407. <div style="position:absolute;top:14717;left:199"><nobr>update the firmware.</nobr></div>
  408. <div style="position:absolute;top:14741;left:162"><nobr>Try to connect to your computer with a cable, and and Y probably appears.</nobr></div>
  409. <div style="position:absolute;top:14764;left:184"><nobr>Citing from PyS60 API doc:</nobr></div>
  410. <div style="position:absolute;top:14795;left:199"><nobr>“Some OS level concepts to which the standard os library module offers an interface do not</nobr></div>
  411. <div style="position:absolute;top:14818;left:199"><nobr>exist as such in Symbian OS environment. An example of this is the concept of current working</nobr></div>
  412. <div style="position:absolute;top:14842;left:199"><nobr>directory.”</nobr></div>
  413. <div style="position:absolute;top:14873;left:162"><nobr>Really? Consider the following statements executed on a N95:</nobr></div>
  414. </span></font>
  415. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  416. <div style="position:absolute;top:14900;left:170"><nobr>&gt;&gt;&gt; import os</nobr></div>
  417. <div style="position:absolute;top:14919;left:170"><nobr>&gt;&gt;&gt; print ’Here we are: ’ + os.path.abspath(’.’)</nobr></div>
  418. <div style="position:absolute;top:14937;left:174"><nobr>Here we are: c:\</nobr></div>
  419. <div style="position:absolute;top:14956;left:170"><nobr>&gt;&gt;&gt; print ’Or, here?: ’ + os.getcwd()</nobr></div>
  420. <div style="position:absolute;top:14974;left:173"><nobr>Or , here ?: E:\\ Private \\2000b1a5\\</nobr></div>
  421. </span></font>
  422. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  423. <div style="position:absolute;top:15002;left:184"><nobr>Let’s try walking around, what about changing directory, or rather drive:</nobr></div>
  424. </span></font>
  425. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  426. <div style="position:absolute;top:15030;left:170"><nobr>&gt;&gt;&gt; chdir(”C:\ Data”)</nobr></div>
  427. <div style="position:absolute;top:15048;left:170"><nobr>&gt;&gt;&gt; print os . path . abspath ( ’ . ’ )</nobr></div>
  428. <div style="position:absolute;top:15067;left:174"><nobr>c :\</nobr></div>
  429. <div style="position:absolute;top:15085;left:170"><nobr>&gt;&gt;&gt; print os . getcwd ()</nobr></div>
  430. <div style="position:absolute;top:15104;left:172"><nobr>C:\\ Data\\</nobr></div>
  431. </span></font>
  432.  
  433. <div style="position:absolute;top:15319;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="14"><b>Page 14</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  434. <div style="position:absolute;top:15435;left:108"><nobr>8</nobr></div>
  435. <div style="position:absolute;top:15435;left:589"><nobr>Chapter 1. Under The Hood</nobr></div>
  436. <div style="position:absolute;top:15504;left:108"><nobr>OK, we’re allowed walking around, however, the ’.’ yields the C drive, no matter where we are.</nobr></div>
  437. <div style="position:absolute;top:15527;left:130"><nobr>Traversing the file system is an essential ability, for finding files, or, more relevant, performing actions,</nobr></div>
  438. <div style="position:absolute;top:15550;left:108"><nobr>possibly complex and conditional, on selected files or directories. To walk around, we use os.path.walk,</nobr></div>
  439. <div style="position:absolute;top:15574;left:108"><nobr>taking a customized callback function to be executed for each visited directory. Here’s the short syntactical</nobr></div>
  440. <div style="position:absolute;top:15597;left:108"><nobr>explanation:</nobr></div>
  441. <div style="position:absolute;top:15633;left:145"><nobr>walk(path, visit, arg):</nobr></div>
  442. <div style="position:absolute;top:15662;left:145"><nobr>Calls the function visit with arguments (arg, dirname, names) for each directory in the di-</nobr></div>
  443. <div style="position:absolute;top:15685;left:145"><nobr>rectory tree rooted at path (including path itself, if it is a directory). The argument dirname</nobr></div>
  444. <div style="position:absolute;top:15708;left:145"><nobr>specifies the visited directory, the argument names lists the files in the directory (gotten from</nobr></div>
  445. <div style="position:absolute;top:15731;left:145"><nobr>os.listdir(dirname)). The visit function may modify names to influence the set of directories</nobr></div>
  446. <div style="position:absolute;top:15755;left:145"><nobr>visited below dirname, e.g., to avoid visiting certain parts of the tree.</nobr></div>
  447. <div style="position:absolute;top:15790;left:108"><nobr>And here is a PyS60 example, printing all directories on the device:</nobr></div>
  448. </span></font>
  449. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  450. <div style="position:absolute;top:15819;left:120"><nobr>import e32</nobr></div>
  451. <div style="position:absolute;top:15838;left:120"><nobr>import os</nobr></div>
  452. <div style="position:absolute;top:15875;left:121"><nobr>class Main :</nobr></div>
  453. <div style="position:absolute;top:15912;left:149"><nobr>def</nobr></div>
  454. <div style="position:absolute;top:15912;left:193"><nobr>init</nobr></div>
  455. <div style="position:absolute;top:15912;left:235"><nobr>( self ):</nobr></div>
  456. <div style="position:absolute;top:15930;left:178"><nobr>self . drives ()</nobr></div>
  457. <div style="position:absolute;top:15967;left:149"><nobr>def drives ( self ):</nobr></div>
  458. <div style="position:absolute;top:15986;left:178"><nobr>drives = e32 . d r i v e l i s t ( )</nobr></div>
  459. <div style="position:absolute;top:16004;left:178"><nobr>for drive in drives :</nobr></div>
  460. <div style="position:absolute;top:16023;left:206"><nobr>os . path . walk ( drive , s e l f . l i s t f i l e s , None )</nobr></div>
  461. <div style="position:absolute;top:16059;left:149"><nobr>def l i s t f i l e s ( arg , dirname , fnames ) :</nobr></div>
  462. <div style="position:absolute;top:16078;left:178"><nobr>print dirname</nobr></div>
  463. <div style="position:absolute;top:16115;left:121"><nobr>i f</nobr></div>
  464. <div style="position:absolute;top:16115;left:154"><nobr>name</nobr></div>
  465. <div style="position:absolute;top:16115;left:205"><nobr>== ’ main</nobr></div>
  466. <div style="position:absolute;top:16115;left:293"><nobr>’:</nobr></div>
  467. <div style="position:absolute;top:16133;left:148"><nobr>main = Main()</nobr></div>
  468. </span></font>
  469.  
  470. <div style="position:absolute;top:16581;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="15"><b>Page 15</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  471. <div style="position:absolute;top:16878;left:162"><nobr>Chapter 2</nobr></div>
  472. </span></font>
  473. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  474. <div style="position:absolute;top:16962;left:162"><nobr>Storing Stuff</nobr></div>
  475. </span></font>
  476. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  477. <div style="position:absolute;top:17060;left:162"><nobr>There’s not much interesting you could without storing data in some way or another. There are basically three</nobr></div>
  478. <div style="position:absolute;top:17084;left:162"><nobr>ways of persisting data with PyS60: Using files, pickling objects and through databases. Databases come in</nobr></div>
  479. <div style="position:absolute;top:17107;left:162"><nobr>these flavors: SQL (lite) db, dictionary db, calender db, and the contacts db.</nobr></div>
  480. <div style="position:absolute;top:17130;left:184"><nobr>In addition, the device stores a variety of log information, like the last incoming calls etc., and to the</nobr></div>
  481. <div style="position:absolute;top:17154;left:162"><nobr>programmer this represents a valuable resource.</nobr></div>
  482. <div style="position:absolute;top:17177;left:184"><nobr>Last, but not least, we have the inbox of messages: sms, mms, bluetooth etc.</nobr></div>
  483. </span></font>
  484. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  485. <div style="position:absolute;top:17230;left:162"><nobr>2.1 Files</nobr></div>
  486. </span></font>
  487. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  488. <div style="position:absolute;top:17273;left:162"><nobr>To use files, you have to be able to navigate in the file system, to create and remove directories and files, and</nobr></div>
  489. <div style="position:absolute;top:17296;left:162"><nobr>write to and read from the files, both in ascii and binary fashion. In PyS60 you create, open, close, write to</nobr></div>
  490. <div style="position:absolute;top:17320;left:162"><nobr>and read from files as in plain Python, likewise with making and deleting directories, see any Python tutorial,</nobr></div>
  491. <div style="position:absolute;top:17343;left:162"><nobr>e.g., ??.</nobr></div>
  492. </span></font>
  493. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  494. <div style="position:absolute;top:17396;left:162"><nobr>2.2 Pickling, and how to easily extend PyS60</nobr></div>
  495. </span></font>
  496. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  497. <div style="position:absolute;top:17439;left:162"><nobr>Pickling is the Python way of serializing objects. Class instances are transformed to a platform independent</nobr></div>
  498. <div style="position:absolute;top:17462;left:162"><nobr>bytestream that can be written to a file, and later read from that file to construct a new instance of that class</nobr></div>
  499. <div style="position:absolute;top:17486;left:162"><nobr>in the exact same state, i.e., with the same values of the variables and methods as the original.</nobr></div>
  500. <div style="position:absolute;top:17509;left:184"><nobr>However, the pickle module is not part of PyS60, but don’t despair. Many Python modules may be directly</nobr></div>
  501. <div style="position:absolute;top:17532;left:162"><nobr>imported, or deployed, on the PyS60 platform by loading the corresponding.py file as a module. Depending</nobr></div>
  502. <div style="position:absolute;top:17556;left:162"><nobr>on the dependencies (no pun intended?), it may work out of the box, or, some minor might do the trick, ...or</nobr></div>
  503. <div style="position:absolute;top:17579;left:162"><nobr>not. Let’s try it out.</nobr></div>
  504. <div style="position:absolute;top:17602;left:184"><nobr>You can grab the module (only one file, pickle.py) from the Python installation on your computer,</nobr></div>
  505. <div style="position:absolute;top:17626;left:162"><nobr>or from the source available from<a href="http://python.org"> python.org. </a>However, the pickle module from recent releases will</nobr></div>
  506. <div style="position:absolute;top:17670;left:482"><nobr>9</nobr></div>
  507. </span></font>
  508.  
  509. <div style="position:absolute;top:17843;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="16"><b>Page 16</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  510. <div style="position:absolute;top:17959;left:108"><nobr>10</nobr></div>
  511. <div style="position:absolute;top:17959;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
  512. <div style="position:absolute;top:18028;left:108"><nobr>not work without major hassle, so rip it from a Python 2.2<a href="#1"></a><font style="font-size:8px"><a href="#1">1 </a></font>installation. Transfer it to your phone, e.g.,</nobr></div>
  513. <div style="position:absolute;top:18051;left:108"><nobr>over bluetooth, and install as a module<a href="#1"></a><font style="font-size:8px"><a href="#1">2 </a></font>If you want to try it in the emulator on a PC, copy the pickle file</nobr></div>
  514. <div style="position:absolute;top:18074;left:108"><nobr>to the Symbian\.9.2\.S60 3rd FP1\.Epoc32\.winscw\.c\.resource folder<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>And now, some</nobr></div>
  515. <div style="position:absolute;top:18098;left:108"><nobr>pickling code. First, the custom class definition in the file answer.py, imported into your environment as</nobr></div>
  516. <div style="position:absolute;top:18121;left:108"><nobr>a module:</nobr></div>
  517. </span></font>
  518. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  519. <div style="position:absolute;top:18152;left:121"><nobr>class TheAnswer :</nobr></div>
  520. <div style="position:absolute;top:18170;left:149"><nobr>def</nobr></div>
  521. <div style="position:absolute;top:18170;left:193"><nobr>init</nobr></div>
  522. <div style="position:absolute;top:18170;left:235"><nobr>( self ):</nobr></div>
  523. <div style="position:absolute;top:18189;left:178"><nobr>self.foo = u’The answer’</nobr></div>
  524. <div style="position:absolute;top:18207;left:178"><nobr>self.bar = 42</nobr></div>
  525. <div style="position:absolute;top:18225;left:149"><nobr>def meaning( self ):</nobr></div>
  526. <div style="position:absolute;top:18244;left:178"><nobr>print self.foo + ” is ” + str(self.bar)</nobr></div>
  527. </span></font>
  528. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  529. <div style="position:absolute;top:18276;left:108"><nobr>Here is the application code:</nobr></div>
  530. </span></font>
  531. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  532. <div style="position:absolute;top:18307;left:120"><nobr>import os</nobr></div>
  533. <div style="position:absolute;top:18325;left:120"><nobr>import pickle</nobr></div>
  534. </span></font>
  535. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  536. <div style="position:absolute;top:18344;left:119"><nobr># import custom class definition</nobr></div>
  537. </span></font>
  538. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  539. <div style="position:absolute;top:18362;left:120"><nobr>import answer</nobr></div>
  540. </span></font>
  541. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  542. <div style="position:absolute;top:18399;left:119"><nobr># initialize answer object</nobr></div>
  543. </span></font>
  544. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  545. <div style="position:absolute;top:18417;left:120"><nobr>answer = answer.TheAnswer()</nobr></div>
  546. </span></font>
  547. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  548. <div style="position:absolute;top:18436;left:119"><nobr># get answer</nobr></div>
  549. </span></font>
  550. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  551. <div style="position:absolute;top:18454;left:120"><nobr>answer . meaning ()</nobr></div>
  552. </span></font>
  553. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  554. <div style="position:absolute;top:18473;left:119"><nobr># modify answer</nobr></div>
  555. </span></font>
  556. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  557. <div style="position:absolute;top:18491;left:120"><nobr>answer.bar = 43</nobr></div>
  558. <div style="position:absolute;top:18528;left:120"><nobr>path = <font color="#4c4c4c">#set your destination directory here</font></nobr></div>
  559. </span></font>
  560. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  561. <div style="position:absolute;top:18547;left:119"><nobr># construct path to pickle file</nobr></div>
  562. </span></font>
  563. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  564. <div style="position:absolute;top:18565;left:120"><nobr>f = path + ” t e s t . pickle</nobr></div>
  565. </span></font>
  566. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  567. <div style="position:absolute;top:18584;left:119"><nobr># open a file to save the pickled answer instance</nobr></div>
  568. </span></font>
  569. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  570. <div style="position:absolute;top:18602;left:121"><nobr>picklefile = open(f, ’w’)</nobr></div>
  571. </span></font>
  572. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  573. <div style="position:absolute;top:18621;left:119"><nobr># pickle it</nobr></div>
  574. </span></font>
  575. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  576. <div style="position:absolute;top:18639;left:121"><nobr>p i c k l e . dump ( answer , p i c k l e f i l e )</nobr></div>
  577. <div style="position:absolute;top:18657;left:121"><nobr>picklefile . close ()</nobr></div>
  578. <div style="position:absolute;top:18676;left:121"><nobr>picklefile = open(f, ’r’)</nobr></div>
  579. </span></font>
  580. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  581. <div style="position:absolute;top:18694;left:119"><nobr># unpickle the answer</nobr></div>
  582. </span></font>
  583. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  584. <div style="position:absolute;top:18713;left:120"><nobr>answer2 = pickle.load(picklefile)</nobr></div>
  585. <div style="position:absolute;top:18731;left:121"><nobr>picklefile . close ()</nobr></div>
  586. </span></font>
  587. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  588. <div style="position:absolute;top:18750;left:119"><nobr># check the answer, should be 43</nobr></div>
  589. </span></font>
  590. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  591. <div style="position:absolute;top:18768;left:120"><nobr>answer2 . meaning ()</nobr></div>
  592. </span></font>
  593. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  594. <div style="position:absolute;top:18800;left:108"><nobr>For more information on pickling, see the Python docs<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>.</nobr></div>
  595. </span></font>
  596. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  597. <div style="position:absolute;top:18829;left:124"><nobr>1<font style="font-size:9px">PyS60 is based on Python 2.2</font></nobr></div>
  598. <div style="position:absolute;top:18844;left:124"><nobr>2<font style="font-size:9px">On 3rd. edition phones you have to copy the file manually to CHECK PATH!</font></nobr></div>
  599. <div style="position:absolute;top:18859;left:124"><nobr>3<font style="font-size:9px">CHECK: In the emulator, if you try to pickle an instance of an object defined in the file where the pickling is performed, an exception</font></nobr></div>
  600. </span></font>
  601. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  602. <div style="position:absolute;top:18875;left:108"><nobr>is raised. However, implementing the class in a separate module file, and importing the class, works OK.</nobr></div>
  603. </span></font>
  604. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  605. <div style="position:absolute;top:18887;left:124"><nobr>4<a href="http://docs.python.org/lib/node317.html"></a><font style="font-size:9px"><a href="http://docs.python.org/lib/node317.html">http://docs.python.org/lib/node317.html</a></font></nobr></div>
  606. </span></font>
  607.  
  608. <div style="position:absolute;top:19105;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="17"><b>Page 17</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  609. <div style="position:absolute;top:19221;left:162"><nobr>2.3. Databases</nobr></div>
  610. <div style="position:absolute;top:19221;left:795"><nobr>11</nobr></div>
  611. </span></font>
  612. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  613. <div style="position:absolute;top:19285;left:162"><nobr>2.3 Databases</nobr></div>
  614. </span></font>
  615. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  616. <div style="position:absolute;top:19329;left:162"><nobr>At first thought, it seems like overkill to have an onboard database on your phone. But, rethinking, there are</nobr></div>
  617. <div style="position:absolute;top:19352;left:162"><nobr>quite a number of application scenarios requiring access to complex information repositories. In many cases,</nobr></div>
  618. <div style="position:absolute;top:19375;left:162"><nobr>the obvious solution is to implement the database stuff server side, however, remember that your phone might</nobr></div>
  619. <div style="position:absolute;top:19398;left:162"><nobr>be offline in periods, or it could be too costly with frequent data transmissions.</nobr></div>
  620. <div style="position:absolute;top:19422;left:184"><nobr>Anyway, since the Symbian core uses a database to structure, store and manipulate various log data, like</nobr></div>
  621. <div style="position:absolute;top:19445;left:162"><nobr>incoming calls, contact lists, calendar, etc., this database engine is made available for the programmer in the</nobr></div>
  622. <div style="position:absolute;top:19469;left:162"><nobr>e32db module. It supports relational data base manipulation with “restricted SQL syntax”<a href="#1"></a><font style="font-size:8px"><a href="#1">5</a></font><a href="#1"></a>.</nobr></div>
  623. <div style="position:absolute;top:19492;left:184"><nobr>There are two main classes, Dbms and Db view. The first performs high level operations, like creating,</nobr></div>
  624. <div style="position:absolute;top:19515;left:162"><nobr>opening, closing, committing and executing SQL statements that in some way affects the database. The other</nobr></div>
  625. <div style="position:absolute;top:19538;left:162"><nobr>class let you issue SQL select statements, yielding database views, which in turn gives you access to the</nobr></div>
  626. <div style="position:absolute;top:19562;left:162"><nobr>rows and columns produced by the query.</nobr></div>
  627. <div style="position:absolute;top:19585;left:184"><nobr>Here is a minimalistic, but working, example that covers the essential functionality:</nobr></div>
  628. </span></font>
  629. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  630. <div style="position:absolute;top:19612;left:174"><nobr>import os</nobr></div>
  631. <div style="position:absolute;top:19630;left:174"><nobr>import e32 , e32db</nobr></div>
  632. </span></font>
  633. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  634. <div style="position:absolute;top:19649;left:173"><nobr># Get instances of the database and database view classes</nobr></div>
  635. </span></font>
  636. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  637. <div style="position:absolute;top:19667;left:173"><nobr>dbm = e32db.Dbms()</nobr></div>
  638. <div style="position:absolute;top:19686;left:173"><nobr>dbv = e32db.Db view()</nobr></div>
  639. </span></font>
  640. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  641. <div style="position:absolute;top:19704;left:173"><nobr># Build a full path to the DB</nobr></div>
  642. </span></font>
  643. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  644. <div style="position:absolute;top:19723;left:174"><nobr>path = <font color="#4c4c4c"># Your path here</font></nobr></div>
  645. <div style="position:absolute;top:19741;left:173"><nobr>dbname = u ’ t e s t . db</nobr></div>
  646. <div style="position:absolute;top:19760;left:174"><nobr>dbpath = path+dbname</nobr></div>
  647. </span></font>
  648. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  649. <div style="position:absolute;top:19778;left:173"><nobr># Open the database</nobr></div>
  650. <div style="position:absolute;top:19797;left:173"><nobr># If it ’s not already there , create , define and populate it</nobr></div>
  651. </span></font>
  652. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  653. <div style="position:absolute;top:19815;left:174"><nobr>try :</nobr></div>
  654. <div style="position:absolute;top:19834;left:201"><nobr>dbm. open ( unicode ( dbpath ))</nobr></div>
  655. <div style="position:absolute;top:19852;left:174"><nobr>except :</nobr></div>
  656. <div style="position:absolute;top:19870;left:201"><nobr>dbm. create ( unicode ( dbpath ))</nobr></div>
  657. <div style="position:absolute;top:19889;left:201"><nobr>dbm. open ( unicode ( dbpath ))</nobr></div>
  658. </span></font>
  659. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  660. <div style="position:absolute;top:19908;left:202"><nobr># Create a database with fields for an ID, a name, and a bluetooth address</nobr></div>
  661. </span></font>
  662. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  663. <div style="position:absolute;top:19926;left:201"><nobr>dbm.execute(u’create table bt (id integer , name varchar , btaddr varchar))</nobr></div>
  664. </span></font>
  665. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  666. <div style="position:absolute;top:19944;left:202"><nobr># Populate database</nobr></div>
  667. </span></font>
  668. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  669. <div style="position:absolute;top:19963;left:201"><nobr>dbm. execute (u ’ insert into bt values (1 , \ ’name 1\ ’ , \ ’bt1 \ ’))</nobr></div>
  670. <div style="position:absolute;top:19981;left:201"><nobr>dbm. execute (u ’ insert into bt values (2 , \ ’name 2\ ’ , \ ’bt2 \ ’))</nobr></div>
  671. </span></font>
  672. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  673. <div style="position:absolute;top:20000;left:173"><nobr># Prepare a database view by selecting all rows</nobr></div>
  674. </span></font>
  675. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  676. <div style="position:absolute;top:20018;left:173"><nobr>dbv . prepare (dbm, u ’ selectfrom bt ’ )</nobr></div>
  677. </span></font>
  678. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  679. <div style="position:absolute;top:20037;left:173"><nobr># Get the number of columns (yeah, ok, we now it is three :−)</nobr></div>
  680. </span></font>
  681. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  682. <div style="position:absolute;top:20055;left:174"><nobr>col num = dbv.col count()</nobr></div>
  683. </span></font>
  684. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  685. <div style="position:absolute;top:20074;left:173"><nobr># Iterate over all rows in the view</nobr></div>
  686. <div style="position:absolute;top:20092;left:173"><nobr># Start with setting the database view cursor on first row</nobr></div>
  687. </span></font>
  688. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  689. <div style="position:absolute;top:20110;left:173"><nobr>dbv. first line ()</nobr></div>
  690. </span></font>
  691. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  692. <div style="position:absolute;top:20135;left:178"><nobr>5<font style="font-size:9px">As always, when the PyS60 API documentation is a bit sketchy, you will find things in more detail in the S60 SDK documentation.</font></nobr></div>
  693. </span></font>
  694. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  695. <div style="position:absolute;top:20152;left:162"><nobr>Remember that PyS60 , in essence, is a thin wrapping over the native C++ core.</nobr></div>
  696. </span></font>
  697.  
  698. <div style="position:absolute;top:20367;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="18"><b>Page 18</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  699. <div style="position:absolute;top:20483;left:108"><nobr>12</nobr></div>
  700. <div style="position:absolute;top:20483;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
  701. </span></font>
  702. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  703. <div style="position:absolute;top:20554;left:120"><nobr>for i in range ( dbv . c o u n t l i n e ( ) ) :</nobr></div>
  704. </span></font>
  705. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  706. <div style="position:absolute;top:20572;left:148"><nobr># Get the current row</nobr></div>
  707. </span></font>
  708. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  709. <div style="position:absolute;top:20591;left:148"><nobr>dbv. get line ()</nobr></div>
  710. <div style="position:absolute;top:20609;left:150"><nobr>result = ’’</nobr></div>
  711. </span></font>
  712. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  713. <div style="position:absolute;top:20628;left:148"><nobr># Iterate over the columns</nobr></div>
  714. </span></font>
  715. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  716. <div style="position:absolute;top:20646;left:149"><nobr>for j in range(col num):</nobr></div>
  717. </span></font>
  718. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  719. <div style="position:absolute;top:20665;left:177"><nobr># Store the fields as strings</nobr></div>
  720. <div style="position:absolute;top:20683;left:177"><nobr># Remember that columns are indexed from 1, not 0</nobr></div>
  721. </span></font>
  722. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  723. <div style="position:absolute;top:20701;left:178"><nobr>result += ’ ’+str(dbv.col(j+1))</nobr></div>
  724. </span></font>
  725. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  726. <div style="position:absolute;top:20720;left:148"><nobr># This should yield the stuff we inserted</nobr></div>
  727. </span></font>
  728. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  729. <div style="position:absolute;top:20738;left:149"><nobr>print ’Row ’ + str(i) + result</nobr></div>
  730. </span></font>
  731. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  732. <div style="position:absolute;top:20757;left:148"><nobr># Move the database view cursor to next row</nobr></div>
  733. </span></font>
  734. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  735. <div style="position:absolute;top:20775;left:148"><nobr>dbv. next line ()</nobr></div>
  736. </span></font>
  737. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  738. <div style="position:absolute;top:20838;left:108"><nobr>2.4 Persistent Dictionaries</nobr></div>
  739. </span></font>
  740. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  741. <div style="position:absolute;top:20882;left:108"><nobr>A dictionary (hashmap in Java) is a versatile and widely used data structure. Simply put, a dictionary is a</nobr></div>
  742. <div style="position:absolute;top:20906;left:108"><nobr>set of key/value pairs, supported by a variety of methods for inserting, modifying and accessing the content.</nobr></div>
  743. <div style="position:absolute;top:20929;left:108"><nobr>In ”plain” Python, the shelve<a href="#1"></a><font style="font-size:8px"><a href="#1">6 </a></font>module offers this functionality. The equivalent in PyS60 is the e32dbm,</nobr></div>
  744. <div style="position:absolute;top:20952;left:108"><nobr>which, as the name indicates, is built on top of the database module.</nobr></div>
  745. <div style="position:absolute;top:20988;left:145"><nobr>Note: Only string keys are accepted<a href="#1"></a><font style="font-size:8px"><a href="#1">7</a></font><a href="#1"></a>.</nobr></div>
  746. <div style="position:absolute;top:21025;left:108"><nobr>Here is a toy implementation with the most important operations.</nobr></div>
  747. </span></font>
  748. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  749. <div style="position:absolute;top:21055;left:120"><nobr>import e32dbm</nobr></div>
  750. <div style="position:absolute;top:21073;left:120"><nobr>path = <font color="#4c4c4c"># Your path here</font></nobr></div>
  751. </span></font>
  752. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  753. <div style="position:absolute;top:21092;left:119"><nobr># Construct a full path to your dictionary file</nobr></div>
  754. </span></font>
  755. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  756. <div style="position:absolute;top:21110;left:119"><nobr>dname = ” t e s t . d i c t ”</nobr></div>
  757. <div style="position:absolute;top:21129;left:120"><nobr>dpath = path + dname</nobr></div>
  758. </span></font>
  759. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  760. <div style="position:absolute;top:21147;left:119"><nobr># Open the dictionary</nobr></div>
  761. <div style="position:absolute;top:21166;left:119"><nobr># With the ”c” parameter a new dictionary will be constructed if not there.</nobr></div>
  762. </span></font>
  763. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  764. <div style="position:absolute;top:21184;left:119"><nobr>d = e32dbm.open(dpath , ”c”)</nobr></div>
  765. </span></font>
  766. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  767. <div style="position:absolute;top:21203;left:119"><nobr># Add an entry with key ”1” and value ”foo”</nobr></div>
  768. </span></font>
  769. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  770. <div style="position:absolute;top:21221;left:119"><nobr>d[1] = ”foo”</nobr></div>
  771. </span></font>
  772. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  773. <div style="position:absolute;top:21240;left:119"><nobr># Close it</nobr></div>
  774. </span></font>
  775. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  776. <div style="position:absolute;top:21258;left:119"><nobr>d. close ()</nobr></div>
  777. </span></font>
  778. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  779. <div style="position:absolute;top:21276;left:119"><nobr># Open i t again , in write mode</nobr></div>
  780. </span></font>
  781. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  782. <div style="position:absolute;top:21295;left:119"><nobr>dd = e32dbm.open(dpath , ”w”)</nobr></div>
  783. </span></font>
  784. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  785. <div style="position:absolute;top:21313;left:119"><nobr># Add a new entry</nobr></div>
  786. </span></font>
  787. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  788. <div style="position:absolute;top:21332;left:119"><nobr>dd[”two”] = ”bar”</nobr></div>
  789. </span></font>
  790. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  791. <div style="position:absolute;top:21350;left:119"><nobr>#Iterate over the dictionary</nobr></div>
  792. </span></font>
  793. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  794. <div style="position:absolute;top:21368;left:120"><nobr>for key in dd :</nobr></div>
  795. </span></font>
  796. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  797. <div style="position:absolute;top:21397;left:124"><nobr>6<a href="http://docs.python.org/lib/module-shelve.html"></a><font style="font-size:9px"><a href="http://docs.python.org/lib/module-shelve.html">http://docs.python.org/lib/module-shelve.html</a></font></nobr></div>
  798. <div style="position:absolute;top:21411;left:124"><nobr>7<font style="font-size:9px">CHECK: Listing has strings!</font></nobr></div>
  799. </span></font>
  800.  
  801. <div style="position:absolute;top:21629;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="19"><b>Page 19</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  802. <div style="position:absolute;top:21745;left:162"><nobr>2.5. Contacts</nobr></div>
  803. <div style="position:absolute;top:21745;left:795"><nobr>13</nobr></div>
  804. </span></font>
  805. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  806. <div style="position:absolute;top:21816;left:203"><nobr>print key + ’:’ + dd[key]</nobr></div>
  807. <div style="position:absolute;top:21834;left:173"><nobr>dd . close</nobr></div>
  808. </span></font>
  809. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  810. <div style="position:absolute;top:21893;left:162"><nobr>2.5 Contacts</nobr></div>
  811. </span></font>
  812. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  813. <div style="position:absolute;top:21936;left:162"><nobr>The contacts module lets programmatically access and modify the contact list. The module has one</nobr></div>
  814. <div style="position:absolute;top:21959;left:162"><nobr>function , open() that returns a ContactDb instance<a href="#1"></a><font style="font-size:8px"><a href="#1">8</a></font></nobr></div>
  815. <div style="position:absolute;top:21983;left:184"><nobr>The Contact class contains the necessary stuff for dealing with the contact data.</nobr></div>
  816. <div style="position:absolute;top:22006;left:184"><nobr>Think of the ContactDb as a dictionary of Contact, and db[key] yields a Contact instance.</nobr></div>
  817. <div style="position:absolute;top:22029;left:184"><nobr>DO A GROUP EXAMPLE!</nobr></div>
  818. </span></font>
  819. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  820. <div style="position:absolute;top:22076;left:177"><nobr>SYMBIAN = True</nobr></div>
  821. <div style="position:absolute;top:22094;left:175"><nobr>i f</nobr></div>
  822. <div style="position:absolute;top:22094;left:199"><nobr>SYMBIAN :</nobr></div>
  823. <div style="position:absolute;top:22113;left:202"><nobr>import e32 , contacts , telephone</nobr></div>
  824. <div style="position:absolute;top:22131;left:205"><nobr>EMULATOR = e32.in emulator()</nobr></div>
  825. <div style="position:absolute;top:22168;left:175"><nobr>i f</nobr></div>
  826. <div style="position:absolute;top:22168;left:199"><nobr>SYMBIAN :</nobr></div>
  827. <div style="position:absolute;top:22186;left:204"><nobr>i f EMULATOR :</nobr></div>
  828. <div style="position:absolute;top:22205;left:232"><nobr>path = os.getcwd()</nobr></div>
  829. <div style="position:absolute;top:22223;left:203"><nobr>else :</nobr></div>
  830. <div style="position:absolute;top:22242;left:232"><nobr>path = ”E:\\ ”</nobr></div>
  831. <div style="position:absolute;top:22260;left:175"><nobr>else :</nobr></div>
  832. <div style="position:absolute;top:22279;left:203"><nobr>path = ”C:\\ tmp\\”</nobr></div>
  833. <div style="position:absolute;top:22334;left:173"><nobr>db = contacts.open()</nobr></div>
  834. </span></font>
  835. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  836. <div style="position:absolute;top:22371;left:173"><nobr>#for entry in db:</nobr></div>
  837. <div style="position:absolute;top:22390;left:173"><nobr>#</nobr></div>
  838. <div style="position:absolute;top:22390;left:211"><nobr>print db[entry]</nobr></div>
  839. <div style="position:absolute;top:22427;left:173"><nobr>#contact = db.add contact()</nobr></div>
  840. <div style="position:absolute;top:22445;left:173"><nobr>#contact.add field(’last name ’, ’jensen ’)</nobr></div>
  841. <div style="position:absolute;top:22463;left:173"><nobr>#contact . commit ()</nobr></div>
  842. <div style="position:absolute;top:22500;left:173"><nobr># Here we access the entries as Contact objects</nobr></div>
  843. </span></font>
  844. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  845. <div style="position:absolute;top:22519;left:174"><nobr>for entry in db :</nobr></div>
  846. <div style="position:absolute;top:22537;left:203"><nobr>cont = db[entry]</nobr></div>
  847. <div style="position:absolute;top:22555;left:203"><nobr>print ’ . . . . . . . . . . . . . . cont : ’ + s t r ( cont )</nobr></div>
  848. <div style="position:absolute;top:22574;left:203"><nobr>print ’ . . . . . . . . . . . . . . cont . id : ’ + s t r ( cont . id )</nobr></div>
  849. <div style="position:absolute;top:22611;left:174"><nobr>c1 =</nobr></div>
  850. <div style="position:absolute;top:22611;left:216"><nobr>db . find ( ’ jensen ’ )</nobr></div>
  851. <div style="position:absolute;top:22629;left:174"><nobr>print ’jensen:’ + str(c1[0].id)</nobr></div>
  852. </span></font>
  853. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  854. <div style="position:absolute;top:22673;left:178"><nobr>8<font style="font-size:9px">Custom contact databases may be created by providing a file argument, but only for testing purposes!</font></nobr></div>
  855. </span></font>
  856.  
  857. <div style="position:absolute;top:22891;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="20"><b>Page 20</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  858. <div style="position:absolute;top:23007;left:108"><nobr>14</nobr></div>
  859. <div style="position:absolute;top:23007;left:613"><nobr>Chapter 2. Storing Stuff</nobr></div>
  860. </span></font>
  861. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  862. <div style="position:absolute;top:23096;left:119"><nobr>#print db. field types ()</nobr></div>
  863. </span></font>
  864. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  865. <div style="position:absolute;top:23157;left:108"><nobr>2.6 Calendar</nobr></div>
  866. </span></font>
  867. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  868. <div style="position:absolute;top:23200;left:108"><nobr>TBD.</nobr></div>
  869. </span></font>
  870. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  871. <div style="position:absolute;top:23254;left:108"><nobr>2.7 Phone Logs</nobr></div>
  872. </span></font>
  873. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  874. <div style="position:absolute;top:23297;left:108"><nobr>Your mobile device keeps track of a lot of events, in various logs. From version 1.4.2, PyS60 , provides an</nobr></div>
  875. <div style="position:absolute;top:23321;left:108"><nobr>interface to these logs with the logs module. Curently the following types of logs are supported: call, sms,</nobr></div>
  876. <div style="position:absolute;top:23344;left:108"><nobr>data, fax, email and scheduler<a href="#1"></a><font style="font-size:8px"><a href="#1">9</a></font><a href="#1"></a>.</nobr></div>
  877. <div style="position:absolute;top:23367;left:130"><nobr>Let’s find out how many log entries we have on the device. Each log entry is represented as a dictionary,</nobr></div>
  878. <div style="position:absolute;top:23391;left:108"><nobr>and most of the access functions returns a list of dictionaries:</nobr></div>
  879. </span></font>
  880. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  881. <div style="position:absolute;top:23420;left:116"><nobr>&gt;&gt;&gt; import logs</nobr></div>
  882. <div style="position:absolute;top:23438;left:116"><nobr>&gt;&gt;&gt; all = logs.raw log data()</nobr></div>
  883. <div style="position:absolute;top:23457;left:116"><nobr>&gt;&gt;&gt; len ( all )</nobr></div>
  884. <div style="position:absolute;top:23475;left:119"><nobr>4</nobr></div>
  885. </span></font>
  886. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  887. <div style="position:absolute;top:23505;left:108"><nobr>We want to print every item in the dictionary representing the log entry. If the key istime”, we convert it to</nobr></div>
  888. <div style="position:absolute;top:23529;left:108"><nobr>readable data, otherwise print it as raw strings:</nobr></div>
  889. </span></font>
  890. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  891. <div style="position:absolute;top:23558;left:116"><nobr>&gt;&gt;&gt; import time</nobr></div>
  892. <div style="position:absolute;top:23576;left:116"><nobr>&gt;&gt;&gt; for key in entry :</nobr></div>
  893. <div style="position:absolute;top:23595;left:122"><nobr>...</nobr></div>
  894. <div style="position:absolute;top:23595;left:178"><nobr>i f key == ’time’:</nobr></div>
  895. <div style="position:absolute;top:23613;left:122"><nobr>...</nobr></div>
  896. <div style="position:absolute;top:23613;left:235"><nobr>value = time.localtime(entry[key])</nobr></div>
  897. <div style="position:absolute;top:23632;left:122"><nobr>...</nobr></div>
  898. <div style="position:absolute;top:23632;left:178"><nobr>else :</nobr></div>
  899. <div style="position:absolute;top:23650;left:122"><nobr>...</nobr></div>
  900. <div style="position:absolute;top:23650;left:235"><nobr>value = entry[key]</nobr></div>
  901. <div style="position:absolute;top:23669;left:122"><nobr>...</nobr></div>
  902. <div style="position:absolute;top:23669;left:178"><nobr>str(key) + ” : ” + str(value)</nobr></div>
  903. <div style="position:absolute;top:23687;left:122"><nobr>...</nobr></div>
  904. <div style="position:absolute;top:23705;left:121"><nobr>’ status : Delivered ’</nobr></div>
  905. <div style="position:absolute;top:23724;left:121"><nobr>’direction : Incoming’</nobr></div>
  906. <div style="position:absolute;top:23742;left:121"><nobr>’description : Short message’</nobr></div>
  907. <div style="position:absolute;top:23761;left:121"><nobr>’duration type : −1</nobr></div>
  908. <div style="position:absolute;top:23779;left:121"><nobr>’ number : +4792462429</nobr></div>
  909. <div style="position:absolute;top:23798;left:121"><nobr>’contact : −1</nobr></div>
  910. <div style="position:absolute;top:23816;left:121"><nobr>’flags : 2</nobr></div>
  911. <div style="position:absolute;top:23835;left:121"><nobr>time : (2008, 2, 16, 18, 17, 55, 5, 47, −1)</nobr></div>
  912. <div style="position:absolute;top:23853;left:121"><nobr>’duration : 0</nobr></div>
  913. <div style="position:absolute;top:23872;left:121"><nobr>’link : 0</nobr></div>
  914. <div style="position:absolute;top:23890;left:121"><nobr>’ s u b j e c t : Klem ’</nobr></div>
  915. <div style="position:absolute;top:23909;left:121"><nobr>’data : \x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00</nobr></div>
  916. </span></font>
  917. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  918. <div style="position:absolute;top:23935;left:124"><nobr>9<font style="font-size:9px">What the heck is scheduler? No google clues...</font></nobr></div>
  919. </span></font>
  920.  
  921. <div style="position:absolute;top:24153;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="21"><b>Page 21</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  922. <div style="position:absolute;top:24269;left:162"><nobr>2.8. Inbox</nobr></div>
  923. <div style="position:absolute;top:24269;left:795"><nobr>15</nobr></div>
  924. </span></font>
  925. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  926. <div style="position:absolute;top:24339;left:173"><nobr>\x00\x00\x01\x00\x00\x00 ’</nobr></div>
  927. <div style="position:absolute;top:24358;left:175"><nobr>id : 86</nobr></div>
  928. <div style="position:absolute;top:24377;left:175"><nobr>’name : ’</nobr></div>
  929. </span></font>
  930. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  931. <div style="position:absolute;top:24437;left:162"><nobr>2.8 Inbox</nobr></div>
  932. </span></font>
  933. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  934. <div style="position:absolute;top:24481;left:162"><nobr>The inbox module offers access to device inbox, outbox, sent and drafts folders. Currently, only the incom-</nobr></div>
  935. <div style="position:absolute;top:24504;left:162"><nobr>ing SMS inbox is supported. Let’s have look in the box<a href="#1"></a><font style="font-size:8px"><a href="#1">10</a></font><a href="#1"></a>:</nobr></div>
  936. </span></font>
  937. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  938. <div style="position:absolute;top:24533;left:170"><nobr>&gt;&gt;&gt; import inbx , time</nobr></div>
  939. <div style="position:absolute;top:24552;left:170"><nobr>&gt;&gt;&gt; box = inbox.Inbox()</nobr></div>
  940. <div style="position:absolute;top:24570;left:170"><nobr>&gt;&gt;&gt; for id in box.sms messages():</nobr></div>
  941. <div style="position:absolute;top:24589;left:176"><nobr>...</nobr></div>
  942. <div style="position:absolute;top:24589;left:231"><nobr>”Time: ” + str(time.localtime(box.time(id)))</nobr></div>
  943. <div style="position:absolute;top:24607;left:176"><nobr>...</nobr></div>
  944. <div style="position:absolute;top:24607;left:231"><nobr>”Content: ” + box.content(id)</nobr></div>
  945. <div style="position:absolute;top:24626;left:176"><nobr>...</nobr></div>
  946. <div style="position:absolute;top:24644;left:175"><nobr>’Time: (2008, 2, 16, 19, 17, 55, 5, 47, −1)</nobr></div>
  947. <div style="position:absolute;top:24663;left:173"><nobr>u’Content: Klem ’</nobr></div>
  948. <div style="position:absolute;top:24681;left:175"><nobr>’Time: (2008, 2, 16, 19, 10, 20, 5, 47, −1)</nobr></div>
  949. <div style="position:absolute;top:24700;left:173"><nobr>u ’ Content : Klem ’</nobr></div>
  950. </span></font>
  951. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  952. <div style="position:absolute;top:24730;left:184"><nobr>A most interesting feature is the bind function, making it possible to trigger any kind of programmable</nobr></div>
  953. <div style="position:absolute;top:24753;left:162"><nobr>action when you receive an SMS. Your callback function is executed with the ID of the incoming message as</nobr></div>
  954. <div style="position:absolute;top:24777;left:162"><nobr>argument, hence you could what you like based on the content and metadata of the message<a href="#1"></a><font style="font-size:8px"><a href="#1">11</a></font><a href="#1"></a>.</nobr></div>
  955. </span></font>
  956. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  957. <div style="position:absolute;top:25169;left:174"><nobr>10<font style="font-size:9px">Note that time stamp differs an hour from the data from the log in the previous section, timezones, localtime, summer/wintertime is</font></nobr></div>
  958. </span></font>
  959. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  960. <div style="position:absolute;top:25185;left:162"><nobr>a real hassle, in PyS60 as in other environments...</nobr></div>
  961. </span></font>
  962. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  963. <div style="position:absolute;top:25197;left:174"><nobr>11<font style="font-size:9px">Example to come...</font></nobr></div>
  964. </span></font>
  965.  
  966. <div style="position:absolute;top:25415;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="22"><b>Page 22</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  967. <div style="position:absolute;top:25712;left:108"><nobr>Chapter 3</nobr></div>
  968. </span></font>
  969. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  970. <div style="position:absolute;top:25796;left:108"><nobr>Applications, user interfaces, daemons</nobr></div>
  971. </span></font>
  972. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  973. <div style="position:absolute;top:25894;left:108"><nobr>In this chapter we deal with GUI important related issues that are not so well documented or examplified. For</nobr></div>
  974. <div style="position:absolute;top:25918;left:108"><nobr>how to use menus, listboxes, query boxes etc., see existing documentation (Section ??. We will in particular</nobr></div>
  975. <div style="position:absolute;top:25941;left:108"><nobr>touch upon multithreading, synchronization, background daemons and custom graphical GUIs.</nobr></div>
  976. </span></font>
  977. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  978. <div style="position:absolute;top:25994;left:108"><nobr>3.1 Application Patterns</nobr></div>
  979. </span></font>
  980. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  981. <div style="position:absolute;top:26037;left:108"><nobr>The appuifw provides the machinery for building GUI based applications. There is no notion of ”main-</nobr></div>
  982. <div style="position:absolute;top:26060;left:108"><nobr>loop”, as for instance as in Java. Here we provide you with two application skeletons, one without, on with,</nobr></div>
  983. <div style="position:absolute;top:26084;left:108"><nobr>a custom main loop.</nobr></div>
  984. </span></font>
  985. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  986. <div style="position:absolute;top:26111;left:120"><nobr>import e32 , appuifw</nobr></div>
  987. </span></font>
  988. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  989. <div style="position:absolute;top:26130;left:119"><nobr># Set application title</nobr></div>
  990. </span></font>
  991. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  992. <div style="position:absolute;top:26148;left:120"><nobr>appuifw.app. title = u’No Main Loop App’</nobr></div>
  993. </span></font>
  994. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  995. <div style="position:absolute;top:26166;left:119"><nobr># Allocate a text component, which essential is an editor like component</nobr></div>
  996. </span></font>
  997. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  998. <div style="position:absolute;top:26185;left:121"><nobr>text = appuifw.Text()</nobr></div>
  999. <div style="position:absolute;top:26203;left:121"><nobr>text.set(u’Hit Exit when you have seen enough!)</nobr></div>
  1000. </span></font>
  1001. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1002. <div style="position:absolute;top:26222;left:119"><nobr># Acquire an a c t i v e o b j e c t s lock , w i l l be used to keep the GUI a l i v e .</nobr></div>
  1003. </span></font>
  1004. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1005. <div style="position:absolute;top:26240;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
  1006. </span></font>
  1007. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1008. <div style="position:absolute;top:26259;left:119"><nobr># Assign the text component as the application body</nobr></div>
  1009. </span></font>
  1010. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1011. <div style="position:absolute;top:26277;left:120"><nobr>appuifw.app.body = text</nobr></div>
  1012. </span></font>
  1013. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1014. <div style="position:absolute;top:26296;left:119"><nobr># Define what’s going to happen when user hits the Exit button</nobr></div>
  1015. </span></font>
  1016. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1017. <div style="position:absolute;top:26314;left:120"><nobr>def quit ():</nobr></div>
  1018. </span></font>
  1019. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1020. <div style="position:absolute;top:26333;left:148"><nobr># Signal to release the lock , so t h a t the a p p l i c a t i o n can move on</nobr></div>
  1021. </span></font>
  1022. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1023. <div style="position:absolute;top:26351;left:149"><nobr>global app lock</nobr></div>
  1024. <div style="position:absolute;top:26369;left:149"><nobr>app lock . signal ()</nobr></div>
  1025. </span></font>
  1026. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1027. <div style="position:absolute;top:26388;left:119"><nobr># Assign the quit function to the exit key handler</nobr></div>
  1028. </span></font>
  1029. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1030. <div style="position:absolute;top:26406;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  1031. </span></font>
  1032. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1033. <div style="position:absolute;top:26425;left:119"><nobr># Wait here until given a signal</nobr></div>
  1034. </span></font>
  1035. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1036. <div style="position:absolute;top:26443;left:120"><nobr>app lock . wait ()</nobr></div>
  1037. </span></font>
  1038. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1039. <div style="position:absolute;top:26462;left:119"><nobr># Notify that we are gracefully terminating the application</nobr></div>
  1040. </span></font>
  1041. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1042. <div style="position:absolute;top:26504;left:425"><nobr>16</nobr></div>
  1043. </span></font>
  1044.  
  1045. <div style="position:absolute;top:26677;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="23"><b>Page 23</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1046. <div style="position:absolute;top:26793;left:162"><nobr>3.2. Active Objects</nobr></div>
  1047. <div style="position:absolute;top:26793;left:795"><nobr>17</nobr></div>
  1048. </span></font>
  1049. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1050. <div style="position:absolute;top:26864;left:174"><nobr>appuifw . note (u ’End!)</nobr></div>
  1051. </span></font>
  1052. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1053. <div style="position:absolute;top:26893;left:162"><nobr>Here is an example of an explicitly coded main loop:</nobr></div>
  1054. </span></font>
  1055. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1056. <div style="position:absolute;top:26922;left:174"><nobr>import e32 , appuifw</nobr></div>
  1057. </span></font>
  1058. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1059. <div style="position:absolute;top:26941;left:173"><nobr># Set title</nobr></div>
  1060. </span></font>
  1061. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1062. <div style="position:absolute;top:26959;left:174"><nobr>appuifw.app. title = u’Main Loop App’</nobr></div>
  1063. <div style="position:absolute;top:26978;left:175"><nobr>text = appuifw.Text()</nobr></div>
  1064. <div style="position:absolute;top:26996;left:175"><nobr>text . set (u’ Iteration no: ’)</nobr></div>
  1065. <div style="position:absolute;top:27015;left:174"><nobr>appuifw.app.body = text</nobr></div>
  1066. </span></font>
  1067. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1068. <div style="position:absolute;top:27033;left:173"><nobr># Define exit behavior</nobr></div>
  1069. </span></font>
  1070. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1071. <div style="position:absolute;top:27051;left:174"><nobr>def quit ():</nobr></div>
  1072. </span></font>
  1073. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1074. <div style="position:absolute;top:27070;left:202"><nobr># Set the globally accessible boolean to False</nobr></div>
  1075. </span></font>
  1076. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1077. <div style="position:absolute;top:27088;left:203"><nobr>global run</nobr></div>
  1078. <div style="position:absolute;top:27107;left:203"><nobr>run = False</nobr></div>
  1079. </span></font>
  1080. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1081. <div style="position:absolute;top:27125;left:173"><nobr># Assign the quit function to the key handler</nobr></div>
  1082. </span></font>
  1083. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1084. <div style="position:absolute;top:27144;left:174"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  1085. </span></font>
  1086. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1087. <div style="position:absolute;top:27162;left:173"><nobr># S t a r t main loop , w i l l run as long as run i s True ,</nobr></div>
  1088. <div style="position:absolute;top:27181;left:173"><nobr># t h a t is , u n t i l the e x i t key i s h i t</nobr></div>
  1089. </span></font>
  1090. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1091. <div style="position:absolute;top:27199;left:174"><nobr>run = True</nobr></div>
  1092. <div style="position:absolute;top:27218;left:175"><nobr>i = 1</nobr></div>
  1093. <div style="position:absolute;top:27236;left:174"><nobr>while run :</nobr></div>
  1094. </span></font>
  1095. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1096. <div style="position:absolute;top:27255;left:202"><nobr># Wait for a second</nobr></div>
  1097. </span></font>
  1098. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1099. <div style="position:absolute;top:27273;left:202"><nobr>e32 . ao sleep (1)</nobr></div>
  1100. </span></font>
  1101. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1102. <div style="position:absolute;top:27291;left:202"><nobr># Put new text in the UI component</nobr></div>
  1103. </span></font>
  1104. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1105. <div style="position:absolute;top:27310;left:203"><nobr>text . set (u’ Iteration no: ’+str ( i ))</nobr></div>
  1106. </span></font>
  1107. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1108. <div style="position:absolute;top:27328;left:202"><nobr># Update counter</nobr></div>
  1109. </span></font>
  1110. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1111. <div style="position:absolute;top:27347;left:203"><nobr>i += 1</nobr></div>
  1112. </span></font>
  1113. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1114. <div style="position:absolute;top:27365;left:173"><nobr># Graceful termination</nobr></div>
  1115. </span></font>
  1116. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1117. <div style="position:absolute;top:27384;left:174"><nobr>appuifw . note (u ’End!)</nobr></div>
  1118. </span></font>
  1119. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  1120. <div style="position:absolute;top:27444;left:162"><nobr>3.2 Active Objects</nobr></div>
  1121. </span></font>
  1122. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1123. <div style="position:absolute;top:27487;left:162"><nobr>TBD</nobr></div>
  1124. </span></font>
  1125. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  1126. <div style="position:absolute;top:27541;left:162"><nobr>3.3 Blocking</nobr></div>
  1127. </span></font>
  1128. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1129. <div style="position:absolute;top:27584;left:162"><nobr>In this program, longtask may be called several times, causing the several overlapping long tasks</nobr></div>
  1130. </span></font>
  1131. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1132. <div style="position:absolute;top:27613;left:174"><nobr>import e32 , appuifw</nobr></div>
  1133. <div style="position:absolute;top:27650;left:174"><nobr>def longtask ():</nobr></div>
  1134. <div style="position:absolute;top:27668;left:203"><nobr>timer = e32.Ao timer()</nobr></div>
  1135. <div style="position:absolute;top:27687;left:202"><nobr>max =</nobr></div>
  1136. <div style="position:absolute;top:27687;left:252"><nobr>20</nobr></div>
  1137. <div style="position:absolute;top:27705;left:203"><nobr>i = 0</nobr></div>
  1138. <div style="position:absolute;top:27724;left:203"><nobr>appuifw.note(u’Long task starting ’ ’info’)</nobr></div>
  1139. </span></font>
  1140.  
  1141. <div style="position:absolute;top:27939;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="24"><b>Page 24</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1142. <div style="position:absolute;top:28055;left:108"><nobr>18</nobr></div>
  1143. <div style="position:absolute;top:28055;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1144. </span></font>
  1145. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1146. <div style="position:absolute;top:28126;left:149"><nobr>while i &lt; max :</nobr></div>
  1147. <div style="position:absolute;top:28144;left:178"><nobr>timer . after (1)</nobr></div>
  1148. <div style="position:absolute;top:28163;left:178"><nobr>i += 1</nobr></div>
  1149. <div style="position:absolute;top:28181;left:149"><nobr>timer . cancel ()</nobr></div>
  1150. <div style="position:absolute;top:28200;left:149"><nobr>appuifw . note (u ’Long task finished ’ ’ info ’ )</nobr></div>
  1151. <div style="position:absolute;top:28236;left:121"><nobr>i f</nobr></div>
  1152. <div style="position:absolute;top:28237;left:154"><nobr>name</nobr></div>
  1153. <div style="position:absolute;top:28237;left:205"><nobr>== ’ main</nobr></div>
  1154. <div style="position:absolute;top:28237;left:293"><nobr>’:</nobr></div>
  1155. <div style="position:absolute;top:28273;left:149"><nobr>def quit ():</nobr></div>
  1156. <div style="position:absolute;top:28292;left:178"><nobr>global app lock</nobr></div>
  1157. <div style="position:absolute;top:28310;left:177"><nobr>appuifw . note (u ’ Exit ’ ’ info ’ )</nobr></div>
  1158. <div style="position:absolute;top:28329;left:178"><nobr>app lock . signal ()</nobr></div>
  1159. <div style="position:absolute;top:28366;left:149"><nobr>appuifw.app. title = u’Long Task’</nobr></div>
  1160. <div style="position:absolute;top:28384;left:149"><nobr>appuifw.app.menu = [(u’Long task’, longtask)]</nobr></div>
  1161. <div style="position:absolute;top:28421;left:149"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  1162. <div style="position:absolute;top:28440;left:149"><nobr>app lock = e32.Ao lock()</nobr></div>
  1163. </span></font>
  1164. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1165. <div style="position:absolute;top:28458;left:148"><nobr># Will wait u n t i l a signal i s give , and</nobr></div>
  1166. <div style="position:absolute;top:28458;left:451"><nobr>a l l a c t i v e processes are terminated</nobr></div>
  1167. <div style="position:absolute;top:28477;left:148"><nobr># Without the wait functions , the application would have ended before you</nobr></div>
  1168. <div style="position:absolute;top:28495;left:148"><nobr># had the chance to push the menu button :)</nobr></div>
  1169. </span></font>
  1170. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1171. <div style="position:absolute;top:28513;left:149"><nobr>app lock . wait ()</nobr></div>
  1172. <div style="position:absolute;top:28532;left:149"><nobr>appuifw . note (u ’End! ’ ’ info ’ )</nobr></div>
  1173. </span></font>
  1174. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  1175. <div style="position:absolute;top:28599;left:108"><nobr>3.4 Multitasking</nobr></div>
  1176. </span></font>
  1177. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1178. <div style="position:absolute;top:28644;left:108"><nobr>TBD: Preemptive vs. cooperating multitasking. Active objects.</nobr></div>
  1179. </span></font>
  1180. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  1181. <div style="position:absolute;top:28703;left:108"><nobr>3.5 Daemons</nobr></div>
  1182. </span></font>
  1183. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1184. <div style="position:absolute;top:28748;left:108"><nobr>A classical application pattern is the daemon concept, i.e., a background process that provides other processes,</nobr></div>
  1185. <div style="position:absolute;top:28771;left:108"><nobr>most often GUI-related, with up-dated information. Obviously, this requires some kind of coordination.</nobr></div>
  1186. </span></font>
  1187. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  1188. <div style="position:absolute;top:28823;left:108"><nobr>3.5.1 Simple daemon</nobr></div>
  1189. </span></font>
  1190. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1191. <div style="position:absolute;top:28860;left:108"><nobr>Consider a simple toy example, where a daemon just performs heartbeats with a specified interval. It uses a</nobr></div>
  1192. <div style="position:absolute;top:28883;left:108"><nobr>wait function, and for each second, it checks the actual duration using the device clock. It stores the longest</nobr></div>
  1193. <div style="position:absolute;top:28907;left:108"><nobr>duration. We communicate with the daemon by global variables<a href="#1"></a><font style="font-size:8px"><a href="#1">1 </a></font>We also time the beats with the system</nobr></div>
  1194. <div style="position:absolute;top:28930;left:108"><nobr>clock, to possibly detect if the thread is suspended in some way if we for instance run other programs in the</nobr></div>
  1195. <div style="position:absolute;top:28953;left:108"><nobr>foreground.</nobr></div>
  1196. </span></font>
  1197. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  1198. <div style="position:absolute;top:28983;left:124"><nobr>1<font style="font-size:9px">Yes, global variables are bad, but in multithreading it sometimes is the best solution.</font></nobr></div>
  1199. </span></font>
  1200.  
  1201. <div style="position:absolute;top:29201;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="25"><b>Page 25</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1202. <div style="position:absolute;top:29317;left:162"><nobr>3.5. Daemons</nobr></div>
  1203. <div style="position:absolute;top:29317;left:795"><nobr>19</nobr></div>
  1204. </span></font>
  1205. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1206. <div style="position:absolute;top:29388;left:174"><nobr>import os , time , e32 , thread , appuifw</nobr></div>
  1207. <div style="position:absolute;top:29425;left:174"><nobr>def heartbeat ():</nobr></div>
  1208. <div style="position:absolute;top:29443;left:203"><nobr>global longest</nobr></div>
  1209. <div style="position:absolute;top:29461;left:203"><nobr>global no</nobr></div>
  1210. <div style="position:absolute;top:29480;left:203"><nobr>global beat</nobr></div>
  1211. </span></font>
  1212. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1213. <div style="position:absolute;top:29499;left:202"><nobr># Use the e32 timer , should be s af e r than time . sleep ( )</nobr></div>
  1214. </span></font>
  1215. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1216. <div style="position:absolute;top:29517;left:203"><nobr>timer = e32.Ao timer()</nobr></div>
  1217. <div style="position:absolute;top:29535;left:203"><nobr>prev = time.clock()</nobr></div>
  1218. <div style="position:absolute;top:29554;left:203"><nobr>while beat :</nobr></div>
  1219. <div style="position:absolute;top:29572;left:232"><nobr>timer . after (1)</nobr></div>
  1220. <div style="position:absolute;top:29591;left:232"><nobr>curr = time.clock()</nobr></div>
  1221. <div style="position:absolute;top:29609;left:232"><nobr>duration = curr − prev</nobr></div>
  1222. <div style="position:absolute;top:29628;left:232"><nobr>i f duration &gt; longest :</nobr></div>
  1223. <div style="position:absolute;top:29646;left:261"><nobr>longest = duration</nobr></div>
  1224. <div style="position:absolute;top:29665;left:231"><nobr>no += 1</nobr></div>
  1225. <div style="position:absolute;top:29683;left:231"><nobr>prev = curr</nobr></div>
  1226. <div style="position:absolute;top:29702;left:203"><nobr>timer . cancel ()</nobr></div>
  1227. <div style="position:absolute;top:29738;left:175"><nobr>i f</nobr></div>
  1228. <div style="position:absolute;top:29738;left:207"><nobr>name</nobr></div>
  1229. <div style="position:absolute;top:29738;left:259"><nobr>== ’ main</nobr></div>
  1230. <div style="position:absolute;top:29738;left:347"><nobr>’:</nobr></div>
  1231. <div style="position:absolute;top:29757;left:203"><nobr>longest = 0</nobr></div>
  1232. <div style="position:absolute;top:29775;left:202"><nobr>no = 0</nobr></div>
  1233. <div style="position:absolute;top:29794;left:203"><nobr>beat = True</nobr></div>
  1234. </span></font>
  1235. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1236. <div style="position:absolute;top:29812;left:202"><nobr>#applock = e32.Ao lock()</nobr></div>
  1237. </span></font>
  1238. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1239. <div style="position:absolute;top:29849;left:203"><nobr>def g e t d u r a t i o n ( ) :</nobr></div>
  1240. <div style="position:absolute;top:29867;left:232"><nobr>global longest</nobr></div>
  1241. <div style="position:absolute;top:29886;left:231"><nobr>appuifw . note ( unicode ( longest ) , ’ info ’ )</nobr></div>
  1242. <div style="position:absolute;top:29923;left:203"><nobr>def exit ():</nobr></div>
  1243. </span></font>
  1244. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1245. <div style="position:absolute;top:29942;left:231"><nobr># Stop the while loop in the daemon</nobr></div>
  1246. </span></font>
  1247. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1248. <div style="position:absolute;top:29960;left:232"><nobr>global beat</nobr></div>
  1249. <div style="position:absolute;top:29978;left:232"><nobr>beat =</nobr></div>
  1250. <div style="position:absolute;top:29978;left:289"><nobr>False</nobr></div>
  1251. </span></font>
  1252. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1253. <div style="position:absolute;top:29997;left:231"><nobr># If we have used Alternative 1 (see below),</nobr></div>
  1254. <div style="position:absolute;top:30015;left:231"><nobr># we use the lock to signal that we are finished</nobr></div>
  1255. <div style="position:absolute;top:30034;left:231"><nobr>#global applock</nobr></div>
  1256. <div style="position:absolute;top:30052;left:231"><nobr>#applock . signal ()</nobr></div>
  1257. <div style="position:absolute;top:30071;left:231"><nobr># If we have used Alternative 2 (see below), the wait function automatically</nobr></div>
  1258. <div style="position:absolute;top:30089;left:231"><nobr># detects that the thread is shutting down,</nobr></div>
  1259. <div style="position:absolute;top:30108;left:231"><nobr># and we do not have to signal explicitly</nobr></div>
  1260. </span></font>
  1261. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1262. <div style="position:absolute;top:30144;left:203"><nobr>appuifw.app. title = u’Heartbeat’</nobr></div>
  1263. <div style="position:absolute;top:30163;left:203"><nobr>appuifw.app.exit key handler = exit</nobr></div>
  1264. <div style="position:absolute;top:30181;left:203"><nobr>appuifw.app.menu = [(u’Beat’, get duration)]</nobr></div>
  1265. </span></font>
  1266. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1267. <div style="position:absolute;top:30218;left:202"><nobr># p r i n t ’ Daemon − Start ’</nobr></div>
  1268. <div style="position:absolute;top:30237;left:202"><nobr># Spawn the daemon in a separate thread , s to r e the thread id</nobr></div>
  1269. </span></font>
  1270.  
  1271. <div style="position:absolute;top:30463;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="26"><b>Page 26</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1272. <div style="position:absolute;top:30579;left:108"><nobr>20</nobr></div>
  1273. <div style="position:absolute;top:30579;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1274. </span></font>
  1275. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1276. <div style="position:absolute;top:30650;left:150"><nobr>tid = thread.start new thread(heartbeat , ())</nobr></div>
  1277. <div style="position:absolute;top:30668;left:149"><nobr>appuifw.note(u’Thread no ’+str(tid)+’ is now running. ’ ’info’)</nobr></div>
  1278. </span></font>
  1279. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1280. <div style="position:absolute;top:30687;left:148"><nobr># Now, we want the main thread to wait for the daemon to quit before continuing</nobr></div>
  1281. <div style="position:absolute;top:30705;left:148"><nobr># Alternative 1: Use the e32.Ao lock()</nobr></div>
  1282. <div style="position:absolute;top:30724;left:148"><nobr># applock . wait ()</nobr></div>
  1283. <div style="position:absolute;top:30742;left:148"><nobr># Alternative 2: Use the thread id and the PyS60 extension to the</nobr></div>
  1284. <div style="position:absolute;top:30761;left:148"><nobr># thread module: thread.ao waittid(tid)</nobr></div>
  1285. </span></font>
  1286. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1287. <div style="position:absolute;top:30779;left:149"><nobr>thread . ao waittid ( tid )</nobr></div>
  1288. </span></font>
  1289. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1290. <div style="position:absolute;top:30798;left:148"><nobr># Now the daemon is dead, and we continue in the main thread</nobr></div>
  1291. </span></font>
  1292. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1293. <div style="position:absolute;top:30816;left:149"><nobr>appuifw.note(u’Beats: ’ + str(no) + u’, longest: ’ + str(longest), ’info’)</nobr></div>
  1294. </span></font>
  1295. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1296. <div style="position:absolute;top:30848;left:130"><nobr>If you play around with this script, run some other applications, maybe browse images in the gallery,</nobr></div>
  1297. <div style="position:absolute;top:30871;left:108"><nobr>make a call...you will notice that the beat intervals may become longer than the sleep time of the timer</nobr></div>
  1298. <div style="position:absolute;top:30894;left:108"><nobr>facility: Why? One reason is that timing stuff is notoriously untrustful, another reason could be that the</nobr></div>
  1299. <div style="position:absolute;top:30918;left:108"><nobr>daemon is suspended while other applications are running<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font></nobr></div>
  1300. </span></font>
  1301. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  1302. <div style="position:absolute;top:30968;left:108"><nobr>3.5.2 Cooperating threads</nobr></div>
  1303. </span></font>
  1304. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1305. <div style="position:absolute;top:31004;left:108"><nobr>TBD: EXPLAIN</nobr></div>
  1306. </span></font>
  1307. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1308. <div style="position:absolute;top:31035;left:120"><nobr>import e32 , appuifw , thread</nobr></div>
  1309. <div style="position:absolute;top:31072;left:120"><nobr>def count ( delta , wait , id ):</nobr></div>
  1310. <div style="position:absolute;top:31090;left:149"><nobr>global run</nobr></div>
  1311. <div style="position:absolute;top:31109;left:149"><nobr>global tasklock</nobr></div>
  1312. <div style="position:absolute;top:31127;left:149"><nobr>global i</nobr></div>
  1313. <div style="position:absolute;top:31146;left:149"><nobr>global no</nobr></div>
  1314. <div style="position:absolute;top:31164;left:149"><nobr>global curr id</nobr></div>
  1315. <div style="position:absolute;top:31201;left:149"><nobr>timer = e32.Ao timer()</nobr></div>
  1316. <div style="position:absolute;top:31220;left:149"><nobr>rounds = 5</nobr></div>
  1317. <div style="position:absolute;top:31256;left:149"><nobr>while run :</nobr></div>
  1318. <div style="position:absolute;top:31275;left:178"><nobr>tasklock . acquire ()</nobr></div>
  1319. <div style="position:absolute;top:31293;left:178"><nobr>r = 0</nobr></div>
  1320. <div style="position:absolute;top:31312;left:177"><nobr>while run and r &lt; rounds :</nobr></div>
  1321. <div style="position:absolute;top:31330;left:206"><nobr>timer . after ( wait )</nobr></div>
  1322. </span></font>
  1323. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1324. <div style="position:absolute;top:31349;left:205"><nobr>#tasklock . acquire ()</nobr></div>
  1325. </span></font>
  1326. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1327. <div style="position:absolute;top:31367;left:207"><nobr>curr id = id</nobr></div>
  1328. <div style="position:absolute;top:31386;left:207"><nobr>i += delta</nobr></div>
  1329. </span></font>
  1330. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1331. <div style="position:absolute;top:31404;left:205"><nobr>#tasklock . release ()</nobr></div>
  1332. </span></font>
  1333. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1334. <div style="position:absolute;top:31423;left:206"><nobr>no = r+1</nobr></div>
  1335. <div style="position:absolute;top:31441;left:206"><nobr>r += 1</nobr></div>
  1336. <div style="position:absolute;top:31460;left:178"><nobr>tasklock . release ()</nobr></div>
  1337. <div style="position:absolute;top:31478;left:149"><nobr>timer . cancel ()</nobr></div>
  1338. </span></font>
  1339. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  1340. <div style="position:absolute;top:31507;left:124"><nobr>2<font style="font-size:9px">Any more explanations, anybody?</font></nobr></div>
  1341. </span></font>
  1342.  
  1343. <div style="position:absolute;top:31725;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="27"><b>Page 27</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1344. <div style="position:absolute;top:31841;left:162"><nobr>3.5. Daemons</nobr></div>
  1345. <div style="position:absolute;top:31841;left:795"><nobr>21</nobr></div>
  1346. </span></font>
  1347. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1348. <div style="position:absolute;top:31930;left:174"><nobr>def quit ():</nobr></div>
  1349. <div style="position:absolute;top:31949;left:203"><nobr>global run</nobr></div>
  1350. <div style="position:absolute;top:31967;left:203"><nobr>run = False</nobr></div>
  1351. <div style="position:absolute;top:31986;left:203"><nobr>appuifw . note (u ’ Exit ’ )</nobr></div>
  1352. <div style="position:absolute;top:32023;left:174"><nobr>appuifw . app . t i t l e = u ’ Counting Race ’</nobr></div>
  1353. <div style="position:absolute;top:32041;left:175"><nobr>text = appuifw.Text()</nobr></div>
  1354. <div style="position:absolute;top:32059;left:174"><nobr>appuifw.app.body = text</nobr></div>
  1355. <div style="position:absolute;top:32078;left:174"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  1356. <div style="position:absolute;top:32115;left:175"><nobr>tasklock = thread.allocate lock()</nobr></div>
  1357. <div style="position:absolute;top:32152;left:175"><nobr>t i d 1 = thread . s t a r t n e w t h r e a d ( count , (1 ,2 , u ’A’ ) )</nobr></div>
  1358. <div style="position:absolute;top:32170;left:175"><nobr>t i d 2 = thread . s t a r t n e w t h r e a d ( count , (10 ,3 , u ’B’ ) )</nobr></div>
  1359. <div style="position:absolute;top:32207;left:175"><nobr>i = 0</nobr></div>
  1360. <div style="position:absolute;top:32226;left:173"><nobr>no = 1</nobr></div>
  1361. <div style="position:absolute;top:32244;left:174"><nobr>run = True</nobr></div>
  1362. <div style="position:absolute;top:32262;left:175"><nobr>curr id = ’X’</nobr></div>
  1363. <div style="position:absolute;top:32281;left:175"><nobr>t = e32.Ao timer()</nobr></div>
  1364. <div style="position:absolute;top:32299;left:174"><nobr>while run :</nobr></div>
  1365. <div style="position:absolute;top:32318;left:203"><nobr>t . after (0.1)</nobr></div>
  1366. </span></font>
  1367. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1368. <div style="position:absolute;top:32336;left:202"><nobr>#tasklock . acquire ()</nobr></div>
  1369. </span></font>
  1370. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1371. <div style="position:absolute;top:32355;left:203"><nobr>text.set(curr id +u’: Counter: ’ +str(i)+u’, Curr: ’+str(no))</nobr></div>
  1372. </span></font>
  1373. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1374. <div style="position:absolute;top:32373;left:202"><nobr>#tasklock . release ()</nobr></div>
  1375. </span></font>
  1376. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1377. <div style="position:absolute;top:32392;left:175"><nobr>t . cancel ()</nobr></div>
  1378. <div style="position:absolute;top:32429;left:174"><nobr>appuifw . note ( u ’The End ’ )</nobr></div>
  1379. </span></font>
  1380. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  1381. <div style="position:absolute;top:32512;left:162"><nobr>3.5.3 Server threads</nobr></div>
  1382. </span></font>
  1383. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1384. <div style="position:absolute;top:32555;left:162"><nobr>TBD</nobr></div>
  1385. <div style="position:absolute;top:32582;left:184"><nobr>FROM API:</nobr></div>
  1386. <div style="position:absolute;top:32629;left:199"><nobr>The thread that initializes the Python interpreter becomes the main Python thread. This is usually</nobr></div>
  1387. <div style="position:absolute;top:32653;left:199"><nobr>the main thread of a UI application. When an application written in Python launches, the Sym-</nobr></div>
  1388. <div style="position:absolute;top:32676;left:199"><nobr>bian platform infrastructure creates the main UI thread that starts the Python environment. If a</nobr></div>
  1389. <div style="position:absolute;top:32699;left:199"><nobr>Python program is started as a server with e32.start server, then the Python main thread</nobr></div>
  1390. <div style="position:absolute;top:32723;left:199"><nobr>is not a UI thread.</nobr></div>
  1391. <div style="position:absolute;top:32770;left:162"><nobr>...started by calling the script file.</nobr></div>
  1392. </span></font>
  1393.  
  1394. <div style="position:absolute;top:32987;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="28"><b>Page 28</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1395. <div style="position:absolute;top:33103;left:108"><nobr>22</nobr></div>
  1396. <div style="position:absolute;top:33103;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1397. </span></font>
  1398. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  1399. <div style="position:absolute;top:33170;left:108"><nobr>3.5.4 Threads and GUI</nobr></div>
  1400. </span></font>
  1401. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1402. <div style="position:absolute;top:33209;left:108"><nobr>The main lesson in this chapter is the following</nobr></div>
  1403. <div style="position:absolute;top:33251;left:145"><nobr>DO NOT USE thread FUNCTIONS IN THE MAIN UI (appuifw) THREAD!</nobr></div>
  1404. <div style="position:absolute;top:33293;left:108"><nobr>When trying to coordinate GUI operations, for instance keep the GUI alive without a main loop, use the</nobr></div>
  1405. <div style="position:absolute;top:33317;left:108"><nobr>Ao lock machinery. Using thread module functionality would most certainly harm the application, per-</nobr></div>
  1406. <div style="position:absolute;top:33340;left:108"><nobr>haps make it hang.</nobr></div>
  1407. <div style="position:absolute;top:33365;left:130"><nobr>This is an example on WHAT YOU SHOULD NOT DO:</nobr></div>
  1408. </span></font>
  1409. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1410. <div style="position:absolute;top:33399;left:120"><nobr>import e32 , appuifw , thread</nobr></div>
  1411. </span></font>
  1412. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1413. <div style="position:absolute;top:33418;left:119"><nobr># Define a task that takes about 10 seconds</nobr></div>
  1414. </span></font>
  1415. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1416. <div style="position:absolute;top:33436;left:120"><nobr>def longtask ():</nobr></div>
  1417. <div style="position:absolute;top:33454;left:149"><nobr>global tasklock</nobr></div>
  1418. </span></font>
  1419. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1420. <div style="position:absolute;top:33473;left:148"><nobr># Get a lock to make sure that only one longtask can run</nobr></div>
  1421. </span></font>
  1422. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1423. <div style="position:absolute;top:33492;left:149"><nobr>tasklock . acquire ()</nobr></div>
  1424. <div style="position:absolute;top:33510;left:149"><nobr>timer = e32.Ao timer()</nobr></div>
  1425. <div style="position:absolute;top:33528;left:148"><nobr>max =</nobr></div>
  1426. <div style="position:absolute;top:33528;left:198"><nobr>10</nobr></div>
  1427. <div style="position:absolute;top:33547;left:149"><nobr>i = 0</nobr></div>
  1428. <div style="position:absolute;top:33565;left:149"><nobr>appuifw.note(u’Long task starting ’ ’info’)</nobr></div>
  1429. <div style="position:absolute;top:33584;left:149"><nobr>while i &lt; max :</nobr></div>
  1430. <div style="position:absolute;top:33602;left:178"><nobr>timer . after (1)</nobr></div>
  1431. <div style="position:absolute;top:33621;left:178"><nobr>i += 1</nobr></div>
  1432. <div style="position:absolute;top:33639;left:149"><nobr>timer . cancel ()</nobr></div>
  1433. <div style="position:absolute;top:33658;left:149"><nobr>appuifw . note (u ’Long task finished ’ ’ info ’ )</nobr></div>
  1434. </span></font>
  1435. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1436. <div style="position:absolute;top:33676;left:148"><nobr># Task is finished</nobr></div>
  1437. </span></font>
  1438. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1439. <div style="position:absolute;top:33695;left:149"><nobr>tasklock . release ()</nobr></div>
  1440. <div style="position:absolute;top:33731;left:120"><nobr>def quit ():</nobr></div>
  1441. <div style="position:absolute;top:33750;left:149"><nobr>global app lock</nobr></div>
  1442. <div style="position:absolute;top:33768;left:149"><nobr>appuifw . note (u ’ Exit ’ ’ info ’ )</nobr></div>
  1443. <div style="position:absolute;top:33787;left:149"><nobr>app lock . signal ()</nobr></div>
  1444. </span></font>
  1445. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1446. <div style="position:absolute;top:33824;left:119"><nobr># Allocate the global lock</nobr></div>
  1447. </span></font>
  1448. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1449. <div style="position:absolute;top:33842;left:121"><nobr>tasklock = thread.allocate lock()</nobr></div>
  1450. <div style="position:absolute;top:33861;left:120"><nobr>appuifw.app. title = u’Erroneous App’</nobr></div>
  1451. <div style="position:absolute;top:33879;left:120"><nobr>appuifw.app.menu = [(u’Long task’, longtask)]</nobr></div>
  1452. <div style="position:absolute;top:33898;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  1453. <div style="position:absolute;top:33916;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
  1454. </span></font>
  1455. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1456. <div style="position:absolute;top:33935;left:119"><nobr># Will wait u n t i l a signal i s give , and</nobr></div>
  1457. <div style="position:absolute;top:33935;left:415"><nobr>a l l</nobr></div>
  1458. <div style="position:absolute;top:33935;left:451"><nobr>a c t i v e processes are terminated</nobr></div>
  1459. </span></font>
  1460. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1461. <div style="position:absolute;top:33953;left:120"><nobr>app lock . wait ()</nobr></div>
  1462. <div style="position:absolute;top:33971;left:120"><nobr>appuifw . note (u ’End! ’ ’ info ’ )</nobr></div>
  1463. </span></font>
  1464. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1465. <div style="position:absolute;top:34008;left:130"><nobr>If you press ”Long task” once, and wait until it finish, everything is OK. Press it a second, before the first</nobr></div>
  1466. <div style="position:absolute;top:34032;left:108"><nobr>task is complete, then you app hangs.</nobr></div>
  1467. </span></font>
  1468.  
  1469. <div style="position:absolute;top:34249;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="29"><b>Page 29</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1470. <div style="position:absolute;top:34365;left:162"><nobr>3.6. Graphics</nobr></div>
  1471. <div style="position:absolute;top:34365;left:795"><nobr>23</nobr></div>
  1472. </span></font>
  1473. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  1474. <div style="position:absolute;top:34429;left:162"><nobr>3.6 Graphics</nobr></div>
  1475. </span></font>
  1476. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1477. <div style="position:absolute;top:34474;left:162"><nobr>PyS60 does not offer high level functionality for developing advanced graphic user interfaces for use in for</nobr></div>
  1478. <div style="position:absolute;top:34498;left:162"><nobr>instance game applications. Basically, you have to draw everything on a canvas, with simple operations</nobr></div>
  1479. <div style="position:absolute;top:34521;left:162"><nobr>as draw lines, circles, rectangles, text etc., and implement custom callback functions for various feedback,</nobr></div>
  1480. <div style="position:absolute;top:34544;left:162"><nobr>typically from keyboard events.</nobr></div>
  1481. <div style="position:absolute;top:34568;left:184"><nobr>To illustrate the basic concepts of low level graphics user interface programming, we will through an</nobr></div>
  1482. <div style="position:absolute;top:34592;left:162"><nobr>implementation of the classical battleship game<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>In this game, you guess where ships are located in an area,</nobr></div>
  1483. <div style="position:absolute;top:34615;left:162"><nobr>drop a bomb at the guessed location, and either you will hit (a part of) a ship and get notified, or you miss,</nobr></div>
  1484. <div style="position:absolute;top:34638;left:162"><nobr>and get notified. The goal is to minimize the number of bombs to sink all the ships.</nobr></div>
  1485. <div style="position:absolute;top:34662;left:184"><nobr>In our implementation<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>, a random ship is generated, and the user may move around in the “ocean” with</nobr></div>
  1486. <div style="position:absolute;top:34686;left:162"><nobr>the navigation keys, and press hit at a guessed location. If there is a ship, an explosion sound will be heard,</nobr></div>
  1487. <div style="position:absolute;top:34709;left:162"><nobr>and a fire image is displayed. Otherwise, the system will do nothing but display an image of an empty ocean.</nobr></div>
  1488. <div style="position:absolute;top:34732;left:162"><nobr>When all parts of the ship are hit, a score will be displayed. The user interface is based on a grid layout, see</nobr></div>
  1489. <div style="position:absolute;top:34756;left:162"><nobr>Figure <a href="#29">3.1.</a></nobr></div>
  1490. </span></font>
  1491. <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
  1492. <div style="position:absolute;top:35113;left:411"><nobr>Figure 3.1: Battleship game</nobr></div>
  1493. </span></font>
  1494. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1495. <div style="position:absolute;top:35154;left:184"><nobr>The first part of the implementation is a utility function for making transparent images. After that comes</nobr></div>
  1496. <div style="position:absolute;top:35178;left:162"><nobr>global definitions of colors, files, etc. Then we implement the game logic in a separate class, BattleShip,</nobr></div>
  1497. <div style="position:absolute;top:35201;left:162"><nobr>and finally we implement the main user interface thread.</nobr></div>
  1498. <div style="position:absolute;top:35225;left:184"><nobr>When doing graphics manipulations, you will soon feel the need for pasting transparent image pieces</nobr></div>
  1499. <div style="position:absolute;top:35248;left:162"><nobr>on top of the canvas. Transparency is not supported on PyS60 , however, the copy function, blit, allows</nobr></div>
  1500. </span></font>
  1501. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  1502. <div style="position:absolute;top:35279;left:178"><nobr>3<font style="font-size:9px">Add a GPS, a map, then you can extend the battleship concept to a fun “mixed reality” application, see e.g., “Battleship by foot”[<a href="#44">1]</a>.</font></nobr></div>
  1503. <div style="position:absolute;top:35293;left:178"><nobr>4<font style="font-size:9px">The implementation is bare-bone, with a minimal amount of security nets and optimized code.</font></nobr></div>
  1504. </span></font>
  1505.  
  1506. <div style="position:absolute;top:35511;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="30"><b>Page 30</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1507. <div style="position:absolute;top:35627;left:108"><nobr>24</nobr></div>
  1508. <div style="position:absolute;top:35627;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1509. <div style="position:absolute;top:35696;left:108"><nobr>you to specify a black-and-white mask, which will copy only the pixels in the white part of the mask, hence,</nobr></div>
  1510. <div style="position:absolute;top:35719;left:108"><nobr>simulating transparency. To accomplish this, we implement a handy automask function, that takes an image</nobr></div>
  1511. <div style="position:absolute;top:35742;left:108"><nobr>and produces a corresponding black-and-white image mask, where we assume the transparency color is found</nobr></div>
  1512. <div style="position:absolute;top:35766;left:108"><nobr>in the upper left corner<a href="#1"></a><font style="font-size:8px"><a href="#1">5</a></font><a href="#1"></a>:</nobr></div>
  1513. </span></font>
  1514. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1515. <div style="position:absolute;top:35794;left:120"><nobr>import appuifw , e32 , key codes , graphics , random , os , audio</nobr></div>
  1516. <div style="position:absolute;top:35830;left:120"><nobr>def automask(im):</nobr></div>
  1517. <div style="position:absolute;top:35849;left:149"><nobr>width , height = im . s i z e</nobr></div>
  1518. <div style="position:absolute;top:35867;left:148"><nobr>mask = graphics.Image.new(im.size , ’1) <font color="#4c4c4c"># black and white</font></nobr></div>
  1519. </span></font>
  1520. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1521. <div style="position:absolute;top:35886;left:119"><nobr># Undocumented getpixel function :)</nobr></div>
  1522. </span></font>
  1523. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1524. <div style="position:absolute;top:35904;left:149"><nobr>tran = im.getpixel((0, 0))[0]</nobr></div>
  1525. </span></font>
  1526. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1527. <div style="position:absolute;top:35905;left:377"><nobr># transparent upper−left</nobr></div>
  1528. </span></font>
  1529. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1530. <div style="position:absolute;top:35923;left:149"><nobr>for y in range ( height ):</nobr></div>
  1531. <div style="position:absolute;top:35941;left:178"><nobr>l i n e = im . g e t p i x e l ( [ ( x , y ) for x in range ( width ) ] )</nobr></div>
  1532. <div style="position:absolute;top:35960;left:178"><nobr>for x in range ( width ):</nobr></div>
  1533. <div style="position:absolute;top:35978;left:207"><nobr>i f line[x] == tran:</nobr></div>
  1534. <div style="position:absolute;top:35997;left:234"><nobr>mask . point (( x , y ) , 0)</nobr></div>
  1535. </span></font>
  1536. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1537. <div style="position:absolute;top:35997;left:392"><nobr># mask on the point</nobr></div>
  1538. </span></font>
  1539. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1540. <div style="position:absolute;top:36015;left:149"><nobr>return mask</nobr></div>
  1541. </span></font>
  1542. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1543. <div style="position:absolute;top:36044;left:108"><nobr>Then we define global constants for colors, files etc.:</nobr></div>
  1544. </span></font>
  1545. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1546. <div style="position:absolute;top:36072;left:118"><nobr>WHITE = (255,255,255)</nobr></div>
  1547. <div style="position:absolute;top:36090;left:118"><nobr>RED = (255,0,0)</nobr></div>
  1548. <div style="position:absolute;top:36109;left:118"><nobr>BLUE = (0,0,255)</nobr></div>
  1549. <div style="position:absolute;top:36127;left:118"><nobr>YELLOW = (255,255,0)</nobr></div>
  1550. <div style="position:absolute;top:36146;left:118"><nobr>BLACK = (0, 0, 0)</nobr></div>
  1551. <div style="position:absolute;top:36164;left:118"><nobr>GRAY = (200, 200, 200)</nobr></div>
  1552. <div style="position:absolute;top:36201;left:118"><nobr>COVER = BLACK</nobr></div>
  1553. <div style="position:absolute;top:36220;left:118"><nobr>SEA = BLUE</nobr></div>
  1554. <div style="position:absolute;top:36238;left:118"><nobr>CURSOR = YELLOW</nobr></div>
  1555. <div style="position:absolute;top:36256;left:117"><nobr>BACKGROUND = BLACK</nobr></div>
  1556. <div style="position:absolute;top:36275;left:118"><nobr>BLAST = RED</nobr></div>
  1557. <div style="position:absolute;top:36293;left:118"><nobr>MESSAGE BG = GRAY</nobr></div>
  1558. <div style="position:absolute;top:36312;left:118"><nobr>MESSAGE FG = BLACK</nobr></div>
  1559. <div style="position:absolute;top:36349;left:118"><nobr>CURSOR OUTLINE WIDTH = 1</nobr></div>
  1560. <div style="position:absolute;top:36386;left:118"><nobr>PATH = u’C:\\ Data\\Images\\ ’</nobr></div>
  1561. <div style="position:absolute;top:36404;left:119"><nobr>SEAFILE = PATH+u’sea1.png</nobr></div>
  1562. <div style="position:absolute;top:36423;left:119"><nobr>BLASTFILE = PATH+u’exp00.png</nobr></div>
  1563. <div style="position:absolute;top:36441;left:118"><nobr>BANGFILE = PATH+u’bang1.wav</nobr></div>
  1564. <div style="position:absolute;top:36478;left:120"><nobr>SHIP SIZE = 3</nobr></div>
  1565. </span></font>
  1566. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1567. <div style="position:absolute;top:36507;left:108"><nobr>We use a separate class to encapsulate the game logic. It uses an image self.ui to implement the graphics</nobr></div>
  1568. <div style="position:absolute;top:36530;left:108"><nobr>actions. The image is copied to the canvas element of the appuifw framework when the redraw function</nobr></div>
  1569. </span></font>
  1570. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  1571. <div style="position:absolute;top:36555;left:124"><nobr>5<font style="font-size:9px">Thanks to Korakot Chaovavan<a href="http://snippets.dzone.com/tag/blit">ich, http://snippets.dzone.com/tag/blit.</a></font></nobr></div>
  1572. </span></font>
  1573.  
  1574. <div style="position:absolute;top:36773;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="31"><b>Page 31</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1575. <div style="position:absolute;top:36889;left:162"><nobr>3.6. Graphics</nobr></div>
  1576. <div style="position:absolute;top:36889;left:795"><nobr>25</nobr></div>
  1577. <div style="position:absolute;top:36958;left:162"><nobr>is called. The class is also taking care of the keyboard events. The first part is initializing the datastructures</nobr></div>
  1578. <div style="position:absolute;top:36981;left:162"><nobr>and variables:</nobr></div>
  1579. </span></font>
  1580. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1581. <div style="position:absolute;top:37007;left:175"><nobr>class BattleShip :</nobr></div>
  1582. <div style="position:absolute;top:37026;left:175"><nobr>’ ’ ’dx , dy : size of each grid cell in pixels .</nobr></div>
  1583. <div style="position:absolute;top:37044;left:175"><nobr>ui size : size of canvas</nobr></div>
  1584. <div style="position:absolute;top:37063;left:172"><nobr>OBS: We assume the the grid size is divisible width the ui size</nobr></div>
  1585. <div style="position:absolute;top:37081;left:175"><nobr>’’’</nobr></div>
  1586. <div style="position:absolute;top:37100;left:203"><nobr>def</nobr></div>
  1587. <div style="position:absolute;top:37100;left:247"><nobr>i n i t</nobr></div>
  1588. <div style="position:absolute;top:37100;left:289"><nobr>( self , dx , dy , u i s i z e ) :</nobr></div>
  1589. <div style="position:absolute;top:37118;left:232"><nobr>self.dx = dx</nobr></div>
  1590. <div style="position:absolute;top:37137;left:232"><nobr>self.dy = dy</nobr></div>
  1591. <div style="position:absolute;top:37155;left:232"><nobr>s e l f .m = u i s i z e [ 0 ] / s e l f . dx</nobr></div>
  1592. <div style="position:absolute;top:37174;left:232"><nobr>s e l f . n = u i s i z e [ 1 ] / s e l f . dy</nobr></div>
  1593. </span></font>
  1594. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1595. <div style="position:absolute;top:37192;left:231"><nobr># Define top row as message pane</nobr></div>
  1596. </span></font>
  1597. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1598. <div style="position:absolute;top:37211;left:232"><nobr>self.message rect = (0, 0, self.dxself .m, 1self .dy)</nobr></div>
  1599. </span></font>
  1600. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1601. <div style="position:absolute;top:37229;left:231"><nobr># Define start point for message text</nobr></div>
  1602. <div style="position:absolute;top:37248;left:231"><nobr># TBD: This is a bit tricky , can be automated.</nobr></div>
  1603. </span></font>
  1604. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1605. <div style="position:absolute;top:37266;left:232"><nobr>self.message pos = (5, self.dy1)</nobr></div>
  1606. </span></font>
  1607. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1608. <div style="position:absolute;top:37285;left:231"><nobr># Keep track bombs used</nobr></div>
  1609. </span></font>
  1610. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1611. <div style="position:absolute;top:37303;left:232"><nobr>self.bombs = 0</nobr></div>
  1612. </span></font>
  1613. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1614. <div style="position:absolute;top:37321;left:231"><nobr># Remember if we have completed sinking the boat</nobr></div>
  1615. </span></font>
  1616. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1617. <div style="position:absolute;top:37340;left:232"><nobr>self.finished = False</nobr></div>
  1618. </span></font>
  1619. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1620. <div style="position:absolute;top:37358;left:231"><nobr># Vertical or horizontal ship</nobr></div>
  1621. </span></font>
  1622. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1623. <div style="position:absolute;top:37377;left:232"><nobr>r = random.randint(0,1)</nobr></div>
  1624. <div style="position:absolute;top:37395;left:232"><nobr>i f r == 0:</nobr></div>
  1625. <div style="position:absolute;top:37414;left:261"><nobr>self.ship vertical = True</nobr></div>
  1626. <div style="position:absolute;top:37432;left:232"><nobr>else :</nobr></div>
  1627. <div style="position:absolute;top:37451;left:261"><nobr>self.ship vertical = False</nobr></div>
  1628. </span></font>
  1629. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1630. <div style="position:absolute;top:37469;left:231"><nobr># Randomly position the ship on the canvas (not in the message area :)</nobr></div>
  1631. </span></font>
  1632. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1633. <div style="position:absolute;top:37487;left:232"><nobr>self.shiplocations = []</nobr></div>
  1634. <div style="position:absolute;top:37506;left:232"><nobr>i f self . ship vertical :</nobr></div>
  1635. <div style="position:absolute;top:37524;left:261"><nobr>i = random.randint(0, self.m1)</nobr></div>
  1636. <div style="position:absolute;top:37543;left:259"><nobr>x = i ∗ self .dx</nobr></div>
  1637. <div style="position:absolute;top:37561;left:261"><nobr>j = y = random.randint(1, self.n−SHIP SIZE )</nobr></div>
  1638. <div style="position:absolute;top:37580;left:259"><nobr>y = j ∗ self .dy</nobr></div>
  1639. <div style="position:absolute;top:37598;left:260"><nobr>for tmp in range(SHIP SIZE):</nobr></div>
  1640. <div style="position:absolute;top:37635;left:290"><nobr>self . shiplocations . append ((x, y))</nobr></div>
  1641. <div style="position:absolute;top:37654;left:288"><nobr>y += self.dy</nobr></div>
  1642. <div style="position:absolute;top:37672;left:289"><nobr>j += 1</nobr></div>
  1643. <div style="position:absolute;top:37690;left:232"><nobr>else :</nobr></div>
  1644. <div style="position:absolute;top:37709;left:261"><nobr>i = random.randint(0, self.m−SHIP SIZE )</nobr></div>
  1645. <div style="position:absolute;top:37727;left:259"><nobr>x = i ∗ self .dx</nobr></div>
  1646. <div style="position:absolute;top:37746;left:261"><nobr>j = random.randint(0, self.n1)</nobr></div>
  1647. <div style="position:absolute;top:37764;left:259"><nobr>y = j ∗ self .dy</nobr></div>
  1648. <div style="position:absolute;top:37783;left:260"><nobr>for tmp in range(SHIP SIZE):</nobr></div>
  1649. <div style="position:absolute;top:37801;left:290"><nobr>self . shiplocations . append ((x, y))</nobr></div>
  1650. <div style="position:absolute;top:37820;left:288"><nobr>x += self.dx</nobr></div>
  1651. </span></font>
  1652.  
  1653. <div style="position:absolute;top:38035;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="32"><b>Page 32</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1654. <div style="position:absolute;top:38151;left:108"><nobr>26</nobr></div>
  1655. <div style="position:absolute;top:38151;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1656. </span></font>
  1657. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1658. <div style="position:absolute;top:38222;left:235"><nobr>i += 1</nobr></div>
  1659. </span></font>
  1660. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1661. <div style="position:absolute;top:38240;left:177"><nobr># For recording hits:</nobr></div>
  1662. </span></font>
  1663. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1664. <div style="position:absolute;top:38259;left:178"><nobr>self.hitlocations = []</nobr></div>
  1665. </span></font>
  1666. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1667. <div style="position:absolute;top:38277;left:177"><nobr># Random start position</nobr></div>
  1668. </span></font>
  1669. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1670. <div style="position:absolute;top:38296;left:178"><nobr>i = random.randint(0, self.m1)</nobr></div>
  1671. <div style="position:absolute;top:38314;left:178"><nobr>j = random.randint(1, self.n1)</nobr></div>
  1672. <div style="position:absolute;top:38333;left:178"><nobr>self.curr pos = (i ∗ self .dx , j ∗ self .dy)</nobr></div>
  1673. </span></font>
  1674. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1675. <div style="position:absolute;top:38351;left:177"><nobr># Need to keep track of both current and next position</nobr></div>
  1676. </span></font>
  1677. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1678. <div style="position:absolute;top:38369;left:178"><nobr>self.next pos = ()</nobr></div>
  1679. </span></font>
  1680. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1681. <div style="position:absolute;top:38388;left:177"><nobr># Initialize the ui image used for double buffering ,</nobr></div>
  1682. <div style="position:absolute;top:38406;left:177"><nobr># set ui to cover the ship locations and the sea</nobr></div>
  1683. </span></font>
  1684. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1685. <div style="position:absolute;top:38425;left:178"><nobr>self.ui = graphics.Image.new(ui size)</nobr></div>
  1686. <div style="position:absolute;top:38443;left:178"><nobr>s e l f . u i . c l e a r (COVER)</nobr></div>
  1687. </span></font>
  1688. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1689. <div style="position:absolute;top:38462;left:177"><nobr># Generate the sea image, equal size as canvas</nobr></div>
  1690. <div style="position:absolute;top:38480;left:177"><nobr># If the seafile is not there , use a SEA colored background</nobr></div>
  1691. </span></font>
  1692. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1693. <div style="position:absolute;top:38498;left:178"><nobr>try :</nobr></div>
  1694. <div style="position:absolute;top:38517;left:207"><nobr>self.sea = graphics.Image.open(SEAFILE)</nobr></div>
  1695. <div style="position:absolute;top:38535;left:178"><nobr>except :</nobr></div>
  1696. <div style="position:absolute;top:38554;left:207"><nobr>self.sea = graphics.Image.new(self.ui.size)</nobr></div>
  1697. <div style="position:absolute;top:38572;left:207"><nobr>self . sea . clear (SEA)</nobr></div>
  1698. </span></font>
  1699. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1700. <div style="position:absolute;top:38591;left:177"><nobr># Generate the blast image, equal size as the grid cells</nobr></div>
  1701. <div style="position:absolute;top:38609;left:177"><nobr># If the blastfile is not there , use a BLAST colored cell</nobr></div>
  1702. </span></font>
  1703. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1704. <div style="position:absolute;top:38628;left:178"><nobr>try :</nobr></div>
  1705. <div style="position:absolute;top:38646;left:207"><nobr>blast = graphics.Image.open(BLASTFILE)</nobr></div>
  1706. </span></font>
  1707. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1708. <div style="position:absolute;top:38665;left:205"><nobr># Make mask for simulating transparency</nobr></div>
  1709. </span></font>
  1710. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1711. <div style="position:absolute;top:38683;left:206"><nobr>blastmask = automask(blast)</nobr></div>
  1712. </span></font>
  1713. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1714. <div style="position:absolute;top:38702;left:205"><nobr># Make mask for simulating transparency</nobr></div>
  1715. </span></font>
  1716. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1717. <div style="position:absolute;top:38720;left:207"><nobr>self.blast = blast.resize((self.dx, self.dy))</nobr></div>
  1718. <div style="position:absolute;top:38739;left:207"><nobr>self.blastmask = blastmask.resize((self.dx, self.dy))</nobr></div>
  1719. <div style="position:absolute;top:38757;left:178"><nobr>except :</nobr></div>
  1720. <div style="position:absolute;top:38775;left:207"><nobr>self.blast = graphics.Image.new((self.dx, self.dy))</nobr></div>
  1721. <div style="position:absolute;top:38794;left:207"><nobr>self . blast . clear (BLAST)</nobr></div>
  1722. <div style="position:absolute;top:38812;left:207"><nobr>self.blastmask = None</nobr></div>
  1723. </span></font>
  1724. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1725. <div style="position:absolute;top:38831;left:177"><nobr># Open BANG file , no fallback :(</nobr></div>
  1726. </span></font>
  1727. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1728. <div style="position:absolute;top:38849;left:178"><nobr>self.bang = audio.Sound.open(BANGFILE)</nobr></div>
  1729. </span></font>
  1730. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1731. <div style="position:absolute;top:38868;left:177"><nobr># Initialize an image to remember the erased part of the canvas</nobr></div>
  1732. <div style="position:absolute;top:38886;left:177"><nobr># Will be used when moving around and dropping bombs</nobr></div>
  1733. </span></font>
  1734. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1735. <div style="position:absolute;top:38905;left:178"><nobr>self.erased cell = graphics.Image.new((self.dx, self.dy))</nobr></div>
  1736. </span></font>
  1737. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1738. <div style="position:absolute;top:38923;left:177"><nobr># Start with copying current cell from the ui image</nobr></div>
  1739. </span></font>
  1740. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1741. <div style="position:absolute;top:38942;left:178"><nobr>self . erased cell . blit ( self .ui , source=self . curr pos)</nobr></div>
  1742. </span></font>
  1743. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1744. <div style="position:absolute;top:38960;left:177"><nobr># Draw cursor rectangle at current position</nobr></div>
  1745. </span></font>
  1746. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1747. <div style="position:absolute;top:38978;left:177"><nobr>pos = (self.curr pos[0], self.curr pos[1], \</nobr></div>
  1748. <div style="position:absolute;top:38997;left:229"><nobr>self . curr pos [0]+ self .dx, self . curr pos [1]+ self .dy)</nobr></div>
  1749. <div style="position:absolute;top:39015;left:178"><nobr>self . ui . rectangle (pos , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
  1750. </span></font>
  1751. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1752. <div style="position:absolute;top:39034;left:177"><nobr># Draw welcome message</nobr></div>
  1753. </span></font>
  1754. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1755. <div style="position:absolute;top:39052;left:178"><nobr>self .drawmessage(u’VELKOMMEN TIL SJ SLAG ’ , RED)</nobr></div>
  1756. </span></font>
  1757. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1758. <div style="position:absolute;top:39080;left:108"><nobr>Then, define utility functions and callback prodedures:</nobr></div>
  1759. </span></font>
  1760.  
  1761. <div style="position:absolute;top:39297;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="33"><b>Page 33</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1762. <div style="position:absolute;top:39413;left:162"><nobr>3.6. Graphics</nobr></div>
  1763. <div style="position:absolute;top:39413;left:795"><nobr>27</nobr></div>
  1764. </span></font>
  1765. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1766. <div style="position:absolute;top:39484;left:203"><nobr>def drawmessage( self , message , col ):</nobr></div>
  1767. <div style="position:absolute;top:39502;left:203"><nobr>’ ’ ’Draw message r e c t a n g e l with color col , the draw message t e x t ’ ’ ’</nobr></div>
  1768. <div style="position:absolute;top:39521;left:232"><nobr>self.ui.rectangle(self.message rect , fill = col)</nobr></div>
  1769. </span></font>
  1770. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1771. <div style="position:absolute;top:39539;left:231"><nobr># print message</nobr></div>
  1772. </span></font>
  1773. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1774. <div style="position:absolute;top:39558;left:232"><nobr>self . ui . text ( self . message pos , message)</nobr></div>
  1775. <div style="position:absolute;top:39594;left:203"><nobr>def move( self , pos ):</nobr></div>
  1776. <div style="position:absolute;top:39613;left:203"><nobr>’’’Move from current position to position pos’’’</nobr></div>
  1777. </span></font>
  1778. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1779. <div style="position:absolute;top:39632;left:231"><nobr># Copy the erased cell back to canvas (cover our traces)</nobr></div>
  1780. </span></font>
  1781. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1782. <div style="position:absolute;top:39650;left:232"><nobr>self . ui . blit ( self . erased cell , target=self . curr pos)</nobr></div>
  1783. </span></font>
  1784. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1785. <div style="position:absolute;top:39668;left:231"><nobr># Update next position</nobr></div>
  1786. </span></font>
  1787. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1788. <div style="position:absolute;top:39687;left:232"><nobr>self.next pos = pos</nobr></div>
  1789. </span></font>
  1790. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1791. <div style="position:absolute;top:39705;left:231"><nobr># Store content of next cell in erased cell</nobr></div>
  1792. </span></font>
  1793. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1794. <div style="position:absolute;top:39724;left:232"><nobr>self . erased cell . blit ( self .ui , source=self . next pos)</nobr></div>
  1795. </span></font>
  1796. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1797. <div style="position:absolute;top:39742;left:231"><nobr># Paint cursor rectangle in next position</nobr></div>
  1798. </span></font>
  1799. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1800. <div style="position:absolute;top:39761;left:232"><nobr>rect = (self.next pos[0], self.next pos[1], \</nobr></div>
  1801. <div style="position:absolute;top:39779;left:290"><nobr>self . next pos[0]+ self .dx, self . next pos[1]+ self .dy)</nobr></div>
  1802. <div style="position:absolute;top:39798;left:232"><nobr>self . ui . rectangle ( rect , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
  1803. </span></font>
  1804. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1805. <div style="position:absolute;top:39816;left:231"><nobr># Prepare for next move</nobr></div>
  1806. </span></font>
  1807. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1808. <div style="position:absolute;top:39834;left:232"><nobr>self.curr pos = self.next pos</nobr></div>
  1809. </span></font>
  1810. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1811. <div style="position:absolute;top:39871;left:202"><nobr># Define nvaigation functions to be used in key event callbacks</nobr></div>
  1812. <div style="position:absolute;top:39890;left:202"><nobr># We implement wrap−around navigation , going over the top brings us to the bottom etc .</nobr></div>
  1813. </span></font>
  1814. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1815. <div style="position:absolute;top:39927;left:203"><nobr>def up( self ):</nobr></div>
  1816. </span></font>
  1817. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1818. <div style="position:absolute;top:39945;left:202"><nobr># Do note move into messagepane</nobr></div>
  1819. </span></font>
  1820. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1821. <div style="position:absolute;top:39963;left:232"><nobr>i f self.curr pos[1] == 1self .dy:</nobr></div>
  1822. <div style="position:absolute;top:39982;left:259"><nobr>y = (self.n1)self .dy</nobr></div>
  1823. <div style="position:absolute;top:40000;left:232"><nobr>else :</nobr></div>
  1824. <div style="position:absolute;top:40019;left:259"><nobr>y = self.curr pos[1]self .dy</nobr></div>
  1825. <div style="position:absolute;top:40037;left:231"><nobr>new pos = (self.curr pos[0], y)</nobr></div>
  1826. <div style="position:absolute;top:40056;left:232"><nobr>self .move(new pos)</nobr></div>
  1827. <div style="position:absolute;top:40093;left:203"><nobr>def down( self ):</nobr></div>
  1828. <div style="position:absolute;top:40111;left:232"><nobr>i f self.curr pos[1] == (self.n1)self .dy:</nobr></div>
  1829. </span></font>
  1830. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1831. <div style="position:absolute;top:40130;left:231"><nobr># Do note move into messagepane</nobr></div>
  1832. </span></font>
  1833. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1834. <div style="position:absolute;top:40148;left:259"><nobr>y = 1self .dy</nobr></div>
  1835. <div style="position:absolute;top:40166;left:232"><nobr>else :</nobr></div>
  1836. <div style="position:absolute;top:40185;left:259"><nobr>y = self.curr pos[1]+self.dy</nobr></div>
  1837. <div style="position:absolute;top:40204;left:231"><nobr>new pos = (self.curr pos[0], y)</nobr></div>
  1838. <div style="position:absolute;top:40222;left:232"><nobr>self .move(new pos)</nobr></div>
  1839. <div style="position:absolute;top:40259;left:203"><nobr>def left ( self ):</nobr></div>
  1840. <div style="position:absolute;top:40277;left:232"><nobr>i f self.curr pos[0] == 0:</nobr></div>
  1841. <div style="position:absolute;top:40296;left:259"><nobr>x = (self.m1)self .dx</nobr></div>
  1842. <div style="position:absolute;top:40314;left:232"><nobr>else :</nobr></div>
  1843. <div style="position:absolute;top:40333;left:259"><nobr>x = self.curr pos[0]self .dx</nobr></div>
  1844. </span></font>
  1845.  
  1846. <div style="position:absolute;top:40559;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="34"><b>Page 34</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1847. <div style="position:absolute;top:40675;left:108"><nobr>28</nobr></div>
  1848. <div style="position:absolute;top:40675;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  1849. </span></font>
  1850. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1851. <div style="position:absolute;top:40746;left:177"><nobr>new pos = (x, self.curr pos[1])</nobr></div>
  1852. <div style="position:absolute;top:40764;left:178"><nobr>self .move(new pos)</nobr></div>
  1853. <div style="position:absolute;top:40801;left:149"><nobr>def right ( self ):</nobr></div>
  1854. <div style="position:absolute;top:40819;left:178"><nobr>i f self.curr pos[0] == (self.m1)self .dx:</nobr></div>
  1855. <div style="position:absolute;top:40838;left:205"><nobr>x = 0</nobr></div>
  1856. <div style="position:absolute;top:40856;left:178"><nobr>else :</nobr></div>
  1857. <div style="position:absolute;top:40875;left:205"><nobr>x = self.curr pos[0]+self.dx</nobr></div>
  1858. <div style="position:absolute;top:40893;left:177"><nobr>new pos = (x, self.curr pos[1])</nobr></div>
  1859. <div style="position:absolute;top:40912;left:178"><nobr>self .move(new pos)</nobr></div>
  1860. </span></font>
  1861. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1862. <div style="position:absolute;top:40946;left:108"><nobr>Further, we implement beahviour for hitting the “fire button”:</nobr></div>
  1863. </span></font>
  1864. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1865. <div style="position:absolute;top:40978;left:149"><nobr>def hit ( self ):</nobr></div>
  1866. <div style="position:absolute;top:40997;left:178"><nobr>self.bombs += 1</nobr></div>
  1867. <div style="position:absolute;top:41015;left:178"><nobr>cell pos = (self.curr pos[0], self.curr pos[1], self.curr pos[0]+self.dx,\</nobr></div>
  1868. <div style="position:absolute;top:41033;left:257"><nobr>self . curr pos [1]+ self .dy)</nobr></div>
  1869. </span></font>
  1870. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1871. <div style="position:absolute;top:41052;left:177"><nobr># Ship hit?</nobr></div>
  1872. </span></font>
  1873. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1874. <div style="position:absolute;top:41070;left:178"><nobr>i f self.curr pos in self . shiplocations :</nobr></div>
  1875. </span></font>
  1876. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1877. <div style="position:absolute;top:41089;left:205"><nobr># First copy the sea background to the cell</nobr></div>
  1878. </span></font>
  1879. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1880. <div style="position:absolute;top:41107;left:207"><nobr>self . ui . blit ( self .sea , target=cell pos , source=cell pos )</nobr></div>
  1881. </span></font>
  1882. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1883. <div style="position:absolute;top:41126;left:205"><nobr># Then, copy the ”transparent” blast image</nobr></div>
  1884. </span></font>
  1885. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1886. <div style="position:absolute;top:41144;left:207"><nobr>self . ui . blit ( self . blast , target=cell pos , mask=self . blastmask)</nobr></div>
  1887. </span></font>
  1888. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1889. <div style="position:absolute;top:41163;left:205"><nobr># Play bang sound : Must check i f i t ’ s s t i l l playing sound of previous h i t .</nobr></div>
  1890. <div style="position:absolute;top:41181;left:205"><nobr># If so , stop it .</nobr></div>
  1891. <div style="position:absolute;top:41200;left:205"><nobr># Remember : Only one speaker , t r y i n g to do overlapping replays r a i s e s error</nobr></div>
  1892. </span></font>
  1893. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1894. <div style="position:absolute;top:41218;left:207"><nobr>i f self.bang.state() == audio.EPlaying:</nobr></div>
  1895. <div style="position:absolute;top:41237;left:236"><nobr>self . bang . stop ()</nobr></div>
  1896. <div style="position:absolute;top:41255;left:207"><nobr>self . bang . play ()</nobr></div>
  1897. </span></font>
  1898. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1899. <div style="position:absolute;top:41274;left:205"><nobr># Mark hit by removing the location , and append to hit locations list</nobr></div>
  1900. </span></font>
  1901. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1902. <div style="position:absolute;top:41292;left:207"><nobr>self . shiplocations .remove( self . curr pos )</nobr></div>
  1903. <div style="position:absolute;top:41310;left:207"><nobr>self . hitlocations .append( self . curr pos )</nobr></div>
  1904. </span></font>
  1905. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1906. <div style="position:absolute;top:41329;left:205"><nobr># Update message pan</nobr></div>
  1907. </span></font>
  1908. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1909. <div style="position:absolute;top:41347;left:207"><nobr>s e l f . drawmessage ( u ’ Antall bomber : ’+unicode ( s e l f . bombs)+u ’ , \</nobr></div>
  1910. <div style="position:absolute;top:41366;left:236"><nobr>antall treff : ’+unicode(len( self . hitlocations )) , GRAY)</nobr></div>
  1911. </span></font>
  1912. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1913. <div style="position:absolute;top:41384;left:205"><nobr># Are we done?</nobr></div>
  1914. </span></font>
  1915. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1916. <div style="position:absolute;top:41402;left:207"><nobr>i f len(self.shiplocations) == 0:</nobr></div>
  1917. <div style="position:absolute;top:41421;left:236"><nobr>if not self . finished :</nobr></div>
  1918. </span></font>
  1919. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1920. <div style="position:absolute;top:41440;left:263"><nobr># Compute score and update message pane</nobr></div>
  1921. </span></font>
  1922. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1923. <div style="position:absolute;top:41458;left:264"><nobr>score = ((SHIP SIZE ∗ 1.0)/( self .bombs1.0))100.0</nobr></div>
  1924. <div style="position:absolute;top:41476;left:264"><nobr>self . drawmessage (u ’ Gratulerer ! Score : ’+unicode ( score )+ ’%’ , GRAY)</nobr></div>
  1925. <div style="position:absolute;top:41495;left:264"><nobr>self.finished = True</nobr></div>
  1926. </span></font>
  1927. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1928. <div style="position:absolute;top:41513;left:177"><nobr># CHECK : U n n e s c e s s a r y ?</nobr></div>
  1929. </span></font>
  1930. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1931. <div style="position:absolute;top:41532;left:179"><nobr>elif self.curr pos in self . hitlocations :</nobr></div>
  1932. <div style="position:absolute;top:41550;left:207"><nobr>self . ui . blit ( self . blast , target=cell pos )</nobr></div>
  1933. </span></font>
  1934. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1935. <div style="position:absolute;top:41569;left:177"><nobr># If no hit ,just paint the sea</nobr></div>
  1936. </span></font>
  1937. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1938. <div style="position:absolute;top:41587;left:178"><nobr>else :</nobr></div>
  1939. <div style="position:absolute;top:41606;left:207"><nobr>self . ui . blit ( self .sea , target=cell pos , source=cell pos )</nobr></div>
  1940. </span></font>
  1941.  
  1942. <div style="position:absolute;top:41821;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="35"><b>Page 35</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1943. <div style="position:absolute;top:41937;left:162"><nobr>3.6. Graphics</nobr></div>
  1944. <div style="position:absolute;top:41937;left:795"><nobr>29</nobr></div>
  1945. </span></font>
  1946. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1947. <div style="position:absolute;top:42026;left:231"><nobr># Remember the current content , and repaint the cursor rectangle ,</nobr></div>
  1948. <div style="position:absolute;top:42045;left:231"><nobr># then we are ready for next move</nobr></div>
  1949. </span></font>
  1950. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1951. <div style="position:absolute;top:42063;left:232"><nobr>self . erased cell . blit ( self .ui , source=self . curr pos)</nobr></div>
  1952. <div style="position:absolute;top:42082;left:232"><nobr>rect = (self.next pos[0], self.next pos[1], \</nobr></div>
  1953. <div style="position:absolute;top:42100;left:290"><nobr>self . next pos[0]+ self .dx, self . next pos[1]+ self .dy)</nobr></div>
  1954. <div style="position:absolute;top:42119;left:232"><nobr>self . ui . rectangle ( rect , outline = CURSOR, width = CURSOR OUTLINE WIDTH)</nobr></div>
  1955. </span></font>
  1956. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  1957. <div style="position:absolute;top:42148;left:162"><nobr>Now the Battleship class is ready, and we continue with implementing the application. We start with the</nobr></div>
  1958. <div style="position:absolute;top:42171;left:162"><nobr>callback functions.</nobr></div>
  1959. </span></font>
  1960. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1961. <div style="position:absolute;top:42200;left:174"><nobr>def handle redraw(rect ):</nobr></div>
  1962. <div style="position:absolute;top:42219;left:175"><nobr>’ ’ ’ Callback for the appuifw canvas object .</nobr></div>
  1963. <div style="position:absolute;top:42237;left:174"><nobr>Will be used each time the canvas needs to be updated’’’</nobr></div>
  1964. </span></font>
  1965. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1966. <div style="position:absolute;top:42256;left:202"><nobr># Could be called before the canvas image has been i n i t i a l i z e d .</nobr></div>
  1967. <div style="position:absolute;top:42274;left:202"><nobr># Otherwise , just copy ui to the canvas object</nobr></div>
  1968. </span></font>
  1969. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1970. <div style="position:absolute;top:42292;left:204"><nobr>i f ui :</nobr></div>
  1971. <div style="position:absolute;top:42311;left:231"><nobr>canvas . blit ( ui )</nobr></div>
  1972. <div style="position:absolute;top:42348;left:174"><nobr>def handle event(event):</nobr></div>
  1973. <div style="position:absolute;top:42366;left:175"><nobr>’ ’ ’ Callback for the appuifw canvas object : Handles key events ’ ’ ’</nobr></div>
  1974. </span></font>
  1975. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  1976. <div style="position:absolute;top:42385;left:202"><nobr># Could be called before the b a t t l e s h i p object has been i n i t i a l i z e d .</nobr></div>
  1977. <div style="position:absolute;top:42403;left:202"><nobr># Otherwise , bind key events to the navigation f u n c t i o n s in b a t t l e s h i p</nobr></div>
  1978. </span></font>
  1979. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  1980. <div style="position:absolute;top:42422;left:204"><nobr>if not battleship :</nobr></div>
  1981. <div style="position:absolute;top:42440;left:231"><nobr>return</nobr></div>
  1982. <div style="position:absolute;top:42459;left:202"><nobr>ev = event[’keycode’]</nobr></div>
  1983. <div style="position:absolute;top:42477;left:204"><nobr>i f ev == key codes.EKeyUpArrow:</nobr></div>
  1984. <div style="position:absolute;top:42495;left:232"><nobr>battleship .up()</nobr></div>
  1985. <div style="position:absolute;top:42514;left:204"><nobr>elif ev == key codes.EKeyRightArrow:</nobr></div>
  1986. <div style="position:absolute;top:42532;left:232"><nobr>battleship . right ()</nobr></div>
  1987. <div style="position:absolute;top:42551;left:204"><nobr>elif ev == key codes.EKeyDownArrow:</nobr></div>
  1988. <div style="position:absolute;top:42569;left:232"><nobr>b a t t l e s h i p . down ( )</nobr></div>
  1989. <div style="position:absolute;top:42588;left:204"><nobr>elif ev == key codes.EKeyLeftArrow:</nobr></div>
  1990. <div style="position:absolute;top:42606;left:232"><nobr>battleship . left ()</nobr></div>
  1991. <div style="position:absolute;top:42625;left:204"><nobr>elif ev == key codes.EKeySelect:</nobr></div>
  1992. <div style="position:absolute;top:42643;left:232"><nobr>battleship . hit ()</nobr></div>
  1993. <div style="position:absolute;top:42662;left:203"><nobr>handle redraw(None)</nobr></div>
  1994. <div style="position:absolute;top:42698;left:174"><nobr>def quit ():</nobr></div>
  1995. <div style="position:absolute;top:42717;left:175"><nobr>’’’To be assigned the exit key handler , closes sound file and gives signal</nobr></div>
  1996. <div style="position:absolute;top:42735;left:204"><nobr>if battleship :</nobr></div>
  1997. <div style="position:absolute;top:42754;left:232"><nobr>battleship . bang . close ()</nobr></div>
  1998. <div style="position:absolute;top:42772;left:203"><nobr>app lock . signal ()</nobr></div>
  1999. </span></font>
  2000. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2001. <div style="position:absolute;top:42802;left:162"><nobr>The last thing to do is to kick off the application framework:</nobr></div>
  2002. </span></font>
  2003. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2004. <div style="position:absolute;top:42831;left:174"><nobr>ui = None</nobr></div>
  2005. <div style="position:absolute;top:42849;left:175"><nobr>battleship = None</nobr></div>
  2006. </span></font>
  2007. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2008. <div style="position:absolute;top:42868;left:173"><nobr># Initialize canvas and bind callback functions</nobr></div>
  2009. </span></font>
  2010.  
  2011. <div style="position:absolute;top:43083;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="36"><b>Page 36</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2012. <div style="position:absolute;top:43199;left:108"><nobr>30</nobr></div>
  2013. <div style="position:absolute;top:43199;left:459"><nobr>Chapter 3. Applications, user interfaces, daemons</nobr></div>
  2014. </span></font>
  2015. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2016. <div style="position:absolute;top:43270;left:120"><nobr>canvas = appuifw.Canvas(\</nobr></div>
  2017. <div style="position:absolute;top:43288;left:250"><nobr>redraw callback = handle redraw ,\</nobr></div>
  2018. <div style="position:absolute;top:43307;left:250"><nobr>event callback = handle event)</nobr></div>
  2019. <div style="position:absolute;top:43325;left:120"><nobr>appuifw.app.body = canvas</nobr></div>
  2020. </span></font>
  2021. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2022. <div style="position:absolute;top:43344;left:119"><nobr># We want a full screen app</nobr></div>
  2023. </span></font>
  2024. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2025. <div style="position:absolute;top:43362;left:120"><nobr>appuifw . app . screen = ’ f u l l ’</nobr></div>
  2026. </span></font>
  2027. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2028. <div style="position:absolute;top:43381;left:119"><nobr># Bind the quit function</nobr></div>
  2029. </span></font>
  2030. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2031. <div style="position:absolute;top:43399;left:120"><nobr>appuifw.app.exit key handler = quit</nobr></div>
  2032. </span></font>
  2033. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2034. <div style="position:absolute;top:43418;left:119"><nobr># CHECK!</nobr></div>
  2035. </span></font>
  2036. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2037. <div style="position:absolute;top:43436;left:120"><nobr>handle redraw(None)</nobr></div>
  2038. </span></font>
  2039. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2040. <div style="position:absolute;top:43454;left:119"><nobr># Initialize the game logic class</nobr></div>
  2041. </span></font>
  2042. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2043. <div style="position:absolute;top:43473;left:121"><nobr>battleship = BattleShip(20, 20, canvas.size)</nobr></div>
  2044. </span></font>
  2045. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2046. <div style="position:absolute;top:43491;left:119"><nobr># Make the ui image accessible to the application thread</nobr></div>
  2047. </span></font>
  2048. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2049. <div style="position:absolute;top:43510;left:120"><nobr>ui = battleship.ui</nobr></div>
  2050. </span></font>
  2051. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2052. <div style="position:absolute;top:43528;left:119"><nobr># CHECK!</nobr></div>
  2053. </span></font>
  2054. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2055. <div style="position:absolute;top:43547;left:120"><nobr>handle redraw(None)</nobr></div>
  2056. </span></font>
  2057. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2058. <div style="position:absolute;top:43565;left:119"><nobr># Wait for the shut down signal</nobr></div>
  2059. </span></font>
  2060. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2061. <div style="position:absolute;top:43584;left:120"><nobr>app lock = e32.Ao lock()</nobr></div>
  2062. <div style="position:absolute;top:43602;left:120"><nobr>app lock . wait ()</nobr></div>
  2063. </span></font>
  2064. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2065. <div style="position:absolute;top:43621;left:119"><nobr>#That ’s it !</nobr></div>
  2066. </span></font>
  2067. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2068. <div style="position:absolute;top:43651;left:130"><nobr>So, play away!</nobr></div>
  2069. </span></font>
  2070.  
  2071. <div style="position:absolute;top:44345;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="37"><b>Page 37</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  2072. <div style="position:absolute;top:44643;left:162"><nobr>Chapter 4</nobr></div>
  2073. </span></font>
  2074. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  2075. <div style="position:absolute;top:44728;left:162"><nobr>Networking</nobr></div>
  2076. </span></font>
  2077. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2078. <div style="position:absolute;top:44828;left:162"><nobr>TBD: HTTP, client server</nobr></div>
  2079. </span></font>
  2080. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  2081. <div style="position:absolute;top:44887;left:162"><nobr>4.1 Bluetooth</nobr></div>
  2082. </span></font>
  2083. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2084. <div style="position:absolute;top:44933;left:162"><nobr>Most (all?) S60 devices may communicate by bluetooth, a short range (typically ¡ 10m) wireless protocol</nobr></div>
  2085. <div style="position:absolute;top:44956;left:162"><nobr>The PyS60 API offers a dedicated socket implementation. Typically, bluetooth devices advert their services,</nobr></div>
  2086. <div style="position:absolute;top:44980;left:162"><nobr>and other devices must discover such devices, and then connect to them, optionally using a shared passkey</nobr></div>
  2087. <div style="position:absolute;top:45003;left:162"><nobr>the devices agree upon. The discovery and connection process implemented in PyS60 requires the user to</nobr></div>
  2088. <div style="position:absolute;top:45026;left:162"><nobr>manually search, select and connect to a device. If you want this process to run silently in the background</nobr></div>
  2089. <div style="position:absolute;top:45050;left:162"><nobr>with no user interaction, you need to use the native API and build your own extension<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>.</nobr></div>
  2090. <div style="position:absolute;top:45074;left:184"><nobr>The bluetooth mechanics are well documented in the standard PyS60 sources, see Section <a href="#42">6.</a></nobr></div>
  2091. </span></font>
  2092. <font size="3" face="Times"><span style="font-size:15px;font-family:Times">
  2093. <div style="position:absolute;top:45127;left:162"><nobr>4.1.1 External GPS</nobr></div>
  2094. </span></font>
  2095. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2096. <div style="position:absolute;top:45165;left:162"><nobr>Communication with an external GPS device (over bluetooth) involves parsing the NMEA formatted ASCII</nobr></div>
  2097. <div style="position:absolute;top:45188;left:162"><nobr>stream from the GPS. NMEA 0183 is a standard from the US based National Marine Electronics Associa-</nobr></div>
  2098. <div style="position:absolute;top:45211;left:162"><nobr>tion. You may download<a href="#1"></a><font style="font-size:8px"><a href="#1">2 </a></font>it for USD 270, or rely on a reversed engineered version, for instance from Dale</nobr></div>
  2099. <div style="position:absolute;top:45235;left:162"><nobr>DePriest<a href="#1"></a><font style="font-size:8px"><a href="#1">3</a></font><a href="#1"></a>, which is the source for the following information.</nobr></div>
  2100. <div style="position:absolute;top:45259;left:184"><nobr>An NMEA device is transmitting a stream of NMEA sentences, all starting with a dollar sign and two</nobr></div>
  2101. <div style="position:absolute;top:45282;left:162"><nobr>characters identifying the “talker”, which in the GPS case is “$GP”. Each sentence is terminated with a</nobr></div>
  2102. <div style="position:absolute;top:45306;left:162"><nobr>checksum starting with “*and followed by two hex digits. The checksum represents an 8 bit exclusive OR</nobr></div>
  2103. <div style="position:absolute;top:45329;left:162"><nobr>of all characters between, but not including, the “$” and*”. The tokens of the sentences are separated by</nobr></div>
  2104. </span></font>
  2105. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2106. <div style="position:absolute;top:45360;left:178"><nobr>1<font style="font-size:9px">Check<a href="http://www.mobilenin.com/pys60/info_bluetooth.htm"> http://www.mobilenin.com/pys60/info_bluetooth.htm if you need</a> non-interactive bluetooth functionality</font></nobr></div>
  2107. <div style="position:absolute;top:45375;left:178"><nobr>2<a href="http://www.nmea.org/pub/0183/"></a><font style="font-size:9px"><a href="http://www.nmea.org/pub/0183/">http://www.nmea.org/pub/0183/</a></font></nobr></div>
  2108. <div style="position:absolute;top:45389;left:178"><nobr>3<a href="http://www.gpsinformation.org/dale/nmea.htm"></a><font style="font-size:9px"><a href="http://www.gpsinformation.org/dale/nmea.htm">http://www.gpsinformation.org/dale/nmea.htm</a></font></nobr></div>
  2109. </span></font>
  2110. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2111. <div style="position:absolute;top:45434;left:478"><nobr>31</nobr></div>
  2112. </span></font>
  2113.  
  2114. <div style="position:absolute;top:45607;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="38"><b>Page 38</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2115. <div style="position:absolute;top:45723;left:108"><nobr>32</nobr></div>
  2116. <div style="position:absolute;top:45723;left:619"><nobr>Chapter 4. Networking</nobr></div>
  2117. <div style="position:absolute;top:45792;left:108"><nobr>commas<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>. A typical NMEA sentence may looks like this:</nobr></div>
  2118. </span></font>
  2119. <font size="3" face="Times"><span style="font-size:11px;font-family:Times">
  2120. <div style="position:absolute;top:45832;left:168"><nobr>$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A</nobr></div>
  2121. </span></font>
  2122. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2123. <div style="position:absolute;top:45868;left:108"><nobr>However:</nobr></div>
  2124. <div style="position:absolute;top:45906;left:168"><nobr>There is no way to indicate anything back to the unit as to whether the sentence is being</nobr></div>
  2125. <div style="position:absolute;top:45929;left:145"><nobr>read correctly or to request a re-send of some data you didn’t get. Instead the receiving unit just</nobr></div>
  2126. <div style="position:absolute;top:45953;left:145"><nobr>checks the checksum and ignores the data if the checksum is bad figuring the data will be sent</nobr></div>
  2127. <div style="position:absolute;top:45976;left:145"><nobr>again sometime later.</nobr></div>
  2128. <div style="position:absolute;top:46014;left:108"><nobr>Each sentence type is identify by three letters following directly after the prefix, in the case above, “RMC”,</nobr></div>
  2129. <div style="position:absolute;top:46037;left:108"><nobr>standing for “Recommended Minimum sentence C”. Hence, a useful parsing algorithm is as follows:</nobr></div>
  2130. <div style="position:absolute;top:46060;left:130"><nobr>• Read one line (terminated by CR/LF) at the time</nobr></div>
  2131. <div style="position:absolute;top:46083;left:130"><nobr>• If the sentence starts with “$GP” and ends with a checksum:</nobr></div>
  2132. <div style="position:absolute;top:46108;left:163"><nobr>– Compute and verify the checksum, and if it’s OK:</nobr></div>
  2133. <div style="position:absolute;top:46130;left:191"><nobr>∗ Identify the sentence type</nobr></div>
  2134. <div style="position:absolute;top:46153;left:191"><nobr>∗ Extract and interpret the tokens according to the NMEA specification</nobr></div>
  2135. <div style="position:absolute;top:46178;left:130"><nobr>Let’s check what sentences our GPS<a href="#1"></a><font style="font-size:8px"><a href="#1">5 </a></font>produces:</nobr></div>
  2136. </span></font>
  2137. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2138. <div style="position:absolute;top:46209;left:120"><nobr>import socket</nobr></div>
  2139. </span></font>
  2140. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2141. <div style="position:absolute;top:46246;left:119"><nobr># Find a bluetooth GPS</nobr></div>
  2142. </span></font>
  2143. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2144. <div style="position:absolute;top:46265;left:120"><nobr>address , s e r v i c e s = socket . b t d i s c o v e r ( )</nobr></div>
  2145. <div style="position:absolute;top:46283;left:120"><nobr>print ”Discovered: %s, %s” % (address , services)</nobr></div>
  2146. <div style="position:absolute;top:46302;left:121"><nobr>t a r g e t = ( address , s e r v i c e s . values ( ) [ 0 ] )</nobr></div>
  2147. </span></font>
  2148. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2149. <div style="position:absolute;top:46339;left:119"><nobr>#Connect</nobr></div>
  2150. </span></font>
  2151. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2152. <div style="position:absolute;top:46357;left:120"><nobr>conn = socket . socket ( socket .AF BT, socket .SOCK STREAM)</nobr></div>
  2153. <div style="position:absolute;top:46376;left:120"><nobr>conn . connect ( target )</nobr></div>
  2154. <div style="position:absolute;top:46394;left:120"><nobr>gps = conn.makefile(”r”, 0)</nobr></div>
  2155. <div style="position:absolute;top:46431;left:120"><nobr>while True :</nobr></div>
  2156. </span></font>
  2157. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2158. <div style="position:absolute;top:46449;left:148"><nobr># Get sentence , strip of CR/NL or other whitespace</nobr></div>
  2159. </span></font>
  2160. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2161. <div style="position:absolute;top:46468;left:149"><nobr>sentence = gps . r e a d l i n e ( ) . s t r i p ( )</nobr></div>
  2162. <div style="position:absolute;top:46486;left:150"><nobr>i f sentence[0:3] == ’$GP’ and sentence[3] == ’∗ ’ :</nobr></div>
  2163. <div style="position:absolute;top:46505;left:178"><nobr>print sentence [3:6]</nobr></div>
  2164. </span></font>
  2165. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2166. <div style="position:absolute;top:46537;left:130"><nobr>Our device speaks the following sentences: RMC: Recommended Minimum sentence C, GGA: Global</nobr></div>
  2167. <div style="position:absolute;top:46561;left:108"><nobr>Positioning System Fix Data, GSV: Satellites in view, GSA: Satellite status, and VTG: Track made good and</nobr></div>
  2168. <div style="position:absolute;top:46584;left:108"><nobr>ground speed.</nobr></div>
  2169. <div style="position:absolute;top:46608;left:130"><nobr>RMC is one of the most used sentences, and is structured as follows:</nobr></div>
  2170. </span></font>
  2171. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2172. <div style="position:absolute;top:46637;left:124"><nobr>4<font style="font-size:9px">Note that prefix “$GP” and the checksum suffix are not comma separated</font></nobr></div>
  2173. <div style="position:absolute;top:46651;left:124"><nobr>5<font style="font-size:9px">In this case a HOLUX GPSlim 240</font></nobr></div>
  2174. </span></font>
  2175.  
  2176. <div style="position:absolute;top:46869;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="39"><b>Page 39</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2177. <div style="position:absolute;top:46985;left:162"><nobr>4.1. Bluetooth</nobr></div>
  2178. <div style="position:absolute;top:46985;left:795"><nobr>33</nobr></div>
  2179. </span></font>
  2180. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2181. <div style="position:absolute;top:47056;left:207"><nobr>RMC</nobr></div>
  2182. <div style="position:absolute;top:47056;left:302"><nobr>Recommended Minimum sentence C</nobr></div>
  2183. <div style="position:absolute;top:47074;left:209"><nobr>123519</nobr></div>
  2184. <div style="position:absolute;top:47074;left:303"><nobr>Fix taken at 12:35:19 UTC</nobr></div>
  2185. <div style="position:absolute;top:47093;left:208"><nobr>A</nobr></div>
  2186. <div style="position:absolute;top:47093;left:304"><nobr>Status A=active or V=Void .</nobr></div>
  2187. <div style="position:absolute;top:47111;left:210"><nobr>4807.038,N</nobr></div>
  2188. <div style="position:absolute;top:47111;left:304"><nobr>Latitude 48 deg 07.038’ N</nobr></div>
  2189. <div style="position:absolute;top:47130;left:210"><nobr>01131.000,E</nobr></div>
  2190. <div style="position:absolute;top:47130;left:303"><nobr>Longitude 11 deg 31.000’ E</nobr></div>
  2191. <div style="position:absolute;top:47148;left:210"><nobr>022.4</nobr></div>
  2192. <div style="position:absolute;top:47148;left:303"><nobr>Speed over the ground in knots</nobr></div>
  2193. <div style="position:absolute;top:47167;left:210"><nobr>084.4</nobr></div>
  2194. <div style="position:absolute;top:47167;left:303"><nobr>Track angle in degrees True</nobr></div>
  2195. <div style="position:absolute;top:47185;left:209"><nobr>230394</nobr></div>
  2196. <div style="position:absolute;top:47185;left:303"><nobr>Date − 23rd of March 1994</nobr></div>
  2197. <div style="position:absolute;top:47203;left:210"><nobr>003.1 ,W</nobr></div>
  2198. <div style="position:absolute;top:47203;left:303"><nobr>Magnetic Variation</nobr></div>
  2199. <div style="position:absolute;top:47221;left:209"><nobr>∗6A</nobr></div>
  2200. <div style="position:absolute;top:47222;left:302"><nobr>The checksum data , always begins with ∗</nobr></div>
  2201. </span></font>
  2202. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2203. <div style="position:absolute;top:47252;left:162"><nobr>For instance, the latitude is the fourth token, and the longitude is the sixth:</nobr></div>
  2204. </span></font>
  2205. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2206. <div style="position:absolute;top:47282;left:174"><nobr>def parse RMC sentence(sentence body):</nobr></div>
  2207. <div style="position:absolute;top:47301;left:203"><nobr>tokens = sentence body . s p l i t ( ” , ” )</nobr></div>
  2208. <div style="position:absolute;top:47319;left:204"><nobr>lat= tokens[3]</nobr></div>
  2209. <div style="position:absolute;top:47338;left:203"><nobr>lon = tokens[5]</nobr></div>
  2210. <div style="position:absolute;top:47356;left:202"><nobr>e w = tokens[6]</nobr></div>
  2211. <div style="position:absolute;top:47374;left:203"><nobr>return [lat , lon]</nobr></div>
  2212. </span></font>
  2213. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2214. <div style="position:absolute;top:47405;left:162"><nobr>Note that the geographic coordinates are a bit oddly formatted, the most common format (in digital applica-</nobr></div>
  2215. <div style="position:absolute;top:47428;left:162"><nobr>tions), is decimal degrees. The following snippet will do the trick:</nobr></div>
  2216. </span></font>
  2217. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2218. <div style="position:absolute;top:47458;left:174"><nobr>def format latlong dec(coord):</nobr></div>
  2219. </span></font>
  2220. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2221. <div style="position:absolute;top:47477;left:202"><nobr># Based on nmea info.py v0.27,</nobr></div>
  2222. <div style="position:absolute;top:47477;left:432"><nobr>Nick Burch (03/12/2007)</nobr></div>
  2223. <div style="position:absolute;top:47495;left:202"><nobr># Turn DDMM.nnnn into DD.ddddd</nobr></div>
  2224. <div style="position:absolute;top:47514;left:202"><nobr># 1 degree = 60 minutes</nobr></div>
  2225. </span></font>
  2226. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2227. <div style="position:absolute;top:47550;left:204"><nobr>i f coord[5:6] == ’.’:</nobr></div>
  2228. <div style="position:absolute;top:47569;left:232"><nobr>degrees = float(coord[0:3])</nobr></div>
  2229. <div style="position:absolute;top:47587;left:232"><nobr>minutes = float(coord[3:])</nobr></div>
  2230. <div style="position:absolute;top:47606;left:204"><nobr>elif coord[3:4] == ’.’:</nobr></div>
  2231. <div style="position:absolute;top:47624;left:232"><nobr>degrees = float(coord[0:1])</nobr></div>
  2232. <div style="position:absolute;top:47643;left:232"><nobr>minutes = float(coord[1:])</nobr></div>
  2233. <div style="position:absolute;top:47661;left:203"><nobr>else :</nobr></div>
  2234. <div style="position:absolute;top:47680;left:232"><nobr>degrees = float(coord[0:2])</nobr></div>
  2235. <div style="position:absolute;top:47698;left:232"><nobr>minutes = float(coord[2:])</nobr></div>
  2236. </span></font>
  2237. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2238. <div style="position:absolute;top:47717;left:202"><nobr># Minutes must be converted to decimal fraction of a degree</nobr></div>
  2239. </span></font>
  2240. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2241. <div style="position:absolute;top:47735;left:203"><nobr>decimals = minutes / 60.0</nobr></div>
  2242. <div style="position:absolute;top:47753;left:203"><nobr>return degrees + decimals</nobr></div>
  2243. </span></font>
  2244. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2245. <div style="position:absolute;top:47784;left:162"><nobr>This works OK in the N/E global quadrant. If you are below equator or west of the Greenwich meridian, use</nobr></div>
  2246. <div style="position:absolute;top:47807;left:162"><nobr>the additional N/S and E/W information to set the proper sign on the coordinate values. And here is how to</nobr></div>
  2247. <div style="position:absolute;top:47831;left:162"><nobr>compute the checksum if you want to make your app as robust as possible:</nobr></div>
  2248. </span></font>
  2249. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2250. <div style="position:absolute;top:47860;left:174"><nobr>def generate checksum(data):</nobr></div>
  2251. <div style="position:absolute;top:47879;left:231"><nobr>”””Generate the NMEA checksum for the supplied data”””</nobr></div>
  2252. <div style="position:absolute;top:47897;left:231"><nobr>”””From Nick Burch − nmea info.py v0.27 (03/12/2007) ”””</nobr></div>
  2253. </span></font>
  2254.  
  2255. <div style="position:absolute;top:48131;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="40"><b>Page 40</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2256. <div style="position:absolute;top:48247;left:108"><nobr>34</nobr></div>
  2257. <div style="position:absolute;top:48247;left:619"><nobr>Chapter 4. Networking</nobr></div>
  2258. </span></font>
  2259. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2260. <div style="position:absolute;top:48318;left:177"><nobr>csum = 0</nobr></div>
  2261. <div style="position:absolute;top:48336;left:178"><nobr>for c in data :</nobr></div>
  2262. <div style="position:absolute;top:48355;left:234"><nobr>csum = csum ˆ ord(c)</nobr></div>
  2263. <div style="position:absolute;top:48373;left:177"><nobr>hex csum = ”%02x” % csum</nobr></div>
  2264. <div style="position:absolute;top:48391;left:177"><nobr>return hex csum . upper ()</nobr></div>
  2265. </span></font>
  2266. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2267. <div style="position:absolute;top:48422;left:108"><nobr>The accuracy of a standard GPS vary quite a bit, but is typically in the range 3-10 meters. You may perhaps</nobr></div>
  2268. <div style="position:absolute;top:48445;left:108"><nobr>want to filter out minor variations, and one way to do this is to update the position only when the distance to</nobr></div>
  2269. <div style="position:absolute;top:48468;left:108"><nobr>the previous position is larger than a given threshold. Since the geographic grid is highly non-uniform, you</nobr></div>
  2270. <div style="position:absolute;top:48492;left:108"><nobr>need a special formulae to compute these distances<a href="#1"></a><font style="font-size:8px"><a href="#1">6</a></font></nobr></div>
  2271. </span></font>
  2272. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2273. <div style="position:absolute;top:48521;left:120"><nobr>import math</nobr></div>
  2274. </span></font>
  2275. <font size="2" color="#4c4c4c" face="Times"><span style="font-size:9px;font-family:Times;color:#4c4c4c">
  2276. <div style="position:absolute;top:48558;left:119"><nobr># radians and degrees are omitted from the pys60 math distribution</nobr></div>
  2277. </span></font>
  2278. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2279. <div style="position:absolute;top:48576;left:120"><nobr>def radians ( degrees ):</nobr></div>
  2280. <div style="position:absolute;top:48595;left:149"><nobr>return ( math . pi ∗ degrees ) / 180.0</nobr></div>
  2281. <div style="position:absolute;top:48632;left:120"><nobr>def distance ( lat1 , lon1 , lat2 , lon2 ):</nobr></div>
  2282. <div style="position:absolute;top:48650;left:177"><nobr>”””Computes the geodesic distance , in meters ,</nobr></div>
  2283. <div style="position:absolute;top:48669;left:177"><nobr>between two locations expressed in geographic coordinates</nobr></div>
  2284. <div style="position:absolute;top:48687;left:177"><nobr>Ref : http : / / en . wikipedia . org / wiki / Haversine formula”””</nobr></div>
  2285. <div style="position:absolute;top:48724;left:176"><nobr>R = 6371000 <font color="#4c4c4c"># Earth radius in meters ( approximately )</font></nobr></div>
  2286. <div style="position:absolute;top:48761;left:177"><nobr>dLat = radians(float(lat2)float ( lat1 ))</nobr></div>
  2287. <div style="position:absolute;top:48780;left:177"><nobr>dLon = radians(float(lon2)float ( lon1 ))</nobr></div>
  2288. <div style="position:absolute;top:48798;left:177"><nobr>a = math.sin(dLat/2.0)math . sin ( dLat /2.0) \</nobr></div>
  2289. <div style="position:absolute;top:48817;left:176"><nobr>+ math . cos ( radians ( f l o a t ( l a t 1 ) ) )math . cos ( radians ( float ( lat2 ))) \</nobr></div>
  2290. <div style="position:absolute;top:48834;left:176"><nobr>math . s i n ( dLon / 2 . 0 )math . s i n ( dLon / 2 . 0 ) ;</nobr></div>
  2291. <div style="position:absolute;top:48853;left:177"><nobr>c = 2.0math . atan2 ( math . sqrt ( a ) , math . sqrt (1.0 − a))</nobr></div>
  2292. <div style="position:absolute;top:48872;left:177"><nobr>return R ∗ c</nobr></div>
  2293. </span></font>
  2294. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2295. <div style="position:absolute;top:49175;left:124"><nobr>6<font style="font-size:9px">Yeah, this is a bit overkill, many approximative approaches can be used in stead...</font></nobr></div>
  2296. </span></font>
  2297.  
  2298. <div style="position:absolute;top:49393;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="41"><b>Page 41</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  2299. <div style="position:absolute;top:49690;left:162"><nobr>Chapter 5</nobr></div>
  2300. </span></font>
  2301. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  2302. <div style="position:absolute;top:49774;left:162"><nobr>Various</nobr></div>
  2303. </span></font>
  2304. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  2305. <div style="position:absolute;top:49879;left:162"><nobr>5.1 Debugging</nobr></div>
  2306. </span></font>
  2307. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2308. <div style="position:absolute;top:49923;left:162"><nobr>When running a GUI application, exceptions, warnings and error messages might be directed to the stdout</nobr></div>
  2309. <div style="position:absolute;top:49946;left:162"><nobr>pipe<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>. The GUI can act strangely, but not go down, thus it might be hard to figure out what’s going on. When</nobr></div>
  2310. <div style="position:absolute;top:49969;left:162"><nobr>exiting the application, some clues can be found among messages written to the python ”console”. Log files</nobr></div>
  2311. <div style="position:absolute;top:49993;left:162"><nobr>should be used: EXAMPLE TBD.</nobr></div>
  2312. </span></font>
  2313. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2314. <div style="position:absolute;top:50437;left:178"><nobr>1<font style="font-size:9px">CHECK!</font></nobr></div>
  2315. </span></font>
  2316. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2317. <div style="position:absolute;top:50482;left:478"><nobr>35</nobr></div>
  2318. </span></font>
  2319.  
  2320. <div style="position:absolute;top:50655;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="42"><b>Page 42</b></a></font></td></tr></tbody></table></div><font size="4" face="Times"><span style="font-size:28px;font-family:Times">
  2321. <div style="position:absolute;top:50953;left:108"><nobr>Chapter 6</nobr></div>
  2322. </span></font>
  2323. <font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  2324. <div style="position:absolute;top:51037;left:108"><nobr>Resources</nobr></div>
  2325. </span></font>
  2326. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  2327. <div style="position:absolute;top:51144;left:108"><nobr>6.1 Python</nobr></div>
  2328. </span></font>
  2329. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2330. <div style="position:absolute;top:51189;left:108"><nobr>A classic Python starter is “Dive Into Python” [<a href="#44">2]</a>, which is available on a variety of formats. The father</nobr></div>
  2331. <div style="position:absolute;top:51212;left:108"><nobr>of Python, Guido van Rossum, has (of course) wriiten a good intro book[4<a href="#44">],</a> “Introduction to Python”, also</nobr></div>
  2332. <div style="position:absolute;top:51235;left:108"><nobr>available online. Documentation of modules, classes, functions etc. is <a href="http://docs.python.org">found on http://docs.python.</a></nobr></div>
  2333. <div style="position:absolute;top:51259;left:108"><nobr><a href="http://docs.python.org">org.</a></nobr></div>
  2334. <div style="position:absolute;top:51283;left:130"><nobr>You can access to the Python source code on python.org. If you want to extend the PyS60 distribution</nobr></div>
  2335. <div style="position:absolute;top:51306;left:108"><nobr>with additional modules, it is best to try the 2.2 version<a href="#1"></a><font style="font-size:8px"><a href="#1">1</a></font><a href="#1"></a>. since this is the one that PyS60 is based on.</nobr></div>
  2336. </span></font>
  2337. <font size="3" face="Times"><span style="font-size:19px;font-family:Times">
  2338. <div style="position:absolute;top:51364;left:108"><nobr>6.2 PyS60</nobr></div>
  2339. </span></font>
  2340. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2341. <div style="position:absolute;top:51409;left:108"><nobr>The main entry for PyS60 information is the proejct’s home page<a href="#1"></a><font style="font-size:8px"><a href="#1">2</a></font><a href="#1"></a>, where you will find links to nescessary</nobr></div>
  2342. <div style="position:absolute;top:51433;left:108"><nobr>software and documentation, for instance “PyS60 Library Reference” for the current version. The 1.2.0</nobr></div>
  2343. <div style="position:absolute;top:51456;left:108"><nobr>release shipped with three useful documents: ”Programming with Python for Series 60” , ”Getting Started</nobr></div>
  2344. <div style="position:absolute;top:51479;left:108"><nobr>with Python for Series 60and ”API Reference for Python”. Grab them from release bundle or from “Forum</nobr></div>
  2345. <div style="position:absolute;top:51503;left:108"><nobr>Nokia”<a href="#1"></a><font style="font-size:8px"><a href="#1">3 </a></font>while they still are available. The PyS60 section of this forum is a good place to pick up snippets</nobr></div>
  2346. <div style="position:absolute;top:51526;left:108"><nobr>and advices, and also a place where you probably will get answers to your posted questions.</nobr></div>
  2347. <div style="position:absolute;top:51550;left:130"><nobr>Another excellent source is the tutorial from the PyS60 evangelist Jurgen Scheible<a href="#1"></a><font style="font-size:8px"><a href="#1">4</a></font><a href="#1"></a>, including lots of</nobr></div>
  2348. <div style="position:absolute;top:51573;left:108"><nobr>working code examples. He is also the first author of “Mobile Python: Rapid Prototyping of Applications on</nobr></div>
  2349. <div style="position:absolute;top:51597;left:108"><nobr>the Mobile Platform”[<a href="#44">3]</a>. You can dowload all the example code from the book web site<font style="font-size:8px"><a href="#1">5</a></font></nobr></div>
  2350. </span></font>
  2351. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2352. <div style="position:absolute;top:51627;left:124"><nobr>1<font style="font-size:9px">http://python.org/download/releases/2.2.3</font></nobr></div>
  2353. <div style="position:absolute;top:51641;left:124"><nobr>2<a href="http://wiki.opensource.nokia.com/projects/PyS60"></a><font style="font-size:9px"><a href="http://wiki.opensource.nokia.com/projects/PyS60">http://wiki.opensource.nokia.com/projects/PyS60</a></font></nobr></div>
  2354. <div style="position:absolute;top:51656;left:124"><nobr>3<a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html"></a><font style="font-size:9px"><a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html">http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/</a></font></nobr></div>
  2355. </span></font>
  2356. <font size="2" face="Times"><span style="font-size:9px;font-family:Times">
  2357. <div style="position:absolute;top:51673;left:108"><nobr><a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html">Python_for_S60.html</a></nobr></div>
  2358. </span></font>
  2359. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2360. <div style="position:absolute;top:51685;left:124"><nobr>4<a href="http://www.mobilenin.com/pys60/menu.htm"></a><font style="font-size:9px"><a href="http://www.mobilenin.com/pys60/menu.htm">http://www.mobilenin.com/pys60/menu.htm</a></font></nobr></div>
  2361. <div style="position:absolute;top:51699;left:124"><nobr>5<a href="http://www.mobilepythonbook.org"></a><font style="font-size:9px"><a href="http://www.mobilepythonbook.org">http://www.mobilepythonbook.org</a></font></nobr></div>
  2362. </span></font>
  2363. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2364. <div style="position:absolute;top:51744;left:425"><nobr>36</nobr></div>
  2365. </span></font>
  2366.  
  2367. <div style="position:absolute;top:51917;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="43"><b>Page 43</b></a></font></td></tr></tbody></table></div><font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2368. <div style="position:absolute;top:52033;left:162"><nobr>6.2. PyS60</nobr></div>
  2369. <div style="position:absolute;top:52033;left:795"><nobr>37</nobr></div>
  2370. <div style="position:absolute;top:52102;left:184"><nobr>There is also good stuff to be find on the blogs from Pankaj Nathani<a href="#1"></a><font style="font-size:8px"><a href="#1">6</a></font><a href="#1"></a>, Nick Burch <font style="font-size:8px"><a href="#1">7 </a></font>and the PyS60</nobr></div>
  2371. <div style="position:absolute;top:52125;left:163"><nobr>über-hacker cyke64<a href="#1"></a><font style="font-size:8px"><a href="#1">8</a></font><a href="#1"></a>.</nobr></div>
  2372. </span></font>
  2373. <font size="2" face="Times"><span style="font-size:6px;font-family:Times">
  2374. <div style="position:absolute;top:52932;left:178"><nobr>6<a href="http://croozeus.googlepages.com/py60"></a><font style="font-size:9px"><a href="http://croozeus.googlepages.com/py60">http://croozeus.googlepages.com/py60</a></font></nobr></div>
  2375. <div style="position:absolute;top:52947;left:178"><nobr>7<a href="http://gagravarr.org/code"></a><font style="font-size:9px"><a href="http://gagravarr.org/code">http://gagravarr.org/code</a></font></nobr></div>
  2376. <div style="position:absolute;top:52961;left:178"><nobr>8<a href="http://cyke64.googlepages.com"></a><font style="font-size:9px"><a href="http://cyke64.googlepages.com">http://cyke64.googlepages.com</a></font></nobr></div>
  2377. </span></font>
  2378.  
  2379. <div style="position:absolute;top:53179;left:0"><hr><table border="0" width="100%"><tbody><tr><td bgcolor="eeeeee" align="right"><font face="arial,sans-serif"><a name="44"><b>Page 44</b></a></font></td></tr></tbody></table></div><font size="5" face="Times"><span style="font-size:35px;font-family:Times">
  2380. <div style="position:absolute;top:53481;left:108"><nobr>Bibliography</nobr></div>
  2381. </span></font>
  2382. <font size="3" face="Times"><span style="font-size:12px;font-family:Times">
  2383. <div style="position:absolute;top:53580;left:108"><nobr>[1] Nicola J Bidwell and Jason Holdsworth. Battleship by foot: learning by designing a mixed reality game.</nobr></div>
  2384. <div style="position:absolute;top:53603;left:133"><nobr>In IE ’06: Procedings of the 3rd Australasian conference on Interactive entertainment, pages 6774,</nobr></div>
  2385. <div style="position:absolute;top:53626;left:133"><nobr>Murdoch University, Australia, Australia, 2006. Murdoch University.</nobr></div>
  2386. <div style="position:absolute;top:53662;left:108"><nobr>[2] M. Pilgrim. Dive Into Python. Apress,<a href="http://www.diveintopython.org"> 2004. http://www.diveintopython.org.</a></nobr></div>
  2387. <div style="position:absolute;top:53697;left:108"><nobr>[3] J. Scheible and V. Tuulos. Mobile Python-Rapid Prototyping on the Mobile Platform, 2007.</nobr></div>
  2388. <div style="position:absolute;top:53732;left:108"><nobr>[4] G. Van Rossum.</nobr></div>
  2389. <div style="position:absolute;top:53732;left:267"><nobr>Introduction to Python.</nobr></div>
  2390. <div style="position:absolute;top:53732;left:444"><nobr>Network Theory Ltd., 2006.</nobr></div>
  2391. <div style="position:absolute;top:53733;left:657"><nobr><a href="http://www.network-theory.co.uk/python/intro">http://www.</a></nobr></div>
  2392. <div style="position:absolute;top:53756;left:133"><nobr><a href="http://www.network-theory.co.uk/python/intro">network-theory.co.uk/python/intro.</a></nobr></div>
  2393. <div style="position:absolute;top:54268;left:425"><nobr>38</nobr></div>
  2394. </span></font>
  2395.  
  2396.  
  2397. </div></body></html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement