tags:

views:

224

answers:

2

Can anyone tell me why num_chars and num_rows have to be the same?

from ctypes import *

num_chars = 8
num_rows = 8
num_cols = 6

buffer = create_string_buffer (num_chars*num_rows*num_cols+num_chars)

for char in range(num_chars):
        for row in range(num_rows):
                for col in range(num_cols):
                        if char == num_chars-1 and col == num_cols-1:
                                buffer[row*num_rows*num_cols+char*num_cols+col+row] = '|'
                                buffer[row*num_rows*num_cols+char*num_cols+col+row+1] = '\n'
                        elif col == num_cols-1:
                                buffer[row*num_rows*num_cols+char*num_cols+col+row] = '|'
                        else:
                                buffer[row*num_rows*num_cols+char*num_cols+col+row] = ('.', '*')[char>row]

print buffer.value

The output

.....|*****|*****|*****|*****|*****|*****|*****|
.....|.....|*****|*****|*****|*****|*****|*****|
.....|.....|.....|*****|*****|*****|*****|*****|
.....|.....|.....|.....|*****|*****|*****|*****|
.....|.....|.....|.....|.....|*****|*****|*****|
.....|.....|.....|.....|.....|.....|*****|*****|
.....|.....|.....|.....|.....|.....|.....|*****|
.....|.....|.....|.....|.....|.....|.....|.....|

And now changing num_chars to 15.

.....|*****|*****|*****|*****|*****|*****|*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
*****|*****|*****|*****|*****|*****|*****|*****|
.....|*****|*****|*****|*****|*****|*****|*****|
+5  A: 

You said you are using ctypes because you want mutable char buffer for this. But you can get the output you want from list comprehension

num_chars = 5
num_rows = 8
empty = ['.' * num_chars]
full = ['*' * num_chars]
print '\n'.join(
    '|'.join(empty * (i + 1) + (num_rows - i - 1) * full)
    for i in xrange(num_rows)
)

.....|*****|*****|*****|*****|*****|*****|*****
.....|.....|*****|*****|*****|*****|*****|*****
.....|.....|.....|*****|*****|*****|*****|*****
.....|.....|.....|.....|*****|*****|*****|*****
.....|.....|.....|.....|.....|*****|*****|*****
.....|.....|.....|.....|.....|.....|*****|*****
.....|.....|.....|.....|.....|.....|.....|*****
.....|.....|.....|.....|.....|.....|.....|.....

EDIT

I'll show you how you can use list comprehensions to draw whatever char bitmap you want to draw. The idea is simple. Build a boolean array with True in the places you want to print the character and False otherwise. And just use the 'or' trick to print the right character. This example will build a chess like board. You can use the same concept to draw any shape you want.

rows = 5
cols = 6
char = '#'
empty = '.'
bitmap = [[ (i + j)%2 == 0 for i in xrange(cols)] for j in xrange(rows)]
print '\n'.join(
    '|'.join(bitmap[j][i] * char or empty for i in xrange(cols))
    for j in xrange(rows)
)
Nadia Alramli
That's a nice solution.
Accipitridae
I'm a little confused by this. I don't get the same output. Why isn't num_cols used? Yet you have that many cols in your characters.
Scott
If you copy and paste my code it'll produce the exact output in the answer
Nadia Alramli
What do you mean by num_cols? you need to be more descriptive. I'm assuming that num_chars means the number of chars in every |.....|
Nadia Alramli
WelI get this:........|********|********|********|********|********|********|********........|........|********|********|********|********|********|********........|........|........|********|********|********|********|********........|........|........|........|********|********|********|********........|........|........|........|........|********|********|********........|........|........|........|........|........|********|********........|........|........|........|........|........|........|********........|........|........|........|........|........|........|........
Scott
Bah. Well the characters are 8 spaces wide.
Scott
So by num_chars you don't really mean the number of chars. You mean the number of columns in a row?
Nadia Alramli
Please explain in words how would you like the program to work.
Nadia Alramli
A char is broken at the |. Chars are listed from left to right. Each char is 8x5, or 8x6 including the |. The last position has a newline character. Your code doesn't have the 5 character wide characters when I use it. I get 8 spaces wide.
Scott
Would you run my answer again? My program takes different numbers of chars as an input
Nadia Alramli
That got it. Confusing. I changed one line to the following: '|'.join(empty * (i + 1) + (num_cols - i - 1) * full). And now it works exactly like I wanted it to. Thanks man.
Scott
I would still like to know what's wrong with my code however. hehe :)
Scott
The problem with this answer is that my original intentions were to be able to create character bitmaps. I don't see how I can do that with this, although it's a really neat trick.
Scott
Here you go, I updated the example to show you how to create character bitmaps with list comprehension. Lists are mutables you can change them the way you like.
Nadia Alramli
Yeah I'm definitely going to be reading on list comprehension tonight. Thanks for the tips. I'll most certainly be using them.
Scott
+1  A: 

There we go. I had row*num_rows instead of row*num_chars I must need a Dr Pepper. And by the way, this wasn't homework. It's for an LCD project.

num_chars = 10
num_rows = 8
num_cols = 6

buffer = create_string_buffer (num_chars*num_rows*num_cols+num_chars)

for char in range(num_chars):
        for row in range(num_rows):
                for col in range(num_cols):
                        if char == num_chars-1 and col == num_cols-1:
                                buffer[row*num_chars*num_cols+char*num_cols+col+row] = '|'
                                buffer[row*num_chars*num_cols+char*num_cols+col+row+1] = '\n'
                        elif col == num_cols-1:
                                buffer[row*num_chars*num_cols+char*num_cols+col+row] = '|'
                        else:
                                buffer[row*num_chars*num_cols+char*num_cols+col+row] = ('.', '*')[char>row]

print repr(buffer.raw)
print buffer.value
Scott