# Windows.py Copyright (c) Kari Laitinen # http://www.naturalprogramming.com # 2006-05-21 File created. # 2022-12-27 Converted to Python 3. # 'Windows' is a registered trademark of Microsoft Corporation. # This program is, however, not related to Microsoft or the # Windows operating system. # This program will print character-based 'windows' into the # Command Prompt or Terminal window. # This is an example of using a longish class hierarchy. class Window : def __init__( self, desired_window_width = 78, desired_window_height = 22, given_background_character = ' ' ) : self.window_contents = [] self.window_width = desired_window_width self.window_height = desired_window_height self.background_character = given_background_character # The following loop both creates the 'two-dimensional' list and # fills the list with the background character # Inside the for loop below, operator * is used to produce a list # that contains as many background characters as is the value of # self.window_height. for column_index in range( self.window_width ) : column_of_characters = self.window_height * \ [ self.background_character ] self.window_contents.append( column_of_characters ) # The name of the following method is show() because the name # print() cannot be used in Python programs because print is # a Python keyword. def show( self ) : print( "" ) # a new line # We cannot print the window character by character with a # print statement because the statement always prints an extra # space character. # Let's then create a string that represents the window. window_contents_as_string = "" for row_index in range ( self.window_height ) : for column_index in range ( self.window_width ) : window_contents_as_string += \ self.window_contents[ column_index ][ row_index ] window_contents_as_string += "\n" print( window_contents_as_string, end="" ) def move( self, destination_x_index, destination_y_index, another_window ) : source_y_index = 0 while source_y_index < another_window.window_height : if destination_y_index >= 0 and \ destination_y_index < self.window_height : source_x_index = 0 saved_destination_x_index = destination_x_index while source_x_index < another_window.window_width : if destination_x_index >= 0 and \ destination_x_index < self.window_width : self.window_contents [ destination_x_index ] \ [ destination_y_index ] = \ another_window.window_contents[ source_x_index ] \ [ source_y_index ] source_x_index += 1 destination_x_index += 1 destination_x_index = saved_destination_x_index source_y_index += 1 destination_y_index += 1 class FrameWindow ( Window ) : def __init__( self, desired_window_width = 40, desired_window_height = 10 ) : Window.__init__( self, desired_window_width, desired_window_height, '|' ) horizontal_lines = Window( self.window_width - 2, self.window_height, '-' ) smaller_window_containing_spaces = Window( self.window_width - 2, self.window_height - 2, ' ' ) self.move( 1, 0, horizontal_lines ) self.move( 1, 1, smaller_window_containing_spaces ) class TextWindow ( FrameWindow ) : def __init__( self, desired_window_width, desired_window_height, given_line_of_text ) : FrameWindow.__init__( self, desired_window_width, desired_window_height ) self.text_inside_window = given_line_of_text self.embed_text_in_window() def embed_text_in_window( self ) : text_length = len ( self.text_inside_window ) text_row = self.window_height // 2 # // is the floor division operator text_start_column = int( ( self.window_width - text_length ) / 2 ) for character_index in range( text_length ) : self.window_contents [ text_start_column + character_index ] \ [ text_row ] = \ \ self.text_inside_window[ character_index ] def change_text( self, new_line_of_text ) : text_inside_window = new_line_of_text self.embed_text_in_window() class DecoratedTextWindow ( TextWindow ) : def __init__( self, desired_window_width, desired_window_height, given_line_of_text ) : TextWindow.__init__( self, desired_window_width, desired_window_height, given_line_of_text ) decoration_frame = Window( desired_window_width, desired_window_height, '*' ) window_inside_window = TextWindow( desired_window_width - 2, desired_window_height - 2, given_line_of_text ) decoration_frame.move( 1, 1, window_inside_window ) self.move( 0, 0, decoration_frame ) # The main program begins. background_window = Window( 76, 22, '/' ) empty_window = FrameWindow( 24, 7 ) greeting_window = TextWindow( 30, 8, "Hello, world." ) smiling_window = DecoratedTextWindow( 28, 11, "Smile!" ) background_window.move( 6, 2, empty_window ) background_window.move( 4, 12, greeting_window ) greeting_window.change_text( "HELLO, UNIVERSE!" ) background_window.move( 43, 11, greeting_window ) background_window.move( 40, 3, smiling_window ) background_window.show() print( "" ) # # The author of this program has done his best to ensure the accuracy of # information presented in this source program file. However, # the author assumes no responsibility for errors in this program. # The author shall not be liable in any event for incidental or # consequential damages in connection with, or arising out of, # any kind of use of this program or other information provided at # the Internet site www.naturalprogramming.com #