#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    5
    Rep Power
    0

    Timetable problem Python bug???


    I have developed an object oriented program that uses Python version 2.7 on a Mac.

    I have a problem with a timetable. The program structure is so simple, that a bug in Python is unlikely. Please help me to understand or tell me another (right) way of coding the task.

    The application is simplified to a simple timetable for a person's actions during a day. The 'Table_object' is used for storing timetables. The Table_object has a list of 'Action_objects' that defines the action and the 'start_time' and the 'stop_time of each action. The program is as follows:
    Code:
    timetable_directory = {}
    
    class Table_object() :
    #   ******************
        name = ''
        table_list = []
                        
        def __init__( self, name ) :
    #       ************************
            self.name = name
    
        def add_action( self, act_ref ) :
    #       *****************************
            self.table_list.append( act_ref )                    #     (*)
    
    class Action_object() :
    #   *******************
        action = None  
        start_time = -1
        stop_time = -1
    
        def __init__( self, action, start_time, stop_time ) :
    #       ***************************************************
            self.action = action
            self.start_time = start_time
            self.stop_time = stop_time
    
    
    def init_timetable( tab_name, action_name, start_time, stop_time ) :
    #   *****************************************************************
    #   Search for timetable name in the timetable directory.
        try :
            tab_ref = timetable_directory[ tab_name ]
        
    #   timetable not found, create a new timetable.
        except :
            tab_ref = Table_object( tab_name )
            timetable_directory[ tab_name ] = tab_ref
            print 'tab_ref.name :', tab_ref.name,  tab_ref
    
    #   Make an action object and store it in the table_list of the current timetable
        act_ref = Action_object( action_name, start_time, stop_time )
        tab_ref.add_action( act_ref )
    
    
    def print_table() : 
    #   ***************
        for tab_name in timetable_directory :
            tab_ref = timetable_directory[ tab_name ]
            print"table name:", tab_ref.name
            print '    ',
            for act_ref in tab_ref.table_list : 
                print '(', act_ref.action, act_ref.start_time, act_ref.stop_time,'), ',
            print
    
        
    if __name__ == '__main__' :
    #   ***********************
        init_timetable( 'night', 'sleep', '0:00', '7:00' )
        init_timetable( 'morning', 'breakfast', '7:00', '8:00' )
        init_timetable( 'morning', 'go_to_work', '8:00', '9:00' )
        init_timetable( 'day', 'work', '9:00', '17:00' )
        print_table()
    The result of running the program is :
    Code:
    tab_ref.name : night  <__main__.Table_object instance at 0x1015af320>
    tab_ref.name : morning <__main__.Table_object instance at 0x1015af3b0>
    tab_ref.name : day <__main__.Table_object instance at 0x1015af488>
    table name: morning 
         ( sleep 0:00 7:00 ),  ( breakfast 7:00 8:00 ),  ( go_to_work 8:00 9:00 ),  ( work 9:00 17:00 ), 
    table name: day 
         ( sleep 0:00 7:00 ),  ( breakfast 7:00 8:00 ),  ( go_to_work 8:00 9:00 ),  ( work 9:00 17:00 ), 
    table name: night
         ( sleep 0:00 7:00 ),  ( breakfast 7:00 8:00 ),  ( go_to_work 8:00 9:00 ),  ( work 9:00 17:00 ),
    Though I expected that the actions should be sorted in different timetables for 'night', 'morning' and 'day' as this faked print out:
    Code:
    tab_ref.name : night  <__main__.Table_object instance at 0x1015af320>
    tab_ref.name : morning <__main__.Table_object instance at 0x1015af3b0>
    tab_ref.name : day <__main__.Table_object instance at 0x1015af488>
    table name: morning
          ( breakfast 7:00 8:00 ),  ( go_to_work 8:00 9:00 ), 
    table name: day 
          ( work 9:00 17:00 ), 
    table name: night 
          ( sleep 0:00 7:00 ),
    Why did all the append actions at (*) got stored in all 'tab_ref.table_list' , though 'tab_ref' are different references? I have tried with another print out and have noticed that 'tab_ref.table_list' gradually grow to four elements.
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    Playing with class and instance variables
    Code:
    >>> class c:
    ...    L = list()  # class data, there is only one of these
    ...    def __init__(self):
    ...        self.L = []
    ...
    >>> o = c()
    >>> c.L          
    []
    >>> o.L
    []
    >>> c.L.append('to class list')
    >>> o.L
    []
    >>> c.L
    ['to class list']
    >>> o.L.extend('instance data')
    >>> c.L
    ['to class list']
    >>> o.L
    ['i', 'n', 's', 't', 'a', 'n', 'c', 'e', ' ', 'd', 'a', 't', 'a']
    >>> p = c()
    >>> p.__class__.L
    ['to class list']
    >>> p.L
    []
    >>>
    Anyway, let's change your program. Make the table_list into an instance variable and your program behaves as you expect.
    Code:
    timetable_directory = {}
    
    class Table_object() :
    #   ******************
        name = ''
                        
        def __init__( self, name ) :
    #       ************************
            self.name = name
            self.table_list = []
    
        def add_action( self, act_ref ) :
    #       *****************************
            self.table_list.append( act_ref )                    #     (*)
    
    class Action_object() :
    #   *******************
        action = None  
        start_time = -1
        stop_time = -1
    
        def __init__( self, action, start_time, stop_time ) :
    #       ***************************************************
            self.action = action
            self.start_time = start_time
            self.stop_time = stop_time
    
    
    def init_timetable( tab_name, action_name, start_time, stop_time ) :
    #   *****************************************************************
    #   Search for timetable name in the timetable directory.
        try :
            tab_ref = timetable_directory[ tab_name ]
        
    #   timetable not found, create a new timetable.
        except :
            tab_ref = Table_object( tab_name )
            timetable_directory[ tab_name ] = tab_ref
            print 'tab_ref.name :', tab_ref.name
    
    #   Make an action object and store it in the table_list of the current timetable
        act_ref = Action_object( action_name, start_time, stop_time )
        tab_ref.add_action( act_ref )
    
    
    def print_table() : 
    #   ***************
        for tab_name in timetable_directory :
            tab_ref = timetable_directory[ tab_name ]
            print"table name:", tab_ref.name, tab_ref
            print '    ',
            for act_ref in tab_ref.table_list :                 #(*)
                print '(', act_ref.action, act_ref.start_time, act_ref.stop_time,'), ',
            print
    
        
    if __name__ == '__main__' :
    #   ***********************
        init_timetable( 'night', 'sleep', '0:00', '7:00' )
        init_timetable( 'morning', 'breakfast', '7:00', '8:00' )
        init_timetable( 'morning', 'go_to_work', '8:00', '9:00' )
        init_timetable( 'day', 'work', '9:00', '17:00' )
        print_table()
    Last edited by b49P23TIvg; October 15th, 2012 at 08:45 PM. Reason: repair code tag
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    5
    Rep Power
    0
    Many thanks for your rapid answer to my timetable problem. But I cannot understand why 'table_list' is not instantiated, when the class 'Table_object' is instantiated in the same way as the attribute 'name' is instantiated. What the difference between class data and attribute? Can you advice to a written documentation of this subject.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    difference between class data and class attribute:
    I meant them as the same. At the time I forgot the word "attribute" and used "variable" or "data" instead, knowing full well these weren't the correct python terms. Sorry!

    scope

    I did not find the reference that explains what happens when python imports a module. It's out there somewhere. As I recall, and this test verifies me, python evaluates all the top level statements as well as all the next-level statements subordinate to class statements.
    Code:
    # suppose this is file p.py
    
    # >>> import p
    # importing module p
    # class c evaluates
    # finished module p import
    # >>> p.c()             # note that we do not see "class c evaluates"
    # <p.c instance at 0x17ffd40>
    # >>> p.c().f()
    # c().f()
    # >>> 
    
    
    print('importing module p')
    
    class c:
    
        print('class c evaluates')
    
        def f(*args):
            print('c().f()')
    
    print('finished module p import')
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo