HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Printing letters in order like a pyramid

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
orderpyramidlikeprintingletters

Problem

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.

Solution

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.

>>> '{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.

>>> piramid_range(4)
[1, 2, 3, 4, 3, 2, 1]
>>> [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

Code Snippets

>>> '{0:-^16}'.format('yo')
'-------yo-------'
1, 2, 3, 4, 3, 2, 1
3, 2, 1, 0, 1, 2, 3
def piramid_range(size):
    return range(1, size) + range(size, 0, -1)
>>> piramid_range(4)
[1, 2, 3, 4, 3, 2, 1]
>>> [4 - i for i in piramid_range(4)]
[3, 2, 1, 0, 1, 2, 3]

Context

StackExchange Code Review Q#119489, answer score: 5

Revisions (0)

No revisions yet.