2016-09-24 13 views
0
import json, os 

def load_data(filepath): 
    if not os.path.exists(filepath): 
     return None 
    with open(filepath, 'r') as file: 
     return json.load(file) 

def get_biggest_bar(data): 
    bars = [] 
    for bar in data: 
     bars.append((bar['Cells']['SeatsCount'] , bar['Number'])) 
    max_number = max(bars)[1] 
    (item for item in data if item['Number'] == max_number).__next__()  
    return item, max_number 

def get_smallest_bar(data): 
    bars = [] 
    for bar in data: 
     bars.append((bar['Cells']['SeatsCount'] , bar['Number'])) 
    min_number = min(bars)[1] 
    (item for item in data if item['Number'] == min_number).__next__()  
    return item, min_number 

def get_closest_bar(data, longitude, latitude): 
    coordinates = [] 
    def get_distance(point, input_point): 
     return ((longitude-input_point[0])**2 + (latitude - input_point[1])**2)**1/2 
    for cell in data: 
     coordinates.append([cell['Cells']['geoData']['coordinates'],cell['Number']]) 
    for coor in coordinates: 
     coor[0] = get_distance(point, coor[0]) 
    closest_bar = min(coordinates)[1] 
    (item for item in data if item['Number'] == closest_bar).__next__() 
    return item, closest_bar 

if __name__ == '__main__': 
    data = load_data("Bars.json") 
    print(get_smallest_bar(data)) 
    print(get_biggest_bar(data)) 
    print(get_closest_bar(data, 50.0, 50.0)) 

から同じ項目を返し、それが出力されます:あなたが見たよう異なる関数はPythonの辞書

(dict_values(['Семёновский переулок, дом 21', 'нет', 'район Соколиная Гора', 'Восточный административный округ', 'да', 177, {'type': 'Point', 'coordinates': [37.717115000077776, 55.78262800012168]}, 'СПБ', 272459722, [{'PublicPhone': '(916) 223-32-98'}], 'SПБ']), 37) 
(dict_values(['Семёновский переулок, дом 21', 'нет', 'район Соколиная Гора', 'Восточный административный округ', 'да', 177, {'type': 'Point', 'coordinates': [37.717115000077776, 55.78262800012168]}, 'СПБ', 272459722, [{'PublicPhone': '(916) 223-32-98'}], 'SПБ']), 434) 
(dict_values(['Семёновский переулок, дом 21', 'нет', 'район Соколиная Гора', 'Восточный административный округ', 'да', 177, {'type': 'Point', 'coordinates': [37.717115000077776, 55.78262800012168]}, 'СПБ', 272459722, [{'PublicPhone': '(916) 223-32-98'}], 'SПБ']), 170) 

は、アイテムがCOMPLETLY同じですが、彼らは切り抜いたです(私は機能をdevideし、それらを実行しようとしましたseperatly、そして彼らは異なる項目を出力する)!また、fucntionのリターンで2番目の数字を見ることができます - それらは異なっています!どうしたの?!

+0

これは機能が壊れていることを示しています。正確性を保証するためにそれらを徹底的にテストしましたか? – Carcigenicate

+0

私はポストで言ったように、私はseperatlyを実行しようとし、彼らは細かく働いた! また、各関数の戻り値では、いくつかの項目が返され、それらはdiffrentです。 –

+0

"filename"がないので、いくつかのテストデータを書きました。あなたは彼らがうまくいくと思うとき、彼らはしません。彼らは単にあなたがそれらを実行する時に正しいと思われるいくつかのグローバル変数を返します。 –

答えて

1

あなたはアイテムを取得するためにジェネレータを使用していますが、次の行でその変数はあなたが思うものではありません。ジェネレータの内側からのアイテムが範囲外です。私は実際に生成された値を返すことを好むでしょう。また、あるポイントに最も近いバーが表示されますが、関数に渡されたバーは表示されません。

私はitemとpointが両方ともあなたの関数内で間違って使っているグローバル変数だと思います。

私はpython2.7を持っていますので、ジェネレータから次の値を取得する構文は若干異なる場合があります。

def load_data(filepath): 
    data = [ 
     {'Number': 10, 'Cells': {'SeatsCount': 10, 'geoData': {'coordinates': (10, 10)}}}, 
     {'Number': 50, 'Cells': {'SeatsCount': 50, 'geoData': {'coordinates': (50, 50)}}}, 
     {'Number': 90, 'Cells': {'SeatsCount': 90, 'geoData': {'coordinates': (90, 90)}}} 
    ] 
    return data 

def get_biggest_bar(data): 
    bars = [] 
    for bar in data: 
     bars.append((bar['Cells']['SeatsCount'] , bar['Number'])) 
    max_number = max(bars)[1] 
    g = (item for item in data if item['Number'] == max_number) 
    return next(g), max_number 

def get_smallest_bar(data): 
    bars = [] 
    for bar in data: 
     bars.append((bar['Cells']['SeatsCount'] , bar['Number'])) 
    min_number = min(bars)[1] 
    g = (item for item in data if item['Number'] == min_number) 
    return next(g), min_number 

def get_closest_bar(data, longitude, latitude): 
    point = (longitude, latitude) 
    coordinates = [] 
    def get_distance(point, input_point): 
     return ((longitude-input_point[0])**2 + (latitude - input_point[1])**2)**1/2 
    for cell in data: 
     coordinates.append([cell['Cells']['geoData']['coordinates'],cell['Number']]) 
    for coor in coordinates: 
     coor[0] = get_distance(point, coor[0]) 
    closest_bar = min(coordinates)[1] 
    g = (item for item in data if item['Number'] == closest_bar) 
    return next(g), closest_bar 

if __name__ == '__main__': 
    data = load_data("Bars.json") 
    print("smallest", get_smallest_bar(data)) 
    print("biggest", get_biggest_bar(data)) 
    print("closest", get_closest_bar(data, 50.0, 50.0)) 

は出力:

('smallest', ({'Cells': {'geoData': {'coordinates': (10, 10)}, 'SeatsCount': 10}, 'Number': 10}, 10)) 
('biggest', ({'Cells': {'geoData': {'coordinates': (90, 90)}, 'SeatsCount': 90}, 'Number': 90}, 90)) 
('closest', ({'Cells': {'geoData': {'coordinates': (50, 50)}, 'SeatsCount': 50}, 'Number': 50}, 50)) 
+0

私はスコープについての考えを理解していますが、 'item'と' point'についての言葉は私を混乱させます。 generetorの後の​​行を正確にどこで扱うのですか?それは 'item'値ですか? –

+0

別の言い方をしましょう。それらの関数だけでテストを行います。アイテムはありません。意味はありません。関数を(それらのように)独立してテストすると、テストはかなり間違っていることをかなり素早く表示します。 –

1

このように、それを返す前に__next__()への呼び出しの結果を割り当てます。

result = (item for item in data if item['Number'] == closest_bar).__next__() 
return result, closest_bar 
1

を間違って与えてきた行ってきましたどのような回答。私の意見では、minとmaxを検索するコードは "pythonic"ではありませんでした。元のコードからget_distanceに基づいて単純なカスタムキーの機能が必要とされる最も近いバーのため

(ケニー・オストロムの答えからのサンプルデータを使用して)

data = [ {'Number': 10, 'Cells': {'SeatsCount': 10, 'geoData': {'coordinates': (10, 10)}}}, 
     {'Number': 50, 'Cells': {'SeatsCount': 50, 'geoData': {'coordinates': (50, 50)}}}, 
     {'Number': 90, 'Cells': {'SeatsCount': 90, 'geoData': {'coordinates': (90, 90)}}} ] 

biggest = max(data, key=lambda bar: bar['Cells']['SeatsCount']) 
smallest = min(data, key=lambda bar: bar['Cells']['SeatsCount']) 

を、しかし:私は別のアプローチを提案したいと思いますあなたはその考えを持っています。

+0

あなたは座席数を使用していると思います。 –

+0

@KennyOstrom:間違いを発見していただきありがとうございます。私はコードを更新しました。 – VPfB