Mercurial > python-cmd2
annotate docs/pycon2010/pycon2010.rst @ 363:2b2836b783be
added hook pic
author | cat@eee |
---|---|
date | Thu, 18 Feb 2010 13:45:43 -0500 |
parents | 18e8487be095 |
children | 29221236d1a1 |
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 | |
12 catherinedevlin.pythoneers.com | |
337 | 13 |
14 Web 2.0 | |
15 ======= | |
16 | |
17 .. image:: web-2-0-logos.gif | |
362 | 18 :height: 250px |
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 ============ | |
344 | 46 |
47 - "Line-oriented command interpreter" | |
48 - "Command-line interface" | |
49 - "Shell" | |
337 | 50 |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
51 1. Accepts free text input at prompt |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
52 2. Outputs lines of text |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
53 3. (repeat) |
337 | 54 |
55 Examples | |
56 ======== | |
57 | |
344 | 58 * Bash, Korn, zsh |
59 * Python shell | |
60 * screen | |
61 * Zork | |
62 * SQL clients: psql, SQL*\Plus, mysql... | |
63 * ed | |
64 | |
65 .. ``ed`` proves that CLI is sometimes the wrong answer. | |
337 | 66 |
67 != Command Line Utilities | |
68 ========================= | |
69 | |
362 | 70 (``ls``, ``grep``, ``ping``, etc.) |
71 | |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
72 1. Accepts arguments at invocation |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
73 2. executes |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
74 3. terminates |
337 | 75 |
344 | 76 Use ``sys.argv``, ``optparse`` |
337 | 77 |
344 | 78 != "Text User Interfaces", "Consoles" |
79 ===================================== | |
337 | 80 |
344 | 81 * Use entire (session) screen |
82 * I/O is *not* line-by-line | |
337 | 83 |
84 .. image:: urwid.png | |
362 | 85 :height: 250px |
337 | 86 |
344 | 87 Use ``curses``, ``urwid`` |
337 | 88 |
351 | 89 Priorities |
90 ========== | |
337 | 91 |
351 | 92 .. image:: strategy.png |
362 | 93 :height: 250px |
344 | 94 |
351 | 95 A ``cmd`` app: pirate.py |
96 ======================== | |
337 | 97 |
98 :: | |
99 | |
100 from cmd import Cmd | |
101 | |
102 class Pirate(Cmd): | |
103 pass | |
104 | |
105 pirate = Pirate() | |
106 pirate.cmdloop() | |
107 | |
351 | 108 .. Nothing here... but history and help |
344 | 109 |
110 .. ctrl-r for bash-style history | |
111 | |
112 Fundamental prrrinciple | |
113 ======================= | |
114 | |
351 | 115 .. class:: huge |
344 | 116 |
351 | 117 :: |
118 | |
119 (Cmd) foo a b c | |
344 | 120 |
121 ``self.do_foo('a b c')`` | |
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)) |
351 | 209 |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
210 cmd2 |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
211 ==== |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
212 |
351 | 213 .. image:: schematic.png |
362 | 214 :height: 250px |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
215 |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
216 Absolutely free |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
217 =============== |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
218 |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
219 * Script files |
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
220 * Commands at invocation |
346 | 221 * Output redirection |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
222 * Python |
346 | 223 * Transcript-based testing |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
224 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
225 But wait, there's more |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
226 ====================== |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
227 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
228 * Abbreviated commands |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
229 * Shell commands |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
230 * Quitting |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
231 * Timing |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
232 * Echo |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
233 * Debug |
345
6fe1e75e3a67
transcript test wasn't running pre and post cmd hooks
catherine@Drou
parents:
344
diff
changeset
|
234 |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
235 For a few keystrokes more... |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
236 ============================ |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
237 |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
238 * Default to shell |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
239 * Color output |
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
240 * Shortcuts |
351 | 241 * Multiline commands |
242 * Environment variables | |
243 | |
244 Minor changes: pirate7.py | |
245 ========================= | |
246 | |
247 :: | |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
248 |
351 | 249 default_to_shell = True |
250 multilineCommands = ['sing'] | |
251 terminators = Cmd.terminators + ['...'] | |
356 | 252 songcolor = 'blue' |
253 settable = Cmd.settable + 'songcolor Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)' | |
254 Cmd.shortcuts.update({'~': 'sing'}) | |
351 | 255 def do_sing(self, arg): |
356 | 256 print(self.colorize(arg, self.songcolor)) |
257 | |
258 Now how much would you pay? | |
259 =========================== | |
260 | |
261 * options / flags | |
262 * Quiet (suppress feedback) | |
263 * BASH-style ``select`` | |
264 * Parsing: terminators, suffixes | |
351 | 265 |
266 Options: pirate8.py | |
267 =================== | |
268 | |
269 :: | |
347
432ccab7c6c8
going to try moving output redirection to outside precmd, postcmd hooks
catherine@Drou
parents:
346
diff
changeset
|
270 |
351 | 271 @options([make_option('--ho', type='int', help="How often to chant 'ho'", default=2), |
272 make_option('-c', '--commas', action="store_true", help="Interspers commas")]) | |
273 def do_yo(self, arg, opts): | |
274 chant = ['yo'] + ['ho'] * opts.ho | |
275 if opts.commas: | |
276 separator = ', ' | |
277 else: | |
278 separator = ' ' | |
352 | 279 chant = separator.join(chant) |
280 print('{0} and a bottle of {1}'.format(chant, arg)) | |
362 | 281 |
282 Serious example: sqlpython | |
283 ========================== | |
284 | |
285 ``cmd``-based app by Luca Canali @ CERN | |
286 | |
287 Replacement for Oracle SQL/*Plus | |
288 | |
289 Now ``cmd2``-based; postgreSQL; MySQL | |
357 | 290 |
362 | 291 sqlpython features |
292 ================== | |
293 | |
294 Everything in ``cmd2`` | |
363 | 295 (scripts, redirection, py) |
357 | 296 |
362 | 297 Multi connections |
298 | |
299 ls, grep | |
300 | |
301 Output to html, csv, inserts, bar graphs | |
357 | 302 |
363 | 303 py session with bind variables |
357 | 304 |
363 | 305 |
306 | |
307 |