for loop & if in a dictionary

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 Bn")

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?

Answer

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.

Leave a Reply

Your email address will not be published. Required fields are marked *