Home > Software engineering >  How to get the first attribute from an object?
How to get the first attribute from an object?

Time:10-11

I'm trying to build a traffic simulation; one of the classes is called lane, and it is representing the road. It has these methods:

  • A constructor __init__(length) that takes the length, i.e. the number of vehicles that can be on the lane. In the beginning, there are no vehicles in the lane.
  • A method get_first() that returns the vehicle at the first position without deleting it. If the first place is empty, None is returned.
  • A method remove_first() that returns and deletes the vehicle in the first place. If the place is empty, None is returned. The method makes no other changes to the Lane object.
  • A method step() that moves all vehicles except the first one on the file (index 0) one position forward. A vehicle may only be moved if the next position is vacant. The move should take place from left to right, i.e. the vehicle on index 1 is moved first, then the vehicle on index 2 is moved, and so on.
  • A method is_last_free() that returns True if the last place is free, otherwise False.
  • A method enter(v) that places vehicle v at the end of the lane.
  • A method number_in_lane() that returns the number of vehicles on the lane.
  • The method __str__() that returns an appropriate string representation of the object. The goal is to get an output like this
[..........]
[.........N]
[........N.]
[.......NS.]
  out:  None
[......NS..]
[.....NS.S.]
[....NS.S..]
  out:  None
[...NS.S.S.]
[..NS.S.S..]
[.NS.S.S.S.]
  out:  None
[NS.S.S.S..]
[NSS.S.S.S.]
[NSSS.S.S..]
  out:  Vehicle(N, 34)
[SSS.S.S.S.]
[SSSS.S.S..]
[SSSSS.S.S.]
  out:  Vehicle(S, 0)
[SSSS.S.S..]
[SSSSS.S.S.]
[SSSSSS.S..]
  out:  Vehicle(S, 2)
[SSSSS.S.S.]
[SSSSSS.S..]
[SSSSSSS.S.]
  out:  Vehicle(S, 4)
[SSSSSS.S..]
Number in lane: 7
    

But what I got is this

Lane demonstration
['.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, <__main__.Vehicle object at 0x10546b6d0>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, <__main__.Vehicle object at 0x10546b6d0>, '.']
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, <__main__.Vehicle object at 0x10546b6d0>, <__main__.Vehicle object at 0x10546b670>, '.']
  out:  None
['.', '.', '.', '.', '.', '.', '.', '.', '.', <__main__.Vehicle object at 0x10546ba30>, <__main__.Vehicle object at 0x10546ba00>, <__main__.Vehicle object at 0x10546b970>, <__main__.Vehicle object at 0x10546b910>, <__main__.Vehicle object at 0x10546b8b0>, <__main__.Vehicle object at 0x10546b850>, <__main__.Vehicle object at 0x10546b7f0>, <__main__.Vehicle object at 0x10546b790>, <__main__.Vehicle object at 0x10546b730>, <__main__.Vehicle object at 0x10546b6d0>, <__main__.Vehicle object at 0x10546b670>, '.']
Number in lane: 11 

There is also class called Vehicle. Its task is only to keep track of when the vehicle was created and where it is going. A vehicle does not need to know where it is, or to check traffic lights, or see other vehicles. Two instance variables are sufficient: named destination and time of creation.

The code is:

class Vehicle:
    """Represents vehicles in traffic simulations"""

    def __init__(self, destination, borntime):
        self.destination = destination


        self.borntime = borntime 
class Lane:
    "Represents a lane with (possible) vehicles"

    def __init__(self, length):

        self.length = length
        self.list = ['.'] * self.length

    def __str__(self):
        return str(self.list)

    def enter(self, vehicle):
        return self.list.insert(-1, vehicle)

    def is_last_free(self):
        if self.list[-1] == '.':
            return True
        else:
            return False

    def step(self):
        pass

    def get_first(self):
        if self.list[0] == '.':
            return None
        else:
            return self.list[0]

    def remove_first(self):
        if self.list[0] == '.':
            return None
        else:
            x = self.list.pop(0)
            self.list.insert(0, '.')
            return x

    def number_in_lane(self):
        count = 0
        for i in self.list:
            if i != '.':
                count  = 1
        return count



def demo_lane():
    """For demonstration of the class Lane"""
    a_lane = Lane(10)
    print(a_lane)
    v = Vehicle('N', 34)
    a_lane.enter(v)
    print(a_lane)

    a_lane.step()
    print(a_lane)
    for i in range(20):
        if i % 2 == 0:
            u = Vehicle('S', i)
            a_lane.enter(u)
        a_lane.step()
        print(a_lane)
        if i % 3 == 0:
            print('  out: ',
                  a_lane.remove_first())
    print('Number in lane:',
          a_lane.number_in_lane())


def main():
    """Demonstrates the classes"""
    print('\nLane demonstration')
    demo_lane()


if __name__ == '__main__':
    main()

CodePudding user response:

Lane is a fixed length and there are bugs in the implementations using insert and pop methods that are making the lane longer. I've implemented step below, fixed the display routines and the bugs:

class Vehicle:
    '''Represents vehicles in traffic simulations
    '''
    def __init__(self, destination, borntime):
        self.destination = destination
        self.borntime = borntime 

    def __repr__(self):
        '''A verbose representation
        '''
        return f'Vehicle({self.destination}, {self.borntime})'

    def __str__(self):
        '''A simple representation
        '''
        return self.destination

class Lane:
    '''Represents a lane with (possible) vehicles
    '''
    def __init__(self, length):
        self.lane = ['.'] * length  # list is the name of a type, changed.

    def __str__(self):
        '''Lane representation
        '''
        return '['   ''.join([str(s) for s in self.lane])   ']'

    def enter(self, vehicle):
        self.lane[-1] = vehicle  # insert was making list longer

    def is_last_free(self):
        return self.lane[-1] == '.' # simplified instead of explicit T/F return.

    def step(self):
        '''Implementation of step
        '''
        for i in range(len(self.lane) - 1):
            if self.lane[i] == '.':  # if a spot is empty
                self.lane[i] = self.lane[i   1] # move next spot forward
                self.lane[i   1] = '.' # and clear next spot
        self.lane[-1] = '.' # clear the very last spot

    def get_first(self):
        if self.lane[0] == '.':
            return None
        else:
            return self.lane[0]

    def remove_first(self):
        x = self.lane[0]
        if x == '.':
            return None
        else:
            self.lane[0] = '.'  # simplified. no need for pop/insert
            return x

    def number_in_lane(self):
        return len(self.lane) - self.lane.count('.') # simplified

def demo_lane():
    '''For demonstration of the class Lane'''
    a_lane = Lane(10)
    print(a_lane)
    v = Vehicle('N', 34)
    a_lane.enter(v)
    print(a_lane)

    a_lane.step()
    print(a_lane)
    for i in range(20):
        if i % 2 == 0:
            u = Vehicle('S', i)
            a_lane.enter(u)
        a_lane.step()
        print(a_lane)
        if i % 3 == 0:
            print(f'  out: {a_lane.remove_first()!r}')  # !r uses __repr__ for display
    print('Number in lane:',
          a_lane.number_in_lane())

def main():
    '''Demonstrates the classes'''
    print('\nLane demonstration')
    demo_lane()

if __name__ == '__main__':
    main()

Output (matches OP requirement):


Lane demonstration
[..........]
[.........N]
[........N.]
[.......NS.]
  out: None
[......NS..]
[.....NS.S.]
[....NS.S..]
  out: None
[...NS.S.S.]
[..NS.S.S..]
[.NS.S.S.S.]
  out: None
[NS.S.S.S..]
[NSS.S.S.S.]
[NSSS.S.S..]
  out: Vehicle(N, 34)
[SSS.S.S.S.]
[SSSS.S.S..]
[SSSSS.S.S.]
  out: Vehicle(S, 0)
[SSSS.S.S..]
[SSSSS.S.S.]
[SSSSSS.S..]
  out: Vehicle(S, 2)
[SSSSS.S.S.]
[SSSSSS.S..]
[SSSSSSS.S.]
  out: Vehicle(S, 4)
[SSSSSS.S..]
Number in lane: 7

CodePudding user response:

Your printing problems can be solved by two quick fixes. In class Vehicle, provide a string converter:

    def __str__(self):
        return self.destination

Then, in class Lane, have the string converter do something useful instead of just blasting the list:

    def __str__(self):
        return '[' (''.join(str(i) for i in self.list)) ']'

The rest of the trouble is because you haven't implemented step yet.

CodePudding user response:

This should fix your problem:

class Vehicle:
    """Represents vehicles in traffic simulations"""

    def __init__(self, destination, borntime):
        self.destination = destination


        self.borntime = borntime

    def __str__(self):
        return f"Vehicle({self.destination}, {self.borntime})"

class Lane:
    "Represents a lane with (possible) vehicles"

    def __init__(self, length):

        self.length = length
        self.list = ['.'] * self.length

    def __str__(self):
        return "["   "".join(it.destination if isinstance(it, Vehicle) else it for it in self.list)   "]"

    def enter(self, vehicle):
        return self.list.append(vehicle)

    def is_last_free(self):
        return self.list[-1] == '.'

    def step(self):
        self.remove_first()
        self.list.append(".")

    def get_first(self):
        if self.list[0] == '.':
            return None
        else:
            return self.list[0]

    def remove_first(self):
        x = self.list.pop(0)
        self.list.append('.')
        if x == '.':
            return None
        else:
            return x

    def number_in_lane(self):
        count = 0
        for i in self.list:
            if i != '.':
                count  = 1
        return count



def demo_lane():
    """For demonstration of the class Lane"""
    a_lane = Lane(10)
    print(a_lane)
    v = Vehicle('N', 34)
    a_lane.enter(v)
    print(a_lane)

    a_lane.step()
    print(a_lane)
    for i in range(20):
        if i % 2 == 0:
            u = Vehicle('S', i)
            a_lane.enter(u)
        a_lane.step()
        print(a_lane)
        if i % 3 == 0:
            print('  out: ',
                  str(a_lane.get_first()))
            a_lane.step()
    print('Number in lane:',
          a_lane.number_in_lane())


def main():
    """Demonstrates the classes"""
    print('\nLane demonstration')
    demo_lane()


if __name__ == '__main__':
    main()

Haven't tested it though. Will probably still need some more fixing - but that's up to you.

  • Related