Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

# -*- coding: UTF-8 -*- 

# Copyright 2013-2014 by Luc Saffre. 

# License: BSD, see LICENSE for more details. 

 

""" 

Turns a list of items into an endless loop. 

Useful when generating demo fixtures. 

 

>>> from lino.utils import Cycler 

>>> def myfunc(): 

...     yield "a" 

...     yield "b" 

...     yield "c" 

 

>>> c = Cycler(myfunc()) 

>>> s = "" 

>>> for i in range(10): 

...     s += c.pop() 

>>> print s 

abcabcabca 

 

An empty Cycler or a Cycler on an empty list will endlessly pop None values: 

 

>>> c = Cycler() 

>>> print c.pop(), c.pop(), c.pop() 

None None None 

 

>>> c = Cycler([]) 

>>> print c.pop(), c.pop(), c.pop() 

None None None 

 

>>> c = Cycler(None) 

>>> print c.pop(), c.pop(), c.pop() 

None None None 

""" 

 

from __future__ import unicode_literals 

from builtins import object 

 

 

class Cycler(object): 

 

    def __init__(self, *args): 

        """ 

        If there is exactly one argument, then this must be an iterable 

        and will be used as the list of items to cycle on. 

        If there is more than one positional argument, then these 

        arguments themselves will be the list of items. 

        """ 

 

        if len(args) == 0: 

            self.items = [] 

        elif len(args) == 1: 

            if args[0] is None: 

                self.items = [] 

            else: 

                self.items = list(args[0]) 

        else: 

            self.items = args 

        self.current = 0 

 

    def pop(self): 

        if len(self.items) == 0: 

            return None 

        item = self.items[self.current] 

        self.current += 1 

        if self.current >= len(self.items): 

            self.current = 0 

        if isinstance(item, Cycler): 

            return item.pop() 

        return item 

 

    def __len__(self): 

        return len(self.items) 

 

    def reset(self): 

        self.current = 0 

 

 

def _test(): 

    import doctest 

    doctest.testmod() 

 

if __name__ == "__main__": 

    _test()