Thank you so much Terry Jan Reedy. You have given best advice - yup, i am beginner in Python. Your reply has done grooming :)
thx, On Thursday, July 10, 2014 12:16:48 AM UTC+5:30, Terry Reedy wrote: > 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 -- https://mail.python.org/mailman/listinfo/python-list