Forum Archive

A class just to draw a grid of buttons. Has some interesting options

Phuket2

Just a class that draws a grid. _COLS & _ROWS determine the grid size. Also in the init function where the buttons are created have a var __USE_COPY. if True is consistently , 80, 90% faster on my iPad Air 2.


import ui
import copy
import time

_ROWS = 16
_COLS = 16

# class, just to draw a grid of button, also
# should rotate.

class grid(ui.View):
    def __init__(self):
        self.btns = []

        # just create the buttons rows * columns
        __USE_COPY = False        
        if not __USE_COPY:
            start = time.time()
            for i in range((_COLS * _ROWS)  ):
                btn = ui.Button(title = str(i))
                btn.action = self.hit_test
                self.btns.append(btn)
                self.add_subview(btn)
            finish = time.time()
        else:
            start = time.time()
            btn = ui.Button()
            for i in range((_COLS * _ROWS)  ):
                new_btn = copy.copy(btn)
                new_btn.title = str(i)
                new_btn.action = self.hit_test
                self.btns.append(new_btn)
                self.add_subview(new_btn)
            finish = time.time()
        print finish - start 

        self.style()

    def style(self):
        self.background_color = 'white'

        for btn in self.btns:
            btn.background_color = 'red'
            btn.tint_color = 'white'
            btn.border_width = .5



    def layout(self):
        if self.superview:
            self.frame = superview.bounds

        w,h = self.width / _COLS, self.height / _ROWS
        x = y = 0
        for btn in self.btns:
            btn.width, btn.height = w,h
            btn.x, btn.y = x * w, y * h
            x += 1
            if not x % _COLS :
                x = 0
                y += 1


    def hit_test(self, sender):
        print 'hit - ', sender.title

if __name__ == '__main__':
    x = grid().present('')
ccc

When timing things, I like to use elapsed_time.py which allows you to write:

with timer("download Pythonista Forums page"):
    html = requests.get('https://omz-forums.appspot.com').text

and it will print Elapsed time (download Pythonista Forums page): 0:00:00.513742

ccc

I ran some timings and did not see much difference between the two approaches:

Elapsed time (True):  0:00:00.285801
Elapsed time (True):  0:00:00.258893
Elapsed time (True):  0:00:00.270147
Elapsed time (True):  0:00:00.289374
Elapsed time (True):  0:00:00.283184 --> avg. 0.2774798 --> 8.56% faster

Elapsed time (False): 0:00:00.369390
Elapsed time (False): 0:00:00.278358
Elapsed time (False): 0:00:00.288801
Elapsed time (False): 0:00:00.280331
Elapsed time (False): 0:00:00.289258 --> avg. 0.3012276

In both cases it almost always takes less than a third of a second to build all the cells.

Phuket2

@ccc, I will run some timings later. I am sure I seen 80 to 90% increase. I did run it multiple times to make sure it wasn't a caching issue. Oh, well, I will just split them out 2 Functions and run the timings as you have with your timer function to see.

I ran it on an iPad 2 air, what did you run it on? I will also try my iphone 6 later, will be interesting to compare.

Thanks again

ccc

import platform ; platform.platform() # --> 'Darwin-14.0.0-iPad3,4-32bit'

I am running iOS 8.3 so why is it still 32-bit??

Phuket2

Elapsed time (False 16x16): 0:00:00.199482
Elapsed time (False 16x16): 0:00:00.221685
Elapsed time (False 16x16): 0:00:00.176133
Elapsed time (False 16x16): 0:00:00.166889
Elapsed time (False 16x16): 0:00:00.192668
avg 191371

Elapsed time (True 16x16): 0:00:00.106144
Elapsed time (True 16x16): 0:00:00.103462
Elapsed time (True 16x16): 0:00:00.121247
Elapsed time (True 16x16): 0:00:00.109012
Elapsed time (True 16x16): 0:00:00.104777
avg 108,928
approx 43% speed increase

Darwin-14.0.0-iPad5,4-32bit
not sure why 32bit, this is what i get

Phuket2

Sorry, tried to fix the formatting 3 times without luck

Phuket2

@ccc, I don't understand the contextlib at all. I sort of think I know what your timer code is doing. I run the below code and it seems ok. Wanted to ask you if the below code is ok, or are there side effects I don't understand?
the code below can not run, it's just the concept

if __name__ == '__main__':
    def month_changing(sender, d)   :
        if _DEBUG :print 'holy crap, month will change', sender, d


    with timer('Create Calender'):
        d = datetime.datetime(2015,11, 5)
        x = cal_view(200, date = d )
        with timer('set an attribute'):
            x.day_widgets[15].day_ind_visible(True)
        x.month_will_change = month_changing
        x.present('sheet')
Phuket2

To mix it up a little further.... I assume it all works. Just want to double check.


if __name__ == '__main__':
    def month_changing(sender, d)   :
        with timer('Month Changing'):
            if _DEBUG :print 'holy crap, month will change', sender, d
            pass


    with timer('Create Calender'):
        d = datetime.datetime(2015,11, 5)
        x = cal_view(200, date = d )
        with timer('set an attribute'):
            x.day_widgets[15].day_ind_visible(True)
        x.month_will_change = month_changing
        x.present('sheet')
ccc

If the code above could run then it would run just as you expect it to run. :-)

The contextlib stuff is supercool in a mind bending way because it allows you to build your own with xxx: context managers thru the magic of the builtin yield command which is the like the quantum leap of Python. Yield and yield from are not easy to get fixed in you mind but they can be quite powerful once mastered.

Phuket2

@ccc, ok thanks. Still learning the simple stuff at the moment. But will put it on my to learn list, it's a big list :) I am sure you got my meaning. The code runs, just too much to include here, wanted to show a real example rather than some test code.
Thanks...