Python 3: creating a Letter Pyramid
Question: I'm trying to create a text pyramid with a height of 291 lines. By this I
mean:

    
    
    Here is an example of a pyramid of height 6:   
     -----a-----    
    ----bcd----   
    ---efghi---  
    --jklmnop--  
    -qrstuvwxy-  
    zabcdefghij  
    
    Notice:   
    -- each line has the same number of characters  
    -- the letters a-z form the pyramid, and are re-used.
    

So far all I have is this:

    
    
    letters="abcdefghijklmnopqrstuvwxyz"
    #(291*2)-1
    for i in range (581):    
    

I really want to learn how to do this, so any help or pushes in the right
direction would be greatly appreciated, rather than the answer itself :)


Answer: 
    from itertools import cycle, islice
    
    letters = "abcdefghijklmnopqrstuvwxyz"
    height = 6
    width = height*2-1
    
    it = cycle(letters)
    for count in range(1, width+1, 2):
        print(''.join(islice(it, count)).center(width, '-'))
    

This solution uses the
[**_itertools_**](http://docs.python.org/dev/library/itertools.html) module.  
The
[**`cycle`**](http://docs.python.org/dev/library/itertools.html#itertools.cycle)
function makes an iterator that repeats our sequence of letters indefinitely,
and
[**`islice`**](http://docs.python.org/dev/library/itertools.html#itertools.islice)
is used to take the next `count` letters from it each time (as they're spitted
out character by character, we make them into one string with
`''.**[join](http://docs.python.org/dev/library/stdtypes.html#str.join)**(...)`).
So we have the next line, but without the dashes. The rest is easy: just
[**`center`**](http://docs.python.org/dev/library/stdtypes.html#str.center)
it.

* * *

Another very similar solution, just without _itertools_ :

    
    
    letters = "abcdefghijklmnopqrstuvwxyz"
    height = 6
    width = height*2-1
    
    buf = ""
    def next_letters(n):
        global buf, letters
        while len(buf)<n:
            buf += letters
        ret, buf = buf[:n], buf[n:]
        return ret
    
    for count in range(1, width+1, 2):
        print(next_letters(count).center(width, '-'))
    

The `buf` (buffer) variable will hold the next letters from the sequence. The
`next_letters` function will check if there are enough letters in it and
extend it as necessary, then return its first `n` letters and "remove" them.

Let's see how it works with a "debug version":

>
>     letters = "abcdefghijklmnopqrstuvwxyz"
>     height = 6
>     width = height*2-1
>  
>     buf = ""
>     def next_letters(n):
>         global buf, letters
>         print("Requested {} letters. Buffer is '{}'".format(n, buf))
>         while len(buf)<n:
>             buf += letters
>             print("Buffer was extended to '{}'".format(buf))
>         ret, buf = buf[:n], buf[n:]
>         print("Returned '{}'; buffer is now '{}'".format(ret, buf))
>         return ret
>  
>     for count in range(1, width+1, 2):
>         print(next_letters(count).center(width, '-'))
>  
>
> Requested 1 letters. Buffer is ''  
>  Buffer was extended to 'abcdefghijklmnopqrstuvwxyz'  
>  Returned 'a'; buffer is now 'bcdefghijklmnopqrstuvwxyz'  
>  \-----a-----  
>  Requested 3 letters. Buffer is 'bcdefghijklmnopqrstuvwxyz'  
>  Returned 'bcd'; buffer is now 'efghijklmnopqrstuvwxyz'  
>  \----bcd----  
>  Requested 5 letters. Buffer is 'efghijklmnopqrstuvwxyz'  
>  Returned 'efghi'; buffer is now 'jklmnopqrstuvwxyz'  
>  \---efghi---  
>  Requested 7 letters. Buffer is 'jklmnopqrstuvwxyz'  
>  Returned 'jklmnop'; buffer is now 'qrstuvwxyz'  
>  \--jklmnop--  
>  Requested 9 letters. Buffer is 'qrstuvwxyz'  
>  Returned 'qrstuvwxy'; buffer is now 'z'  
>  -qrstuvwxy-  
>  Requested 11 letters. Buffer is 'z'  
>  Buffer was extended to 'zabcdefghijklmnopqrstuvwxyz'  
>  Returned 'zabcdefghij'; buffer is now 'klmnopqrstuvwxyz'  
>  zabcdefghij

