Mercurial > python-cmd2
annotate docs/pycon2010/pycon2010.rst @ 373:a381f8dd3a45
mention py3
author | cat@eee |
---|---|
date | Fri, 19 Feb 2010 12:20:44 -0500 |
parents | bf314710e64b |
children | 89e38f922c25 |
rev | line source |
---|---|
351 | 1 ================================================ |
2 Easy command-line interpreters with cmd and cmd2 | |
3 ================================================ | |
4 | |
5 :author: Catherine Devlin | |
6 :date: 2010-02-20 | |
7 | |
8 Quit scribbling | |
9 =============== | |
10 | |
11 Slides are *already* posted at | |
366 | 12 homepage: http://pypi.python.org/pypi/cmd2 |
337 | 13 |
14 Web 2.0 | |
15 ======= | |
16 | |
17 .. image:: web-2-0-logos.gif | |
372 | 18 :height: 350px |
337 | 19 |
20 But first... | |
21 ============ | |
22 | |
23 .. image:: sargon.jpg | |
362 | 24 :height: 250px |
344 | 25 |
351 | 26 .. image:: akkad.png |
362 | 27 :height: 250px |
351 | 28 |
344 | 29 Sargon the Great |
30 Founder of Akkadian Empire | |
31 | |
32 .. twenty-third century BC | |
337 | 33 |
34 In between | |
35 ========== | |
36 | |
37 .. image:: apple.jpg | |
362 | 38 :height: 250px |
337 | 39 |
344 | 40 Command-Line Interface |
41 Unlike the Akkadian Empire, | |
42 the CLI will never die. | |
337 | 43 |
351 | 44 Defining CLI |
45 ============ | |
372 | 46 |
47 Also known as | |
344 | 48 |
49 - "Line-oriented command interpreter" | |
50 - "Command-line interface" | |
51 - "Shell" | |
337 | 52 |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
53 1. Accepts free text input at prompt |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
54 2. Outputs lines of text |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
55 3. (repeat) |
337 | 56 |
57 Examples | |
58 ======== | |
59 | |
344 | 60 * Bash, Korn, zsh |
61 * Python shell | |
62 * screen | |
63 * Zork | |
64 * SQL clients: psql, SQL*\Plus, mysql... | |
65 * ed | |
66 | |
67 .. ``ed`` proves that CLI is sometimes the wrong answer. | |
337 | 68 |
69 != Command Line Utilities | |
70 ========================= | |
71 | |
362 | 72 (``ls``, ``grep``, ``ping``, etc.) |
73 | |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
74 1. Accepts arguments at invocation |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
75 2. executes |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
76 3. terminates |
337 | 77 |
344 | 78 Use ``sys.argv``, ``optparse`` |
337 | 79 |
372 | 80 !="Text User Interface", "Console" |
81 ================================== | |
337 | 82 |
344 | 83 * Use entire (session) screen |
84 * I/O is *not* line-by-line | |
372 | 85 * See ``curses``, ``urwid`` |
337 | 86 |
87 .. image:: urwid.png | |
362 | 88 :height: 250px |
337 | 89 |
90 | |
372 | 91 Decide your priorities |
92 ====================== | |
337 | 93 |
351 | 94 .. image:: strategy.png |
372 | 95 :height: 350px |
344 | 96 |
351 | 97 A ``cmd`` app: pirate.py |
98 ======================== | |
337 | 99 |
100 :: | |
101 | |
102 from cmd import Cmd | |
103 | |
104 class Pirate(Cmd): | |
105 pass | |
106 | |
107 pirate = Pirate() | |
108 pirate.cmdloop() | |
109 | |
351 | 110 .. Nothing here... but history and help |
344 | 111 |
112 .. ctrl-r for bash-style history | |
113 | |
114 Fundamental prrrinciple | |
115 ======================= | |
116 | |
351 | 117 .. class:: huge |
118 | |
372 | 119 Transform ``(Cmd) foo a b c`` |
344 | 120 |
372 | 121 to ``self.do_foo('a b c')`` |
344 | 122 |
123 ``do_``-methods: pirate2.py | |
124 =========================== | |
125 | |
126 :: | |
127 | |
128 class Pirate(Cmd): | |
351 | 129 gold = 3 |
344 | 130 def do_loot(self, arg): |
131 'Seize booty frrrom a passing ship.' | |
132 self.gold += 1 | |
133 print('Now we gots {0} doubloons'.format(self.gold)) | |
134 def do_drink(self, arg): | |
135 'Drown your sorrrows in rrrum.' | |
136 self.gold -= 1 | |
137 print('Now we gots {0} doubloons'.format(self.gold)) | |
138 | |
139 .. do_methods; more help | |
140 | |
141 Hooks | |
142 ===== | |
143 | |
363 | 144 .. image:: hook.jpg |
362 | 145 :height: 250px |
344 | 146 |
363 | 147 preloop, postloop, precmd, postcmd |
148 | |
344 | 149 Hooks: pirate3.py |
150 ================= | |
151 | |
152 :: | |
337 | 153 |
351 | 154 def do_loot(self, arg): |
155 'Seize booty from a passing ship.' | |
156 self.gold += 1 | |
157 def do_drink(self, arg): | |
158 'Drown your sorrrows in rrrum.' | |
159 self.gold -= 1 | |
160 def precmd(self, line): | |
161 self.initial_gold = self.gold | |
162 return line | |
163 def postcmd(self, stop, line): | |
164 if self.gold != self.initial_gold: | |
165 print('Now we gots {0} doubloons'.format(self.gold)) | |
344 | 166 |
167 Arguments: pirate4.py | |
168 ===================== | |
169 | |
170 :: | |
171 | |
172 def do_drink(self, arg): | |
173 '''Drown your sorrrows in rrrum. | |
174 | |
175 drink [n] - drink [n] barrel[s] o' rum.''' | |
176 try: | |
177 self.gold -= int(arg) | |
178 except: | |
179 if arg: | |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
180 print('''What's "{0}"? I'll take rrrum.''' |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
181 .format(arg)) |
344 | 182 self.gold -= 1 |
183 | |
184 quitting: pirate5.py | |
185 ==================== | |
186 | |
187 :: | |
188 | |
351 | 189 def postcmd(self, stop, line): |
190 if self.gold != self.initial_gold: | |
191 print('Now we gots {0} doubloons'.format(self.gold)) | |
344 | 192 if self.gold < 0: |
351 | 193 print("Off to debtorrr's prison. Game overrr.") |
344 | 194 return True |
195 return stop | |
196 def do_quit(self, arg): | |
197 print("Quiterrr!") | |
351 | 198 return True |
344 | 199 |
200 prompts and defaults: pirate6.py | |
201 ================================ | |
202 | |
203 :: | |
204 | |
205 prompt = 'arrr> ' | |
206 def default(self, line): | |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
207 print('What mean ye by "{0}"?' |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
208 .format(line)) |
372 | 209 |
210 Other CLI packages | |
211 ================== | |
212 | |
213 * cmdlin | |
214 * cmd2 | |
215 | |
216 Demo | |
217 ==== | |
218 | |
219 Convert ``cmd`` app to ``cmd2`` | |
220 | |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
221 cmd2 |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
222 ==== |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
223 |
351 | 224 .. image:: schematic.png |
372 | 225 :height: 350px |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
226 |
373 | 227 As you wish, Guido |
228 ================== | |
229 | |
230 Python 3 compatible | |
231 | |
232 (um, mostly) | |
233 | |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
234 Absolutely free |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
235 =============== |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
236 |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
237 * Script files |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
238 * Commands at invocation |
346 | 239 * Output redirection |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
240 * Python |
346 | 241 * Transcript-based testing |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
242 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
243 But wait, there's more |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
244 ====================== |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
245 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
246 * Abbreviated commands |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
247 * Shell commands |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
248 * Quitting |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
249 * Timing |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
250 * Echo |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
251 * Debug |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
252 |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
253 For a few keystrokes more... |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
254 ============================ |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
255 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
256 * Default to shell |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
257 * Color output |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
258 * Shortcuts |
351 | 259 * Multiline commands |
260 * Environment variables | |
261 | |
262 Minor changes: pirate7.py | |
263 ========================= | |
264 | |
265 :: | |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
266 |
351 | 267 default_to_shell = True |
268 multilineCommands = ['sing'] | |
269 terminators = Cmd.terminators + ['...'] | |
356 | 270 songcolor = 'blue' |
271 settable = Cmd.settable + 'songcolor Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)' | |
272 Cmd.shortcuts.update({'~': 'sing'}) | |
351 | 273 def do_sing(self, arg): |
356 | 274 print(self.colorize(arg, self.songcolor)) |
275 | |
276 Now how much would you pay? | |
277 =========================== | |
278 | |
279 * options / flags | |
280 * Quiet (suppress feedback) | |
281 * BASH-style ``select`` | |
282 * Parsing: terminators, suffixes | |
351 | 283 |
284 Options: pirate8.py | |
285 =================== | |
286 | |
287 :: | |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
288 |
351 | 289 def do_yo(self, arg, opts): |
290 chant = ['yo'] + ['ho'] * opts.ho | |
372 | 291 separator = ', ' if opts.commas else ' ' |
352 | 292 chant = separator.join(chant) |
372 | 293 print('{0} and a bottle of {1}' |
294 .format(chant, arg)) | |
362 | 295 |
296 Serious example: sqlpython | |
297 ========================== | |
298 | |
299 ``cmd``-based app by Luca Canali @ CERN | |
300 | |
364 | 301 Replacement for Oracle SQL\*Plus |
362 | 302 |
303 Now ``cmd2``-based; postgreSQL; MySQL | |
357 | 304 |
362 | 305 sqlpython features |
306 ================== | |
307 | |
372 | 308 * from ``cmd2``: scripts, redirection, |
309 py, etc. | |
310 * multiple connections | |
311 * UNIX: ls, cat, grep | |
312 * Special output | |
357 | 313 |
372 | 314 File reporter |
315 ============= | |
316 | |
317 Gather info: Python | |
362 | 318 |
372 | 319 Store: postgresql |
320 | |
321 Report: html | |
362 | 322 |
372 | 323 Thank you |
324 ========= | |
357 | 325 |
373 | 326 pypi.python.org/pypi/cmd2 |
372 | 327 |
328 catherinedevlin.blogspot.com | |
329 | |
330 catherinedevlin.pythoneers.com | |
357 | 331 |
363 | 332 |