Welcome, guest | Sign In | My Account | Store | Cart

There are probably other, better ways of printing ASCII graphics in Python; but since I do not know what they are, this is the product from that lack of knowledge. This is not meant to be the complete, final version -- there were other versions before this. Definitions and descriptions were finally written, and the code here tries to hold closely to concept that were put forth. Following the code are the specification for how the code should work.

Python, 137 lines
  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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
================================================================================
window.py
================================================================================
# This is the first version of the page class.
class page_v1:

    def __init__(self, rows, columns, default = None):
        # (page_v1, int, int, str)
        if default is None:
            default = ' '
        self.__page = list()
        for index in range(rows):
            self.__page.append(list(default[0] * columns))

    def mutate(self, row, column, string):
        # (page_v1, int, int, str)
        try:
            if row >= 0:
                for index in range(len(string)):
                    if column + index >= 0:
                        self.__page[row][column + index] = string[index]
        except:
            pass

    def access(self, row, column, length = 1):
        # (page_v1, int, int, int)
        string = str()
        try:
            for index in range(length):
                string += self.__page[row][column + index]
        except:
            pass
        return string

    def internal(self):
        # (page_v1)
        array = list()
        for row in self.__page:
            array.append(row[:])
        return array

    def __str__(self):
        # (page_v1)
        string = str()
        for row in self.__page:
            for character in row:
                string += character
            string += '\n'
        return string[:-1]

# This is the first version of a theoretical window.
class window_v1:

    def __init__(self, height, width, border = None, background = None):
        # (window_v1, int, int, str, str)
        self.__height = height
        self.__width = width
        self.__border = border
        self.__background = background
        self.__draw = True
        self.__buffer = None
        self.__contents = list()

    def append(self, instance, position, visible = True, index = None):
        # (window_v1, page_v1 OR window_v1, [int, int], bool, int)
        self.__draw = True
        if index is None:
            self.__contents.append([instance, position, visible])
        else:
            self.__contents.insert(index, [instance, position, visible])

    def remove(self, instance):
        # (window_v1, page_v1 OR window_v1)
        for index in range(len(self.__contents)):
            if instance is self.__contents[index][0]:
                self.__draw = True
                del self.__contents[index]

    def __getitem__(self, index):
        # (window_v1, int)
        self.__draw = True
        return self.__contents[index]

    def __delitem__(self, index):
        # (window_v1, int)
        self.__draw = True
        del self.__contents[index]

    def size(self, height = None, width = None):
        # (window_v1, int, int)
        if height is not None:
            self.__draw = True
            self.__height = height
        if width is not None:
            self.__draw = True
            self.__width = width
        if height is None and width is None:
            return self.__height, self.__width

    def look(self, border = 0, background = 0):
        # (window_v1, str, str)
        if border is not 0:
            self.__draw = True
            self.__border = border
        if background is not 0:
            self.__draw = True
            self.__background = background
        if border is 0 and background is 0:
            return self.__border, self.__background

    def __update(self):
        # (window_v1)
        if self.__draw:
            self.__draw = False
            self.__buffer = page_v1(self.__height, self.__width, self.__background)
            for item in self.__contents:
                if item[2]:
                    internal = item[0].internal()
                    for row in range(len(internal)):
                        for column in range(len(internal[0])):
                            self.__buffer.mutate(row + item[1][0], column + item[1][1], internal[row][column])
            if self.__border is not None:
                self.__buffer.mutate(0, 0, self.__border[0] * self.__width)
                self.__buffer.mutate(self.__height - 1, 0, self.__border[0] * self.__width)
                for row in range(1, self.__height - 1):
                    self.__buffer.mutate(row, 0, self.__border[0])
                    self.__buffer.mutate(row, self.__width - 1, self.__border[0])

    def internal(self):
        # (window_v1)
        self.__update()
        return self.__buffer.internal()

    def __str__(self):
        # (window_v1)
        self.__update()
        return str(self.__buffer)

WINDOW THEORY V1

================

Windows should contain zero or more pages.

Windows should contain zero or more windows.

----------------

Pages should be buffers that cannot be resized once created.

Pages should be in the form of 2D list.

Pages should be editable.

Pages should be able to return a plain representation of their contents (a copy of the 2D list).

----------------

(INCOMPLETE)

GENERAL THEORY V2

=================

#

Page Theory

===========

A page is a buffer.

A page is created with a size that cannot be changed.

Internally, a page is a 2D list of length 1 strings.

A the contents of a page can be edited with length 1 strings.

A page can be created with a default cell value; otherwise, the value is a space.

A copy of the internal buffer of a page can be returned.

A string representation of a page can be returned; there is to be no newline added to the last row of a page.

#

Window Theory

=============

A window is created with a size, outline (which can be None etc. or a length 1 string), and background (a length 1 string [defaults to space]).

A window can contain 0 or more pages and 0 or more windows.

A window can have an outline (1 character); otherwise, it does not have an outline.

A window can have a background character; otherwise, the background is a space.

A window must have a size.

Internally, besides outline, background, and size, a windows consists of a list of information (page(s) and window(s) etc.).

The list consists of lists of the following information: position of the object, the object, and if the object is visible (displayed).

The ordering of the list indicates what object is on top of another object; list[0] is the bottom-most object to be displayed.

A look of a window can be returned as a 2D list (so that it has the same form as a page).

A string representation of the window can be returned and does not have a newline tacked onto its end.

#

=============

Ultimately, windows should be able to be printed, along with all of the window's contents and sub-contents.

Windows should not be reversible; pages might optionally be reversible to show only a second side.

4 comments

Paul Jimenez 18 years, 5 months ago  # | flag

You seem to be struggling very hard to replace the curses module.

Walter Brunswick 18 years, 5 months ago  # | flag

And you, Paul Jimenez, seem to be forgetting that there is no 'curses' module on the Win32 platform.

Paul Jimenez 18 years, 5 months ago  # | flag

Indeed. Indeed I did - I avoid that platform whenever possible. For portability's sake perhaps this should be turned into 'win32curses' or somesuch and given an identical API - then it would 1) make existing curses-using programs easier to port and 2) let windows python programmers learn an API that will be useful to them on other platforms.

Josiah Carlson 18 years, 5 months ago  # | flag

list/mmap. With lists and/or mmap objects, you could make this faster for older Python versions (removing the += operation on strings). Just an idea.

If I remember correctly, Python for cygwin has curses (if you want/need it), though I would understand not wanting to use it (I don't).

Created by Stephen Chappell on Fri, 28 Oct 2005 (PSF)
Python recipes (4591)
Stephen Chappell's recipes (233)

Required Modules

  • (none specified)

Other Information and Tasks