2
\$\begingroup\$

I have two solutions (in Jython) to take two pictures and copy and paste alternate sections of one picture to the other, like so:

pic1pic2newpic

for x in range (0,w):
  for y in range (0,h):
    sourcePx=getPixel(pic1,x,y)
    targetPx=getPixel(pic2,x,y)
    if (y>=0 and y<20) or (y>=40 and y<60)or (y>=80 and y<=100):
      setColor(targetPx, getColor(sourcePx))
repaint (pic2)

for y in range(0,h):
  leaf = (y>=0 and y<20) or (y>=40 and y<60)or (y>=80 and y<=100):
  if leaf:
    for x in range(width):
      sourcePx = getPixel(pic1, x, y)
      targetPx = getPixel(pic2, x, y)
      setColor(targetPx, getColor(sourcePx))
  repaint(pic2)

I have been trying to work this out and have two questions about this:

  1. Which is the more efficient way to loop through the pixels and why?
  2. Does it make any difference to efficiency (and if so how), creating the variable leaf and then using that in the if statement?
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Minor point (not worth an answer): You an rewrite (y>=0 and y<20) to 0 <= y < 20. \$\endgroup\$
    – tobias_k
    Jul 31, 2013 at 20:15

1 Answer 1

1
\$\begingroup\$

The second one is more efficient. Simply because in the first one you are calculating the if w * h times but in the second you are calculating it h times.

Also it can be made more readable and efficient just by using this. It eliminates leaf which you aren't using anywhere. Readability doesn't need explaining.

for y in range(0,h):
  if (20 > y >= 0) or (60 > y >= 40)or (100 >= y >= 80):
    for x in range(width):
      sourcePx = getPixel(pic1, x, y)
      targetPx = getPixel(pic2, x, y)
      setColor(targetPx, getColor(sourcePx))
  repaint(pic2)

Update 1

As limelights has suggested, use of xrange is better than use of range in Python2. If your h or w are big then using range would return a list which occupies memory while use of xrange returns a generator which is much more memory efficient. Performance might suffer a bit but in most cases it is worth it.

\$\endgroup\$
4
  • \$\begingroup\$ ty Aseem, yes I can see what you are saying about the loops, for some reason I can stare at something and it's like a brain jam and I can't figure out the simplest of concepts.. cheers \$\endgroup\$
    – user90823
    Jul 31, 2013 at 4:37
  • \$\begingroup\$ This could be optimised even further, just FYI. The use of xrange() for example if width is massive would speed the program up. \$\endgroup\$ Jul 31, 2013 at 13:29
  • \$\begingroup\$ @limelights I have been using Python 3 for some time and forgot that unless Python3 tag is used questions are about 2 not 3. I'll add that. Thanks. \$\endgroup\$ Jul 31, 2013 at 13:30
  • 1
    \$\begingroup\$ Not worth an answer but... I would start it with for y in range(20) + range(40, 60) + range(80, 100) which seems cleaner than having an if condition. \$\endgroup\$
    – Stuart
    Jul 31, 2013 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.