14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm'''
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmA class which presents the reverse of a sequence without duplicating it.
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFrom: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIt works on mutable or inmutable sequences.
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> chars = list(Rev('Hello World!'))
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> print ''.join(chars)
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm!dlroW olleH
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe .forw is so you can use anonymous sequences in __init__, and still
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmkeep a reference the forward sequence. )
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIf you give it a non-anonymous mutable sequence, the reverse sequence
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwill track the updated values. ( but not reassignment! - another
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgood reason to use anonymous values in creating the sequence to avoid
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconfusion. Maybe it should be change to copy input sequence to break
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthe connection completely ? )
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> nnn = range(3)
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> rnn = Rev(nnn)
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> for n in rnn: print n
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm...
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm2
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm1
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm0
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> for n in range(4, 6): nnn.append(n)   # update nnn
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm...
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> for n in rnn: print n     # prints reversed updated values
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm...
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm5
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm4
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm2
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm1
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm0
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> nnn = nnn[1:-1]
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> nnn
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm[1, 2, 4]
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> for n in rnn: print n     # prints reversed values of old nnn
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm...
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm5
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm4
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm2
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm1
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm0
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> WH = Rev('Hello World!')
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> print WH.forw, WH.back
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmHello World! !dlroW olleH
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> nnn = Rev(range(1, 10))
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> print nnn.forw
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm[1, 2, 3, 4, 5, 6, 7, 8, 9]
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> print nnn.back
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm[9, 8, 7, 6, 5, 4, 3, 2, 1]
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> rrr = Rev(nnn)
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm>>> rrr
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm<1, 2, 3, 4, 5, 6, 7, 8, 9>
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm'''
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Rev:
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, seq):
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.forw = seq
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.back = self
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __len__(self):
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return len(self.forw)
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __getitem__(self, j):
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.forw[-(j + 1)]
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __repr__(self):
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        seq = self.forw
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(seq, list):
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrap = '[]'
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sep = ', '
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(seq, tuple):
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrap = '()'
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sep = ', '
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(seq, str):
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrap = ''
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sep = ''
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrap = '<>'
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            sep = ', '
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        outstrs = [str(item) for item in self.back]
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return wrap[:1] + sep.join(outstrs) + wrap[-1:]
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test():
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import doctest, Rev
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return doctest.testmod(Rev)
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _test()
96