[Tutor] Already Initialized Object Inheritance?

2011-06-14 Thread WolfRage
I can not get this to behave in the manor that I would like. I am trying
to have an object refereed to as CursesApp.Screen become the already
initialized object "stdscr". To elaborate I would like it to become that
object but to also be able to define additional methods and properties,
so more along the lines of inherit from "stdscr". Is this even possible?
Well I can make it equal to that object I can not add additional methods
and properties to it? Additionally, so that I learn; where has my
thinking been too short sited? Thank you for your help.
--
Jordan

CODE BELOW

#!/usr/bin/python3
"""With thi method I can make the class "Screen" become "stdscr" but if
I refernce any of the new methods or properties the applications
promptly fails and notifies me that the method or property does not
exist. Another downside of this method is I can not reference
self.Screen.* or it crashes."""
import curses
class CursesApp:
def __init__(self, stdscr):
self.Screen(stdscr) #This is the stdscr object.
curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
#self.Screen.bkgd(' ', curses.color_pair(1))
#self.mainLoop()

#def mainLoop(self):
#while 1:
#self.Screen.refresh()
#key=self.Screen.getch()
#if key==ord('q'): break

class Screen:
def __init__(self,stdscr):
self=stdscr
#self.height, self.width = self.getmaxyx() # any reference
to these crashes
#self.offsety, self.offsetx = -self.height/2, -self.width/2
# any reference to these crashes
#self.curx, self.cury = 1, 1 # any reference to these
crashes
self.clear()
self.border(0)
while 1:
self.refresh()
key=self.getch()
if key==ord('q'): break

def main():
cursesapp = curses.wrapper(setup)

def setup(stdscr): 
CursesApp(stdscr)

if __name__ == '__main__':
main()



CODE BELOW

#!/usr/bin/python3
"""With this method I can make "Screen" become "stdscr" but if I
obviously can not even define any new methods or properties. But atleast
the references can be used through out the class with out crashing."""
import curses
class CursesApp:
def __init__(self, stdscr):
self.Screen=stdscr #This is the stdscr object.
curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
self.Screen.bkgd(' ', curses.color_pair(1))
self.mainLoop()

def mainLoop(self):
while 1:
self.Screen.refresh()
key=self.Screen.getch()
if key==ord('q'): break

def main():
cursesapp = curses.wrapper(setup)

def setup(stdscr): 
CursesApp(stdscr)

if __name__ == '__main__':
main()

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Already Initialized Object Inheritance?

2011-06-14 Thread WolfRage
Unfortunately I am not able to inherit "stdscr" using that method. As
Python returns with an error stating that "stdscr" is not defined. This
error is returned at run time and by the compiler prior to actual
execution. If you would like I can write a quick example that will
generate the error message for that method.
--
Jordan
On Wed, 2011-06-15 at 02:04 -0400, Japhy Bartlett wrote:
> When you're subclassing something, you use the syntax:
> 
> class Foo(Bar):
> 
> It seems like you're trying to do:
> 
> class Bar:
> class Foo:
> 
> - Japhy
> 
> On Wed, Jun 15, 2011 at 12:47 AM, WolfRage  wrote:
> > I can not get this to behave in the manor that I would like. I am trying
> > to have an object refereed to as CursesApp.Screen become the already
> > initialized object "stdscr". To elaborate I would like it to become that
> > object but to also be able to define additional methods and properties,
> > so more along the lines of inherit from "stdscr". Is this even possible?
> > Well I can make it equal to that object I can not add additional methods
> > and properties to it? Additionally, so that I learn; where has my
> > thinking been too short sited? Thank you for your help.
> > --
> > Jordan
> >
> > CODE BELOW
> >
> > #!/usr/bin/python3
> > """With thi method I can make the class "Screen" become "stdscr" but if
> > I refernce any of the new methods or properties the applications
> > promptly fails and notifies me that the method or property does not
> > exist. Another downside of this method is I can not reference
> > self.Screen.* or it crashes."""
> > import curses
> > class CursesApp:
> >def __init__(self, stdscr):
> >self.Screen(stdscr) #This is the stdscr object.
> >curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
> >#self.Screen.bkgd(' ', curses.color_pair(1))
> >#self.mainLoop()
> >
> >#def mainLoop(self):
> >#while 1:
> >#self.Screen.refresh()
> >#key=self.Screen.getch()
> >#if key==ord('q'): break
> >
> >class Screen:
> >def __init__(self,stdscr):
> >self=stdscr
> >#self.height, self.width = self.getmaxyx() # any reference
> > to these crashes
> >#self.offsety, self.offsetx = -self.height/2, -self.width/2
> > # any reference to these crashes
> >#self.curx, self.cury = 1, 1 # any reference to these
> > crashes
> >self.clear()
> >self.border(0)
> >while 1:
> >self.refresh()
> >key=self.getch()
> >if key==ord('q'): break
> >
> > def main():
> >cursesapp = curses.wrapper(setup)
> >
> > def setup(stdscr):
> >CursesApp(stdscr)
> >
> > if __name__ == '__main__':
> >main()
> >
> >
> >
> > CODE BELOW
> >
> > #!/usr/bin/python3
> > """With this method I can make "Screen" become "stdscr" but if I
> > obviously can not even define any new methods or properties. But atleast
> > the references can be used through out the class with out crashing."""
> > import curses
> > class CursesApp:
> >def __init__(self, stdscr):
> >self.Screen=stdscr #This is the stdscr object.
> >curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
> >self.Screen.bkgd(' ', curses.color_pair(1))
> >self.mainLoop()
> >
> >def mainLoop(self):
> >while 1:
> >self.Screen.refresh()
> >key=self.Screen.getch()
> >if key==ord('q'): break
> >
> > def main():
> >cursesapp = curses.wrapper(setup)
> >
> > def setup(stdscr):
> >CursesApp(stdscr)
> >
> > if __name__ == '__main__':
> >main()
> >
> > ___
> > Tutor maillist  -  Tutor@python.org
> > To unsubscribe or change subscription options:
> > http://mail.python.org/mailman/listinfo/tutor
> >


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Already Initialized Object Inheritance?

2011-06-15 Thread WolfRage
Christopher,

Thank you for the explanation of the error. I see now why I am unable to
reference it outside of __init__'s scope. No, I did not mean to do that.
I will include further details in my reply to Steven. Please feel free
to jump in on that conversation to continue my learning. Thank you for
your help and time thus far. 
--
Jordan

On Wed, 2011-06-15 at 09:45 -0400, Christopher King wrote:
> Oh, I think I see the error.
> self=stdscr
> This will just make the variable called self be assigned to
> stdscr with in __init__ This will not make the object actually turn
> into stdscr
> Or maybe you meant do that, because I don't know what stdscr or
> the curses module is
> 
> On Wed, Jun 15, 2011 at 12:47 AM, WolfRage 
> wrote:
> I can not get this to behave in the manor that I would like. I
> am trying
> to have an object refereed to as CursesApp.Screen become the
> already
> initialized object "stdscr". To elaborate I would like it to
> become that
> object but to also be able to define additional methods and
> properties,
> so more along the lines of inherit from "stdscr". Is this even
> possible?
> Well I can make it equal to that object I can not add
> additional methods
> and properties to it? Additionally, so that I learn; where has
> my
> thinking been too short sited? Thank you for your help.
> --
> Jordan
> 
> CODE BELOW
> 
> #!/usr/bin/python3
> """With thi method I can make the class "Screen" become
> "stdscr" but if
> I refernce any of the new methods or properties the
> applications
> promptly fails and notifies me that the method or property
> does not
> exist. Another downside of this method is I can not reference
> self.Screen.* or it crashes."""
> import curses
> class CursesApp:
>def __init__(self, stdscr):
>self.Screen(stdscr) #This is the stdscr object.
> 
>  curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
>#self.Screen.bkgd(' ', curses.color_pair(1))
>#self.mainLoop()
> 
>#def mainLoop(self):
>#while 1:
>#self.Screen.refresh()
>#key=self.Screen.getch()
>#if key==ord('q'): break
> 
>class Screen:
>def __init__(self,stdscr):
>self=stdscr
>#self.height, self.width = self.getmaxyx() # any
> reference
> to these crashes
>#self.offsety, self.offsetx = -self.height/2,
> -self.width/2
> # any reference to these crashes
>#self.curx, self.cury = 1, 1 # any reference to
> these
> crashes
>self.clear()
>self.border(0)
>while 1:
>self.refresh()
>key=self.getch()
>if key==ord('q'): break
> 
> def main():
>cursesapp = curses.wrapper(setup)
> 
> def setup(stdscr):
>CursesApp(stdscr)
> 
> if __name__ == '__main__':
>main()
> 
> 
> 
> CODE BELOW
> 
> #!/usr/bin/python3
> """With this method I can make "Screen" become "stdscr" but if
> I
> obviously can not even define any new methods or properties.
> But atleast
> the references can be used through out the class with out
> crashing."""
> import curses
> class CursesApp:
>def __init__(self, stdscr):
>self.Screen=stdscr #This is the stdscr object.
> 
>  curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
>self.Screen.bkgd(' ', curses.color_pair(1))
>self.mainLoop()
> 
>def mainLoop(self):
>while 1:
>self.Screen.refresh()
>key=self.Screen.getch()
>if key==ord('q'): break
> 
> def main():
>cursesapp = curses.wrapper(setup)
> 
> def setup(stdscr):
>CursesApp(stdscr)
> 
> if __name__ == '__main__':
>main()
> 
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
> 
> 


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Tutor Digest, Vol 88, Issue 56

2011-06-15 Thread WolfRage
> From: Steven D'Aprano 
> To: Python Tutor 
> Subject: Re: [Tutor] Already Initialized Object Inheritance?
> Message-ID: <4df898e9.5050...@pearwood.info>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
> 
> WolfRage wrote:
> > Unfortunately I am not able to inherit "stdscr" using that method. As
> > Python returns with an error stating that "stdscr" is not defined. This
> > error is returned at run time and by the compiler prior to actual
> > execution. If you would like I can write a quick example that will
> > generate the error message for that method.
> 
> You shouldn't need to ask that question, just do it.

Ahh... sorry?

CODE BELOW
#!/usr/bin/python3
"""With this method I can make the class "Screen" become "stdscr" but if
I refernce any of the new methods or properties the applications
promptly fails and notifies me that the attribute does not exist."""
import curses
class CursesApp:
def __init__(self, stdscr):
self.Screen=stdscr #This is the stdscr object.
curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
self.Screen.bkgd(' ', curses.color_pair(1))
self.mainLoop()

def mainLoop(self):
while 1:
self.Screen.refresh()
key=self.Screen.getch()
if key==ord('q'): break
self.Screen.height=10 #This is the line that crashes,
because it is not an attribute of "stdscr".

class Screen:
def __init__(self):
self.height, self.width = self.getmaxyx()
self.offsety, self.offsetx = -self.height/2, -self.width/2
self.curx, self.cury = 1, 1

def main():
cursesapp = curses.wrapper(setup)

def setup(stdscr):
CursesApp(stdscr)

if __name__ == '__main__':
main()
CODE ABOVE
> 
> My guess is that the error you get is a NameError. The solution to that 
> is to fix the name error, not to run off chasing wild geese. Object 
> inheritance? This has nothing to do with that!

Hmm... You seem to think that I should know this automatically, but
obviously I do not. Did I write the correct mailing-list? Is this not a
place to learn? Exclamation points are very similar to all caps.

The error is actually an attribute does not exist error, output as
requested is further down in the email. 

Although you would think I would cause a name collision, but Python
ignores the class defined as Screen; even if I initialize it, because it
is already defined. So this does not cause a NameError, but it does
cause a TypeError, because "self.Screen" is a "curses.curses window"
which is not a callable object. The code demonstrating this error is
also listed below at the end of the email.

> What is stdscr? Where does it come from? How is it defined?

"stdscr" is a Curses window object. Window objects in Curses are usually
created with the "curses.newwin()" function. However "stdscr" is special
in that it is created when "curses.initscr()" is run. "curses.initscr()"
creates a window object and returns it, "stdscr", that takes up the
available space in the terminal or screen. 
"curses.initscr()" is not present in the code because it is executed by
"curses.wrapper()", as part of the terminal safe initialization process
for Curses.  Hopefully this answers your three questions
satisfactorily. 
Reference: http://docs.python.org/library/curses.html 
> 
> Please copy and paste the *exact* error message you get, including the 
> full traceback.
> 
CODE/ERROR OUTPUT BELOW
$ python3 quick_test.py 
Traceback (most recent call last):
  File "quick_test.py", line 31, in 
main()
  File "quick_test.py", line 25, in main
cursesapp = curses.wrapper(setup)
  File "/usr/lib/python3.2/curses/wrapper.py", line 43, in wrapper
return func(stdscr, *args, **kwds)
  File "quick_test.py", line 28, in setup
CursesApp(stdscr)
  File "quick_test.py", line 9, in __init__
self.mainLoop()
  File "quick_test.py", line 16, in mainLoop
self.Screen.height=10 #This is the line that crashes, because it is
not an attribute of "stdscr".
AttributeError: '_curses.curses window' object has no attribute 'height'
CODE/ERROR OUTPUT ABOVE
> 
> -- 
> Steven

CODE BELOW
#!/usr/bin/python3
"""With this method we cause a TypeError, because the window object is
not callable."""
import curses
class CursesApp:
def __init__(self, stdscr):
self.Screen=stdscr #This is the stdscr object.
curses.init_pair(1,curses.COLOR_BLUE,curses.COLOR_YELLOW)
self.Screen() #So now we will initialize "self.Scree

Re: [Tutor] Already Initialized Object Inheritance?

2011-06-15 Thread WolfRage
All,

I have found a way to use __getattr__() to redirect failed calls to the
variable that holds 'stdscr'. I will draw up some better potential code
tomorrow, and then you can provide me feedback, for a potentially better
method. Or perhaps optimized code. I think I also understand OOP a
little better and realize I was making some simple silly mistakes with
things like trying to call static methods versus initializing a object
and thus my examples need a drastic re-work to make them make more
sense.
Thank you Steven and Christopher for your help so far. I should have the
new code out tomorrow night. But now it is time for bed.
--
Jordan

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] CPU Scheduling

2015-04-27 Thread WolfRage

On 04/27/2015 01:13 PM, Danny Yoo wrote:

On 27/04/15 02:18, alex gonsalez wrote:


Need help trying to implement a CPU scheduling algorithm.
Can I recommend that you read this: 
http://www.dabeaz.com/coroutines/Coroutines.pdf
About half way through it has a Excellent example of how an OS schedules 
processes.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Integrating TDD into my current project work-flows

2015-05-04 Thread WolfRage

I would like some help integrating TDD into my current projects.
My chosen TDD framework is unittest from the standard library.
My system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for 
version control).


My projects are structured like:
Project > develop > Project > Project > __main__.py
  tests   > __main__.py
I want to be able to execute my Project from a cwd of:
Project/develop/Project
as: Python3 -m Project
That currently works.
But executing my tests as: Python3 -m tests
requires that test_Project.py has this hack to import the Project module:
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
do you consider that OK? Is there a better way?
I call it a hack because every testcase file will have to have this line 
added to it in order to work.


I am also using coverage.py and it is good but seems to be testing the 
coverage of my tests, which is not desired, how can I stop this 
behaviour. Or is it really OK.


Output of running the tests:
python3 -m tests
Ran Main.
.
--
Ran 1 test in 0.001s

OK
Name Stmts   Miss  Cover   Missing
--
Project/Project  3  0   100%
tests/test_Project   8  0   100%
--
TOTAL   11  0   100%


The test files:
{FileName = __main__.py}
# -*- coding: utf-8 -*-
if __name__ == '__main__':
import coverage
import unittest
cov = coverage.coverage()
cov.start()
# .. call your code ..
from .test_Project import ProjectTestCase  # lint:ok
unittest.main(exit=False)
cov.stop()
cov.save()
import sys
cov.report(file=sys.stdout)


{FileName = test_Project.py}
# -*- coding: utf-8 -*-
import os
import sys
import unittest
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from Project import Project


class ProjectTestCase(unittest.TestCase):

def test_example(self):
self.assertTrue(Project.main())


The Project Files:
{FileName = __main__.py}
# -*- coding: utf-8 -*-

if __name__ == '__main__':
from . import Project
Project.main()

{FileName = Project.py}
# -*- coding: utf-8 -*-


def main():
return True
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread WolfRage

On 05/05/2015 10:59 AM, Oscar Benjamin wrote:


My projects are structured like:
Project > develop > Project > Project > __main__.py
   tests   > __main__.py
I want to be able to execute my Project from a cwd of:
Project/develop/Project
as: Python3 -m Project
That currently works.


That will only work if there is also a file __init__.py under the
Project/develop/Project/Project directory (alongside the __main__.py
file). Adding a __main__.py file allows the directory to be treated as
a Python script e.g.:

But actually there is no __init__.py in Project/develop/Project/Project/
There is only __main__.py and Project.py files. The __main__.py file 
imports Project.py.

$ python3 Project/develop/Project/Project
$ python3 Project  # Assuming cwd is Project/develop/Project

I tested the above on the terminal and it does not work. I get:
wolfrage@wolfrage-Lemur-UltraThin 
~/HomePlusWolfrage/Projects/Project/develop/Project $ python3 Project

Traceback (most recent call last):
  File "/usr/lib/python3.4/runpy.py", line 170, in _run_module_as_main
"__main__", mod_spec)
  File "/usr/lib/python3.4/runpy.py", line 85, in _run_code
exec(code, run_globals)
  File "Project/__main__.py", line 4, in 
from . import Project
SystemError: Parent module '' not loaded, cannot perform relative import


The -m switch searches for a script as if it were a module using the
module search path. In this case the directory containing the package
Project must be on sys.path and one way to achieve this is to change
directory to the Project/develop/Project directory. Then the Project
folder in this directory is on sys.path.

Did you perhaps mean the Project/develop/Project/Project/ directory?


However a directory is not considered a package unless it contains a
file __init__.py. So if the directory is on sys.path (e.g. in the cwd)
AND their is an __init__.py file then you can do

$ python3 -m Project

and the code in __main__.py will run.

Assuming you have the same setup in the
Project/develop/Project/Project/tests directory (both __init__.py and
__main__.py and Project is on sys.path) then you can run
tests/__main__.py using the module search path as

I think I may have confused you. The layout is like this:
Project/develop/Project/Project
Project/develop/Project/tests
Thus tests is not contained in module's directory.
My reasoning for this is that the tests would be shipped with my 
production code. I am currently undecided as to whether this is a good 
or bad thing. But the more that I read about testing the more it seems 
to be a good thing. So perhaps the best solution is to move the tests 
into the module's directory. Then the below information would probably work.


$ python3 -m Project.tests

Note that this is the same name that you would use to import from the
tests package in interpreter e.g.


from Project.tests import test_stuff


imports from the __init__.py in the tests folder.




Oscar



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread WolfRage

On 05/04/2015 04:49 PM, Martin A. Brown wrote:


Hi there,

Yes, a bit ugly.  Have you tried using nose?  I have used a similar
project development tree and use nose to run the tests.
I had thought about it, but decided not too, since it was not part of 
the standard library. But then again, it is not like I don't know how to 
install additional dependencies for my projects.

Here are a few sample command-lines (I'm on an opensuse-13.2 system with
Python 3.4 and nose for Python-3.4, which is called 'nosetests-3.4'):

   nosetests-3.4 -- ./tests/
   nosetests-3.4 --with-coverage -- ./tests/
   nosetests-3.4 --with-coverage --cover-package=Project -- ./tests/

I like nose because it will discover any unittest and doctest testing
code under the specified files/directories.
It looks pretty easy to use, does it have an API like coverage and 
unittest so that I can write my test scripts and simply execute them 
rather than running commands from the terminal? I find that scripts 
prevent errors as compared to typing commands on the terminal.





-Martin



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread WolfRage

Update: My previous hack, has been changed. I now put:

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

in the __main__.py file located under the tests/ directory and it is 
only needed the one time in that one file. Not sure why I was thinking I 
would need to do that for every test. But that now makes the tests 
standalone.


Also I understand the benefit of coverage showing the coverage for test 
files too, so this is not a problem.


As I am reading about TDD and unittests and the likes. I am thinking 
that testing from a "higher" level is better as compared to the "unit" 
level testing.
It seems to me that in order to get the benefits of testing I need to 
have less test code that will actually test more of my real code. I am 
seeing many potential names for this concept (Blackbox Automated 
Testing; System Level Test; API Level Tests) and would like your inputs 
on it.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread WolfRage

On 05/05/2015 06:49 PM, Alan Gauld wrote:


Not better, just necessary. The two concepts are complementary.
You need both. The developer primarily needs unit testing, the
integrator*(who may of course be the developer in a different
role) needs integration testing and the client/project manager
needs system testing and acceptance testing. They are all part
of a project (especially big/commercial projects)
So how low level of unit testing is acceptable. My use case is the sole 
programmer on a team project. Their is potential for another programmer 
to join the ranks but that has not happened yet. Additionally the 
project is well under way. But Feature additions have slowed so I want 
to make the code less buggy, and so I am hoping to re-factor my code 
now. I think some unit tests could improve the end result of my 
re-factoring, but where to start is the toughest problem for me to 
solve. Especially given the time trade off that is at least initially 
required for unit tests.




Don't underestimate the scale of testing. It is not unusual to
have more test code than functional code! (although it is still
the exception!) In real-world commercial projects testing (and
the associated debugging) typically consumes about 25-40% of
the total project budget. Baseline coding by contrast is only
about 10-25%, sometimes much less.
I agree I have seen this sort of budget numbers in the government 
project that I have been involved in. Especially once the project hits a 
more general life cycle/maintenance mode.


So how can I make unit testing apply to my project without starting from 
scratch? And how low should I test(ie. every function; every class; 
every interface; system level)?

Thank you for any insight and all of your help.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Integrating TDD into my current project work-flows

2015-05-05 Thread WolfRage
I find myself in the same mind set as this individual: 
http://stackoverflow.com/a/64453/4285911
It is hard to write a proper test with out me initially outlining where 
I am going. Perhaps I need to better understand planning and drafting a 
programming project before I can hope to emulate TDD.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Making Doubly Linked List with Less Lines of Code.

2014-12-24 Thread WolfRage
I wrote some code recently to make a linked list of Nodes for a 2d 
graph, so it consists of rows and columns. Now I wanted to make the code 
support being doubly linked, forwards and backwards.  The difficult part 
of this is that the links are per row and per column. But the code I 
think is overly bloated. I am currently working on reducing the 
complexity of it. If any one has the time to look at it, if you have 
ideas for how I can re-write it to be much smaller I would appreciate 
the information. If you need more code let me know, but I tried to 
condense it since this singular function is around 325 lines of code. 
Thank you.


The function to make the linked list:

def make_linked_lists(self):
previous_row_node = None
previous_col0_node = None
previous_col1_node = None
previous_col2_node = None
previous_col3_node = None
previous_col4_node = None
previous_col5_node = None
previous_col6_node = None
previous_col7_node = None
current_node = None
self.tile_list = list()
for row in range(0, self.rows):
for col in range(0, self.cols):
current_node = self.get_instance_of_id(str(col) + ',' +
str(row))
self.tile_list.append(current_node)
if row == 0:
if col == 0:
self.row0 = current_node
self.col0 = current_node
previous_col0_node = current_node
elif col == 1:
self.col1 = current_node
previous_col1_node = current_node
elif col == 2:
self.col2 = current_node
previous_col2_node = current_node
elif col == 3:
self.col3 = current_node
previous_col3_node = current_node
elif col == 4:
self.col4 = current_node
previous_col4_node = current_node
elif col == 5:
self.col5 = current_node
previous_col5_node = current_node
elif col == 6:
self.col6 = current_node
previous_col6_node = current_node
elif col == 7:
self.col7 = current_node
previous_col7_node = current_node
if previous_row_node is not None:
previous_row_node.next_row_node = current_node
current_node.prev_row_node = previous_row_node
previous_row_node = current_node
elif row == 1:
if col == 0:
self.row1 = current_node
previous_row_node = None
previous_col0_node.next_col_node = current_node
current_node.prev_col_node = previous_col0_node
previous_col0_node = current_node
elif col == 1:
previous_col1_node.next_col_node = current_node
current_node.prev_col_node = previous_col1_node
previous_col1_node = current_node
elif col == 2:
previous_col2_node.next_col_node = current_node
current_node.prev_col_node = previous_col2_node
previous_col2_node = current_node
elif col == 3:
previous_col3_node.next_col_node = current_node
current_node.prev_col_node = previous_col3_node
previous_col3_node = current_node
elif col == 4:
previous_col4_node.next_col_node = current_node
current_node.prev_col_node = previous_col4_node
previous_col4_node = current_node
elif col == 5:
previous_col5_node.next_col_node = current_node
current_node.prev_col_node = previous_col5_node
previous_col5_node = current_node
elif col == 6:
previous_col6_node.next_col_node = current_node
current_node.prev_col_node = previous_col6_node
previous_col6_node = current_node
elif col == 7:
previous_col7_node.next_col_node = current_node
current_node.prev_col_node = previous_col7_node
previous_col7_node = current_node
if previous_row_node is not None:
previous_row_node.next_row_node = current_node
previous_row_node = current_node
el

Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2014-12-24 Thread WolfRage
OK thanks for the rapid response, I will start rewriting the functions 
in this way now, and will come back with what I wind up with.

Also Merry Christmas!

On 12/24/2014 04:56 PM, Steven D'Aprano wrote:

On Wed, Dec 24, 2014 at 04:35:06PM -0500, WolfRage wrote:

I wrote some code recently to make a linked list of Nodes for a 2d
graph, so it consists of rows and columns. Now I wanted to make the code
support being doubly linked, forwards and backwards.  The difficult part
of this is that the links are per row and per column. But the code I
think is overly bloated. I am currently working on reducing the
complexity of it. If any one has the time to look at it, if you have
ideas for how I can re-write it to be much smaller I would appreciate
the information. If you need more code let me know, but I tried to
condense it since this singular function is around 325 lines of code.

Wow. It certainly is bloated.

I don't have time to look at it in any detail right now, as it is
Christmas Day here, but I'll give you a suggestion. Any time you find
yourself writing more than two numbered variables, like this:


 previous_col0_node = None
 previous_col1_node = None
 previous_col2_node = None
 previous_col3_node = None
 previous_col4_node = None
 previous_col5_node = None
 previous_col6_node = None
 previous_col7_node = None

you should instead think about writing a list:

 previous_col_nodes = [None]*8

Then, instead of code like this:


 if col == 0:
 self.col0 = current_node
 previous_col0_node = current_node
 elif col == 1:
 self.col1 = current_node
 previous_col1_node = current_node
 elif col == 2:
 self.col2 = current_node
 previous_col2_node = current_node

etc.

you can just write:

 for col in range(number_of_columns):
 self.columns[col] = current_node
 previous_col_nodes[col] = current_node


Look for the opportunity to write code like this instead of using range:

 for col, the_column in enumerate(self.columns):
 self.columns[col] = process(the_column)


Any time you write more than a trivial amount of code twice, you should
move it into a function. Then, instead of:

 if row == 0:
if col == 0: a
elif col == 1: b
elif col == 2: c
elif col == 3: d
elif col == 4: e
elif row == 1:
if col == 0: a
elif col == 1: b
elif col == 2: c
elif col == 3: d
elif col == 4: e
elif row == 3:
# same again

you can write a function:

def process_cell(row, col):
if col == 0: a
elif col == 1: b
elif col == 2: c
elif col == 3: d
elif col == 4: e
 
# later on


for row in rows:
 for col in cols:
 process_cell(row, col)



Try those suggestions, and come back to us if you still need help.






___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2014-12-24 Thread WolfRage
Here is a condensed version of all of the applicable code but with out 
Linked List filled in, as I am preparing to re-write it.


class GameTile():
def __init__(self, id, **kwargs):
self.id = id

class GameGrid():
def __init__(self, **kwargs):
self.cols = 8
self.rows = 10
# Each variable below is a link to the head Node in the respective
# row or column.
self.row0 = None
self.row1 = None
self.row2 = None
self.row3 = None
self.row4 = None
self.row5 = None
self.row6 = None
self.row7 = None
self.row8 = None
self.row9 = None
self.col0 = None
self.col1 = None
self.col2 = None
self.col3 = None
self.col4 = None
self.col5 = None
self.col6 = None
self.col7 = None
self.skip_to_row = None
self.skip_to_col = None
self.tile_list = list()

def make_linked_lists(self):
prev_row_node = None
prev_col0_node = None
current_node = None
for row in range(0, self.rows):
for col in range(0, self.cols):
for node in self.tile_list:
if node.id == str(col) + ',' + str(row):
current_node = node


def update(self):
for row in range(0, self.rows):
element = None
if row < 7:
pass
for column in range(0, self.cols):
self.tile_list.append(GameTile(id=str(column) + ',' + 
str(row)))


def print_lists(self):
for node in self.tile_list:
print(node.id)


temp = GameGrid()
temp.update()
temp.make_linked_lists()
temp.print_lists()
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2014-12-25 Thread WolfRage
Thanks, definitely adding this concept into my code. And re-writing. I 
originally hard coded everything just to get it working... but 
obviously, it would have been more time efficient to have thought in 
these terms from the beginning. Hopefully I can learn to write code more 
like this to begin with, even when I just want to get something working.

Reading the rest of your recommendations now.

On 12/25/2014 12:15 AM, Danny Yoo wrote:

Quick comment: the structure of the code here catches my eye:



 # Each variable below is a link to the head Node in the respective
 # row or column.
 self.row0 = None
 self.row1 = None
 self.row2 = None
 self.row3 = None
 self.row4 = None
 self.row5 = None
 self.row6 = None
 self.row7 = None
 self.row8 = None
 self.row9 = None

It seems highly regular; the code here is maintaining a collection of
row variables.  Because it's so regular, you might consider using a
list to represent this collection.  Concretely:

 self.rows = [None, None, None, None, None, None, None, None, None, None]

We can express this more concisely in Python as:

 self.row = [None] * 10

Once we have this, then we can get at any particular row through its
offset.  So instead of:

 self.row0

we say:

 self.row[0]

The big win with a list representation is that the offset can be
computed.  So if we need to do an operation on each row, we might say:

 for i in range(10):
 ## ... Do something with self.row[i]

And if you see the full power of this, you'll realize that this allows
us to express loops to do something to _all_ the rows, expressing that
action just once.  Or if we need to do something for every other row,
that too is not too difficult to express:

 for i in range(0, 10, 2):
 ## ... Do something with self.row[i]


In contrast, doing the same thing without using an explicit container
representation means that doing container-wide actions is harder to
do.  This is the code smell that we saw at the beginning of this post,
where we see repetitive code.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2014-12-30 Thread WolfRage
This is my most recent rendition of the code. It still needs to be 
improved. Below I am answering some questions that were posed. Also I 
think my code is currently wrong because I think the print_by functions 
are both printing the list the same way. Tomorrow I will fix this and 
improve the code.


Thank you guys for your help so far.



class GameTile():

def __init__(self, id, **kwargs):

self.id = id

self.value = None

self.next_node_in_row = None

self.next_node_in_col = None

self.prev_node_in_row = None

self.prev_node_in_col = None


class GameGrid():

def __init__(self, **kwargs):

self.num_of_cols = 8

self.num_of_rows = 10

# Each variable below is a list of links to the head

# node in the respective row or column.

self.rows = [None] * self.num_of_rows

self.cols = [None] * self.num_of_cols

self.skip_to_row = None

self.skip_to_col = None

self.tile_list = list()


def make_grid_nodes(self):

for row in range(0, self.num_of_rows):

for column in range(0, self.num_of_cols):

tile = GameTile(id=str(column) + ',' + str(row))

self.tile_list.append(tile)

if column == 0: # New Head of Row

self.rows[row] = tile

else:

prev_row.next_node_in_row = tile

tile.prev_node_in_row = prev_row

prev_row = tile

if row == 0: # New Head of Column

self.cols[column] = tile

else:

prev_col.next_node_in_col = tile

tile.prev_node_in_col = prev_col

prev_col = tile


def print_by_rows(self):

for col, the_column in enumerate(self.cols):

print(the_column.id)

if the_column.next_node_in_row is not None:

node = the_column.next_node_in_row

while node.next_node_in_row is not None:

print(node.id)

node = node.next_node_in_row


def print_by_row(self):

for row in self.rows:

print(row.id)

if row.next_node_in_row is not None:

node = row.next_node_in_row

while node.next_node_in_row is not None:

print(node.id)

node = node.next_node_in_row


def print_by_col(self):

for col in self.cols:

print(col.id)

if col.next_node_in_col is not None:

node = col.next_node_in_col

while node.next_node_in_col is not None:

print(node.id)

node = node.next_node_in_col


def draw_grid(self):

import time

sep = '─'

f = '░│'

l = '◈│'

row = sep + '\n│'

last_col = None

current_col = None

val = None

for node in self.tile_list:

if node.value == None:

val = l

else:

val = f

current_col = node.id.split(',')[1]

if last_col is None:

row += val

elif current_col == last_col:

row += val

else:

row += '\n' + sep + '\n│' + val

last_col = node.id.split(',')[1]

row += '\n' + sep

print(row)

#time.sleep(1)


temp = GameGrid()

temp.make_grid_nodes()

#temp.draw_grid()

temp.print_by_row()

print('BREAK Now COLUMNS')

temp.print_by_col()



On 12/25/2014 12:31 AM, Danny Yoo wrote:

What are the _operations_ you want to support?  Can you say more about this?
I need to support lookups, no insertions or deletions are required. This 
code will be used to quickly lookup nodes, and check for specific 
patterns by checking the nodes values in either a row or column. The 
code to perform the pattern matching was already written and is fast, 
but I will add it to the code once the creation


On 12/24/2014 04:56 PM, Steven D'Aprano wrote:

Wow. It certainly is bloated.

Agreed.

Look for the opportunity to write code like this instead of using range:

 for col, the_column in enumerate(self.columns):
 self.columns[col] = process(the_column)
This caught my eye, and I did try to implement it. But why use this 
instead of range? I am using Python3. I did find that enumerate is 
potentially faster but sometimes slower, as it depends on what is being 
done. Perhaps because it is considered more Pythonic? So what is your 
reason for this suggestion?

Any time you write more than a trivial amount of code twice, you should
move it into a function. Then, instead of:

I agree, should have done, and need to look for these opportunities sooner.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help on Python drop-down list options

2014-12-31 Thread WolfRage
What is the user interface that your program is using, currently? IE: 
QT, GTK, Tkinter, Curses, Kivy, Pygame, Or None?

What is the target system on which your program runs?
How are you currently viewing the mean and standard deviation results?
What version of Python are you using and what is your OS?

On 12/31/2014 08:49 AM, Tammy Miller wrote:

Hello All,

  


I need help on the
following:  I have a created a project from a csv file to calculate the
mean and standard deviation.

However, I would like to
create a drop-down list and display the mean and standard deviation?  Is there 
a module
for that?

  


Thank you,

  


Tammy

  

  

  

  



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Convert string to bytes

2014-12-31 Thread WolfRage
I wrote a program to help me break out hex strings awhile ago. It was 
written to communicate with a Atmega 168. This is written for Python 3. 
Here is a snippet, see if this helps you.


s4 = "28 40 7A 7C 05 00 00 34"
hex_array = bytearray.fromhex(s4)
print(s4)
print(list(hex_array))
print(hex_array)
for byte in list(hex_array):
print(hex(byte))
print(bytes([byte]))


On 12/31/2014 05:08 AM, shweta kaushik wrote:

Hi all,

I need help on this problem.

I have one message packet in form of string s = '0xFE, 0x01, 0x01, 0x22,
0xFE, 0x02'. I have to send this data to MSP430 microcontroller, but it is
not taking data if it is string. If I am passing this as hardcoded value s1
= 0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02 then board is responding. I want to
convert s as s1 using python.

Please help me out to convert string in normal format for microcontroller
to respond.

Thanks in advance.

Regards,
Shweta
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-01 Thread WolfRage

Final Code Using 2d List instead of Doubly Linked List.


class GameTile():

def __init__(self, id, **kwargs):

# id is (X,Y)

self.id = id


class GameGrid():

def __init__(self, **kwargs):

self.cols = 7

self.rows = 8

# grid is 2d array as y, x ie [y][x].

self.grid = [[None] * self.rows for i in range(self.cols)]



def make_grid(self):

for row in range(0, self.rows):

for col in range(0, self.cols):

self.grid[col][row] = GameTile(id=str(row) + ',' + str(col))



def print_by_row(self):

for col in range(0, self.cols):

for row in range(0, self.rows):

print(self.grid[col][row].id)



def print_by_col(self):

for row in range(0, self.rows):

for col in range(0, self.cols):

print(self.grid[col][row].id)


def check_bounds(self, x, y):

if (0 <= x < self.rows) and (0 <= y < self.cols):

return True

return False


def lookup_node(self, x, y):

if not self.check_bounds(x, y):

return False

return self.grid[y][x]


def draw_grid(self):

for col in range(0, self.cols):

print(end='| ')

for row in range(0, self.rows):

print(self.grid[col][row].id, end=' | ')

print()



temp = GameGrid()

temp.make_grid()

temp.draw_grid()


Any feedback for my code is appreciated. Thank you.

On 12/31/2014 06:57 PM, Steven D'Aprano wrote:
Trust me on this, there is no linked list code you can write in Python 
that will be faster than using a list of lists. Even in C, traversing 
a linked list is slower than array access, and Python is not C. 

OK. I do trust you.

Bounds checking is easy: cell [i, j] is in bounds if this is true:

 (0 <= i < NUM_ROWS) and (0 <= j < NUM_COLS)

Fast access to any cell is possible:

 array[i][j]

Implemented both.

from sys import getsizeof

Thanks I forgot about getsizeof.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage


On 01/02/2015 12:28 AM, Dave Angel wrote:

On 01/01/2015 11:48 PM, WolfRage wrote:

Final Code Using 2d List instead of Doubly Linked List.




Please don't top-post.  Instead, post your comments inline with the 
parts of the previous message to which you're responding.
I did reply in-line, but it appears even though I selected plan-text 
only. Thunderbird still messed it up. Not much I can do about that. 
Sorry I am used to top posting. But the rest of my response was in-line 
even if Thunderbird messed it up.


Is there a reason you doublespaced the whole thing?  And why did you 
retype it instead of just copy/pasting it?  And why lose the 
indentation, so nobody can actually try it without guessing at your 
indentation?
No I did not double-space it, not in what I sent or was shown by 
Thunderbird.
I definitely did not re-type it, I copy and pasted. But it seems that 
Thunderbird has a real hard time when also replying in-line to quotes.
As far as the rest I will repost with just the code so that hopefully it 
is not messed up as I imagine that made it incredibly hard to read.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage

import sys



class GameTile():

def __init__(self, id, **kwargs):

# id is (X,Y)

self.id = id



class GameGrid():

def __init__(self, **kwargs):

self.cols = 8

self.rows = 8

# grid is 2d array as y, x ie [y][x].

self.grid = [[None] * self.rows for i in range(self.cols)]


def make_grid(self):

for row in range(0, self.rows):

for col in range(0, self.cols):

self.grid[col][row] = GameTile(id=str(row) + ',' + str(col))


def print_by_row(self):

for col in range(0, self.cols):

for row in range(0, self.rows):

print(self.grid[col][row].id)


def print_by_col(self):

for row in range(0, self.rows):

for col in range(0, self.cols):

print(self.grid[col][row].id)


def check_bounds(self, x, y):

if (0 <= x < self.rows) and (0 <= y < self.cols):

return True

return False


def lookup_node(self, x, y):

if not self.check_bounds(x, y):

return False

return self.grid[y][x]


def draw_grid(self):

for col in range(0, self.cols):

print(end='| ')

for row in range(0, self.rows):

print(self.grid[col][row].id, end=' | ')

print()



temp = GameGrid()

temp.make_grid()

temp.draw_grid()

print(sys.getsizeof(temp.grid))


#The above code shows fine to me with indentation preserved. Plain-Text 
was selected in Thunderbird.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage


On 01/02/2015 02:21 AM, Steven D'Aprano wrote:

Fixing the mangled formatting, as best as I am able (and can be
bothered).

On Thu, Jan 01, 2015 at 11:48:18PM -0500, WolfRage wrote:

class GameTile():
 def __init__(self, id, **kwargs):
 # id is (X,Y)
 self.id = id

What is the purpose of the **kwargs? It doesn't get used, it just
silently ignores them.
These are Kivy Buttons, when GameTile is written as a whole. But I broke 
it out in order to solve this specific problem.


Actually, what is the purpose of this GameTile class? It has no methods
apart from the constructor. That is a sign of a class that isn't pulling
its weight, its not doing anything. All the other code in your program
looks inside the GameTile and accesses self.id directly. This is a sure
sign of a class that doesn't need to exist.
It manages the on_press, on_release, and the image currently being 
displayed on the displayed tiles. But that is all that it does. But I 
still think I have to have it, since it is a button which inherits from 
Kivy's Button class.


It may be better to give this at least a __str__ method, so if
nothing else you can print it without looking inside:
Excellent idea, I will add this __str__ method so that I can print it 
directly.



class GameTile():
 def __init__(self, x, y):
 self.x = x
 self.y = y
 def __str__(self):
 return "%d, %d" % (self.x, self.y)



class GameGrid():
 def __init__(self, **kwargs):
 self.cols = 7
 self.rows = 8
 # grid is 2d array as y, x ie [y][x].
 self.grid = [[None] * self.rows for i in range(self.cols)]

Why do you have GameTiles use X,Y but the grid uses the opposite order,
Y,X? This is going to cause confusion. I'm already confused!
Well my lack of understanding as to how to implement the 2d list 
resulted in the row and col count being opposite, but I see now simply 
re-arranging those would fix this problem and the resulting hacks in the 
rest of the code, as it goes back and forth.



 def make_grid(self):
 for row in range(0, self.rows):
 for col in range(0, self.cols):
 self.grid[col][row] = GameTile(id=str(row) + ',' + str(col))

No need to write range(0, Whatever), since range defaults to 0. Better
to write range(Whatever).

Good point.


Why does the GameTile record the coordinates as strings?

I would prefer something like this:

 def make_grid(self):
 for row in range(self.rows):
 for col in range(self.cols):
 self.grid[col][row] = GameTile(row, col)
I did this when I was writing the previous Kivy code, the coordinates 
actually serve as the id which is a Kivy variable that I am able to 
quickly lookup via there method, but I have mostly replaced this lookup 
with the new 2d list lookup now and so it is no longer necessary (At 
least I think, I will have to see how much of my previous code relied on 
this functionality and then weed it out).

http://kivy.org/docs/api-kivy.uix.widget.html#kivy.uix.widget.Widget.id



although it looks strange due to the backwards ordering of col/row.


Your __init__ method should automatically call make_grid. That is:

 def __init__(self, **kwargs):
 self.cols = 7
 self.rows = 8
 # grid is 2d array as y, x ie [y][x].
 self.grid = [[None] * self.rows for i in range(self.cols)]
 self.make_grid()


Actually, even better will be to move the self.grid = ... line out of
the __init__ method, and make it part of make_grid. Since it is part of
making the grid.
The making of the grid was put in the update because of Kivy, literally. 
I did not want to delay the display of the next screen while I was 
building my linked list. The previous linked list code was even bigger 
than what I posted initially and the execution of this code took around 
1-2 seconds which caused the previous screen to hang. To prevent that I 
called update as a task to happen after the screens had flipped. But now 
that the grid creation is so fast, I can do this and no delay will be 
experienced.



 def print_by_row(self):
 for col in range(0, self.cols):
 for row in range(0, self.rows):
 print(self.grid[col][row].id)

This now becomes:

 def print_by_row(self):
 for col in range(0, self.cols):
 for row in range(0, self.rows):
 print(self.grid[col][row])
That is a cool feature with the __str__ method. haven't really learned 
to use the "Magic" or "special" methods yet. But will definitely start 
too now.



since GameTiles now know how to print themselves. Likewise for this:

 def print_by_col(self):
 for row in range(0, self.rows):
 for col in range(0, self.cols):
 print(self.grid[col][row])


Another simplification here:


 def check_bounds(self, x, y):
 retu

Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage
Dave or Steve, what mail program do you use? It appears Thunderbird is 
still posting the code all messed up. Which makes it impossible to 
communicate effectively with the list.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage

On 01/02/2015 10:37 AM, Alan Gauld wrote:



I use Thunderbird for posting too, and nobody has complained yet about
my code layout.
My account settings are:

Composition&Addressing
Compose in HTML - OFF
Auto quote original then "START REPLY BELOW QUOTE"

My Tbird prefs are:
Composition->General tab-> Send Options button
Text Format set to "Convert to plain text"
Plain Text domains tab -> includes python.org and gmane.org

And in my Address book I have the python tutor list entry set to

Prefers messages formatted as PLAIN TEXT

HTH
Using Alan's settings above I can already see the difference in the 
composition window.


Reposting my code to see if it comes out correctly now. I am still 
applying Steve's suggestions.


import sys


class GameTile():
def __init__(self, col, row, **kwargs):
# id is (X,Y)
self.id = str(row) + ',' + str(col)
self.col = col
self.row = row

def __str__(self):
return '%d, %d' % (self.col, self.row)


class GameGrid():
def __init__(self, **kwargs):
self.cols = 8
self.rows = 8
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = [[None] * self.cols for i in range(self.rows)]
for row in range(self.rows):
for col in range(self.cols):
self.grid[row][col] = GameTile(row=row, col=col)

def print_by_row(self):
for col in range(self.cols):
for row in range(self.rows):
print(self.grid[row][col])

def print_by_col(self):
for row in range(self.rows):
for col in range(self.cols):
print(self.grid[row][col])

def check_bounds(self, x, y):
if (0 <= x < self.rows) and (0 <= y < self.cols):
return True
return False

def lookup_node(self, x, y):
if not self.check_bounds(x, y):
return False
return self.grid[x][y]

def draw_grid(self):
for col in range(self.cols):
print(end='| ')
for row in range(self.rows):
print(self.grid[row][col], end=' | ')
print()


grid = GameGrid()
grid.draw()
print(sys.getsizeof(grid.grid))

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage

On 01/02/2015 02:21 AM, Steven D'Aprano wrote:

What is the purpose of the **kwargs? It doesn't get used, it just
silently ignores them.


Hopefully you got the answer for this from the previous message.


Why does the GameTile record the coordinates as strings?


Hopefully you got the answer for this from the previous message.


Your lookup_node method returns a GameTile or False on failure:

 def lookup_node(self, x, y, ):
 if not self.check_bounds(x, y):
 return False
 return self.grid[y][x]

I'm not sure about that design. I wonder whether it would be better to
return None, or raise an exception.
What would you suggest this code does on error, when the Node looked up 
is out of bounds?


Latest copy of the code. I think I got every ones suggestion.

import sys


class GameTile():
def __init__(self, col, row, **kwargs):
# id is (X,Y)
self.id = str(row) + ',' + str(col)
self.col = col
self.row = row

def __str__(self):
return '%d, %d' % (self.col, self.row)


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
self.cols = cols
self.rows = rows
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = [[None] * self.cols for i in range(self.rows)]
for row in range(self.rows):
for col in range(self.cols):
self.grid[row][col] = GameTile(row=row, col=col)

def print_by_row(self):
for col in self.grid:
for row in col:
print(row)

def print_by_col(self):
for row in self.grid:
for col in row:
print(col)

def check_bounds(self, x, y):
return (0 <= x < self.rows) and (0 <= y < self.cols)

def lookup_node(self, x, y):
if not self.check_bounds(x, y):
return False
return self.grid[x][y]

def draw(self):
for col in self.grid:
print(end='| ')
for row in col:
print(row, end=' | ')
print()


grid = GameGrid(3, 3)
grid.draw()
print(sys.getsizeof(grid.grid))

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage

On 01/02/2015 12:08 PM, Dave Angel wrote:

class GameGrid():
 def __init__(self, cols=8, rows=7, **kwargs):


You probably want to reverse the order of the parameters;  you've got
almost everything else row-major

You are right, a lot of inconsistency that will lead to errors latter 
on. I need to make everything column-major. So that the grid (x,y) are 
the same to grid (col,row). I have too much confusion throughout my 
code, so I will correct the code.



Since both stages are being done in the same method, you don't need the
part which initializes to None.

 def make_grid(self):
 # grid is 2d array as x, y ie [x][y].
 self.grid = []
 for row_num in range(self.rows):
 self.grid.append( [GameTile(row=row_num, col=col_num)  for
col_num in range(self.cols)] )


Implemented the second version.


 def print_by_row(self):
 for col in self.grid:
 for row in col:
 print(row)


This cannot work.  The items in self.grid are rows.  Calling one of them
col doesn't make it so.  In other words, the method as written will do
exactly what print_by_col() does.


Good point, I did not read the output thoroughly enough to catch this.


Try the following:

 def print_by_row(self):
 for col_number in range(self.cols):
 for row in self.grid:
 print(row[col_number])


Implemented.


This one should work fine.  But one of the names could be improved:


 def print_by_col(self):
 for row in self.grid:
 for tile in row:
 print(tile)


Thanks, improved.


All code untested.  i hope it helps.


Definitely. Thanks.

I have updated the code and I realized that all of my earlier confusion 
was even greater, so I have also added comments to make things make 
sense. Now the print_by_ methods work as I envision and in accordance 
with the comments.


import sys


class GameTile():
def __init__(self, col, row, **kwargs):
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row

def __str__(self):
return '%d, %d' % (self.col, self.row)


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
self.cols = cols
self.rows = rows
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
self.grid.append([GameTile(col=col_num, row=row_num) for
col_num in range(self.cols)])

def print_by_col(self):
# As in going down the column assuming we started at the top.
for col_num in range(self.cols):
for row in self.grid:
print(row[col_num])

def print_by_row(self):
# As in going right across the row assuming we started at the left.
for row in self.grid:
for node in row:
print(node)

def check_bounds(self, x, y):
return (0 <= x < self.rows) and (0 <= y < self.cols)

def lookup_node(self, x, y):
if not self.check_bounds(x, y):
return False
return self.grid[x][y]

def draw(self):
for col in self.grid:
print(end='| ')
for row in col:
print(row, end=' | ')
print()


grid = GameGrid(3, 3)
grid.draw()
print(sys.getsizeof(grid.grid))
print()
grid.print_by_row()
print()
grid.print_by_col()

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Making Doubly Linked List with Less Lines of Code.

2015-01-02 Thread WolfRage
Tutors, on my next iteration I am going to add more of the game code. 
Since I am no longer using Doubly Linked Lists, should I create a new 
thread? Or should I continue with this thread to continue with the 
established context?

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-02 Thread WolfRage
First an explanation of how the game works: The game is a simple 
matching game but with a twist. Instead of matching a straight 3 in a 
row, we have some rules that only certain combinations will result in an 
elimination. In general 2 of the same value in a row with with 1 of 2 
other possible values will eliminate all three nodes. Eliminations can 
occur either horizontally or vertically but not diagonally. Each tile 
has a value now, that value is used when evaluating the rules. Currently 
there are only 5 allowed values of 0-4 although more could be added 
later, so any solution needs to be expandable.
These are the basic rules that allow for an elimination to occur(values 
are put in quotes to distinguish values):

2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes.

The main focus of the code is the find_eliminations method. I think its 
implementation is smart since it uses a math trick, but then again I 
wrote it.
My math trick works by first finding 2 matching nodes next to each other 
out of every 3 nodes, then adding the values of all 3 nodes together and 
checking for specific totals. None of the possible totals overlap.


Here is the code:

import random


class GameTile():
def __init__(self, value, col, row, **kwargs):
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
self.value = value
self.eliminated = False

def __str__(self):
#return '%d, %d' % (self.col, self.row)
if len(str(self.value)) == 1:
return ' ' + str(self.value)
return str(self.value)


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
self.cols = cols
self.rows = rows
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
self.grid.append([GameTile(value=random.choice([5, 6, 11, 
19, 20]), col=col_num,

row=row_num) for col_num in range(self.cols)])

def print_by_col(self):
# As in going down the column assuming we started at the top.
for col_num in range(self.cols):
for row_list in self.grid:
print(row_list[col_num])

def print_by_row(self):
# As in going right across the row assuming we started at the left.
for row in self.grid:
for node in row:
print(node)

def check_bounds(self, x, y):
return (0 <= x < self.rows) and (0 <= y < self.cols)

def lookup_node(self, x, y):
if not self.check_bounds(x, y):
return False
return self.grid[x][y]

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def find_eliminations(self):
# I define 3 variables for holding the 3 nodes/tiles that I am
# currently checking to see if an elimination possibility exists.
# It uses a math trick to check for elimination by adding the 
values
# and checking for specific totals. None of the possible totals 
overlap.

#First Down the columns.
for col_num in range(self.cols):
first = None
second = None
third = None
for row_list in self.grid:
if row_list[col_num].row == 0:
first = row_list[col_num]
elif row_list[col_num].row == 1:
second = row_list[col_num]
elif row_list[col_num].row == 2:
third = row_list[col_num]
else:
first = second
second = third
third = row_list[col_num]
if third is not None:
self.check_total_and_eliminate(first, second, third)
# Now across the rows.
for row in self.grid:
first = None
second = None
third = None
for node in row:
if node.col == 0:
first = node
elif node.col == 1:
second = node
elif node.col == 2:
third = node
else:
first = 

[Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-02 Thread WolfRage
Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, 
Windows, Linux, OSX).


First an explanation of how the game works: The game is a simple 
matching game but with a twist. Instead of matching a straight 3 in a 
row, we have some rules that only certain combinations will result in an 
elimination. In general 2 of the same value in a row with with 1 of 2 
other possible values will eliminate all three nodes. Eliminations can 
occur either horizontally or vertically but not diagonally. Each tile 
has a value now, that value is used when evaluating the rules. Currently 
there are only 5 allowed values of 0-4 although more could be added 
later, so any solution needs to be expandable.
These are the basic rules that allow for an elimination to occur(values 
are put in quotes to distinguish values):

2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes.

The main focus of the code is the find_eliminations method. I think its 
implementation is smart since it uses a math trick, but then again I 
wrote it.
My math trick works by first finding 2 matching nodes next to each other 
out of every 3 nodes, then adding the values of all 3 nodes together and 
checking for specific totals. None of the possible totals overlap.


Here is the code:

import random


class GameTile():
def __init__(self, value, col, row, **kwargs):
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
self.value = value
self.eliminated = False

def __str__(self):
#return '%d, %d' % (self.col, self.row)
if len(str(self.value)) == 1:
return ' ' + str(self.value)
return str(self.value)


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
self.cols = cols
self.rows = rows
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
self.grid.append([GameTile(value=random.choice([5, 6, 11, 
19, 20]), col=col_num,

row=row_num) for col_num in range(self.cols)])

def print_by_col(self):
# As in going down the column assuming we started at the top.
for col_num in range(self.cols):
for row_list in self.grid:
print(row_list[col_num])

def print_by_row(self):
# As in going right across the row assuming we started at the left.
for row in self.grid:
for node in row:
print(node)

def check_bounds(self, x, y):
return (0 <= x < self.rows) and (0 <= y < self.cols)

def lookup_node(self, x, y):
if not self.check_bounds(x, y):
return False
return self.grid[x][y]

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def find_eliminations(self):
# I define 3 variables for holding the 3 nodes/tiles that I am
# currently checking to see if an elimination possibility exists.
# It uses a math trick to check for elimination by adding the 
values
# and checking for specific totals. None of the possible totals 
overlap.

#First Down the columns.
for col_num in range(self.cols):
first = None
second = None
third = None
for row_list in self.grid:
if row_list[col_num].row == 0:
first = row_list[col_num]
elif row_list[col_num].row == 1:
second = row_list[col_num]
elif row_list[col_num].row == 2:
third = row_list[col_num]
else:
first = second
second = third
third = row_list[col_num]
if third is not None:
self.check_total_and_eliminate(first, second, third)
# Now across the rows.
for row in self.grid:
first = None
second = None
third = None
for node in row:
if node.col == 0:
first = node
elif node.col == 1:
second = node
elif n

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/02/2015 10:21 PM, Dave Angel wrote:


This code is way too complex for what it accomplishes. See  below.

Yes, that it why it needs to be optimized. It is unfortunate that my 
first goes at many tasks are not the most efficient. But hopefully that 
will get better as I learn from all of you.


If the self.rows is 3, this is equivalent to just:
first, second, third = row
If the self.rows is larger, it's equivalent to:
first, second, third = row[p: p+3]  for some value of p


 if third is not None:
 self.check_total_and_eliminate(first, second, third)


But even better, let the method   check_total_and_eliminate take a slice
as its argument.
   self.check-total_and_eliminate(row[p: p+3])

I was able to implement this for the rows, but I was not able yet to get 
it to work with the column code, at least not before I went to sleep 
last night.
Here is what I did for the method find_eliminations, now called 
find_eliminations2.


def find_eliminations2(self):
#First Down the columns.
i = 0
for col_num in range(self.cols):
for row_list in self.grid:
try:  # row_list[col_num]
first, second, third = row_list[i: i + 3]
print(first, second, third, sep=' | ')
# The print above is not giving me the nodes down
# each column as I would expect.
# The above print is one of many tries. Will have
# to keep trying.
#self.check_total_and_eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
i = 0
for row in self.grid:
for node in row:
try:
self.check_total_and_eliminate(row[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0

def check_total_and_eliminate(self, slices):
first, second, third = slices
total = None
if first.value == second.value:
total = first.value + second.value + third.value
elif second.value == third.value:
total = first.value + second.value + third.value
if total == 17 or total == 21 or total == 28 or total == 29 or \
total == 31 or total == 42 or total == 45 or total == 46 \
or total == 49 or total == 58:
first.eliminated = True
second.eliminated = True
third.eliminated = True



This doesn't come close to implementing the test you describe above. For
example, a total of 29 could be your first case, 5,5,19.  But it could
also be 4,4,21.   Or 6,6,17.  Etc.


Sorry I did not fully explain myself. The test case could not be 4,4,21 
because I made a list of acceptable numbers and only acceptable numbers 
are allowed. Actually it is a table of letters on the top and side, the 
letters on the top occur once in the sequence, the letters on the side 
occur twice in the sequence. Each letter is representative of my earlier 
values. The table resolves all of the possible outcomes or totals from 
each sequence, allowing me to detect every possibility.


 |B  |N  |F  |H  |W  |E  |Z  |X  |Y   *1
B|0  |5  |6  |11 |19 |20 |52 |61 |67
N|10 |15 |16 |21 |29 |30 |62 |71 |77
F|12 |17 |18 |23 |31 |32 |64 |73 |79
H|22 |27 |28 |33 |41 |42 |74 |83 |89
W|38 |43 |44 |49 |57 |58 |90 |99 |105
E|40 |45 |46 |51 |59 |60 |92 |101|107
Z|104|109|110|115|123|124|156|165|171
X|122|127|128|133|141|142|174|183|189
Y|134|139|140|145|153|154|186|195|201

*2

B=0
N=5
F=6
H=11
W=19
E=20
Z=52
X=61
Y=67

NNH=21 | NNW=29
FFN=17 | FFW=31
HHF=28 | HHE=42
WWE=58 | WWH=49
EEF=46 | EEN=45




I suggest instead that you compare the values against a table of
interesting values.  If you make your table a list of 3-tuples, it can
be searched simply by:
   if tuple(nodes) in table:
 do-something


I definitely want to improve the code so if there is a better way that 
is expandable then I would definitely like to implement it.


So you don't need the separate variables first, second, and third at all.

SNIP


for what you've described so far, it might be convenient to store the
board and its transposed equivalent.  Then search the one for columns,
and the other for rows.  That's a later optimization, but it might save
time getting the more complicated parts figured out.


OK can you give me an example of how this would go.
On to reading and answering the next emails.

___
Tutor maillist  -  Tutor@python.org
To unsub

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 06:58 AM, Dave Angel wrote:



My error.  Since nodes are GameTile objects, not values, converting to a
tuple is a little trickier:

values = tuple( [node.value for node in nodes] )
if values in table:
 do-something


I will try an implement this after I see what values winds up yielding.



For example, print_by_col would look just like print_by_row, except that
it would start with self.transposed_grid

The only real assumption needed for this simplification is that once the
grid is set up, you never create any more GameTile objects, just
manipulate the existing rectangle of objects.

To transpose a grid, you want to use the zip() function.
 self.transposed_grid = zip(*self.grid)



Thanks for the example of making the transposed_grid. I will implement this.
Also your assumption is correct, once the grid is created it never gets 
changed as far as it's structure, only the game tiles with in are 
manipulated, and at that we just change there appearance and value.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 10:09 AM, Steven D'Aprano wrote:

On Fri, Jan 02, 2015 at 09:00:22PM -0500, WolfRage wrote:

Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile,
Windows, Linux, OSX).

First an explanation of how the game works: The game is a simple
matching game but with a twist. Instead of matching a straight 3 in a
row, we have some rules that only certain combinations will result in an
elimination. In general 2 of the same value in a row with with 1 of 2
other possible values will eliminate all three nodes.


Do you mean "1 of 2" or "1 or 2"?

1 of 2.




Eliminations can
occur either horizontally or vertically but not diagonally. Each tile
has a value now, that value is used when evaluating the rules. Currently
there are only 5 allowed values of 0-4 although more could be added
later, so any solution needs to be expandable.


Okay, so the values are 0, 1, 2, 3, and 4. This doesn't match your code
belong. Is the code wrong or your description?

My description was wrong, I am sorry I had started to simplify my code 
when I was first writing this, but realized that ruined my algorithm for 
finding matches.That is probably where I confused Dave.



These are the basic rules that allow for an elimination to occur(values
are put in quotes to distinguish values):
2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes.

[...]

Since neither 5 nor 19 is a possible value, this can never apply.


Sorry again, these are actually the correct values. But my earlier 
mistake misleads on this section that is actually correct.


All the other rules you give include values greater than 4, and likewise
can never apply. That means that no eliminations are ever possible. I
think your description needs some work :-)


Yes. Sorry. Let me re-do that.

First an explanation of how the game works: The game is a simple
matching game but with a twist. Instead of matching a straight 3 in a
row, we have some rules that only certain combinations will result in an 
elimination. In general 2 of the same value in a row with with 1 of 2

other possible values will eliminate all three nodes. Eliminations can
occur either horizontally or vertically but not diagonally. Each tile
has a value now, that value is used when evaluating the rules. Currently 
there are only 5 allowed values of [5, 6, 11, 19, 20] although more 
could be added [52, 61, 67, etc] later, so any solution needs to be 
expandable.

The remainder of the explanation was correct. Sorry about that.




class GameTile():

[...]

 def __str__(self):
 #return '%d, %d' % (self.col, self.row)
 if len(str(self.value)) == 1:
 return ' ' + str(self.value)
 return str(self.value)


Eliminate comments which no longer apply. Don't use them for keeping
old, obsolete or wrong code.


OK, good point, I should be using my bzr revision control.


This method can be better written like this:

 def __str__(self):
 return "%2d" % self.value

I was switching between the 2 implementations of __str__ when I was 
testing some new code, but now need. I will just make it concrete and 
then directly request any other values.



class GameGrid():
 def __init__(self, cols=8, rows=7, **kwargs):
 self.cols = cols
 self.rows = rows
 self.make_grid()

 def make_grid(self):
 # grid is 2d array as x, y ie [x][y].
 self.grid = []
 for row_num in range(self.rows):
 self.grid.append([GameTile(value=random.choice([5, 6, 11,
19, 20]), col=col_num,
 row=row_num) for col_num in range(self.cols)])


That's rather gnarly code. If you're going to do that, it's probably
nice to use a temporary variable to clarify your intention:

 for row_num in range(self.rows):
 row = [GameTile(
value=random.choice([5, 6, 11,19, 20]), col=col_num,
row=row_num) for col_num in range(self.cols)
]
 self.grid.append(row)


Which is still pretty gnarly. You only have three arguments to GameTile,
why do you need to use keyword arguments? This is neater and less
noisy, although it does require you get the order right:

I don't need them. Just hadn't settled on the order of them. But I will 
eliminate the requirement for the keyword arguments.



 # untested
 for row_num in range(self.rows):
 row = [GameTile(row_num, col_num, random.choice([5, 6, 11,19, 20])
for col_num in range(self.cols)
]
 self.grid.append(row)

Even better:

 for row_num in range(self.rows):
 self.make_row(row_num)

 def make_row(self, row_num):
 values = self.allowed_values   # [5, 6, 11,19, 20]
 row = [GameTile(row_num, col_num, random.choice(values)
for col_num in ran

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 06:58 AM, Dave Angel wrote:

self.transposed_grid = zip(*self.grid)
zip() sounds confusing. But I am going to try this and see what it gives 
me. But Somehow I think it will require me to understand yield, which I 
still do not totally get how to use.
Also from the documentation, will this work on my 2d List given that the 
lengths of the lists may not be the same? IE: 4 columns and 8 Rows.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 06:58 AM, Dave Angel wrote:

To transpose a grid, you want to use the zip() function.
 self.transposed_grid = zip(*self.grid)
I see this gives me a list that is the column. Thus it solves the column 
iteration problem, because now I can feed it to my checking and 
elimination functions that take a slice.

Thanks!
Implementing now.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 04:42 PM, Dave Angel wrote:

On 01/03/2015 04:22 PM, WolfRage wrote:

On 01/03/2015 06:58 AM, Dave Angel wrote:

To transpose a grid, you want to use the zip() function.
 self.transposed_grid = zip(*self.grid)

I see this gives me a list that is the column. Thus it solves the column
iteration problem, because now I can feed it to my checking and
elimination functions that take a slice.
Thanks!
Implementing now.


I suspect you want instead:

 self.transposed_grid = list( zip(*self.grid) )

in Python 3.4.  zip gives an iterable for python 3.x, while it gave a
list in python 2.x

This is what I meant by "untested."

OK, I will try that implementation next. But I think this currently 
works well. Here is the latest iteration of my code.


import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(row_num, col_num, self.values)
   for col_num in range(self.cols)]
self.grid.append(row)
self.transposed_grid = zip(*self.grid)

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0

def check_total(self, slices):
first, second, third = slices
if first.value == second.value or second.value == third.value:
total = first.value + second.value + third.value
return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58)

def eliminate(self, slices):
first, second, third = slices
first.eliminated = True
second.eliminated = True
third.eliminated = True

def drop_floating_nodes(self):
pass
# Now we can used the transposed_grid!




grid = GameGrid(4, 8)
grid.draw()
grid.find_eliminations()
print('After Eliminations')
grid.draw()
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 04:42 PM, Dave Angel wrote:

self.transposed_grid = list( zip(*self.grid) )

This results in the same thing with or with out the list() wrapper. Using
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-03 Thread WolfRage

On 01/03/2015 06:46 PM, Steven D'Aprano wrote:

On Sat, Jan 03, 2015 at 06:10:31PM -0500, WolfRage wrote:

On 01/03/2015 04:42 PM, Dave Angel wrote:

self.transposed_grid = list( zip(*self.grid) )



This results in the same thing with or with out the list() wrapper. Using
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux


I don't think so. Perhaps you need to look a little more closely?

py> grid = [(1,2), (3,4), (5,6)]
py> zip(*grid)

py> list(zip(*grid))
[(1, 3, 5), (2, 4, 6)]

Zip objects are not lists, although they can often (but not always) be
used where you are expecting a list.


Yes, you are correct. I was to naive, the result of both work the same 
in my code. But they are of different types.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-11 Thread WolfRage

On 01/05/2015 06:21 PM, Danny Yoo wrote:
SNIP

if total in (17, 21, 28, ...):

Implemented, thanks.
SNIP


The other comment I'd make is to start thinking about how you'd _test_
your program automatically.

SNIP
You are right, I should. But I am fighting with myself on this topic. I 
have been fighting myself for some time. As it seems the test slow me 
down. I am sure latter they may speed me up, but then again I am still a 
relatively new programmer and so my code is very fluid to the situation 
at hand, so tests for immature code seems like a bad idea. Still you are 
right.



Now I am having problem implementing a way to drop the zero values to 
the bottom of the grid. I need to look at more of the column at once 
possibly all of it, or remember where I was dropping. This is my latest 
code any help would be appreciated.



import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(row_num, col_num, self.values)
   for col_num in range(self.cols)]
self.grid.append(row)
self.transposed_grid = list(zip(*self.grid))

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def draw_by_id(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0

def check_total(self, slices):
first, second, third = slices
if first.value == second.value or second.value == third.value:
total = first.value + second.value + third.value
return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58)

def eliminate(self, slices):
first, second, third = slices
first.eliminated = True
second.eliminated = True
third.eliminated = True

def drop_floating_nodes0(self):
i = self.rows
# first_zero_row serves as memory for how far to drop non-zero 
values

first_zero_row = None
for col_list in self.transposed_grid:
while True:
low, high = col_list[i - 2: i]  # Goes Up the Rows
if high.value == 0 and low.value != 0:
if first_zero_row is None:
high.value = low.value
low.value = 0
first_zero_row = low
else:
first_zero_row.value = low.value
low.value = 0
high.value = 0
i -= 1
if i == 1:
i = self.rows
first_zero_row = None
break

def drop_floating_nodes1(self):
i = 0
for col_list in self.transposed_grid:
while True:
try:
low, 

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-11 Thread WolfRage
I had an issue in my logic and again my named variables provided for 
confusion, so I had to add some comments to clarify.


I got much closer by editing my code like this:

def drop_floating_nodes0(self):
i = self.rows
# first_zero_row serves as memory for how far to drop non-zero 
values

first_zero_row = None
for col_list in self.transposed_grid:
while True:
# Low is on Top, High is on Bottom
low, high = col_list[i - 2: i]  # Goes Up the Rows
if high.value == 0:
if low.value != 0:
if first_zero_row is None:
high.value = low.value
low.value = 0
first_zero_row = low
else:
first_zero_row.value = low.value
low.value = 0
high.value = 0
first_zero_row = low
else:
if first_zero_row is None:
first_zero_row = high
i -= 1
if i == 1:
i = self.rows
first_zero_row = None
break

But it still fails as you can see here from the output:

| 20 | 19 | 11 | 20 |
| 11 |  5 |  5 | 11 |
| 19 |  5 | 11 | 11 |
| 19 | 20 | 20 |  5 |
| 11 | 19 | 19 | 11 |
| 20 |  6 |  6 | 11 |
| 19 | 11 |  5 | 20 |
| 11 | 20 | 11 | 20 |
After Eliminations
| 20 |  0 | 11 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 | 11 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
| 20 |  6 |  6 |  0 |
| 19 | 11 |  5 |  0 |
| 11 | 20 | 11 | 20 |
After Drops
|  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 | 11 |  0 |
|  0 |  0 |  0 |  0 |
| 20 |  0 | 11 |  0 |
| 20 |  6 |  6 |  0 |
| 19 | 11 |  5 |  0 |
| 11 | 20 | 11 | 20 |
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-11 Thread WolfRage
Ok, now the code works as expected to drop the non zero values. But I 
think there exist an error in the naming and display of the col and row 
variables at least from with in the GameTile() class, looking into that 
now. All Suggestions Welcome! Thank You All.


import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(row_num, col_num, self.values)
   for col_num in range(self.cols)]
self.grid.append(row)
self.transposed_grid = list(zip(*self.grid))

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def draw_by_id(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0

def check_total(self, slices):
first, second, third = slices
if first.value == second.value or second.value == third.value:
total = first.value + second.value + third.value
return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58)

def eliminate(self, slices):
first, second, third = slices
first.eliminated = True
second.eliminated = True
third.eliminated = True

def drop_floating_nodes0(self):
i = self.rows
# first_zero_row serves as memory for how far to drop non-zero 
values

first_zero_row = None
for col_list in self.transposed_grid:
while True:
# Low is on Top, High is on Bottom
low, high = col_list[i - 2: i]  # Goes Up the Rows
if high.value == 0:
if low.value != 0:
if first_zero_row is None:
high.value = low.value
low.value = 0
first_zero_row = low
else:
first_zero_row.value = low.value
low.value = 0
try:
row = first_zero_row.row
col = first_zero_row.col -1
first_zero_row = self.grid[col][row]
except:
i = self.rows
first_zero_row = None
break
else:
if first_zero_row is None:
first_zero_row = high
i -= 1
if i == 1:
i = self.rows
first_zero_row = None
break

def drop_floating_nodes1(self):
i = 0
for col_list in self.transposed_grid:
while True:
try:
low, h

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
So I was write as I suspected; the grid is not actually being built like 
I thought it was. Sure the ID's print fine but when the grid positions 
are procedurally accessed the program fails with IndexError.


python3 test1.py
| 19 |  5 |  5 |  5 |
| 11 |  6 | 19 | 11 |
|  6 |  6 | 11 | 19 |
| 11 | 20 |  6 |  5 |
| 11 |  5 | 20 |  5 |
| 20 | 20 | 11 | 11 |
| 19 | 19 |  5 |  5 |
| 11 | 19 | 19 |  5 |
After Eliminations
|  0 |  0 |  0 |  5 |
| 11 |  0 | 19 | 11 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  5 | 20 |  0 |
|  0 |  0 |  0 |  0 |
| 19 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
broke 0 5
0 6
broke 1 6
1 7
broke 2 6
2 7
broke 3 6
3 7
After Drops
|  0 |  0 |  0 |  5 |
|  0 |  0 | 19 |  0 |
|  0 |  0 | 11 |  0 |
|  0 | 20 |  6 |  0 |
|  0 |  0 |  0 |  0 |
|  0 |  0 |  0 |  0 |
| 11 |  0 |  0 |  0 |
| 19 |  5 | 20 | 11 |
Normal
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
# The first printed pair is the id, the second pair in parentheses is
# the procedurally accessed id, which should be all ordered as (column,
# row)
| 0,0 (0,0) | 1,0 (0,1) | 2,0 (0,2) | 3,0 (0,3) | Traceback (most recent 
call last):

  File "test1.py", line 186, in 
grid.draw_by_id_proc()
  File "test1.py", line 75, in draw_by_id_proc
print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + 
str(row_num) + ')', end=' | ')

IndexError: list index out of range


I am attempting to fix it now. Any help is appreciated.

#Code Below

import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.grid.append(row)
self.transposed_grid = list(zip(*self.grid))

def draw(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node, end=' | ')
print()

def draw_by_id(self):
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_trans(self):
for col in self.transposed_grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for col_num in range(self.cols):
print(end='| ')
for row_num in range(self.rows):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.grid:

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
Now I have the output that I expect and procedurally they output matches 
the id of the Node/Tile. But I am thoroughly confused as to why my by_id 
functions use the opposite grid to get the correct output?


# Output
python3 test1.py
|  6 | 20 | 19 | 11 | 11 | 20 |  5 | 11 |
| 20 | 19 | 20 | 11 | 11 | 19 | 19 | 20 |
|  6 | 19 | 19 |  6 |  5 | 20 |  5 | 11 |
| 11 |  5 |  5 | 11 | 11 |  6 |  6 |  5 |
By ID
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
| 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) |
| 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) |
| 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) |
| 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) |
| 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) |
| 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) |
| 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) |
| 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) |
Tansposed
| 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 |
| 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 |
| 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 |
| 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 |
Transposed & Procedurally
| 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) 
| 0,6 (0,6) | 0,7 (0,7) |
| 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) 
| 1,6 (1,6) | 1,7 (1,7) |
| 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) 
| 2,6 (2,6) | 2,7 (2,7) |
| 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) 
| 3,6 (3,6) | 3,7 (3,7) |


# Code Below
import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.transposed_grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
for row in self.grid:
print(end='| ')
for node in row:
print(node, end=' | ')
print()

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for row_num in range(self.rows):
print(end='| ')
for col_num in range(self.cols):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def draw_by_id_trans(self):
# Why does this one use self.grid instead of self.transposed_grid ?
for col in self.grid:
print(end='| ')
for node in col:
print(node.id, end=' | ')
print()

def draw_by_id_proc_trans(self):
# Draw Procedurally & Transposed
for col_num in range(self.cols):
print(end='| ')
for row_num in range(self.rows):
print(self.transposed_grid[row_num][col_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

print()

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.transposed_grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(co

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
I fixed the other functions to again work as expected. But the 
procedural access of the self.grid and self.transposed_grid also 
function correctly. That is good because now I can again do lookups if I 
need to. Although I do not have a need to at this time.


Can anyone see anything wrong with the logic as it is at this time? If 
anyone has any improvements or things to think about, I would love to 
hear it. I am going to work on some tests that will specifically involve 
the procedural code to verify that the id's are arranged in the grid as 
I expect them to be.


I would also appreciate an explanation of why my by_id functions use the 
opposite grid to get the correct output?


#Output Below
python3 test1.py
| 19 | 11 |  5 | 19 |
| 11 | 19 | 19 |  5 |
| 20 | 19 | 20 |  6 |
| 11 | 19 | 11 |  5 |
| 11 |  6 |  5 | 20 |
|  6 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |
After Eliminations
| 19 |  0 |  5 | 19 |
|  0 |  0 |  0 |  5 |
|  0 |  0 | 20 |  6 |
|  0 | 19 | 11 |  5 |
|  0 |  6 |  5 | 20 |
|  0 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |

After Drops
|  0 |  0 |  0 | 19 |
|  0 |  0 |  5 |  5 |
|  0 |  0 | 20 |  6 |
|  0 | 19 | 11 |  5 |
|  0 |  6 |  5 | 20 |
| 19 |  5 | 19 | 19 |
| 20 | 19 | 20 | 20 |
|  6 | 20 | 19 | 20 |
By ID
| 0,0 | 1,0 | 2,0 | 3,0 |
| 0,1 | 1,1 | 2,1 | 3,1 |
| 0,2 | 1,2 | 2,2 | 3,2 |
| 0,3 | 1,3 | 2,3 | 3,3 |
| 0,4 | 1,4 | 2,4 | 3,4 |
| 0,5 | 1,5 | 2,5 | 3,5 |
| 0,6 | 1,6 | 2,6 | 3,6 |
| 0,7 | 1,7 | 2,7 | 3,7 |
Procedurally
| 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) |
| 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) |
| 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) |
| 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) |
| 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) |
| 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) |
| 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) |
| 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) |
Tansposed
| 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 |
| 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 |
| 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 |
| 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 |
Transposed & Procedurally
| 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) 
| 0,6 (0,6) | 0,7 (0,7) |
| 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) 
| 1,6 (1,6) | 1,7 (1,7) |
| 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) 
| 2,6 (2,6) | 2,7 (2,7) |
| 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) 
| 3,6 (3,6) | 3,7 (3,7) |


# Code Below
import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid (X,Y) which is equal to grid (col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
self.transposed_grid = []
for row_num in range(self.rows):
# Do you still think this needs to be broken into a smaller 
method?

row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node, end=' | ')
print()

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
for row in self.transposed_grid:
print(end='| ')
for node in row:
print(node.id, end=' | ')
print()

def draw_by_id_proc(self):
# Draw Procedurally
for row_num in range(self.rows):
print(end='| ')
for col_num in range(self.cols):
print(self.grid[col_num][row_num].id, '(' + 
str(col_num) + ',' + str(row_num) + ')', end=' | ')

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage




I haven't looked carefully at your code but there's always a smell in
Python when you see structure[x][y].  Can you change the grid so you
always write something like:-

for row in grid:
 for cell in row:
 process(cell)

I say this as I'm all for short term pain, long term gain, especially
when it's guaranteed to eliminate "list index out of range" errors.

I think in this case I have to say no. I purposely wrote those "proc" or 
"procedurally" style functions to ensure that access to the grid in this 
way would result in the correct output from id, and to test that it 
worked as expected.
However there are other places in my code where I think I can eliminate 
this smell such as the new function that drops the non-zero values.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage

On 01/12/2015 05:00 PM, Alan Gauld wrote:


Sorry, no time to read the detail, but one thing I thought might be
handy is to convert the draw method to return a string and make it the
__str__methodf of the grid.
Then the draw method becomes print(self)

And you can also just use print(aGrid) etc.

Something like (untested):

def __str__(self):
 output = []
 for row in self.transposed_grid:
 s='| '
 for node in row:
 s += (str(node) + ' | ')
 output.append(s)
 return '\n'.join(output)

def draw(self): print (self)


Just a thought.

OK. I will implement this, thanks. It goes well with the __str__ method 
of the tiles/nodes.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage

On 01/12/2015 05:00 PM, Alan Gauld wrote:


__str__methodf of the grid.
Then the draw method becomes print(self)

And you can also just use print(aGrid) etc.



Implemented with some other improvements using the same idea but applied 
to several of the other functions, that provide output.


Now I am going to try and add the ability to have the table generated 
but with a set number of rows empty or pre-set to zero.


#CODE BELOW
import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid(X,Y) which is equal to grid(col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, **kwargs):
if cols < 3 or rows < 3:
raise ValueError("Minimum board size is 3x3! %sx%s is too 
small."

 % (cols, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid()

def __str__(self):
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node) + ' | '
output.append(s)
return '\n'.join(output)

def make_grid(self):
# grid is 2d array as x, y ie [x][y].
# transposed_grid is 2d array as y, x ie [y][x]
self.transposed_grid = []
for row_num in range(self.rows):
row = [GameTile(col_num, row_num, self.values)
   for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
print(self)

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)

def draw_by_id_proc(self):
# Draw Procedurally
output = []
for row_num in range(self.rows):
s = '| '
for col_num in range(self.cols):
s += (str(self.grid[col_num][row_num].id) + '(' + 
str(col_num) +

',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)

def draw_by_id_trans(self):
# Why does this one use self.grid instead of self.transposed_grid ?
output = []
for col in self.grid:
s = '| '
for node in col:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)

def draw_by_id_trans_proc (self):
# Draw Transposed & Procedurally
output = []
for col_num in range(self.cols):
s = '| '
for row_num in range(self.rows):
s += (str(self.transposed_grid[row_num][col_num].id) + 
'(' +

str(col_num) + ',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.transposed_grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(row_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Set all eliminated nodes to a value of 0.
for col in self.transposed_grid:
for node in col:
if node.eliminated is True:
node.eliminated = False
node.value = 0

def check_total(self, slices):
first, second, third = slices
if first.value == second.value or second.value == third.value:
total = first.

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-12 Thread WolfRage
Updated the code to now allow for a fill_rows optional argument for 
Grid, that determines how many rows are filled with values.
I have also added some experimental code to invert the dropping, as in 
all of the values can float to the top. Other code is even more 
experimental and not yet working right that pulls the nodes to the right 
or left, with hope of being able to apply gravity in all 4 directions. 
But I still need to work out the bugs. Any help is greatly appreciated. 
Thanks for all of the contributions so far.


#CODE BELOW
import random


class GameTile():
def __init__(self, col, row, values=None, value=None, **kwargs):
# values is not required because the value can be directly set.
# This is to support a future feature that will allow me to build a
# board off of a list.
# id is grid(X,Y) which is equal to grid(col,row)
self.id = str(col) + ',' + str(row)
self.col = col
self.row = row
if value is None:
value = random.choice(values)
self.value = value
self.eliminated = False
# hide_anim = hidden for animation purposes
self.hide_anim = False
# drop_value = value to be dropped during animation
self.drop_value = None
# drop_to could have inversely been a drop_from
# drop_to = the id of where the value should be dropped too.
self.drop_to = None

def __str__(self):
return "%2d" % self.value


class GameGrid():
def __init__(self, cols=8, rows=7, fill_rows=None, **kwargs):
if cols < 3 or rows < 3:
raise ValueError('Minimum board size is 3x3! %sx%s is too 
small.'

 % (cols, rows))
if fill_rows > rows:
string = 'Can not fill more rows than actual rows ' + \
'exist. fill_rows=%s rows=%s'
raise ValueError(string % (fill_rows, rows))
self.cols = cols
self.rows = rows
self.values = [5, 6, 11, 19, 20]
self.make_grid(fill_rows)

def __str__(self):
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node) + ' | '
output.append(s)
return '\n'.join(output)

def make_grid(self, fill_rows=None):
# grid is 2d array as x, y ie [x][y].
# transposed_grid is 2d array as y, x ie [y][x]
self.transposed_grid = []
for row_num in range(self.rows):
if fill_rows is None:
values = self.values
elif row_num < self.rows - fill_rows:
values = [0, ]
else:
values = self.values
row = [GameTile(col_num, row_num, values)
for col_num in range(self.cols)]
self.transposed_grid.append(row)
self.grid = list(zip(*self.transposed_grid))

def draw(self):
print(self)

def draw_by_id(self):
# Why does this one use self.transposed_grid instead of self.grid ?
output = []
for row in self.transposed_grid:
s = '| '
for node in row:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)

def draw_by_id_proc(self):
# Draw Procedurally
output = []
for row_num in range(self.rows):
s = '| '
for col_num in range(self.cols):
s += (str(self.grid[col_num][row_num].id) + '(' + 
str(col_num) +

',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)

def draw_by_id_trans(self):
# Why does this one use self.grid instead of self.transposed_grid ?
output = []
for col in self.grid:
s = '| '
for node in col:
s += str(node.id) + ' | '
output.append(s)
return '\n'.join(output)

def draw_by_id_trans_proc (self):
# Draw Transposed & Procedurally
output = []
for col_num in range(self.cols):
s = '| '
for row_num in range(self.rows):
s += (str(self.transposed_grid[row_num][col_num].id) + 
'(' +

str(col_num) + ',' + str(row_num) + ')' + ' | ')
output.append(s)
return '\n'.join(output)

def find_eliminations(self):
#First Down the columns.
i = 0
for col_list in self.grid:
while True:
try:
if self.check_total(col_list[i: i + 3]):
self.eliminate(col_list[i: i + 3])
i += 1
except ValueError:
i = 0
break
# Now across the rows.
for row_list in self.transposed_grid:
while True:
try:
if self.check_total(row_list[i: i + 3]):
self.eliminate(ro

Re: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning

2015-01-16 Thread WolfRage

On 01/12/2015 04:47 PM, Mark Lawrence wrote:


I haven't looked carefully at your code but there's always a smell in
Python when you see structure[x][y].  Can you change the grid so you
always write something like:-

for row in grid:
 for cell in row:
 process(cell)

I say this as I'm all for short term pain, long term gain, especially
when it's guaranteed to eliminate "list index out of range" errors.

Revisiting this, I think I will write a function specifically to perform 
look-ups, kind of like your process() function. My purpose is going to 
be to prevent out of bounds look-ups. Although none of my posted code 
has had potential for this so far, I am writing more code to help play 
the game and one of the things I am needing now is to look at the 
neighbours of a selected node. This look-up can provide me two errors, 
one is the index out of range the and the more subtle error is going 
backwards in the list and giving me the end of the list which is not a 
valid neighbour.

I will also use this look-up throughout the rest of my code where possible.
Thank you Mark.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Idle - ImportError: No module named numpy

2015-03-06 Thread WolfRage

Well on the python interpretor did you use python3 or just python?

On 03/06/2015 01:27 PM, Markos wrote:

Hi,

I'm beginning to study the numpy.

When I open a terminal (Debian Squeeze) and run the python interpreter
the command "import numpy as np" run without errors.

But when I run the same command on idle3 the following error appears.

 >>> import numpy as np
Traceback (most recent call last):
   File "", line 1, in 
 import numpy as np
ImportError: No module named numpy

How configure idle to load the numpy module?

Thanks,
Markos
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Functional Programming in Python

2015-04-02 Thread WolfRage
These are just some questions that I have regarding the topic of 
Functional Programming. I am working towards a more functional approach 
to programming but acknowledge that it is far from Functional, 
especially since this is mostly impossible in Python.

Questions:
What are the best practices to create more Functional Python?
What are your thoughts on Functional in Python?
Currently I am re-writing functions to reduce their side effects.
I am also removing the state from objects and putting it into a closure 
type function.
However with callback based systems (GUI) this seemed impossible, so 
instead I am abusing a coroutine to maintain the state of the application.
But is it abuse or does it seem like a good way to handle the callback 
system? The benefit to me at this time is limited, but any errors in 
state are confined to a single location, which is nice.
What do you think about using a coroutine to handle state, how would you 
do it better in a callback based system.

Thank you for your insights.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functional Programming in Python

2015-04-02 Thread WolfRage

On 04/02/2015 01:07 PM, Alan Gauld wrote:


I'm not sure what you mean is impossible? The specific issues
you are having or the general FP paradigm?
I mean achieving truely functional code, atleast to the extent of some 
of the things that I have read. But in general I do not need nor want 
any of those special features. I.E. single assignment, optimized tail 
call, etc.


Python has fairly good support for FP, much better than
most non-FP-specific languages.

I agree.


Everything goes in functions which do not change their inputs and return
outputs.

I am getting better at this.


Use tools like itertools and functools to avoid explicit loops.

I am beginning to use them more.



What are your thoughts on Functional in Python?


It's good enough to use where the problem suits FP. It's no
more a pure FP language than it is a pure OOP language.
But in both cases you can get close enough for practical
purposes. What is your problem scenario that makes FP seem
like the best idiom?

Since I am making a game, three things got out of control.
1. Managing transitions and instances of objects between transitions. 
Like loading the Main Menu then starting a Game, then returning to the 
Menu and Starting a New Game, the old game was still hanging around in 
memory which becomes a problem on Phones.
2. Side effects have gotten out of hand, and so adding a feature often 
meant adding bugs.
3. Duplication of code got out of hand. Several functions doing similar 
things but slightly different. I turned this into pipe-lining to reduce 
out the different cases and eliminate the duplication.


But since it is a game the amount of state does make FP seem very 
difficult and thus the game is a mixture of OOP and FP, which I am glad 
to see people saying mix as needed.



Currently I am re-writing functions to reduce their side effects.


Good, nearly always the best way.


I am also removing the state from objects and putting it into a closure
type function.


That may or may not be a good idea. FP object handling can
get awfully messy and awfully inefficient.


However with callback based systems (GUI) this seemed impossible, so
instead I am abusing a coroutine to maintain the state of the
application.


Trying to force a non-FP framework(eg a GUI)_ to work in an FP
way is usually an exercise in frustration.
Yeah, it took me awhile to think about what to do in this case. Thus I 
decided it was best to accept that the interface between the GUI and my 
code had to be more OOP.



But is it abuse or does it seem like a good way to handle the callback
system? The benefit to me at this time is limited, but any errors in
state are confined to a single location, which is nice.


That should be true in an OOP based system too. The whole point
of OOP is to contain and hide state (as opposed to eliminating it)
I think since I am mostly self taught I perhaps failed to learn this 
containment of state until recently. So before now it was fairly common 
for my state to be spread out amongst several objects. It seems hard for 
me to contain state in a OOP manor, just because it is so easy to use self.



What do you think about using a coroutine to handle state, how would you
do it better in a callback based system.


Without seeing how you are doing it we can't comment on *better*.
We need a baseline. Your approach may be brilliant, or it may
be awful, we can't tell.

Yeah probably not brilliant. More like hopefully not completely stupid.


But remember that there is no such thing as the perfect paradigm.
FP has many strengths but it has many weaknesses too. As does OOP.
Even procedural programming has advantages over OOP and FP in
some circumstances. By all means learn the paradigms, but don't get hung
up on any one. They all play a part.

Agreed. I am still trying to learn the right mixture.

The GUI is Kivy, but I could probably apply the same concept to QT.
Example of my Abused coroutine:

def coroutine(func):
# A decorator function that takes care of starting a coroutine
# automatically on call.
def start(*args, **kwargs):
cr = func(*args, **kwargs)
cr.send(None)
return cr
return start


@coroutine
def app_state(APP):
# APP = kivy.app.App.get_running_app()  # So you know what APP is.
while True:
signal = yield
# Pass if signal is None or less than 1.
if signal >= 0 and signal < 1:
pass  # Ignore this range
elif signal >= 1 and signal < 2:
if signal == 1.01:  # Load Main Menu
print('Load File for Displaying Main Menu')
# This acts as a callback with the benefit of yielding
# to Kivy's main loop.
kivy.clock.Clock.schedule_once(APP.signal, 0)
yield 1.02
print('Add Main Menu to ScreenManager.')
kivy.clock.Clock.schedule_once(APP.signal, 0)
yield 1.03
print('Start Music for Main Menu')
 

Re: [Tutor] Functional Programming in Python

2015-04-02 Thread WolfRage

On 04/02/2015 02:07 PM, Steven D'Aprano wrote:


What are the best practices to create more Functional Python?


Best practices:

* Don't force your code to use one style exclusively. Use the most
   natural style for the task. Python makes it easy to mix functional,
   procedural, imperative and object oriented code in the one
   application. Use whatever is most natural for your task.
Good point, but still trying to understand how this is best determined 
beyond trial and error, and to make sure that my assumptions are correct 
about this decision.


* Where possible, write your functions and methods in a functional
   style. That means:

- Avoid global variables.

I have got this down.


- Avoid side-effects where possible.

Now getting better at this.


- Separate the logic of your algorithm from the display of results (e.g.
   don't have a method that calculates a result AND prints it; have the
   method calculate the result, and then have the caller print it).

Need to always do this and do it first rather than during re-factoring.






- Many uses of map() and filter() are better written as generator
   expressions; e.g. instead of:
I now understand generators and I am now using them whenever I see the 
opportunity.


  filter(lambda s: s.lower().startswith("a"), map(str, mylist))

   you can use:

  (str(x) for x in mylist if s.lower().startswith("a"))


- Where useful, write your code to take advantage of "pipelining"
   style, e.g. using lazy iterators rather than lists. You can then chain
   iterators together to get the desired result.

Yes I have started to do this since seeing the power of pipe-lining.


What do you mean? Can you show an example?

I added an example in the reply to Alan.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functional Programming in Python

2015-04-02 Thread WolfRage

On 04/02/2015 02:52 PM, Danny Yoo wrote:


This is not to say that closures are bad.  It's just to point out that
just because functional programs use closures quite a lot, doesn't
automatically mean closures are the most appropriate tool for
everything.  If there are parts of the language that already do the
sort of thing you're trying to accomplish, it might be good to reuse
those parts, rather than reinvent the universe.
I agree that closures are not the best tool for every job. And in the 
case of a callback based GUI they simply do not work, since execution 
needs to leave a function in order to run the GUI's main loop. Thus I 
abused a coroutine.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functional Programming in Python

2015-04-02 Thread WolfRage

On 04/02/2015 03:08 PM, Tim Johnson wrote:


   You have already received valuable replies from two advanced
   python experts.
   If you are looking for a book (available digitally for kindle)
   I would recommend
   Guide To: Functional Python & Comprehension Constructs
 by Matt Harrison
Thanks I will look into this book. I have been reading a lot of articles 
on the topic lately.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functional Programming in Python

2015-04-04 Thread WolfRage


So I was surprised I did not get more feedback on my abused coroutine, 
maybe that is good or bad, not sure.
Any ways I am on to trying to make that coroutine act more like the 
State Pattern from Gang of Four. And well reading this:

http://gameprogrammingpatterns.com/state.html
I am not sure how to do this:
class Heroine
{
public:
  virtual void handleInput(Input input)
  {
state_->handleInput(*this, input);
  }

  virtual void update()
  {
state_->update(*this);
  }

  // Other methods...
private:
  HeroineState* state_;
};

(Pointing to the different classes. Since C++ has virtual methods but 
Python does not?) in Python? Do I just reference the new method? Because 
state_ will always be the correct object?

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor