2015-11-19 1 views
1

Примечание: я новичок в Python.для цикла и если в словаре

У меня есть задача разработать программу, которая будет выводить иностранных номерных знаков из списка из 10 номерных знаков (смесь британских и зарубежных), но только если они ускоряются. Я сделал несколько ошибок на этом пути, и я не знаю, как я могу решить эти проблемы. #UK и #F - это всего лишь мои заметки для меня, чтобы иметь возможность быстро взглянуть на то, что это британская номерная табличка и которая является иностранной.

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

я получаю этот выход:

>>> 
{'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 

предполагалось Две последние строки были иметь разные скорости. Я понимаю, что скорости, возникающие в результате ввода &, остаются бесчеловечными, но это не проблема.

Третья выходная линия показала, что времена были назначены на разные номерные знаки. Я ищу способ исправить это.

Последние две выходные линии должны сделать с:

for key,value in Timestaken4.items(): 
    speed=distance/int(value) 
    if speed>speedlimit: 
     print(key,"is speeding with",distance/int(value),"mps") 

Помимо раз назначаются на разные номерные знаки, как я могу изменить код так, что он отображает правильную скорость?

ответ

2

Вы могли бы сделать что-то вроде этого:

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 

Это дает:

{'100 GBS 12': 18749.99999999998, 
'24TEG 5063': 10714.285714285807, 
'524 WAL 75': 3124.9999999999973, 
'5T314 10A02': 2678.571428571426, 
'D3S11 EUBG 20': 10714.28571428567} 

Что можно форматировать:

for plate, speed in foreign_speeders.items(): 
    print("{0:>14s} was speeding at {1:8.1f} m/s".format(plate, speed)) 

блоки кажутся поддатый. Я предполагаю, что ограничение скорости фактически находится в милях в час.Кстати, если бы это был я, и у меня было много данных, я бы, вероятно, был в pandas или, по крайней мере, NumPy ... тогда вам не нужно быть настолько осторожным, чтобы держать все эти списки в правильном порядке и правильной длины , Но эти радости могут подождать, пока вы не увидите больше Python.

+0

Я попытался работать с милями в час, но для меня это не сработало. Я преобразовал все значения так, чтобы они соответствовали метрам в секунду, но есть ли способ округлить прошедшее время? После 'elapsed = [l - e для l, e в zip (leave, enter)]', я получил результаты, такие как «D3S11 EUBG 20» ускорялся со скоростью 2727.3 м/с, где результат должен был быть «27.2727» и т. Д. Извините, если это проблема, я все еще выясняю ваш код. –

+1

Вместо 'l-e' put' (l-e)/100' в этом понимании списка. Может быть, 'distance' находится в cm? Или время минут ... – kwinkunks

+0

Я понял, но '(l-e)/100' был полезен. Наконец, не могли бы вы объяснить мне, что «(» {0:> 14s} ускорялось при {1: 8.1f} м/с? .format (plate, speed)) 'делает? Это первый раз, когда я сталкиваюсь с таким методом, и часть моей задачи - также объяснить каждую часть кода. Надеюсь, вы понимаете. Заранее спасибо! –

1

Вот как я бы решить это

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) 

Сначала я хотел бы использовать словари вместо списков для хранения данных с камер. Это делает вещи немного проще (и у вас не будет проблем, если один из автомобилей обгонит другой автомобиль и испортит заказ вашего списка). Мне не нужен отдельный список для номерных знаков, поскольку я мог бы просто использовать клавиши из словаря camera_a

Я бы затем перебирал пары ключ/значение камеры A, проверял, была ли тарелка ключом в оба словаря (если он отсутствовал в Camera B, это означало бы, что автомобиль либо находился между камерами, либо использовал выход, чтобы выйти с дороги).

Функция скорости преобразует значения из камер A и B в объекты datetime. Я предполагаю, что значения находятся на Minute.Second-формате и возвращает скорость автомобиля, в mp/h

Наконец, мы проверяем, работал ли автомобиль быстрее, чем ограничение скорости, и распечатывает сообщение.

В моем примере я не решил ваши последние критерии («вывод иностранных номеров»). Для достижения этой цели я хотел бы сделать вторую функцию под названием «is_foreign», который занимает номерной знак в качестве входных данных, и возвращает True/False

+0

Это для Python 2.7? –

+0

Да. (Я оставил глупую ошибку в своем ответе, когда я упростил ее вчера. Я исправил ошибку и протестировал ее на python 2.7.10). – liasis

Смежные вопросы