Reputation: 271
Note: I am new to Python.
I have a task to design a program that will output foreign number plates out of a list of 10 number plates (a mix of UK and foreign ones), but only if they're speeding. I have done a few mistakes along the way, and I'm not sure how I can fix these problems. #UK and #F are just my notes for me to be able to have a quick look at which is a UK Number Plate and which is a Foreign.
import re
distance=750 #variable for the distance between the Camera A and B (in m)
speedlimit=60 # (mps)
NumberPlates=["DV61 GGB",#UK
"D3S11 EUBG 20",#F
"5T314 10A02",#F
"24TEG 5063",#F
"TR09 TRE",#UK
"524 WAL 75",#F
"TR44 VCZ",#UK
"FR52 SWD",#UK
"100 GBS 12",#F
"HG55 BPO"#UK
]
Enter=[7.12,7.17,7.20,7.45,7.23,7.33,7.18,7.25,7.33,7.38]
#A list for the times of cars passing Camera A
Leave=[7.56,7.24,7.48,7.52,7.45,7.57,7.22,7.31,7.37,7.47]
#A list for the times of cars passing Camera B
Timestaken=[]
Timestaken2=[]
Timestaken3={}
for enter_data, leave_data in zip(Enter, Leave):
Timestaken.append(leave_data-enter_data)
Timestaken=["%.2f" % (leave_data-enter_data) for enter_data, leave_data in zip(Enter, Leave)]
Timestaken2=[s.strip("0") for s in Timestaken]
Timestaken2=[s.strip('.') for s in Timestaken2]
for key,value in zip(NumberPlates,Timestaken2):
Timestaken3[key]=value
print(Timestaken3)
for item in NumberPlates:
UK_Numbers=list(filter(lambda x: re.match("[A-Z]{2}\d{2}\s+[A-Z]{3}$",x),NumberPlates))
for item in UK_Numbers:
if item in UK_Numbers:
NumberPlates.remove(item)
print(NumberPlates) #These are foreign number plates only.
Timestaken4={}
for key,value in zip(NumberPlates,Timestaken2):
Timestaken4[key]=value
print(Timestaken4) #NumberPlate:Time
print("10 cars have passed Camera A, then Camera B\n")
for key,value in Timestaken4.items():
speed=distance/int(value)
if speed>speedlimit:
print(key,"is speeding with",distance/int(value),"mps")
I get this output:
>>>
{'5T314 10A02': '28', '100 GBS 12': '04', '524 WAL 75': '24', 'D3S11 EUBG 20': '07', '24TEG 5063': '07', 'HG55 BPO': '09', 'TR44 VCZ': '04', 'TR09 TRE': '22', 'DV61 GGB': '44', 'FR52 SWD': '06'}
['D3S11 EUBG 20', '5T314 10A02', '24TEG 5063', '524 WAL 75', '100 GBS 12']
{'5T314 10A02': '07', '100 GBS 12': '22', '524 WAL 75': '07', '24TEG 5063': '28', 'D3S11 EUBG 20': '44'}
10 cars have passed Camera A, then Camera B
5T314 10A02 is speeding with 107.14285714285714 mps
524 WAL 75 is speeding with 107.14285714285714 mps
The two last lines were supposed to have different speeds. I realize that the speeds resulting from enter & leave time are inhumane but this is not the problem I have.
The third output line showed that times were assigned to different number plates. I am looking for a way to fix that.
The last two output lines are to do with:
for key,value in Timestaken4.items():
speed=distance/int(value)
if speed>speedlimit:
print(key,"is speeding with",distance/int(value),"mps")
Aside from the times being assigned to different number plates, how can I modify the code so that it displays the right speed?
Upvotes: 1
Views: 180
Reputation: 96
Here's how I would solve it
from datetime import datetime
distance = 750
speed_limit = 60
camera_a = {
"DV61 GGB": 7.12,
"D3S11 EUBG 20": 7.17,
}
camera_b = {
"DV61 GGB": 7.56,
"D3S11 EUBG 20": 7.24,
}
def velocity(a, b):
entry = datetime.strptime(str(a), '%M.%S')
exit = datetime.strptime(str(b), '%M.%S')
elapsed_time_in_seconds = (exit - entry).total_seconds()
velocity_mph = (distance / elapsed_time_in_seconds) / (1609.44/3600)
return velocity_mph
for number_plate, t in camera_a.iteritems():
if number_plate in camera_b.keys():
velocity_mph = velocity(t, camera_b[number_plate])
if velocity_mph > speed_limit:
print '%s was speeding: %.2f mp/h' % (number_plate, velocity_mph)
First I would use dictionaries instead of lists to store the data from the cameras. This makes things a bit easier (and you won't have a problem if one of the cars overtake another car and mess up the ordering of your list). I won't need a separate list for number plates as I could just use the keys from the camera_a-dictionary
I would then iterate through the key/value-pairs of Camera A, check if the plate was a key in both dictionaries (if it was missing from Camera B it would mean that the car either was between the the cameras or used an exit to get off the road).
The velocity-function converts the values from camera A and B into datetime-objects. I assume the values are on the Minute.Second-format and returns the velocity of the car, in mp/h
At last we check if the car was running faster than the speed limit and prints out a message.
In my example I haven't solved your last criteria ("output foreign number plates"). To accomplish this I would make a second function named "is_foreign", who takes a number plate as input, and returns True/False
Upvotes: 1
Reputation: 8122
You could do something like this:
import re
# DATA
distance = 750 # Distance between the Camera A and B (in m)
speed_limit = 60 # (mps)
number_plates = ["DV61 GGB", #UK
"D3S11 EUBG 20", #F
"5T314 10A02", #F
"24TEG 5063", #F
"TR09 TRE", #UK
"524 WAL 75", #F
"TR44 VCZ", #UK
"FR52 SWD", #UK
"100 GBS 12", #F
"HG55 BPO" #UK
]
enter = [7.12,7.17,7.20,7.45,7.23,7.33,7.18,7.25,7.33,7.38]
leave = [7.56,7.24,7.48,7.52,7.45,7.57,7.22,7.31,7.37,7.47]
# Find the non-UK plates
pattern = "(?![A-Z]{2}\d{2}\s+[A-Z]{3}$)"
foreign_numbers = list(filter(lambda x: re.match(pattern, x), number_plates))
# Compute speeds
elapsed = [l - e for l, e in zip(leave, enter)]
speed = [distance/t for t in elapsed]
# Conditional dictionary comprehension
foreign_speeders = {plate: speed
for plate, speed in zip(number_plates, speed)
if (plate in foreign_numbers) and (speed > speed_limit)}
foreign_speeders
This gives:
{'100 GBS 12': 18749.99999999998,
'24TEG 5063': 10714.285714285807,
'524 WAL 75': 3124.9999999999973,
'5T314 10A02': 2678.571428571426,
'D3S11 EUBG 20': 10714.28571428567}
Which you could format:
for plate, speed in foreign_speeders.items():
print("{0:>14s} was speeding at {1:8.1f} m/s".format(plate, speed))
The units seem screwy. My guess is that the speed limit is actually in miles per hour. BTW if it was me and there's a lot of data, I'd probably be in pandas or at least NumPy... then you don't have to be so careful about keeping all these lists in the right order and of the right length. But these joys can wait till you've seen more Python.
Upvotes: 2