2016-08-16 22 views
5

Napisałem funkcję, która ma stopień i zwraca orientację jako "N", "NE", ... itd. Bardzo proste, ale brzydkie - czy istnieje sposób na przepisanie tego, aby było ... ładniejsze?Prosta, brzydka funkcja umożliwiająca orientację pod kątem.

def orientation(tn): 
    if 23 <= tn <= 67: 
     o = 'NE' 
    elif 68 <= tn <= 113: 
     o = 'E'  
    elif 114 <= tn <= 158: 
     o = 'SE' 
    elif 159 <= tn <= 203: 
     o = 'S' 
    elif 204 <= tn <= 248: 
     o = 'SW' 
    elif 249 <= tn <= 293: 
     o = 'W' 
    elif 294 <= tn <= 338: 
     o = 'NW' 
    else: 
     o = 'N' 
    return o 
+0

Jeśli nie masz jakichś szalonych przeciążeń, których nie pokazujesz, to się nie uda dla tn = 340. W rzeczywistości, to nawet nie będzie działać, jak pokazano. – JETM

+0

dobry połów, ustalony – mk8efz

+0

Co się stanie, jeśli wprowadzę 510? – Mast

Odpowiedz

18

Zastosowanie bisection:

from bisect import bisect_left 

directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'] 
boundaries = [22, 67, 113, 158, 203, 248, 293, 338, 360] 

def orientation(tn): 
    return directions[bisect_left(boundaries, tn)] 

bisect_left() (bardzo skutecznie) wyszukuje indeks, do którego chcesz wstawić tn do listy boundaries; indeks jest następnie mapowany na listę directions, aby przetłumaczyć go na ciąg znaków.

Bisekcja zajmuje tylko 4 kroki, aby znaleźć odpowiednią granicę (log2(len(boundaries))).

Można też dodać 22 i podzielić wartość modulo 360 przez 45:

directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'] 

def orientation(tn): 
    index = ((tn + 22) % 360) // 45 
    return directions[index] 

Jednak oryginalne granice nie były równomiernie rozłożone pod kątem 45 stopni każdy, więc to daje nieco inny wynik (swoje granice N rozpiętość 44 stopni, podczas gdy E jest przydzielony 46 stopni). Bisection nie dba o takie wyjątki; możesz dowolnie przesuwać granice.

+2

daaaamn Martijn. Wróć do niego ponownie z biblioteką "bisect". –

+0

Cieszę się, że tak, nie wiedziałem o tym. – JulienD

4

Spróbuj dokonać podziału liczby całkowitej przez 45 i adres członkowi tablicy według tego numeru (indeks). Tablica powinna zawierać wskazówki.

6

Można obliczyć indeks całkowitą na liście kierunków kompasu:

def compass(angle): 
    return ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'][int(8*(angle+22.)/360)] 
+0

Podczas gdy jest krótki, irytujące jest analizowanie u człowieka w porównaniu do [Odpowiedź Martijna] (http://stackoverflow.com/a/38982734/476496). –

1

samej zasadzie, ale znacznie jaśniejsze imo, dzięki czemu korzystanie z ternary operator Zamiast:

def orientation(tn): 
    tn = mod(tn, 360) 
    return "N" if tn < 23 else \ 
     "NE" if tn < 68 else \ 
     "E" if tn < 114 else \ 
     "SE" if tn < 159 else \ 
     "S" if tn < 204 else \ 
     "SW" if tn < 249 else \ 
     "W" if tn < 294 else \ 
     "NW" if tn < 339 else \ 
     "N" 

Oczywiście ta metoda nie robi nie generalizuję innych scenariuszy, ale osobiście, dla twojego konkretnego problemu, wolałbym to bardziej od bardziej ogólnej alternatywy, ponieważ jest to prosty, czytelny, czytelny, prosty kod: każdy, kto wyląduje na tej definicji, będzie wiedział dokładnie, co robi w mgnieniu oka, niezależnie od umiejętności programowania. : p

Powiązane problemy