Help me write better Code
sssdevelop
sssdevelop at gmail.com
Thu Jul 10 16:38:19 CEST 2014
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
More information about the Python-list
mailing list