   Pygame Tutorial - Graphics
  Hello, I'm having much difficulty with a chapter from an online book.Here is the chapter:http://inventwithpython.com/chapter17.htmlHere is the source code:http://inventwithpython.com/pygameHelloWorld.pyThe confusion starts shortly after the bolded line:Fonts, and the pygame.font.SysFont() FunctionEverything makes sense until line 23.   He explains the code on line 22 very well, but then suddenly it seems like line 23 is skipped, there's no explanation on it.  I also don't understand line 24 or 25, there doesn't seem to be much of a direct explanation for those lines, which is uncharacteristic of the book. Instead, there is a sub heading titled Attributes where he talks about the pygame.Rect data type.  But I've looked over the lines of code carefully, and nowhere in the program is there any module named Rect.  However, there is a method called get_rect() that gets appended to the surface object.  He goes on to explain that the surface object is stored in the variable "text", and from what I can see, this surface object gets appended to the get_rect method, which I'm guessing turns it into a rect object, and this object is stored in the variable "textRect".   Establishing the textRect variable happens on line 23, and there is very little explanation on it.   I assume line 23 is the creation of the a rect object, but I could be wrong.My theory is that using the get_rect method somehow invokes the Rect module.  But don't you need to call the module first before you can use any of the modules methods? I read further along the chapter to get clearer on the get_rect method, but I found that it got more confusing.  He said:"Notice that both the Font object (stored in the text variable) and the Surface object (stored in windowSurface variable) both have a method called get_rect()."See, this seems to completely contradict what he said earlier as well as the code itself. Early in the chapter he said he stored the surface object in the text variable, and I can see that for myself.  The font object was stored in the basicFont variable, and I can see that as well.  Why is he saying the font object is stored in the text variable?  It's not.   Same for the surface object, it is clearly not stored int he windowSurface variable.   Very confusing!  To summarize my issues - his explanations don't seem to correspond with the code that's actually there. It's almost like he's talking about a different program. The book has been fantastic, and I've learned a lot, but chapter 17 is really giving me trouble.Hopefully the problem is with me and not the book!    I look forward to your reply, thanks.   
  I don't think his explanation is particularly bad, but there is one error he's made, which is probably not helping with your understanding. I'll explain below.There isn't a module called Rect because there doesn't need to be. It's just a data type. A module in Python is a place where functions, classes, and data can be stored, but not every function, class, or piece of data has its own module.Things also don't get "appended" to methods. I'm not sure what you mean by this, and I think it's the root of some of your confusion. A method is associated with a data type, and specifically a certain instance of a data type. It means a bit of code that does something with or about the instance of the data.In this case, 'get_rect' is a method of the pygame.font.Font and pygame.Surface objects, as he states after the Attributes section. It means that objects of those types have a method called get_rect, which when you call it returns something about those objects, in this case a rectangle (ie. a pygame.Rect) that represents a virtual box on the screen that would enclose the object.When he says "The get_rect() Methods for pygame.font.Font  and pygame.Surface Objects" it really means "The get_rect() Methods for objects of type 'pygame.font.Font' and 'pygame.Surface'". A method is part of a class and can be called on any object which is an instance of that class. When using Pygame you will be working with many objects that are all pygame.Surfaces (and indeed several that are pygame.font.Fonts too). windowSurface is one pygame.Surface; text is another pygame.Surface.When he says, "the Font object (stored in the text variable)", he really means 'stored in the basicFont variable'. You are completely correct about this. But a surface variable is indeed stored in the windowSurface variable - you are working with more than one pygame.Surface.Is that any help?   ;  Hi Kylotan, thanks for replying.  :)Quote:There isn't a module called Rect because there doesn't need to be. It's just a data type. But when you say "it's" what are you referring to?  See, the problem is that the word 'Rect' isn't in the code.  The only datatypes I see that could possibly be called Rect are get_rect and render.  But he says himself that datatypes start with an uppercase letter.  his exact words are:"The Pygame programmers made the modules begin with a lowercase letter, and the data types begin with an uppercase letter" For instance, consider line 19:basicFont = pygame.font.SysFont(None, 48) SysFont starts with an uppercase letter, so it conforms to the rules he laid out.  But that's the only instance of a datatype beginning with an uppercase letter.  Which is confusing, because you seem to be implying that objects are created via datatypes.Quote:Things also don't get "appended" to methods. I'm not sure what you mean by this, and I think it's the root of some of your confusion. yes, I went back to some previous chapters and yes, I was mixed up.  So what is the term for when we take a module name and use a period to attach it to a data type?e.g., pygame.font.SysFontQuote:A method is associated with a data type, and specifically a certain instance of a data type. It means a bit of code that does something with or about the instance of the data.In this case, 'get_rect' is a method of the pygame.font.Font and pygame.Surface objects, I'm glad to hear that get_rect is a method and not a data type.  What I don't understand is how a surface object is invoked without using a datatype word that is uppercase.  The only other word I'm seeing that could represent a datatype is render, but it's not uppercase.  I suppose render is perhaps a method that exists within the font module?   Is it the case that the font module can generate both font objects and surface objects?    Quote:It means that objects of those types have a method called get_rect, which when you call it returns something about those objects, in this case a rectangle (ie. a pygame.Rect) that represents a virtual box on the screen that would enclose the object. I think a big part of my confusion comes from not really understanding the conditions that are required to make an object.  I'm also under the impression that there are different types of objects (e.g., font objects as opposed to surface objects), and I'm not sure if that's the best way to look at it. Quote:When he says "The get_rect() Methods for pygame.font.Font  and pygame.Surface Objects" it really means "The get_rect() Methods for objects of type 'pygame.font.Font' and 'pygame.Surface'". A method is part of a class and can be called on any object which is an instance of that class. Alright, so how about I put it this way: pygame.font.Font and pygame.Surface are two different classes that each contain a version of the get_rect() method.  is that right?If I'm correct, then I still have a question.  How come the former piece of code has 3 words? (pygame.font.Font), and the later only has two words? (pygame.Surface)And how come "Surface" starts with an uppercase letter, yet on the actual code, there are no words that start with an upper case?Quote:When using Pygame you will be working with many objects that are all pygame.Surfaces (and indeed several that are pygame.font.Fonts too). windowSurface is one pygame.Surface; text is another pygame.Surface.Perhaps I'm being blinded by the assumption that the object type has anything to do with the datatype or module?  I keep trying to find a correlation between the module or datatype used and then object type that results.   Are you saying that it's the method type that dictates if an object is surface or font?  Quote:When he says, "the Font object (stored in the text variable)", he really means 'stored in the basicFont variable'. So was it a typo he made, or to I have to learn to look at things more subtly?Quote:But a surface variable is indeed stored in the windowSurface variable - you are working with more than one pygame.Surface. I just don't get why you capitalize "Surface" when the actual code is:pygame.display.set_modedisplay is not capitalized, and neither is the set_mode method.  I'm also not clear if display is it's own module.Quote:Is that any help?yeah, definitely.  I still don't really understand, but my questions I think are clearer.  I hope you have the time and inclination to reply to this!   I don't expect you to reply to every point, I just figured I'd lay it all out so you can get a clear idea on where I'm going wrong with this.[Edited by - CoryD on May 13, 2010 12:19:16 PM];  Here are some more questions.  I don't neccesarily want anyone to reply to every question, I'm just trying to give people an idea of where I'm going wrong in my thinking:Basically, I'm going to focus on each section of code, from lines 7 to 28Quote:   7. # set up the window   8. windowSurface = pygame.display.set_mode((500, 400), 0, 32)   9. pygame.display.set_caption('Hello world!')I don't understand how line 9 relates with line 8.  Line 8 is a surface object.  Isn't line 9 a second surface object?  Or does it somehow build upon the surface object of line 8?Also, how come the set_caption method is not capitalized?   Isn't set_caption and set_mode a data type?  If not, how can I tell the difference between a data type and a method?   He said that modules are supposed to start with lower case and datatypes begin with upercase.   Lastly, he says: "To see how tiny a pixel is, look at the bottom right corner of the "Hello World!" window. This program sets just one pixel as white."Sets the one pixel to white?  The background surface is white, the single pixel in the bottom right corner window is black.Quote:  18. # set up fonts  19. basicFont = pygame.font.SysFont(None, 48)this line of code seems clear to me.  The font module contains the SysFont data type.  But I'm still not clear on the difference between a data type and a method. Quote:  21. # set up the text  22. text = basicFont.render('Hello world!', True, WHITE, BLUE)  23. textRect = text.get_rect()basicFont is a font object.  But what is render()?  It is not capitalized, so it's not a data type.  Is it a method that can be called from anywhere?  Or is it contained within the font module?   If it's contained in the font module, then does that mean that within a font module, you can make objects either font objects or surface objects?  does the type of module dictate what the type of object the entire piece of code will be?Quote:   24. textRect.centerx = windowSurface.get_rect().centerx  25. textRect.centery = windowSurface.get_rect().centeryThe equal sign is throwing me off here.  I've always used the equal sign to store data within variables.  textRect.centerx is already storing data, and attaching an attribute (centerx) to a variable while you set it strikes me as very confusing.   Lines 24 and 25 baffle me the most of all.Quote:  27. # draw the white background onto the surface  28. windowSurface.fill(WHITE)This method seems straightforward.   ;  Hello CoryD.Quote:Original post by CoryDQuote:There isn't a module called Rect because there doesn't need to be. It's just a data type. But when you say "it's" what are you referring to?  See, the problem is that the word 'Rect' isn't in the code.  The only datatypes I see that could possibly be called Rect are get_rect and render.  But he says himself that datatypes start with an uppercase letter. He's referring to Rect, which is a data type.In Python you typically create an object or instance of a data type by invoking the type like a function: x = Rect() creates an object, x, which is of type Rect. However we could wrap this up in another function and arrive at the same result:def create_rect():    r = Rect()    return rx = create_rect()The above code creates an instance of Rect, r, inside the create_rect function such that when we assign the return value of the function to x below, it is set to the value of r. We can even store the object created and then return it later via another function, as in the following example:class HasARect:    def __init__(self):   self.__rect = Rect()    # create the Rect and store it in a private variable    def get_rect(self):   return self.__rectx = HasARect()y = x.get_rect()It should then be obvious that calling a function such as get_rect() in Pygame simply retrieves the actual Rect object associated with the Surface, SysFont or other type we are querying. In fact, the Rect may not be stored at all, but created as needed:class Square:    def __init__(self, x, y, side):   self.__x = x   self.__y = y   self.__side = side    def get_rect(self):   return Rect(self.__x, self.__y, self.__side, self.__side)   # uses the Rect constructor that takes left and top coordinates and width and height, respectivelyQuote:So what is the term for when we take a module name and use a period to attach it to a data type?e.g., pygame.font.SysFontThere's no real name for that. What it tells you, however, is that the data type (SysFont) is part of the module (pygame.font). Modules can be nested hierarchically, which is how we come to have pygame.font, pygame.display et al in the first place: font, display and more live inside the pygame module. Sometimes the top-level module (pygame) is used by the developers simply to collect all their modules "in one place" and to reduce the likelihood of name collisions. That is, it's very likely PyGame isn't the only Python project that would produce a class named font, so qualifying it as pygame.font makes ambiguity impossible unless another team creates a project and also names it PyGame (boo, bad karma!) or if the user explicitly imports multiple identically named sub-modules (from pygame import font).Quote:What I don't understand is how a surface object is invoked without using a datatype word that is uppercase.  The only other word I'm seeing that could represent a datatype is render, but it's not uppercase.  I suppose render is perhaps a method that exists within the font module?   Is it the case that the font module can generate both font objects and surface objects?I'm not clear on your usage of "invoke" here. Do you mean how a surface object came to be created without an explicit call to Surface()? Or do you mean calling a method on a surface object without capitalization?First, realize that the capitals/lower-case thing is merely a PyGame-specific convention. As you learn Python you will inevitably come across projects that do it differently, so learn to understand the Python language itself and don't rely on visual shorthand like this.The key piece of information is that there are a variety of Python entities that are "callable" - that can be called like functions. Data types are callable, invoking the type constructor and returning a constructed object instance. Functions are callable, causing their bodies to execute and optionally return a value (including multi-value collections like lists and tuples). Objects can be callable if the class (data type) they are instances of overloaded the appropriate operator; this can allow you to write a matrix object that allows you to subscript elements as m(x, y), for example (for a 2-dimensional matrix type), or just use an object like a function: myObject(someData).It can be quite confusing at first, but with practice you'll come to understand and appreciate this property of the Python programming language.Quote:I think a big part of my confusion comes from not really understanding the conditions that are required to make an object.  I'm also under the impression that there are different types of objects (e.g., font objects as opposed to surface objects), and I'm not sure if that's the best way to look at it.Objects are trivial to make in Python. Unlike some other languages, Python makes (very) liberal use of objects - in fact, everything in Python is an object, including data types: every data type is itself an instance (object) of the class (data type) Class! Objects are instances of a class - think of classes as schematics for constructing objects, and objects as the actual "product" the schematic describes. Generally speaking, objects are not interchangeable: calling a constructor twice yields different objects, and objects of different classes as very different.That said, Python embodies a concept sometimes referred to as "duck typing" or "generic programming": it generally doesn't matter if an object is of a specific type in code but rather whether it has the attributes (public data members) and operations (public methods) the calling code needs. You see this exemplified in PyGame with the .get_rect() member function. In PyGame, any object of a class that implements a .get_rect()method can be used in place of an actual pygame.Rect, obviously requiring that the .get_rect() method return a usable pygame.Rect.Quote:pygame.font.Font and pygame.Surface are two different classes that each contain a version of the get_rect() method.  is that right?Correct.Quote:If I'm correct, then I still have a question.  How come the former piece of code has 3 words? (pygame.font.Font), and the later only has two words? (pygame.Surface)Simple: the Font type is part of the pygame.font module whereas the Surface type is part of the top-level pygame module. Why isn't Surface part of a sub-module? It's a decision made by the PyGame developers, but it's most likely because it is used by virtually every other module in PyGame, so the top level was the logical place to put it. Same thing with pygame.Rect.Quote:And how come "Surface" starts with an uppercase letter, yet on the actual code, there are no words that start with an upper case?You're not calling the pygame.Surface constructor directly. Instead you're calling functions on other objects and in modules that return constructed Surfaces for your use.Try this. Open up your interactive interpreter and type the following lines of code, pressing enter after each one:import pygamepygame.display.set_mode((640, 480))You should see a PyGame window open up, but you should also see some text output in your interpreter console. Something like <Surface(640x480x32 SW)>. See the capitalized "Surface" there? pygame.display.set_mode does a bunch of stuff to create a pygame.Surface for you, then returns it to you when it's done. This is why we typically capture the return value from set_mode; something like screen = pygame.display.set_mode((640, 480)).In summary, the upper-case data types you're looking for are there. They're just being created for you.Quote:Perhaps I'm being blinded by the assumption that the object type has anything to do with the datatype or module?  I keep trying to find a correlation between the module or datatype used and then object type that results.   Are you saying that it's the method type that dictates if an object is surface or font?No. A programmer is free to do anything in a function, and return any value - or none. The only way to know what the function does is to ask him. Or, more realistically, to read the documentation he helpfully provided. The PyGame documentation tells you what each function in each module does and what type of object and value(s) it returns, if any. Reading that may reduce your confusion.Quote:Quote:When he says, "the Font object (stored in the text variable)", he really means 'stored in the basicFont variable'. So was it a typo he made, or to I have to learn to look at things more subtly?It wasn't a typo, it was technical jargon. Remember, an object is an instance of a type. basicFont (object) is an instance of Font (type). As a shorthand, then, we may refer to basicFont as a "Font object," but we're actually saying "instance of type Font."Quote:Original post by CoryD   7. # set up the window   8. windowSurface = pygame.display.set_mode((500, 400), 0, 32)   9. pygame.display.set_caption('Hello world!')I don't understand how line 9 relates with line 8.  Line 8 is a surface object.  Isn't line 9 a second surface object?  Or does it somehow build upon the surface object of line 8?display is not a Surface object; it is a PyGame module that handles a wide variety of things related to display/presentation. display.set_mode is a function that sets the video mode of the surface PyGame will ultimately be drawing all user-visible graphics on, and then returns that surface to you (in case you want to refer to it later; we do, and we save it in the windowSurface variable).display.set_caption, on the other hand, has nothing to do with the display surface. It deals with the window decoration, specifically setting the caption of the application window in which our display surface is presented.Quote:Also, how come the set_caption method is not capitalized?   Isn't set_caption and set_mode a data type?  If not, how can I tell the difference between a data type and a method?No, neither set_caption nor set_mode are data types. You can not generally rely on capitalization to tell you whether an entity is an object, type (class) or method. You must learn to read documentation that describes the various entities and their functions, read code and look at what role the entity actually serves, examine the definition/declaration of the entity if possible, as well as optionally employ introspection tools when necessary.Quote:...I'm still not clear on the difference between a data type and a method.A data type describes a way of organizing data and operating on it. The data organization is done via member variables, while the data operation is done via member functions or methods. Methods don't have to be declared/define inside data types, though; some can live on their own. These definitions of data type and method are generally true, but in some more advanced contexts programmers may intentionally blur the lines between the two.Quote:  21. # set up the text  22. text = basicFont.render('Hello world!', True, WHITE, BLUE)  23. textRect = text.get_rect()basicFont is a font object.  But what is render()?  It is not capitalized, so it's not a data type.  Is it a method that can be called from anywhere? ... Or is it contained within the font module?render() is a method of SysFont, meaning it is indirectly in the font module. It can only be called on SysFont objects. There may be other functions/methods with the same name, but they will do different things and can not be called (successfully) on SysFont objects.Quote:If it's contained in the font module, then does that mean that within a font module, you can make objects either font objects or surface objects? does the type of module dictate what the type of object the entire piece of code will be?The name of a module has no technical bearing on what kinds of objects can be created by functions or data types within the module.Quote:  24. textRect.centerx = windowSurface.get_rect().centerx  25. textRect.centery = windowSurface.get_rect().centeryThe equal sign is throwing me off here.  I've always used the equal sign to store data within variables.  textRect.centerx is already storing data, and attaching an attribute (centerx) to a variable while you set it strikes me as very confusing.   Lines 24 and 25 baffle me the most of all.You're still using the equal sign to store data within variables. It's just that you're not overwriting the whole variable.textRect is a variable that holds a Rect instance. The pygame.Rect data type is a compound/aggregate data type, meaning that it is made up of a number of variables of its own, each of which may also be of a compound/aggregate type. The dot notation is used to access an attribute or member of any entity in Python, be it object/instance/variable, class/data type, module or more. Heck, you can do it to literals:'5'.isalnum()(5).real'this is a string'.split(' ')So what is happening in the snippet you quote is that the .centerx and .centery members of textRect are being overwritten with new values, implicitly moving the rectangle so that it is centered within the display window.Hope that helped.   ;  Alright guys, thanks for the help.  I got through the whole book.   