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.