A Graphical Smile

Jed Rembold & Fred Agbo

February 14, 2024

Announcements

  • Project 1 is due on Monday next week at 10pm
  • Please attend your section! Attendance counts for participation
  • Majority of what you need for the project is learned in the section
  • Polling continues https://www.polleverywhere.com/agbofred203

Wordle Tidbits

  • Two useful ideas for Wordle:
    • You can check if an individual element is in a particular sequence of elements using the in keyword

      "1" in "12345"
      • Always returns a boolean (True/False)
    • You can change the case of all letters in a string using upper() or lower() methods

      lowered = "ABCDEF".lower()
      uppered = "abcDEF".upper()
      • The method returns a new string, so make sure you assign it to something

Other Simple Objects

  • Remember we introduced the GWindow(width, height) in last class

Functions to create simple geometric objects:

  • Rectangles!
    • GRect( x, y, width, height )
    • Creates a rectangle whose upper left corner is at (x,y) of the specified size
  • Circles/Ovals!
    • GOval( x, y, width, height )
    • Creates an oval that fits inside the rectangle with the same dimensions
  • Lines!
    • GLine( x1, y1, x2, y2 )
    • Creates a line extending from (x1,y1) to (x2,y2)

Classification

  • In the mid-18th century, Scandinavian botanist Carl Linnaeus revolutionized the field of biology by developing a new system for classifying plants and animals in a way that revealed their structural relationships.
  • Recognized that organisms fit into a hierarchy in which the placement of individual species reflects their anatomical similarities.
  • Paved the way for Darwin’s theory of evolution a century later
Carl Linnaeus

Biological Hierarchy

image/svg+xml Kingdom Phylum Class Order Family Genus Species

Instance vs Pattern

  • Important to distinguish between a class of object and a specific instance of that class
    • Iridomyrmex purpureus is a class of ant, not an individual ant
    • There can be many individual ants, all sharing the same class
  • Each ant is said to be an instance of a particular class
  • An individual ant belongs to a species class of purpureus, family of Formicidae, Phylum of Arthropoda, etc

The GObject Hierarchy

  • The types of graphical objects form a hierarchy:

image/svg+xml GObject GFillableObject GLine GRect GOval GLabel

  • The GObject class represents the collection of all graphical objects
  • The GFillableObject class represents those that have a fillable interior

Interacting with the GWindow

  • We’ve already shown creation:
gw = GWindow(width, height)
  • You have several more operations that you can apply to the GWindow object:
gw.add(object) Adds an object to the window
gw.add(object, x, y) Adds an object to the window after moving it to (x,y)
gw.remove(object) Removes an object from the window
gw.get_width() Returns the width of the graphics window in pixels
gw.get_height() Returns the height of the graphics window in pixels

Interacting with GObjects

  • The following operations apply to all GObjects, where object is the name of any specific instance.
object.get_x() Returns the x coordinate of this object
object.get_y() Returns the y coordinate of this object
object.get_width() Returns the width of this object
object.get_height() Returns the height of this object
object.set_color(color) Sets the color of the object to the specified color
  • All coordinates and distances are measured in pixels

Interacting with GFillableObjects

  • Fillable GObjects have a smaller subset of commands that also apply to them.
  • Initially the only fillable objects available to you are rectangles and ovals
object.set_filled(bool) Sets the fill state of the object
object.set_fill_color(color) Sets the color to be used to fill the interior, otherwise same as the outer line
object.get_fill_color() Gets the current color used to display the object interior
object.is_filled() Returns True or False depending on whether the object is currently filled

Smile!

gw = GWindow(400, 400)

head = GOval(20, 20, 360, 360)
head.set_fill_color("yellow")
head.set_filled(True)
gw.add(head)

reye = GOval(110, 100, 40, 40)
reye.set_filled(True)
gw.add(reye)

leye = GOval(250, 100, 40, 40)
leye.set_filled(True)
gw.add(leye)

mouth = GLine(150, 250, 250, 250)
mouth.set_line_width(5)
gw.add(mouth)
 

Label It!

  • Sometimes you need to add some text to the window
  • Can display any string using GLabel using the following format:
msg = GLabel(string_to_add, x_location, y_location)
  • Here string_to_add is the text you want to display, and x_location and y_location are the (x,y) coordinates of where you want to place the string

Label Geometry

  • The GLabel class relies on some geometrical concepts that are derived from classical typesetting
    • The baseline is the imaginary line on which the characters rest
    • The origin is the point on the baseline at which the text begins
    • The width is the horizontal distance from the origin to the end of the text
    • The height of the font is the distance between adjacent baselines
    • The ascent is the distance the characters rise above the baseline
    • The descent is the distance the characters drop below the baseline

image/svg+xml The quick brown foxjumped over the lazy dog Baseline Origin Descent Ascent Height Width
 

Interacting with Labels

  • A GLabel has several special methods that you can use to interact with it
    • You can use: get_width(), get_height(), get_ascent(), and get_descent() methods to obtain the geometric properties
    • You can set a special font for the label using
    labelname.set_font(font)
    • The font is a string comprised of the following elements:
      • The font style, which is usually blank or italic
      • The font weight, which is usually blank or bold
      • The font size, which is a number followed by the units (typically pt, px, or em)
      • The font family, which is the name of the font. Because what fonts are available can differ from machine to machine, the family is usually a sequence of fonts separated by commas
      • The font family sequence usually ends with a standard family (serif, sans-serif, or monospace) to ensure that the label can display

Label Example

gw = GWindow(500, 200)
msg = GLabel("hello world!", 50, 100)
msg.set_font("italic bold 80px 'times new roman'")
gw.add(msg)



A bold new (friendly) world

Centering a GLabel

  • Frequently useful to center within the window or some shape
  • To center properly, you need to know the label dimensions, but you can’t determine the dimensions until after you’ve created the label!
  • The main idea then is to:
    • Create a GLabel without setting its location
    • Call the .set_font() method to set the desired font (which could change the size)
    • Determine the horizontal position of the origin by subtracting half the width from the desired location x
    • Determine the vertical position of the baseline by adding half the ascent to the desired location y
    • Add the GLabel at the newly calculated position

Centering Example

gw = GWindow(500, 200)
msg = GLabel("hello world!")
msg.set_font("italic bold 20px 'times new roman'")
x = 250 - msg.get_width() / 2
y = 100 + msg.get_ascent() / 2
gw.add(msg, x, y)

Stepwise Refinement

  • The most effective way to solve complex problems is to break them down into successively smaller and simpler sub-problems
  • Start by breaking the whole task into simpler parts
    • Some of those parts may need more sub-parts
  • Entire process is called stepwise refinement or decomposition

Choosing a Decomposition

The proposed steps should be easy to explain.
One indication that you have succeeded is being able to find simple names.
The steps should be as general as possible.
Code gets reused all the time in programming. If your functions perform general tasks, they are much easier to reuse.
The steps should make sense at the level of abstraction in which they are used.
If you have a function or method that does the correct job but whose name doesn’t fit or make sense in the contex of the problem, consider defining a new method that calls the old one.

House Decomposition - try it

How could we think about decomposing the problem of drawing the below house?

image/svg+xml
Desired House
// reveal.js plugins