Printing letters in order like a pyramid There is this hackerrank question, where we need a rhombus of letters. As to my opinion it can be viewed as some fractal, or similar logic.

Well I solved the question, but I am obviously disappointed with the code I come up with. Actually when I started writing I knew how I would end-up and I was ready to ask a question here.

I am reluctant to share this code of mine but it is necessary, if I am to improve.

size = int(raw_input())
alphabet = "abcdefghijklmnopqrstuvwxyz"
def draw(size):
    shape = "" # The answer
    tmp_size = size # defining a temporary size variable to help with the solution
    tmp_size -= 1
    while tmp_size+1:
        hyphen_count = (size-tmp_size) *2 - 2 # Needed hyphen count for the left-right of new_line
        hypens = hyphen_count*"-" # Hyphens to be added

        # The new line, the strange ranges I used was to get the correct letters in place. Probably needs simplifying.
        new_line = "-".join([alphabet[abs(num)] for num in range(1-size,tmp_size-size+1) + range(size-tmp_size-1, size)])

        # Draw one line if it is the first line
        if tmp_size == size - 1:
            shape = shape + new_line
        # Draw to both top and bottom if it is not the first line.
        else:
            shape = hypens + new_line + hypens + "\n" + shape + "\n" + hypens + new_line + hypens
        tmp_size -= 1
    return shape
print draw(size)


I added many comments for easier evaluation of this badly-written code. So what I ask is:


Dear users with algorithm experience, please help me find a better method if not the code itself. (Maybe a recursion ?)
Dear programmers, please help me implement better python.
Dear users that know everything, please teach me everything.
I propose a different method!
If you generate the center, and the size of the shape you can do the entire thing easily with str.format.

&gt;&gt;&gt; '{0:-^16}'.format('yo')
'-------yo-------'


Simple.

The biggest problem is getting the diamond shape.
But this can be done with ease.
For the amount of different letters you want per line it goes:

1, 2, 3, 4, 3, 2, 1


Where the character you want goes:

3, 2, 1, 0, 1, 2, 3


If you make a range that goes like the first, you can change it to the second by subtracting from 4 each time.

I'll define this range as:

def piramid_range(size):
    return range(1, size) + range(size, 0, -1)


A quick run of size 4 gives us the correct output.
And subtracting from 4 each time gives us the correct output too.

&gt;&gt;&gt; piramid_range(4)
[1, 2, 3, 4, 3, 2, 1]
&gt;&gt;&gt; [4 - i for i in piramid_range(4)]
[3, 2, 1, 0, 1, 2, 3]


and so adding this all together, with two comprehensions makes for a nice small function:

def draw(size):
    fmt = '{{0:-^{size}}}'.format(size=4 * size - 3)
    return '\n'.join(
        fmt.format('-'.join([alphabet[size - s] for s in piramid_range(inner_size)]))
        for inner_size in piramid_range(size)
    )


And finally, as I think your separator character is quite ugly, I think adding the ability to change it would be nice. This is just replacing its two occurrences.

def draw(size, char='-'):
    fmt = '{{0:{char}^{size}}}'.format(char=char, size=4 * size - 3)
    return '\n'.join(
        fmt.format(char.join([alphabet[size - s] for s in piramid_range(inner_size)]))
        for inner_size in piramid_range(size)
    )

print draw(4)
print
print draw(4, char=' ')


Which would have the following output:




------d------
----d-c-d----
--d-c-b-c-d--
d-c-b-a-b-c-d
--d-c-b-c-d--
----d-c-d----
------d------

      d
    d c d
  d c b c d
d c b a b c d
  d c b c d
    d c d
      d