Page 1 of 1
drawing classes
Posted: Fri Mar 09, 2012 9:49 pm
by Isaac
Code: Select all
import os,time
from math import sin,cos
class grid:
def __init__(self,x,y):
self.x=x
self.y=y
def me(self,x,y,character):
self.xm=int(x)
self.ym=int(y)
self.ch=character
self._draw()
time.sleep(0.5)
def decor(self,x,char):
self.bot=char
self.xbot=int(x)
def _build(self,x,y,z):
xprint=" "
if x==self.xm and y==self.ym:
return self.ch
if y==10:
return "_"
if x<=self.xbot+sin(y)*4+z%10-10:
return self.bot
else:
return xprint
def _draw(self):
for z in range (self.y):
os.system("clear")
for y in range(self.y):
print "|",
for x in range(self.x):
print self._build(x,y,z),
print ("|")
plane=grid(40,20)
while 1==1:
[[plane.decor(20,")"),plane.me((sin(x)*4+20),(cos(x)*4+10),"8")] for x in range(1000)]
It draws waves moving left and right. It also draws a bee, or number 8, flying around in a circle.
Now, this runs very badly in a terminal window. I run this in regular terminal (ctrl+alt+f1 in ubuntu) for a faster print.
lol... I just typed :w out of habit.
Enjoy my fine art!
edit:
Oh yes! The purpose of this. I'm trying to figure out why people bother with classes, when you can just as easily import whatever you want from a file of functions, which basically acts like a class. This little task is forcing me to think more in classes and I'm starting to see why they're better. However, if you think I'm not really using them correctly, like if you see something that's drifting from oop, let me know! Thanks.
Re: drawing classes
Posted: Sat Mar 10, 2012 11:16 am
by fliptw
so you are wondering about object-orientated programming?
Re: drawing classes
Posted: Sat Mar 10, 2012 11:59 am
by Isaac
In general? It's pretty straight forward I think: Your program draws from functions rather than having every event listed.
I'm really wondering about loose functions vs classes. You see, in Python, both functions and classes use global variables or internal ones. They can be embedded in other functions. You can import a file with a bunch of functions you wrote and make it equal a variable, which has some class like behavior.
tl;dr; classes and functions have enough similarities in python to be almost equals. I'm trying to understand the differences better.
edit: I've started pygame tutorials to get a better understanding of classes.
Re: drawing classes
Posted: Sat Mar 10, 2012 2:37 pm
by Jeff250
One of the advantages of classes is that you can instantiate them (like you did above) and have each object instantiation have its own state that it can reference. Another is inheritance and overriding methods.
Isaac wrote:1==1
This is just True, right?
Isaac wrote:[[plane.decor(20,")"),plane.me((sin(x)*4+20),(cos(x)*4+10),"8")] for x in range(1000)]
Don't use list comprehensions only for their side effects! You're building a list of lists of junk in memory for no reason! How about just a for loop like this:
Code: Select all
plane.decor(20, ")")
for x in xrange(1000):
plane.me((sin(x)*4+20), cos(x)*4+10, "8")
?
Re: drawing classes
Posted: Sat Mar 10, 2012 3:55 pm
by fliptw
the form x import y is syntactical sugar: python is importing the class and assigning aliases to the items imported(which may be a object itself) specified.
Classes have data about themselves and methods which they can be changed. they also can be used as the basis for new classes by inheritance.
Re: drawing classes
Posted: Sun Mar 11, 2012 9:15 am
by Isaac
Jeff250 wrote:One of the advantages of classes is that you can instantiate them (like you did above) and have each object instantiation have its own state that it can reference. Another is inheritance and overriding methods.
But you can also do this when importing a file with modules, no?
I mean if you import mydoc, rather than from mydoc import onemodule.
Then you can x=mydoc and y=mydoc. Then you can x.onemodule(23,22,2) and y.onemodule(33,2,1).
Even pygame has a regular init() module instead of an __init__ method.
As for overridding, this could be done within a new module, just as long as it doesn't effect the other variables, y and x.
But it is more straight forward using classes. I think I like the __init__ better.
Jeff250 wrote:
Isaac wrote:1==1
This is just True, right?
haha yeah. Sorry.
Jeff250 wrote:
Isaac wrote:[[plane.decor(20,")"),plane.me((sin(x)*4+20),(cos(x)*4+10),"8")] for x in range(1000)]
Don't use list comprehensions only for their side effects! You're building a list of lists of junk in memory for no reason! How about just a for loop like this:
Code: Select all
plane.decor(20, ")")
for x in xrange(1000):
plane.me((sin(x)*4+20), cos(x)*4+10, "8")
?
Hhahah! Yeah. That should have been obvious to me.
Re: drawing classes
Posted: Sun Mar 11, 2012 4:20 pm
by fliptw
Isaac wrote:Jeff250 wrote:One of the advantages of classes is that you can instantiate them (like you did above) and have each object instantiation have its own state that it can reference. Another is inheritance and overriding methods.
But you can also do this when importing a file with modules, no?
you should read up on object orientated programming. importing is a different concept than OOP.
Re: drawing classes
Posted: Sun Mar 11, 2012 4:43 pm
by Jeff250
Isaac wrote:I mean if you import mydoc, rather than from mydoc import onemodule.
Then you can x=mydoc and y=mydoc. Then you can x.onemodule(23,22,2) and y.onemodule(33,2,1).
Even pygame has a regular init() module instead of an __init__ method.
Let's try this...
Code: Select all
# foo.py
params = {'x': None, 'y': None, 'z': None}
def set_xyz(x, y, z):
params['x'] = x
params['y'] = y
params['z'] = z
def get_xyz():
return params['x'], params['y'], params['z']
Code: Select all
>>> import foo
>>> x = foo
>>> y = foo
>>> x.set_xyz(1, 2, 3)
>>> y.set_xyz(4, 5, 6)
>>> x.get_xyz()
(4, 5, 6)
>>> y.get_xyz()
(4, 5, 6)
What if you want x and y to have separate state?
Re: drawing classes
Posted: Sun Mar 11, 2012 4:54 pm
by Isaac
Oh crap.. Wow thanks! Ok that clears it up really well!
Re: drawing classes
Posted: Mon Mar 12, 2012 6:54 am
by snoopy
Funny...
In my recent reading on python I hadn't gotten a really clear understanding of modules & functions vs. classes. Mostly, because I hadn't read the documentation on classes very carefully yet.
Discussions like this prove to be useful! It appears that you can, in fact, conveniently choose between the two specifically depending upon how you want Jeff's example to behave.
Re: drawing classes
Posted: Mon Mar 12, 2012 8:36 am
by Isaac
Yeah. What I see is, if values are going to be stored in a file like foo you will have a result like Jeff's example. If you want variables in the imported file to be their own instance then use classes or be sure to include a delete function. Classes will be easier.
Re: drawing classes
Posted: Mon Mar 12, 2012 9:03 am
by snoopy
I haven't (thus far) gotten to the point where I think some global variables are the better way to go, so I haven't really learned the python global variable thing yet.
So far, I have one variable that I'm passing most of the time, but that's not even *all the time.* My memory of programming mojo is that global variables should be generally avoided unless they are really a variable that's globally used. For one part, having global variables makes it harder to test individual modules/functions/classes because you have to do the proper global variable configuration before you can run the function with success.
If you just make sure that you pass *everything* that function needs, then a 1-line invocation in the interpreter would suffice to test it.
Re: drawing classes
Posted: Mon Mar 12, 2012 9:29 am
by Isaac
In my example, I believe "gl" is a global variable because it can be used by any function in the script.
Code: Select all
>>> gl=3
>>> def bb(loc):
... return gl+loc
...
>>> bb(3)
6
>>>
The local variable "loc", however, is invisible to anything written outside the internals of bb().
You can also use the "global" syntax to specify your variable is global, assuming a variable was first defined within the function or class. I never use it, though. In a class you can call any variable, assuming you don't hide it with "_" in front. like
amrite?
Re: drawing classes
Posted: Mon Mar 12, 2012 10:59 am
by snoopy
I don't know the correct terminology for this, but I don't think gl in your example is really a global variable, it's a variable that belongs to the "terminal" module (whatever you call it) and since you're defining bb within the "terminal" module as well, it knows what gl is.
(I can test this tonight but don't have access to the python interpreter right now.)
If you do this:
And then in the interpreter:
Code: Select all
>>> import bb
>>> gl=3
>>> bb.bb(3)
Error: bb doesn't know what gl is!
>>>
However, if you did:
Code: Select all
bb.py
gl=3
def bb(loc):
return gl+loc
def cc(loc):
return gl*loc
And then in terminal:
Code: Select all
>>> import bb
>>> gl=25
>>> bb.bb(3)
6
>>> bb.cc(3)
9
>>>
I.E. you can define "gl" multiple places, but each value stays with the module within which it was defined... that you you don't have to worry about variables stepping on each other from module to module.
By a global variable I mean everything would use the same "gl" and if you change it in module x, then module y will operate on the changed value... if you aren't really careful to keep track of "gl" being global, you can accidentally change it and then mess something else up. Also, if you want to test your module stand-alone, and within the module your global variable isn't defined, you have to remember to define the global variable, as a global variable, every time before you try to run your module, which is a pain.
For my program, I'm thinking of a "program_path" variable. A lot of my functions are going to want to know what the program_path variable is, and it's going to be the same value for every function - is that something that makes sense to make a global variable? If so, is there a convenient way to define it so I don't have to manually define it each time I want to test an individual module from the interpreter?
Four possible answers that I can think of:
1. For particularly this case, would it work to make the program cd to my program path, and then just have all of my modules use the working path instead of some external variable?
2. Write a module/class/function that does the leg work to figure out the path, and invoke it each time I need to know the path
3. Write a module/class/function that does the leg work to figure out the path and define it as a global variable, then make each module invoke it during initialization if the variable is unknown.
4. Just pass the path to the function when you call the function
I think there's a way to do any of them, but I don't know which approach would be the most efficient from a time/memory standpoint.
Re: drawing classes
Posted: Mon Mar 12, 2012 11:49 am
by Isaac
Just to be clear, you're saying you'll be using mymainloop.__file__ to first define the main location of your app, then put that value into a variable called program path, so that every part of your program will know where it's "head" is.
Right? Remember I'm a slow DBBer.
Re: drawing classes
Posted: Mon Mar 12, 2012 1:58 pm
by Jeff250
snoopy wrote:By a global variable I mean everything would use the same "gl" and if you change it in module x, then module y will operate on the changed value...
In python, "global" means global to the module. There's no inter-module global without referencing the module (to prevent modules from clobbering each other's variables). So if
Code: Select all
# main.py
. . .
DIRNAME = os.path.dirname(__file__)
. . .
Then you just say in any module
or
Code: Select all
from main import DIRNAME
. . .
DIRNAME
Re: drawing classes
Posted: Mon Mar 12, 2012 2:09 pm
by Jeff250
snoopy wrote:Discussions like this prove to be useful! It appears that you can, in fact, conveniently choose between the two specifically depending upon how you want Jeff's example to behave.
There's also an "art" to it as well. For instance, the idea of
singleton classes really throws a monkey wrench at my example.
Modules are ways to organize related global variables, functions, and *classes* (so the two aren't even mutually exclusive).
Classes are things like "Person" or "Location" or "Color" or "Connection" whose object instantiations semantically refer to objects. A "Person" or "Location" or "Color" or "Connection" seem like actual "things."
Re: drawing classes
Posted: Mon Mar 12, 2012 2:14 pm
by snoopy
Issac: Yes, that was the idea. Though, when I think about it, it may actually be minimally necessary - to the point where it just makes sense to pass it as a function variable. One example of when I'm using it is when I'm trying to read config files: I try to read from the user's home directory first, then fall back to /etc/, and finally fall back to the program path.
Beyond that, there probably aren't going to be a whole lot of instances where it's going to be used, since all of the data that's written to the drive shouldn't reside in the program path... just canned template configuration files that would be transferred prior to actual usage. In fact... maybe I should make my config file read function fail after the second path (/etc) and just complain to the user about needing to copy config files appropriately.
Jeff: I suppose that this is the most efficient way to do it?
Re: drawing classes
Posted: Tue Mar 13, 2012 8:32 pm
by Jeff250
I don't know what you mean by most efficient, but your plan sounds good to me.