two.4. Graphics¶

Graphics make programming more than fun for many people. To fully innovate graphics would involve many ideas that would be a distraction now. This department introduces a simplified graphics module developed by John Zelle for use with his Python Programming volume. My slight elaboration of his bundle is graphics.py in the example programs.

Warning

You need the file graphics.py in the same binder as whatsoever graphics program you write. Exist certain to save any graphics program you write in such a folder (like my examples folder). The easiest manner to ensure this is to start in the desired folder, as discussed in Starting Idle for Editing.

Warning

To work on the most systems, this version of graphics.py cannot be used from the Idle beat out. At that place is an effect with the utilize of multiple threads of execution.

2.4.1. A Graphics Introduction¶

Note

You will just be a user of the graphics.py code, so you do non demand to understand the inner workings! Information technology uses all sorts of features of Python that are way across these tutorials. There is no particular demand to open graphics.py in the Idle editor.

Load into Idle and start running example graphIntroSteps.py , or start running from the operating system folder. Each time you press render, look at the screen and read the explanation for the next line(s).

Press return:

              from              graphics              import              *              win              =              GraphWin              ()            

Zelle'south graphics are not a part of the standard Python distribution. For the Python interpreter to find Zelle's module, it must be imported. The first line above makes all the types of object of Zelle'southward module attainable, equally if they were already defined similar built-in types str or list .

Await around on your screen, and possibly underneath other windows: There should exist a new window labeled "Graphics Window", created by the second line. Bring it to the superlative, and preferably drag it around to get in visible beside your Shell window. A GraphWin is a type of object from Zelle's graphics package that automatically displays a window when it is created. The assignment statement remembers the window object as win for hereafter reference. (This volition exist our standard proper name for our graphics window object.) A small-scale window, 200 past 200 pixels is created. A pixel is the smallest piddling square that tin can by displayed on your screen. Modern screen commonly accept more than 1000 pixels across the whole screen.

Press render:

This creates a Point object and assigns it the name pt . Unlike when a GraphWin is created, goose egg is immediately displayed: In theory yous could have more than one GraphWin . Zelle designed the graphics module so you lot must tell Python into which GraphWin to depict the Betoken . A Point object, like each of the graphical objects that tin exist drawn on a GraphWin , has a method [1] draw .

Press return:

Now you should see the Indicate if y'all look difficult in the Graphics Window - it shows as a single, small, blackness pixel. Graphics windows have a Cartesian (x,y) coordinate organization. The dimensions are initially measured in pixels. The first coordinate is the horizontal coordinate, measured from left to right, so 100 is about half way across the 200 pixel wide window. The second coordinate, for the vertical management, increases going downwards from the summit of the window by default, not upwardly every bit yous are likely to wait from geometry or algebra class. The coordinate 50 out of the total 200 vertically should be near i/4 of the way downwards from the top. We volition see later that nosotros can reorient the coordinate organization to fit our taste.

Henceforth you will see a draw method call subsequently each object is created, so there is something to run into.

Press return:

              cir              =              Circumvolve              (              pt              ,              25              )              cir              .              draw              (              win              )            

The showtime line creates a Circle object with eye at the previously defined pt and with radius 25. This object is remembered with the name cir . As with all graphics objects that may be fatigued within a GraphWin , information technology is merely fabricated visible past explicitly using its draw method.

So far, everything has been drawn in the default colour black. Graphics objects like a Circle have methods to change their colors. Basic color name strings are recognized. You lot tin can cull the color for the circle outline too as filling in the within.

Press render:

              cir              .              setOutline              (              'reddish'              )              cir              .              setFill              (              'blueish'              )            

Note the method names. They can exist used with other kinds of Graphics objects, likewise. (Nosotros filibuster a word of fancier colors until Color Names and Custom Colors.)

Press return:

              line              =              Line              (              pt              ,              Signal              (              150              ,              100              ))              line              .              draw              (              win              )            

A Line object is synthetic with 2 Points as parameters. In this case nosotros apply the previously named Bespeak, pt , and specify some other Point directly. Technically the Line object is a segment between the the ii points.

Warning

In Python (150, 100) is a tuple , non a Point . To make a Point , you must use the full constructor: Point(150, 100) . Point s, non tuple s, must be used in the constructors for all graphics objects.

A rectangle is too specified past two points. The points must be diagonally opposite corners.

Press return:

              rect              =              Rectangle              (              Point              (              20              ,              ten              ),              pt              )              rect              .              draw              (              win              )            

In this elementary organization, a Rectangle is restricted to have horizontal and vertical sides. A Polygon , introduced in the adjacent section, is used for all more general straight-sided shapes.

Yous can move objects around in a GraphWin. Soon this volition be handy for blitheness. The parameters to the movement method are the amount to shift the x and y coordinates. See if you lot can guess the result earlier you printing return:

Did you remember that the y coordinate increases down the screen?

Take your last look at the Graphics Window, and make certain that all the steps make sense. Then destroy the window win with the GraphWin method close .

Press return:

The example program graphIntro.py starts with the same graphics code every bit graphIntoSteps.py , just without the need for pressing returns.

An add-on I accept made to Zelle's bundle is the ability to print a string value of graphics objects for debugging purposes. If some graphics object isn't visible because information technology is underneath something else of off the screen, temporarily calculation this sort of output might be a good reality bank check.

At the finish of graphIntro.py , I added print lines to illustrate the debugging possibilities:

              impress              (              'cir:'              ,              cir              )              print              (              'line:'              ,              line              )              impress              (              'rect:'              ,              rect              )            

You lot tin load graphIntro.py into Idle, run information technology, and add farther lines to experiment if yous similar. Of course you lot will not see their consequence until you run the whole program! Unfortunately the graphics do not work when entered directly into the Shell.

two.four.2. Sample Graphics Programs¶

In graphIntro.py , a prompt to end the graphics program appeared in the Shell window, requiring you to pay attention to two windows. Instead consider a very simple example program, face up.py , where all the action takes identify in the graphics window. The only interaction is to click the mouse to close the graphics window.

In Windows, have a folder window open to the Python examples folder containing face.py , where your operating system setup may allow you exist just double click on the icon for face.py to run it. If that does not work on your system, you tin can e'er run from inside Idle.

Subsequently you take checked out the movie, click with the mouse within the film, every bit requested, to end the programme.

After you have run the program, yous can examine the program in Idle or await beneath. The whole program is shown first; smaller pieces of it are discussed subsequently:

              '''A simple graphics example constructs a face from basic shapes.              '''              from              graphics              import              *              def              chief              ():              win              =              GraphWin              (              'Confront'              ,              200              ,              150              )              # give title and dimensions              win              .              yUp              ()              # brand right side upwards coordinates!              head              =              Circle              (              Point              (              40              ,              100              ),              25              )              # fix center and radius              head              .              setFill              (              "yellowish"              )              head              .              draw              (              win              )              eye1              =              Circle              (              Point              (              thirty              ,              105              ),              5              )              eye1              .              setFill              (              'blue'              )              eye1              .              depict              (              win              )              eye2              =              Line              (              Point              (              45              ,              105              ),              Point              (              55              ,              105              ))              # ready endpoints              eye2              .              setWidth              (              3              )              eye2              .              describe              (              win              )              oral fissure              =              Oval              (              Bespeak              (              xxx              ,              90              ),              Point              (              l              ,              85              ))              # set up corners of bounding box              oral cavity              .              setFill              (              "cherry-red"              )              mouth              .              draw              (              win              )              characterization              =              Text              (              Point              (              100              ,              120              ),              'A face up'              )              label              .              draw              (              win              )              message              =              Text              (              Point              (              win              .              getWidth              ()              /              two              ,              20              ),              'Click anywhere to quit.'              )              bulletin              .              draw              (              win              )              win              .              getMouse              ()              win              .              close              ()              primary              ()            

Let united states wait at individual parts.

Until further notice the prepare-off code is for y'all to read and have explained.

Immediately after the documentation string, e'er take the import line in your graphics program, to allow easy admission to the graphics.py module.

              win              =              GraphWin              (              'Face'              ,              200              ,              150              )              # give title and dimensions              win              .              yUp              ()              # make correct side upward coordinates!            

The first line shows the more general parameters for constructing a new GraphWin, a window title plus width and tiptop in pixels. The second line shows how to turn the coordinate arrangement right-side-upwardly, so the y coordinate increases up the screen, using the yUp method. (This is one of my additions to Zelle's graphics.) Thereafter, all coordinates are given in the new coordinate system. All the lines of code up to this betoken in the program are my standard graphics program starting lines (other than the specific values for the championship and dimensions). You lot volition likely kickoff your programs with like code.

              head              =              Circle              (              Point              (              40              ,              100              ),              25              )              # ready center and radius              head              .              setFill              (              'yellow'              )              head              .              depict              (              win              )              eye1              =              Circle              (              Point              (              30              ,              105              ),              v              )              eye1              .              setFill              (              'blue'              )              eye1              .              draw              (              win              )            

The lines higher up create two circles, in each instance specifying the centers straight. They are filled in and made visible. Also note, that because the earlier win.yUp call put the coordinates in the normal orientation, the y coordinate, 100 and 105, are above the middle of the 150 pixel high window.

If the code was switched to put the head function second, the center would go hidden. The virtually recent thing drawn is on tiptop.

              eye2              =              Line              (              Bespeak              (              45              ,              105              ),              Point              (              55              ,              105              ))              # ready endpoints              eye2              .              setWidth              (              3              )              eye2              .              draw              (              win              )            

The lawmaking to a higher place draws and displays a line, and illustrates some other method available to graphics object, setWidth , making a thicker line.

              rima oris              =              Oval              (              Betoken              (              xxx              ,              xc              ),              Point              (              50              ,              85              ))              # prepare corners of bounding box              mouth              .              setFill              (              'red'              )              mouth              .              draw              (              win              )            

The code to a higher place illustrates another kind of graphics object, an Oval (or ellipse). There are several ways an oval could exist specified. Zelle chose to accept yous specify the corners of the bounding box that is just every bit high and as broad as the oval. This rectangle is only imagined, not actually drawn. (If yous desire to see such a rectangle, create a Rectangle object with the same two Points as parameters....)

              characterization              =              Text              (              Bespeak              (              100              ,              120              ),              'A face'              )              label              .              draw              (              win              )            

The code to a higher place illustrates how a Text object is used to place text on the window. The parameters to construct the Text object are the point at the center of the text, and the text string itself.

The exact coordinates for the parts were determined past a number of trial-and-mistake refinements to the program. An advantage of graphics is that you can run across the results of your programming, and make changes if you lot practice not similar the results! In this uncomplicated organisation, there is not a practiced way to predict the dimensions of text on the screen.

The concluding action is to have the user bespeak to close the window. Simply as with waiting for keyboard input from input , it is of import to prompt the user before waiting for a response! In a GraphWin, that means using prompt must be made with a Text object displayed explicitly before the response is expected.

              message              =              Text              (              Point              (              win              .              getWidth              ()              /              ii              ,              20              ),              'Click anywhere to quit.'              )              message              .              draw              (              win              )              win              .              getMouse              ()              win              .              close              ()            

The new addition to the Text parameters hither is win.getWidth() to obtain the window width. (There is too a win.getHeight() .) Using win.getWidth()/2 means the horizontal position is set up up to be centered, half way across the window'due south width.

After the first two lines draw the prompting text, the line win.getMouse() waits for a mouse click. In this program, the position of the mouse click is non important. (In the next case the position of this mouse click will be used.) As you accept seen before, win.close() closes the graphics window.

While our earlier text-based Python programs have automatically terminated afterwards the final line finishes executing, that is not truthful for programs that create new windows: The graphics window must exist explicitly airtight. The win.close() is necessary.

We will by and large want to prompt the user to finally close the graphics window. Because such a sequence is so mutual, I accept added another method for Zelle'south GraphWin objects, promptClose , so the terminal four lines tin can be reduced to

              win              .              promptClose              (              win              .              getWidth              ()              /              2              ,              20              )            

where the only specific information needed is the coordinates of the center of the prompt.

The modified program is in face2.py . You tin copy the course of this program for other simple programs that just draw a picture. The size and title on the window volition change, as well as the specific graphical objects, positions, and colors. Something like the last line tin can be used to terminate the programme.

Warning

If you lot write a program with a bug, and the program bombs out while there is a GraphWin on the screen, a dead GraphWin lingers. The best manner to clean things up is to make the Crush window be the electric current window and select from the carte .

Another uncomplicated drawing example is balloons.py . Feel free to run it and await at the code in Idle. Notation that the steps for the cosmos of all three balloons are identical, except for the location of the center of each airship, then a loop over a listing of the centers makes sense.

The next case, triangle.py , illustrates like starting and ending code. In addition it explicitly interacts with the user. Rather than the code specifying literal coordinates for all graphical objects, the program remembers the Points where the user clicked the mouse. They are used as the vertices of a triangle.

Return to the directory window for the Python examples. In Windows yous may exist able to double click on the icon for triangle.py to run it. Or on a Mac, y'all tin can run it using the Python Launcher, rather than Idle.

While running the program, follow the prompts in the graphics window and click with the mouse as requested.

After you have run the programme, you can examine the plan in Idle or look below:

              '''Programme: triangle.py or triangle.pyw (best name for Windows)              Interactive graphics program to depict a triangle,              with prompts in a Text object and feedback via mouse clicks.              '''              from              graphics              import              *              def              main              ():              win              =              GraphWin              (              'Draw a Triangle'              ,              350              ,              350              )              win              .              yUp              ()              # right side upwards coordinates              win              .              setBackground              (              'yellow'              )              message              =              Text              (              Indicate              (              win              .              getWidth              ()              /              ii              ,              30              ),              'Click on three points'              )              message              .              setTextColor              (              'red'              )              bulletin              .              setStyle              (              'italic'              )              message              .              setSize              (              20              )              message              .              draw              (              win              )              # Get and draw three vertices of triangle              p1              =              win              .              getMouse              ()              p1              .              depict              (              win              )              p2              =              win              .              getMouse              ()              p2              .              draw              (              win              )              p3              =              win              .              getMouse              ()              p3              .              draw              (              win              )              vertices              =              [              p1              ,              p2              ,              p3              ]              # Use Polygon object to draw the triangle              triangle              =              Polygon              (              vertices              )              triangle              .              setFill              (              'greyness'              )              triangle              .              setOutline              (              'cyan'              )              triangle              .              setWidth              (              4              )              # width of boundary line              triangle              .              depict              (              win              )              message              .              setText              (              'Click anywhere to quit'              )              # change text message              win              .              getMouse              ()              win              .              close              ()              main              ()            

Permit u.s. expect at individual parts.

The lines before the new line:

              win              .              setBackground              (              'yellow'              )            

are standard starting lines (except for the specific values called for the width, height, and title). The background color is a property of the whole graphics window that you lot tin can set up.

              message              =              Text              (              Point              (              win              .              getWidth              ()              /              two              ,              20              ),              'Click on three points'              )              message              .              setTextColor              (              'red'              )              message              .              setStyle              (              'italic'              )              bulletin              .              setSize              (              20              )              message              .              draw              (              win              )            

Again a Text object is created. This is the prompt for user activeness. These lines illustrate almost of the ways the advent of a Text object may be modified, with results like in most word processors. The reference pages for graphics.py give the details. This reference is introduced soon in The Documentation for graphics.py.

After the prompt, the program looks for a response:

              # Get and describe three vertices of triangle              p1              =              win              .              getMouse              ()              p1              .              draw              (              win              )              p2              =              win              .              getMouse              ()              p2              .              draw              (              win              )              p3              =              win              .              getMouse              ()              p3              .              draw              (              win              )            

The win.getMouse() method (with no parameters), waits for yous to click the mouse inside win . Then the Point where the mouse was clicked is returned. In this code 3 mouse clicks are waited for, remembered in variables p1 , p2 , and p3 , and the points are fatigued.

Next we introduce a very versatile type of graphical object, a Polygon , which may have any number of vertices specified in a list as its parameter. Nosotros run across that the methods setFill and setOutline that we used earlier on a Circle , and the setWidth method nosotros used for a Line , also apply to a Polygon , (and also to other graphics objects).

              vertices              =              [              p1              ,              p2              ,              p3              ]              triangle              =              Polygon              (              vertices              )              triangle              .              setFill              (              'gray'              )              triangle              .              setOutline              (              'cyan'              )              triangle              .              setWidth              (              4              )              triangle              .              draw              (              win              )            

Too changing the fashion of a Text object, the text itself may be inverse:

              message              .              setText              (              'Click anywhere to quit'              )            

Then lines responding to this prompt:

              win              .              getMouse              ()              win              .              shut              ()            

If you desire to apply an existing Text object to display the quitting prompt, as I did here, I provide a variation on my window closing method that could supervene upon the concluding iii lines:

An existing Text object may be given every bit parameter rather than coordinates for a new text object. The complete code with that substitution is in triangle2.py .

If you want to make regular polygons or stars, y'all need some trigonometry, not required for this tutorial, but you can see its use in example polygons.py .

2.4.3. A Windows Operating Organisation Specialization: .pyw¶

This Windows-specific section is not essential. It does draw how to brand some Windows graphical programs run with less clutter.

If you ran the triangle.py program by double clicking its icon under Windows, you might take noticed a console window first appearing, followed past the graphics window. For this program, at that place was no keyboard input or screen output through the panel window, so the console window was unused and unnecessary. In such cases, nether Windows, you can change the source file extension from .py to .pyw, suppressing the display of the console window. If you lot are using Windows, alter the filename triangle.py to triangle.pyw , double click on the icon in its directory folder, and check information technology out.

The distinction is irrelevant inside Idle, which always has its Shell window.

2.iv.4. Graphics.py vs. Outcome Driven Graphics¶

This optional section only looks forward to more elaborate graphics systems than are used in this tutorial.

One limitation of the graphics.py module is that information technology is not robust if a graphics window is closed by clicking on the standard operating system close button on the title bar. If you shut a graphics window that way, you are likely to get a Python error message. On the other hand, if your plan creates a graphics window and then terminates abnormally due to some other error, the graphics window may exist left orphaned. In this example the close button on the title bar is important: information technology is the easiest method to clean upwards and get rid of the window!

This lack of robustness is tied to the simplification designed into the graphics module. Modernistic graphics environments are event driven. The plan tin be interrupted by input from many sources including mouse clicks and key presses. This style of programming has a considerable learning curve. In Zelle's graphics packet, the complexities of the result driven model are pretty well hidden. If the developer wants user input, only one blazon can exist specified at a time (either a mouse click in the graphics window via the getMouse method, or via the input keyboard entry methods into the Beat window).

2.4.5. The Documentation for graphics.py

Thus far various parts of Zelle's graphics package have been introduced by instance. A systematic reference to Zelle's graphics packet with the form of all function calls is at http://mcsp.wartburg.edu/zelle/python/graphics/graphics/alphabetize.html. Nosotros have introduced most of the important concepts and methods.

One special graphics input object type, Entry , will be discussed subsequently. You might skip it for now. Another section of the reference that volition not be pursued in the tutorials is the Epitome grade.

Meanwhile you can expect at http://mcsp.wartburg.edu/zelle/python/graphics/graphics/alphabetize.html. Information technology is important to pay attention to the organization of the reference: Virtually graphics object share a number of common methods. Those methods are described together, start. Then, under the headings for specific types, merely the specialized additional methods are discussed.

The version for this Tutorial has a few elaborations. Here is all their documentation together:

GraphWin method yUp (y increases up)

When y'all first create a GraphWin, the y coordinates increase downward the screen. To reverse to the normal orientation employ my GraphWin yUp method.

                  win                  =                  Graphwin                  (                  'Correct side up'                  ,                  300                  ,                  400                  )                  win                  .                  yUp                  ()                
GraphWin method promptClose (Prompt and Close Graphics Window)

You generally want to go on displaying your graphics window until the user chooses to have it closed. The GraphWin promptClose method posts a prompt, waits for a mouse click, and closes the GraphWin. There are two means to call it, depending on whether you desire to utilise an existing Text object, or simply specify a location for the center of the prompt.

                  win                  .                  promptClose                  (                  win                  .                  getWidth                  ()                  /                  2                  ,                  xxx                  )                  # specify 10, y coordinates of prompt                

or

                  msg                  =                  Text                  (                  Signal                  (                  100                  ,                  50                  ),                  'Original message...'                  )                  msg                  .                  depict                  (                  win                  )                  # ...                  # ... simply important that at that place is a drawn Text object                  win                  .                  promptClose                  (                  msg                  )                  # use existing Text object                
String Representations of all Graphics Object Types

Each graphical blazon tin can exist converted to a cord or printed, and a descriptive string is produced (for debugging purposes). It but shows position, not other parts of the state of the object.

                  >>>                                    pt                  =                  Bespeak                  (                  30                  ,                  50                  )                  >>>                                    impress                  (                  pt                  )                  Point(30, 50)                  >>>                                    ln                  =                  Line                  (                  pt                  ,                  Point                  (                  100                  ,                  150                  ))                  >>>                                    impress                  (                  ln                  )                  Line(Point(30, 50), Point(100, 150))                

2.4.5.1. Scene Do¶

Make a plan scene.py creating a scene with the graphics methods. You are likely to need to adjust the positions of objects by trial and error until you lot become the positions you want. Brand sure you have graphics.py in the same directory as your program.

2.4.5.2. Changing Scene Do¶

Elaborate the scene program above so it becomes changeScene.py , and changes one or more times when you click the mouse (and use win.getMouse() ). Y'all may utilise the position of the mouse click to impact the result, or information technology may only indicate you lot are set up to go on to the next view.

ii.4.half dozen. Issues with Mutable Objects¶

Zelle chose to have the constructor for a Rectangle take diagonally opposite corner points every bit parameters. Suppose you prefer to specify but one corner and likewise specify the width and height of the rectangle. You might come upward with the post-obit part, makeRect , to return such a new Rectangle. Read the following try:

              def              makeRect              (              corner              ,              width              ,              height              ):              '''Return a new Rectangle given one corner Point and the dimensions.'''              corner2              =              corner              corner2              .              move              (              width              ,              height              )              return              Rectangle              (              corner              ,              corner2              )            

The 2nd corner must be created to use in the Rectangle constructor, and it is done above in two steps. Starting time corner2 from the given corner and shift information technology past the dimensions of the Rectangle to the other corner. With both corners specified, you can utilise Zelle'south version of the Rectangle constructor.

Unfortunately this is an incorrect argument. Run the example programme makeRectBad.py :

              '''Program: makeRectBad.py              Effort a part makeRect (incorrectly),              which takes a takes a corner point and dimensions to construct a Rectangle.              '''              from              graphics              import              *              def              makeRect              (              corner              ,              width              ,              meridian              ):              # Incorrect!              '''Return a new Rectangle given one corner Point and the dimensions.'''              corner2              =              corner              corner2              .              move              (              width              ,              height              )              render              Rectangle              (              corner              ,              corner2              )              def              principal              ():              win              =              GraphWin              (              'Draw a Rectangle (Non!)'              ,              300              ,              300              )              win              .              yUp              ()              rect              =              makeRect              (              Betoken              (              20              ,              fifty              ),              250              ,              200              )              rect              .              draw              (              win              )              win              .              promptClose              (              win              .              getWidth              ()              /              two              ,              20              )              primary              ()            

By stated blueprint, this programme should draw a rectangle with one corner at the bespeak (20,50) and the other corner at (xx+250,50+200) or the point (270,250), and then the rectangle should take up nearly of the 300 by 300 window. When you run information technology however that is not what you lot see. Wait carefully. You should just see one Point toward the upper correct corner, where the second corner should exist. Since a Rectangle was beingness drawn, it looks like it is the tiniest of Rectangle s, where the opposite corners are at the same indicate! Hm, well the program did make the corners be the aforementioned initially. Recall we prepare

What happens after that?

Read and follow the details of what happens.

We need to have a much more conscientious look at what naming an object means. A good style to visualize this clan between a name and an object is to draw an pointer from the name to the object associated with it. The object here is a Betoken , which has an 10 and y coordinate describing its state, so when the makeRect method is started the parameter name corner is associated with the actual parameter, a Point with coordinates (20, 50).

image

Next, the assignment argument associates the name corner2 with the same object. It is some other proper noun, or alias, for the original Point .

image

The adjacent line,

              corner2              .              movement              (              width              ,              tiptop              )            

internally changes or mutates the Point object, and since in this case width is 250 and height is 200, the coordinates of the Bespeak associated with the name corner2 change to 20+250=270 and l+200=250:

image

Look! The proper noun corner is still associated with the same object, merely that object has inverse internally! That is the problem: we wanted to proceed the name corner associated with the point with original coordinates, but it has been modified.

The solution is to apply the clone method that is divers for all the graphical objects in graphics.py. It creates a split up object, which is a re-create with an equivalent state. We just need to change the line

to

A diagram of the situation after the cloning is:

image

Though corner and corner2 refer to points with equivalent coordinates, they practise not refer to the same object. And then subsequently

              corner2              .              move              (              width              ,              height              )            

we become:

image

No disharmonize: corner and corner2 refer to the corners we desire. Run the corrected example program, makeRectangle.py .

2.4.seven. More than on Mutable and Immutable Types¶

Read this section if you want a deeper understanding of the significance of mutable and immutable objects.

This alias problem merely came up considering a Signal is mutable. We had no such problems with the immutable types int or str .

Read and follow the give-and-take of the following code.

Merely for comparison, consider the respective diagrams for code with int s that looks superficially similar:

Afterwards the first two lines nosotros have an alias once again:

image

The third line does not change the int object 2. The result of the add-on performance refers to a different object, 5, and the proper name b is assigned to information technology:

image

Hence a is even so associated with the integer two - no disharmonize.

It is not technically correct to think of b every bit existence the number 2, and and so five, but a little sloppiness of thought does non get yous in trouble with immutable types. With mutable types, still, be very careful of aliases. Then it is very important to retrieve the indirectness: that a name is non the same affair as the object it refers to.

Another mutable type is list . A list can be cloned with the piece notation: [:]. Try the following in the Trounce: [2]

              nums              =              [              one              ,              2              ,              3              ]              numsAlias              =              nums              numsClone              =              nums              [:]              nums              .              append              (              four              )              numsAlias              .              suspend              (              5              )              nums              numsAlias              numsClone            

two.4.eight. Animation¶

Run the instance programme, backAndForth0.py. The whole program is shown below for convenience. Then each individual new part of the code is discussed individually:

              '''Test animation and depth.              '''              from              graphics              import              *              import              time              def              chief              ():              win              =              GraphWin              (              'Back and Forth'              ,              300              ,              300              )              win              .              yUp              ()              # make right side up coordinates!              rect              =              Rectangle              (              Point              (              200              ,              90              ),              Point              (              220              ,              100              ))              rect              .              setFill              (              "blue"              )              rect              .              depict              (              win              )              cir1              =              Circle              (              Betoken              (              xl              ,              100              ),              25              )              cir1              .              setFill              (              "yellow"              )              cir1              .              describe              (              win              )              cir2              =              Circle              (              Bespeak              (              150              ,              125              ),              25              )              cir2              .              setFill              (              "red"              )              cir2              .              describe              (              win              )              for              i              in              range              (              46              ):              cir1              .              move              (              5              ,              0              )              time              .              sleep              (              .              05              )              for              i              in              range              (              46              ):              cir1              .              move              (              -              5              ,              0              )              time              .              slumber              (              .              05              )              win              .              promptClose              (              win              .              getWidth              ()              /              2              ,              20              )              master              ()            

Read the discussion below of pieces of the lawmaking from the program in a higher place. Do not try to execute fragments alone.

There are both an onetime and a new course of import statement:

              from              graphics              import              *              import              fourth dimension            

The program uses a office from the time module. The syntax used for the fourth dimension module is really the safer and more typical mode to import a module. Every bit you will see later in the program, the sleep part used from the fourth dimension module will be referenced as time.sleep() . This tells the Python interpreter to wait in the time module for the sleep function.

If we had used the import argument

and then the sleep function could but be referenced with sleep() . This is obviously easier, but it obscures the fact that the slumber function is not a role of the current module. Also several modules that a program imports might have functions with the same proper name. With the private module name prefix, there is no ambiguity. Hence the form import moduleName is really safer than from moduleName import * .

You might think that all modules could avoid using any of the same role names with a bit of planning. To get an idea of the magnitude of the outcome, have a look at the number of modules available to Python. Endeavor the post-obit in the in the Shell (and likely look a number of seconds):

Without module names to separate things out, it would be very hard to totally avoid name collisions with the enormous number of modules y'all run across displayed, that are all bachelor to Python!

Back to the electric current example program: The primary program starts with standard window creation, and then makes iii objects:

              rect              =              Rectangle              (              Signal              (              200              ,              90              ),              Point              (              220              ,              100              ))              rect              .              setFill              (              'blue'              )              rect              .              draw              (              win              )              cir1              =              Circumvolve              (              Indicate              (              twoscore              ,              100              ),              25              )              cir1              .              setFill              (              'yellow'              )              cir1              .              draw              (              win              )              cir2              =              Circle              (              Indicate              (              150              ,              125              ),              25              )              cir2              .              setFill              (              'red'              )              cir2              .              draw              (              win              )            

Zelle's reference pages do non mention the fact that the order in which these object are outset drawn is significant. If objects overlap, the ones which used the describe method subsequently appear on acme. Other object methods like setFill or move practice not alter which are in front of which. This becomes significant when cir1 moves. The moving cir1 goes over the rectangle and behind cir2 . (Run the program once again if you missed that.)

The animation starts with the code for a simple repeat loop:

              for              i              in              range              (              46              ):              # breathing cir1 to the right              cir1              .              motility              (              v              ,              0              )              fourth dimension              .              sleep              (              .              05              )            

This very simple loop animates cir1 moving in a straight line to the correct. Equally in a movie, the illusion of continuous motion is given by jumping only a short distance each time (increasing the horizontal coordinate past 5). The time.slumber function, mentioned earlier, takes as parameter a time in seconds to have the plan sleep, or delay, before continuing with the iteration of the loop. This delay is of import, because modern computers are so fast, that the intermediate motion would be invisible without the delay. The filibuster tin be given as a decimal, to permit the fourth dimension to exist a fraction of a second.

The next three lines are well-nigh identical to the previous lines, and move the circle to the left (-5 in the horizontal coordinate each fourth dimension).

              for              i              in              range              (              46              ):              # animate cir1 to the left              cir1              .              move              (              -              5              ,              0              )              time              .              sleep              (              .              05              )            

The next case program, backAndForth1.py, information technology only a slight variation, looking to the user simply like the concluding version. Only the small changes are shown below. This version was written after noticing how similar the two animation loops are, suggesting an improvement to the programme: Animating whatsoever object to move in a straight line is a logical brainchild well expressed via a function.

The loop in the initial version of the plan contained a number of arbitrarily called constants, which make sense to turn into parameters. Also, the object to be animated does not need to be cir1 , it can exist any of the drawable objects in the graphics package. The name shape is used to make this a parameter:

              def              moveOnLine              (              shape              ,              dx              ,              dy              ,              repetitions              ,              delay              ):              for              i              in              range              (              repetitions              ):              shape              .              motion              (              dx              ,              dy              )              time              .              slumber              (              delay              )            

And so in the main function the ii like animation loops are reduced to a line for each direction:

              moveOnLine              (              cir1              ,              v              ,              0              ,              46              ,              .              05              )              moveOnLine              (              cir1              ,              -              v              ,              0              ,              46              ,              .              05              )            

Make sure you come across these two lines with function calls behave the same manner equally the two animation loops in the chief program of the original version.

Run the next example version, backAndForth2.py. The changes are more than substantial here, and the display of the whole program is followed by display and discussion of the private changes:

              '''Test animation of a group of objects making a face.              '''              from              graphics              import              *              import              time              def              moveAll              (              shapeList              ,              dx              ,              dy              ):              ''' Move all shapes in shapeList past (dx, dy).'''              for              shape              in              shapeList              :              shape              .              movement              (              dx              ,              dy              )              def              moveAllOnLine              (              shapeList              ,              dx              ,              dy              ,              repetitions              ,              filibuster              ):              '''Breathing the shapes in shapeList along a line.                              Move by (dx, dy) each fourth dimension.                              Repeat the specified number of repetitions.                              Have the specified filibuster (in seconds) after each repeat.                              '''              for              i              in              range              (              repetitions              ):              moveAll              (              shapeList              ,              dx              ,              dy              )              fourth dimension              .              slumber              (              filibuster              )              def              main              ():              win              =              GraphWin              (              'Back and Forth'              ,              300              ,              300              )              win              .              yUp              ()              # make right side upwardly coordinates!              rect              =              Rectangle              (              Point              (              200              ,              xc              ),              Point              (              220              ,              100              ))              rect              .              setFill              (              "blueish"              )              rect              .              draw              (              win              )              head              =              Circle              (              Point              (              40              ,              100              ),              25              )              head              .              setFill              (              "yellowish"              )              caput              .              draw              (              win              )              eye1              =              Circumvolve              (              Signal              (              thirty              ,              105              ),              5              )              eye1              .              setFill              (              'blueish'              )              eye1              .              draw              (              win              )              eye2              =              Line              (              Betoken              (              45              ,              105              ),              Betoken              (              55              ,              105              ))              eye2              .              setWidth              (              3              )              eye2              .              draw              (              win              )              mouth              =              Oval              (              Point              (              30              ,              90              ),              Point              (              l              ,              85              ))              oral fissure              .              setFill              (              "red"              )              mouth              .              describe              (              win              )              faceList              =              [              head              ,              eye1              ,              eye2              ,              mouth              ]              cir2              =              Circle              (              Point              (              150              ,              125              ),              25              )              cir2              .              setFill              (              "red"              )              cir2              .              draw              (              win              )              moveAllOnLine              (              faceList              ,              v              ,              0              ,              46              ,              .              05              )              moveAllOnLine              (              faceList              ,              -              five              ,              0              ,              46              ,              .              05              )              win              .              promptClose              (              win              .              getWidth              ()              /              2              ,              20              )              primary              ()            

Read the following discussion of program parts.

Moving a single unproblematic shape is rather limiting. It is much more interesting to compose a more complicated combination, like the face up from the earlier example face.py . To animate such a combination, y'all cannot utilise the old moveOnLine role, because we want all the parts to movement together, not ane eye all the way across the screen and and then have the other eye catch upwards! A variation on moveOnLine is needed where all the parts motility together. We demand all the parts of the face to move one step, and then sleep once, and all move once more, slumber once, .... This could all exist coded in a unmarried method, merely there are really two ideas here:

  1. Moving a group of objects 1 stride.
  2. Animative a number of moves for the grouping.

This suggests two functions. Another event is how to handle a grouping of uncomplicated graphics objects. The most basic combination of objects in Python is a list , and then we assume a parameter shapeList , which is a list of uncomplicated graphics objects. For the get-go function, moveAll, just movement all the objects in the listing one step. Since we assume a list of objects and nosotros want to move each, this suggests a for-each loop:

              def              moveAll              (              shapeList              ,              dx              ,              dy              ):              ''' Move all shapes in shapeList past (dx, dy).'''              for              shape              in              shapeList              :              shape              .              movement              (              dx              ,              dy              )            

Having this function, we tin easily write the 2nd role moveAllOnLine , with a simple modify from the moveOnLine office, substituting the moveAll function for the line with the motion method:

              def              moveAllOnLine              (              shapeList              ,              dx              ,              dy              ,              repetitions              ,              delay              ):              '''Animate the shapes in shapeList along a line.                              Move by (dx, dy) each time.                              Repeat the specified number of repetitions.                              Have the specified delay (in seconds) after each repeat.                              '''              for              i              in              range              (              repetitions              ):              moveAll              (              shapeList              ,              dx              ,              dy              )              time              .              sleep              (              filibuster              )            

The code in chief to construct the face is the aforementioned equally in the earlier example confront.py . Once all the pieces are synthetic and colored, they must be placed in a listing, for use in moveAllOnLine :

              faceList              =              [              head              ,              eye1              ,              eye2              ,              mouth              ]            

Then, later, the animation uses the faceList to make the confront go back and forth:

              moveAllOnLine              (              faceList              ,              v              ,              0              ,              46              ,              .              05              )              moveAllOnLine              (              faceList              ,              -              5              ,              0              ,              46              ,              .              05              )            

This version of the program has encapsulated and generalized the moving and animating by creating functions and adding parameters that can be substituted. Once again, brand sure you see how the functions communicate to make the whole plan work. This is an important and non-piddling use of functions.

In fact all parts of the face do not actually motility at once: The moveAll loop lawmaking moves each part of the face up separately, in sequence. Depending on your reckoner setup, all the parts of the face may announced to move together. Again, the reckoner is much faster than our optics. On a computer that repaints the screen fast plenty, the only images nosotros notice are the ones on the screen when the animation is sleeping.

Notation

On a fast plenty computer you lot tin brand many consecutive changes to an epitome before the next slumber statement, and they all appear to happen at once in the animation.

Optional refinement: Not all computers are prepare for the same graphics speed in Python. One machine that I apply animates backAndForth2.py quite well. Another seems to have the mouth wiggle. On the latter sort of machine, during animation it is useful not to have visible screen changes for every private motility. Instead you can explicitly tell the estimator when it is the right time to redraw the screen. The computer can store changes and then update the screen. Withholding updates is controlled past win.autoflush . It starts as True, merely can exist changed to False before animation. When set to False, you must call update() every time you lot want the screen refreshed. That is going to exist just before the time.sleep() in an animation. In backAndForth2Update.py this is illustrated, with moveAllOnLine replaced by moveAllOnLineUpdate :

              #NEW update version, added win param              def              moveAllOnLineUpdate              (              shapeList              ,              dx              ,              dy              ,              repetitions              ,              delay              ,              win              ):              '''Animate the shapes in shapeList along a line in win.                              Movement past (dx, dy) each time.                              Repeat the specified number of repetitions.                              Have the specified delay (in seconds) after each repeat.                              '''              win              .              autoflush              =              False              # NEW: set before blitheness              for              i              in              range              (              repetitions              ):              moveAll              (              shapeList              ,              dx              ,              dy              )              update              ()              # NEW needed to make all the changes appear              fourth dimension              .              slumber              (              delay              )              win              .              autoflush              =              True              # NEW: set afterwards animation            

Run the adjacent instance programme backAndForth3.py .

The final version, backAndForth3.py and its variant, backAndForth3Update.py , employ the ascertainment that the code to make a confront embodies one unified idea, suggesting encapsulation inside a office. Once y'all have encapsulated the code to make a face, nosotros can make several faces! So the trouble with the original lawmaking for the face is that all the positions for the facial elements are hard-coded: The face can but exist drawn in one position. The full listing of backAndForth3.py below includes a makeFace function with a parameter for the position of the center of the face.

Below the listing of the whole plan is a discussion of the individual changes:

              '''Exam animation of a group of objects making a confront.              Combine the face up elements in a role, and apply it twice.              Have an extra level of repetition in the blitheness.              This version may exist wobbly and slow on some machines:              Then see backAndForthFlush.py.              '''              from              graphics              import              *              import              time              def              moveAll              (              shapeList              ,              dx              ,              dy              ):              ''' Move all shapes in shapeList by (dx, dy).'''              for              shape              in              shapeList              :              shape              .              move              (              dx              ,              dy              )              def              moveAllOnLine              (              shapeList              ,              dx              ,              dy              ,              repetitions              ,              delay              ):              '''Animate the shapes in shapeList along a line.                              Motion by (dx, dy) each time.                              Echo the specified number of repetitions.                              Accept the specified delay (in seconds) after each repeat.                              '''              for              i              in              range              (              repetitions              ):              moveAll              (              shapeList              ,              dx              ,              dy              )              time              .              sleep              (              delay              )              def              makeFace              (              heart              ,              win              ):              '''display face centered at center in window win.                              Return a listing of the shapes in the face.                              '''              caput              =              Circumvolve              (              eye              ,              25              )              head              .              setFill              (              "yellow"              )              caput              .              draw              (              win              )              eye1Center              =              center              .              clone              ()              # face positions are relative to the heart              eye1Center              .              move              (              -              10              ,              5              )              # locate further points in relation to others              eye1              =              Circle              (              eye1Center              ,              5              )              eye1              .              setFill              (              'bluish'              )              eye1              .              draw              (              win              )              eye2End1              =              eye1Center              .              clone              ()              eye2End1              .              move              (              fifteen              ,              0              )              eye2End2              =              eye2End1              .              clone              ()              eye2End2              .              move              (              10              ,              0              )              eye2              =              Line              (              eye2End1              ,              eye2End2              )              eye2              .              setWidth              (              3              )              eye2              .              draw              (              win              )              mouthCorner1              =              centre              .              clone              ()              mouthCorner1              .              move              (              -              10              ,              -              10              )              mouthCorner2              =              mouthCorner1              .              clone              ()              mouthCorner2              .              movement              (              20              ,              -              five              )              mouth              =              Oval              (              mouthCorner1              ,              mouthCorner2              )              mouth              .              setFill              (              "red"              )              mouth              .              draw              (              win              )              render              [              head              ,              eye1              ,              eye2              ,              mouth              ]              def              chief              ():              win              =              GraphWin              (              'Back and Along'              ,              300              ,              300              )              win              .              yUp              ()              # make right side upward coordinates!              rect              =              Rectangle              (              Betoken              (              200              ,              xc              ),              Indicate              (              220              ,              100              ))              rect              .              setFill              (              "bluish"              )              rect              .              depict              (              win              )              faceList              =              makeFace              (              Point              (              40              ,              100              ),              win              )              faceList2              =              makeFace              (              Point              (              150              ,              125              ),              win              )              stepsAcross              =              46              dx              =              5              dy              =              3              wait              =              .              05              for              i              in              range              (              3              ):              moveAllOnLine              (              faceList              ,              dx              ,              0              ,              stepsAcross              ,              wait              )              moveAllOnLine              (              faceList              ,              -              dx              ,              dy              ,              stepsAcross              //              2              ,              wait              )              moveAllOnLine              (              faceList              ,              -              dx              ,              -              dy              ,              stepsAcross              //              ii              ,              wait              )              win              .              promptClose              (              win              .              getWidth              ()              /              ii              ,              20              )              main              ()            

Read the following discussion of program parts.

As mentioned to a higher place, the face construction function allows a parameter to specify where the center of the face is. The other parameter is the GraphWin that will contain the confront.

              def              makeFace              (              centre              ,              win              ):            

then the head is easily drawn, using this center , rather than the previous cir1 with its specific center betoken (forty, 100):

              caput              =              Circumvolve              (              centre              ,              25              )              head              .              setFill              (              'yellow'              )              head              .              describe              (              win              )            

For the remaining Point s used in the construction there is the issue of keeping the right relation to the center. This is accomplished much as in the creation of the second corner betoken in the makeRectangle role in Section Issues with Mutable Objects. A clone of the original center Signal is made, and and so moved by the difference in the positions of the originally specified Point s. For case, in the original confront, the heart of the caput and first eye were at (40, 110) and (30, 115) respectively. That means a shift between the two coordinates of (-10, 5), since 30-40 = -10 and 130-110 = 20.

              eye1Center              =              centre              .              clone              ()              # face positions are relative to the center              eye1Center              .              movement              (              -              10              ,              five              )              # locate further points in relation to others              eye1              =              Circle              (              eye1Center              ,              5              )              eye1              .              setFill              (              'blueish'              )              eye1              .              draw              (              win              )            

The only other changes to the face are like, cloning and moving Indicate s, rather than specifying them with explicit coordinates.

              eye2End1              =              eye1Center              .              clone              ()              eye2End1              .              move              (              fifteen              ,              0              )              eye2End2              =              eye2End1              .              clone              ()              eye2End2              .              move              (              ten              ,              0              )              eye2              =              Line              (              eye2End1              ,              eye2End2              )              eye2              .              setWidth              (              three              )              eye2              .              depict              (              win              )              mouthCorner1              =              centre              .              clone              ()              mouthCorner1              .              move              (              -              ten              ,              -              10              )              mouthCorner2              =              mouthCorner1              .              clone              ()              mouthCorner2              .              move              (              xx              ,              -              5              )              oral fissure              =              Oval              (              mouthCorner1              ,              mouthCorner2              )              rima oris              .              setFill              (              'ruddy'              )              mouth              .              describe              (              win              )            

Finally, the list of elements for the face must be returned to the caller:

              return              [              head              ,              eye1              ,              eye2              ,              mouth              ]            

Then in the principal function, the program creates a face up in exactly the same identify as before, but using the makeFace function, with the original center of the face up Bespeak(40, 100) every bit parameter. Now with the makeFace part, with its heart parameter, it is also easy to supersede the old cir2 with a whole confront!

              faceList              =              makeFace              (              Point              (              40              ,              100              ),              win              )              faceList2              =              makeFace              (              Point              (              150              ,              125              ),              win              )            

The animation section is considerably elaborated in this version.

              stepsAcross              =              46              dx              =              v              dy              =              3              wait              =              .              01              for              i              in              range              (              3              ):              moveAllOnLine              (              faceList              ,              dx              ,              0              ,              stepsAcross              ,              wait              )              moveAllOnLine              (              faceList              ,              -              dx              ,              dy              ,              stepsAcross              //              2              ,              wait              )              moveAllOnLine              (              faceList              ,              -              dx              ,              -              dy              ,              stepsAcross              //              2              ,              wait              )            

The unidentified numeric literals that were used before are replaced by named values that hands identify the meaning of each one. This likewise allows the numerical values to be stated only once, assuasive piece of cake modification.

The whole animation is repeated 3 times past the utilize of a simple repeat loop. Since moveAllOnLine has a for-loop within it, it illustrates nesting of loops.

The animations in the loop body illustrate that the straight line of movement does non need to be horizontal. The second and third lines utilise a not-zero value of both dx and dy for the steps, and motion diagonally.

Make sure you lot encounter at present how the whole program works together, including all the parameters for the moves in the loop.

By the way, the documentation of the functions in a module you have but run in the Beat is directly available. Endeavour in the Shell:

2.4.8.1. Nose in Face Exercise¶

* Save backAndForth3.py or backAndForth3Update.py to the new name backAndForth4.py . Add together a triangular nose in the middle of the face up in the makeFace role. Like the other features of the face, make sure the position of the nose is relative to the center parameter. Make sure the nose is included in the final listing of elements of the face that get returned!

2.iv.8.2. Faces Practice¶

* Make a program faces.py that asks the user to click the mouse, and and so draws a face at the bespeak where the user clicked. Copy the makeFace function definition from the previous do, and utilize it! Elaborate this with a Simple Echo Loop, so this is repeated six times: After each of six mouse clicks, a confront immediately appears at the location of the latest click. Call back how yous tin can reuse your code each time through the loop!

2.4.eight.3. Moving Faces Do¶

* Animate 2 faces moving in dissimilar directions at the same time in a plan move2Faces.py . You lot cannot use the moveAllOnLine function. You will have to make a variation of your ain. You tin use the moveAll function separately for each face.

Hint: imagine the onetime way of making an animated cartoon. If each face was on a split up piece of newspaper, and you wanted to animate them moving together, y'all would identify them separately, record ane frame, move them each a bit toward each other, record another frame, motion each another chip toward each other, record another frame, .... In our animations "record a frame" is replaced by a short sleep to make the position visible to the user. Brand a loop to contain the repetition of the moves.

2.four.ix. Entry Objects¶

(Optional department) Read this section if you desire to permit the user to enter text directly into a graphics window.

When using a graphics window, the shell window is all the same available. Keyboard input tin can exist washed in the normal text fashion, waiting for a response, and going on after the user presses the Enter key. Information technology is annoying to make a user pay attention to 2 windows, and so the graphics module provides a mode to enter text within a graphics window, with the Entry type. The entry is a fractional replacement for the input function.

Run the simple case, greet.py, which is copied below:

              """Elementary example with Entry objects.              Enter your proper noun, click the mouse, and see greetings.              """              from              graphics              import              *              def              main              ():              win              =              GraphWin              (              "Greeting"              ,              300              ,              300              )              win              .              yUp              ()              instructions              =              Text              (              Bespeak              (              win              .              getWidth              ()              /              2              ,              xl              ),              "Enter your name.              \north              Then click the mouse."              )              instructions              .              draw              (              win              )              entry1              =              Entry              (              Signal              (              win              .              getWidth              ()              /              2              ,              200              ),              10              )              entry1              .              depict              (              win              )              Text              (              Betoken              (              win              .              getWidth              ()              /              2              ,              230              ),              'Name:'              )              .              describe              (              win              )              # label for the Entry              win              .              getMouse              ()              # To know the user is finished with the text.              name              =              entry1              .              getText              ()              greeting1              =              'Hello, '              +              proper noun              +              '!'              Text              (              Bespeak              (              win              .              getWidth              ()              /              3              ,              150              ),              greeting1              )              .              draw              (              win              )              greeting2              =              'Bonjour, '              +              name              +              '!'              Text              (              Bespeak              (              ii              *              win              .              getWidth              ()              /              3              ,              100              ),              greeting2              )              .              draw              (              win              )              win              .              promptClose              (              instructions              )              chief              ()            

The only part of this with new ideas is:

              entry1              =              Entry              (              Point              (              win              .              getWidth              ()              /              2              ,              200              ),              10              )              entry1              .              depict              (              win              )              Text              (              Betoken              (              win              .              getWidth              ()              /              two              ,              230              ),              'Proper noun:'              )              .              describe              (              win              )              # characterization for the Entry              win              .              getMouse              ()              # To know the user is finished with the text.              name              =              entry1              .              getText              ()            

The first line of this extract creates an Entry object, supplying its centre point and a number of characters to exit infinite for (ten in this example).

Equally with other places where input is requested, a separate static characterization is added.

The way the underlying events are hidden in graphics.py, in that location is no signal when the user is washed inbound text in an Entry box. To betoken the program, a mouse press is used above. In this case the location of the mouse printing is non relevant, but once the mouse press is processed, execution can go on and read the Entry text. The method name getText is the aforementioned as that used with a Text object.

Run the side by side instance, addEntries.py, also copied below:

              """Example with two Entry objects and type conversion.              Do addition.              """              from              graphics              import              *              def              principal              ():              win              =              GraphWin              (              "Addition"              ,              300              ,              300              )              win              .              yUp              ()              instructions              =              Text              (              Signal              (              win              .              getWidth              ()              /              2              ,              thirty              ),              "Enter two numbers.              \n              Then click the mouse."              )              instructions              .              draw              (              win              )              entry1              =              Entry              (              Point              (              win              .              getWidth              ()              /              2              ,              250              ),              25              )              entry1              .              setText              (              '0'              )              entry1              .              draw              (              win              )              Text              (              Bespeak              (              win              .              getWidth              ()              /              2              ,              280              ),              'Commencement Number:'              )              .              depict              (              win              )              entry2              =              Entry              (              Signal              (              win              .              getWidth              ()              /              2              ,              180              ),              25              )              entry2              .              setText              (              '0'              )              entry2              .              draw              (              win              )              Text              (              Point              (              win              .              getWidth              ()              /              2              ,              210              ),              'Second Number:'              )              .              draw              (              win              )              win              .              getMouse              ()              # To know the user is finished with the text.              numStr1              =              entry1              .              getText              ()              num1              =              int              (              numStr1              )              numStr2              =              entry2              .              getText              ()              num2              =              int              (              numStr2              )              sum              =              num1              +              num2              result              =              "The sum of              \n              {num1}              \northward              plus              \due north              {num2}              \n              is {sum}."              .              format              (              **              locals              ())              Text              (              Bespeak              (              win              .              getWidth              ()              /              two              ,              110              ),              result              )              .              draw              (              win              )              win              .              promptClose              (              instructions              )              main              ()            

As with the input statement, you lot can just read strings from an Entry . With conversions, information technology is still possible to piece of work with numbers.

Simply 1 new graphical method has been included higher up:

Again the same method proper name is used as with a Text object. In this example I chose not to get out the Entry initially blank. The 0 value too reinforces that a numerical value is expected.

There is also an entry2 with almost identical lawmaking. Afterward waiting for a mouse click, both entries are read, and the chosen names emphasizes they are strings. The strings must be converted to integers in order to practice arithmetics and display the result.

The most identical lawmaking for the ii entries is a strong proposition that this lawmaking could be written more hands with a role. You may look at the identically functioning example programme addEntries2.py . The only changes are shown below. Offset there is a office to create an Entry and a centered static characterization over information technology.

              def              makeLabeledEntry              (              entryCenterPt              ,              entryWidth              ,              initialStr              ,              labelText              ,              win              ):              '''Return an Entry object with specified heart, width in characters, and                              initial string value.  As well create a static label over information technology with                              specified text.  Depict everything in the GraphWin win.                              '''              entry              =              Entry              (              entryCenterPt              ,              entryWidth              )              entry              .              setText              (              initialStr              )              entry              .              draw              (              win              )              labelCenter              =              entryCenterPt              .              clone              ()              labelCenter              .              move              (              0              ,              thirty              )              Text              (              labelCenter              ,              labelText              )              .              draw              (              win              )              return              entry            

In case I desire to make more Entries with labels afterwards, and refer to this code again, I put some actress attempt in, making things be parameters even if only ane value is used in this programme. The position of the label is made 30 units in a higher place the entry by using the clone and move methods. Simply the Entry is returned, on the assumption that the characterization is static, and in one case it is drawn, I can forget well-nigh information technology. Since I do non refer later to the Text object, I do not carp to name information technology, merely just describe it immediately.

Then the corresponding alter in the chief function is just two calls to this part:

              entry1              =              makeLabeledEntry              (              Betoken              (              win              .              getWidth              ()              /              ii              ,              250              ),              25              ,              '0'              ,              'First Number:'              ,              win              )              entry2              =              makeLabeledEntry              (              Point              (              win              .              getWidth              ()              /              two              ,              180              ),              25              ,              '0'              ,              'Second Number:'              ,              win              )            

These lines illustrate that a statement may take more than than one line. In particular, equally in the Beat, Python is smart enough to realize that there must be a continuation line if the parentheses practise not lucifer.

While I was improving things, I also inverse the conversions to integers. In the first version I wanted to emphasize the existence of both the string and integer data equally a instruction signal, but the num1Str and num2Str variables were simply used once, so a more curtailed way to read and convert the values is to eliminate them:

              num1              =              int              (              entry1              .              getText              ())              num2              =              int              (              entry2              .              getText              ())            

2.4.10. Colour Names¶

Thus far we have merely used mutual color names. In fact there are a very big number of immune color names, and also the ability to depict with custom colors.

Starting time, the graphics package is built on an underlying graphics system, Tkinter, which has a big number of colour names defined. Each of the names can be used by itself, like 'reddish', 'salmon' or 'aquamarine' or with a lower intensity by specifying with a abaft number 2, 3, or 4, like 'red4' for a dark carmine.

Though the ideas for the coding have not all been introduced, it is still informative to run the case program colors.py . As you lot click the mouse over and over, you run across the names and appearances of a wide variety of congenital-in color names. The names must be place in quotes, simply capitalization is ignored.

2.iv.11. Custom Colors¶

Custom colors can also be created. To exercise that requires some agreement of human eyes and color (and the Python tools). The simply colors detected direct by the man eyes are blood-red, dark-green, and blue. Each amount is registered by a different kind of cone cell in the retina. As far every bit the eye is concerned, all the other colors nosotros see are just combinations of these three colors. This fact is used in color video screens: they merely direct brandish these iii colors. A mutual calibration to use in labeling the intensity of each of the bones colors (red, light-green, blueish) is from 0 to 255, with 0 meaning none of the colour, and 255 being the about intense. Hence a color tin be described by a sequence of red, green, and blue intensities (often abbreviated RGB). The graphics parcel has a part, color_rgb , to create colors this way. For instance a color with about half the maximum red intensity, no green, and maximum blue intensity would be

              aColor              =              color_rgb              (              128              ,              0              ,              255              )            

Such a creation can be used any identify a color is used in the graphics, (i.e. circumvolve.setFill(aColor) ).

ii.4.12. Random Colors¶

Some other interesting use of the color_rgb function is to create random colors. Run example programme randomCircles.py . The lawmaking also is hither:

              """Describe random circles.              """              from              graphics              import              *              import              random              ,              fourth dimension              def              main              ():              win              =              GraphWin              (              "Random Circles"              ,              300              ,              300              )              for              i              in              range              (              75              ):              r              =              random              .              randrange              (              256              )              b              =              random              .              randrange              (              256              )              g              =              random              .              randrange              (              256              )              color              =              color_rgb              (              r              ,              1000              ,              b              )              radius              =              random              .              randrange              (              3              ,              xl              )              ten              =              random              .              randrange              (              5              ,              295              )              y              =              random              .              randrange              (              five              ,              295              )              circle              =              Circumvolve              (              Point              (              10              ,              y              ),              radius              )              circumvolve              .              setFill              (              color              )              circle              .              draw              (              win              )              fourth dimension              .              sleep              (              .              05              )              win              .              promptClose              (              win              .              getWidth              ()              /              2              ,              20              )              main              ()            

Read the fragments of this program and their explanations:

To do random things, the program needs a function from the random module. This example shows that imported modules may be put in a comma separated list:

You accept already seen the congenital-in function range . To generate a sequence of all the integers 0, 1, ... 255, y'all would use

This is the total list of possible values for the carmine, light-green or blue intensity parameter. For this program we randomly choose any one element from this sequence. Instead of the range function, use the random module's randrange function, as in

              r              =              random              .              randrange              (              256              )              b              =              random              .              randrange              (              256              )              k              =              random              .              randrange              (              256              )              colour              =              color_rgb              (              r              ,              g              ,              b              )            

This gives randomly selected values to each of r , g , and b , which are and so used to create the random color .

I want a random circle radius, but I do not want a number as modest as 0, making information technology invisible. The range and randrange functions both refer to a possible sequence of values starting with 0 when a unmarried parameter is used. It is also possible to add a different starting value equally the outset parameter. Y'all withal must specify a value past the end of the sequence. For instance

would refer to the sequence 3, 4, 5, ... , 39 (starting with iii and not quite reaching 40). Similarly

randomly selects an arbitrary element of range(3, 40) .

I use the ii-parameter version to select random parameters for a Circumvolve:

              radius              =              random              .              randrange              (              3              ,              40              )              x              =              random              .              randrange              (              v              ,              295              )              y              =              random              .              randrange              (              5              ,              295              )              circumvolve              =              Circle              (              Bespeak              (              x              ,              y              ),              radius              )            

What are the smallest and largest values I permit for x and y? [three]

Random values are often useful in games.

2.4.12.1. Ranges Exercise¶

Write a program ranges.py in three parts. (Test after each added part.)

This problem is not a graphics plan. It is just a regular text program to illustrate your understanding of ranges and loops.

For simplicity each of the requested number sequences can just exist printed with one number per line. Print a label for each number sequence before you print the sequence, like Numbers one-4 , Numbers 1-n , Five random numbers in 1-n .

  1. First employ the range function and a for-loop to produce the sequence i, two, 3, four, and so impress the numbers, one number per line.
  2. Prompt the user to input an integer northward and print the sequence one, ii, 3, ... , north - including due north, using a for-loop. Hint: [iv]
  3. Apply a Simple Repeat Loop to detect and print five randomly called numbers from the range 1, 2, 3, ... , due north. Utilize the same value of north that the user chose before in the plan. Information technology should be possible that the number north is printed sometimes.

ii.4.12.2. Text Triangle Exercise¶

* Write a program texttriangle.py .

This, too, is not a graphics program. Prompt the user for a small positive integer value, that I'll call north . Then apply a for-loop with a range function call to make a triangular arrangement of '#'characters, with due north '#' characters in the last line. Hint: [5]

And then go out a blank line. Then make a like triangle, except start with the line with n '#' characters. To make the 2d triangle, you can use a for-loop of the class discussed so far, merely that is trickier than looking ahead to The Almost General range Function and using a for-loop where a range function call has a negative step size.

Here is the screen subsequently a posible run with user input 4:

                Enter                a                small                positive                integer                :                4                #                ##                ###                ####                ####                ###                ##                #              

And another possible run with user input ii:

                Enter                a                small                positive                integer                :                two                #                ##                ##                #              
[i] The basic ideas of objects and methods were introduced in Object Orientation.
[2] Actually, lists are fifty-fifty trickier, because private elements of a list may be mutable: Each mutable element in the cloned listing is an alias of the corresponding chemical element in the original list, so if you mutate its state in the cloned list, you also make a change to the original listing. This is distinct from the situation if you replace an element in the cloned listing by a totally dissimilar i: and so you do not alter the original listing.
[3] 5 and 294 (one less than 295).
[four] If iv or n is the last number, what is the offset number past the end of the sequence?
[5] A row of '#' characters is easiest if you recollect the cord multiplication operator *.