@@ -203,3 +203,165 @@ Instances of :class:`Cmd` subclasses have some public instance variables:
203203 :mod: `readline `, on systems that support it, the interpreter will automatically
204204 support :program: `Emacs `\ -like line editing and command-history keystrokes.)
205205
206+ Cmd Example
207+ ===========
208+
209+ .. sectionauthor :: Raymond Hettinger <python at rcn dot com>
210+
211+ The :mod: `cmd ` module is mainly useful for building custom shells that let a
212+ user work with a program interactively.
213+
214+ This section presents a simple example of how to build a shell around a few of
215+ the commands in the :mod: `turtle ` module.
216+
217+ Basic turtle commands such as :meth: `~turtle.forward ` are added to a
218+ :class: `Cmd ` subclass with method named :meth: `do_forward `. The argument is
219+ converted to a number and dispatched to the turtle module. The docstring is
220+ used in the help utility provided by the shell.
221+
222+ The example also includes a basic record and playback facility implemented with
223+ the :meth: `~Cmd.precmd ` method which is responsible for converting the input to
224+ lowercase and writing the commands to a file. The :meth: `do_playback ` method
225+ reads the file and adds the recorded commands to the :attr: `cmdqueue ` for
226+ immediate playback::
227+
228+ import cmd, sys
229+ from turtle import *
230+
231+ class TurtleShell(cmd.Cmd):
232+ intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n'
233+ prompt = '(turtle) '
234+ file = None
235+
236+ # ----- basic turtle commands -----
237+ def do_forward(self, arg):
238+ 'Move the turtle forward by the specified distance: FORWARD 10'
239+ forward(*parse(arg))
240+ def do_right(self, arg):
241+ 'Turn turtle right by given number of degrees: RIGHT 20'
242+ right(*parse(arg))
243+ def do_left(self, arg):
244+ 'Turn turtle left by given number of degrees: LEFT 90'
245+ right(*parse(arg))
246+ def do_goto(self, arg):
247+ 'Move turtle to an absolute position with changing orientation. GOTO 100 200'
248+ goto(*parse(arg))
249+ def do_home(self, arg):
250+ 'Return turtle to the home postion: HOME'
251+ home()
252+ def do_circle(self, arg):
253+ 'Draw circle with given radius an options extent and steps: CIRCLE 50'
254+ circle(*parse(arg))
255+ def do_position(self, arg):
256+ 'Print the current turle position: POSITION'
257+ print('Current position is %d %d\n' % position())
258+ def do_heading(self, arg):
259+ 'Print the current turle heading in degrees: HEADING'
260+ print('Current heading is %d\n' % (heading(),))
261+ def do_color(self, arg):
262+ 'Set the color: COLOR BLUE'
263+ color(arg.lower())
264+ def do_undo(self, arg):
265+ 'Undo (repeatedly) the last turtle action(s): UNDO'
266+ def do_reset(self, arg):
267+ 'Clear the screen and return turtle to center: RESET'
268+ reset()
269+ def do_bye(self, arg):
270+ 'Stop recording, close the turtle window, and exit: BYE'
271+ print('Thank you for using Turtle')
272+ self.close()
273+ bye()
274+ sys.exit(0)
275+
276+ # ----- record and playback -----
277+ def do_record(self, arg):
278+ 'Save future commands to filename: RECORD rose.cmd'
279+ self.file = open(arg, 'w')
280+ def do_playback(self, arg):
281+ 'Playback commands from a file: PLAYBACK rose.cmd'
282+ self.close()
283+ cmds = open(arg).read().splitlines()
284+ self.cmdqueue.extend(cmds)
285+ def precmd(self, line):
286+ line = line.lower()
287+ if self.file and 'playback' not in line:
288+ print(line, file=self.file)
289+ return line
290+ def close(self):
291+ if self.file:
292+ self.file.close()
293+ self.file = None
294+
295+ def parse(arg):
296+ 'Convert a series of zero or more numbers to an argument tuple'
297+ return tuple(map(int, arg.split()))
298+
299+ if __name__ == '__main__':
300+ TurtleShell().cmdloop()
301+
302+
303+ Here is a sample session with the turtle shell showing the help functions, using
304+ blank lines to repeat commands, and the simple record and playback facility::
305+
306+ Welcome to the turtle shell. Type help or ? to list commands.
307+
308+ (turtle) ?
309+
310+ Documented commands (type help <topic>):
311+ ========================================
312+ bye color goto home playback record right
313+ circle forward heading left position reset undo
314+
315+ Undocumented commands:
316+ ======================
317+ help
318+
319+ (turtle) help forward
320+ Move the turtle forward by the specified distance: FORWARD 10
321+ (turtle) record spiral.cmd
322+ (turtle) position
323+ Current position is 0 0
324+
325+ (turtle) heading
326+ Current heading is 0
327+
328+ (turtle) reset
329+ (turtle) circle 20
330+ (turtle) right 30
331+ (turtle) circle 40
332+ (turtle) right 30
333+ (turtle) circle 60
334+ (turtle) right 30
335+ (turtle) circle 80
336+ (turtle) right 30
337+ (turtle) circle 100
338+ (turtle) right 30
339+ (turtle) circle 120
340+ (turtle) right 30
341+ (turtle) circle 120
342+ (turtle) heading
343+ Current heading is 180
344+
345+ (turtle) forward 100
346+ (turtle)
347+ (turtle) right 90
348+ (turtle) forward 100
349+ (turtle)
350+ (turtle) right 90
351+ (turtle) forward 400
352+ (turtle) right 90
353+ (turtle) forward 500
354+ (turtle) right 90
355+ (turtle) forward 400
356+ (turtle) right 90
357+ (turtle) forward 300
358+ (turtle) playback spiral.cmd
359+ Current position is 0 0
360+
361+ Current heading is 0
362+
363+ Current heading is 180
364+
365+ (turtle) bye
366+ Thank you for using Turtle
367+
0 commit comments