Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #74272

Re: Help me write better Code

From Terry Reedy <tjreedy@udel.edu>
Subject Re: Help me write better Code
Date 2014-07-09 14:46 -0400
References <3a608dd2-d8bf-429e-af21-ce5ac8f18272@googlegroups.com>
Newsgroups comp.lang.python
Message-ID <mailman.11706.1404931649.18130.python-list@python.org> (permalink)

Show all headers | View raw


On 7/9/2014 10:27 AM, sssdevelop wrote:
> Hello,
>
> I have working code - but looking for better/improved code. Better coding practices, better algorithm :)
>
> Problem: Given sequence of increasing integers, print blocks of consecutive integers.

> Input: [51, 53, 55, 67, 68, 91, 92, 93, 94, 99]
> Outout: [67, 68], [91, 92, 93, 94]

Recommendations:
1. If you are just beginning Python, use the current version, now 3.4.

2. Separate interface code that gets input and presents output from the 
function that processes the increasing sequence. The function should not 
care whether the ints come from a user, file, or calculation.

3. Think in terms of iterables and iterators rather than lists (this is 
clearer in 3.x, where some builtins have been converted). The function 
should not care what class is used to convey the sequence of numbers. 
This happens to make it easier to solve the 'pump-priming' problem you 
stumbled over.

4. For designing a loop, what is the loop invariant that you want, that 
will make writing the code easy. For this problem, "tem is a non-emptly 
list of consecutive integers". Remember that a list of one int 
qualifies. Using for loops with the proper iterable solves the other 
part of the loop invariant: the current item is the next item to be 
compared to the last item of tem. If tem is always non-empty, that 
comparison is always possible.

5. Remember that Python code is generic unless constrained. What should 
happen if the function gets non-int numbers, with or without an integer 
value? What should happen if the sequence is not increasing, but 
contains consecutive subsequences. For beginning code, one could decide 
to meet the spec given for input that meets the condition and not care 
otherwise.  The code below works for any sequence (even infinite) of 
objects that can be incremented by 1 and compared to the next.

6. Write an automated test. For one test, something like this works.

ci = consec([51, 53, 55, 67, 68, 91, 92, 93, 94, 99])
print(next(ci) == [67, 68], next(ci) == [91, 92, 93, 94])

but since you (properly) noted several test cases

a = [51, 53, 55, 67, 68, 91, 92, 93, 94, 99]
#a = []
#a = [10]
#a = [10, 11, 12, 15]

I went ahead and used unittest, at the cost of three lines of 
'boilerplate' code. I added a case with a final consecutive sequence. 
Good thing, because it initially failed because I initially forgot to 
check tem after the loop.

import unittest

def consec(iterable):
     "Yield blocks of consecutive integers as a list."
     it = iter(iterable)
     first = next(it)
     tem = [first]
     for n in it:
         # tem is a non-empty list of consecutive ints
         if n == tem[-1] + 1:
             tem.append(n)
         else:
             if len(tem) >= 2:
                 yield tem
             tem = [n]
     if len(tem) >= 2:
         yield tem

class Test(unittest.TestCase):
     def test_consec(self):
         def eq(seq, blocks):
             self.assertEqual(list(consec(seq)), blocks)
         eq((), [])
         eq([1], [])
         eq([1,2,3], [[1,2,3]])  # block at beginning or end
         eq([-1, 1,2,3, 5], [[1,2,3]])  # block in middle
         eq((-1, 1,2,3, 5, 7,8,9, 11), [[1,2,3], [7,8,9]])  # 2 blocks

unittest.main(verbosity=2)
 >>>
test_consec (__main__.Test) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.016s

OK

-- 
Terry Jan Reedy

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Help me write better Code sssdevelop <sssdevelop@gmail.com> - 2014-07-09 07:27 -0700
  Re: Help me write better Code Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-07-09 16:44 +0100
    Re: Help me write better Code sssdevelop <sssdevelop@gmail.com> - 2014-07-10 07:39 -0700
      Re: Help me write better Code Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-07-10 15:51 +0100
    Re: Help me write better Code Rustom Mody <rustompmody@gmail.com> - 2014-07-10 11:38 -0700
  Re: Help me write better Code Ian Kelly <ian.g.kelly@gmail.com> - 2014-07-09 12:16 -0600
    Re: Help me write better Code sssdevelop <sssdevelop@gmail.com> - 2014-07-10 07:38 -0700
  Re: Help me write better Code Terry Reedy <tjreedy@udel.edu> - 2014-07-09 14:46 -0400
    Re: Help me write better Code sssdevelop <sssdevelop@gmail.com> - 2014-07-10 07:38 -0700

csiph-web