I have two lists:
A=[0, 45, 90, 135, 180, 225, 270, 315, 360] k8=[4.729216146562631, 4.979995034716688, 5.83433020080749, 5.834682335428627, 5.555339121638964, 4.292788277464533, 5.875322012861815, 5.214309700178062]
As I started using python recently I developed one very inelegant code (below). The aim is to do calculation with every element of k8 if the element of A falls within certain angle defined by az. So if g is between az-45 and az+45 it will be multiplied by 1 and so on. The results of the multiplication are then appended to empty list k9. At the end the code should check at which place in list (k9) is the highest element and exstract value at the same place from another list (k1).
The code runs without errors, however I'm not certain if it produces correct results and if it will do so with any az. Could please some one with experience check if the code is correct. Also if someone knows a better solution for the problem, go ahead.
for g in A: for h in k8: bz1=az-45 if bz1<0: bz1=bz1+360 bz2=az+45 if bz2>360: bz2=bz2-360 if g>bz1 and g<bz2: k=h*1.0 k9.append(k) bz3=az-90 if bz3<0: bz3=bz3+360 bz4=az+90 if bz4>360: bz4=bz4-360 if g>bz3 and g<bz4: k=h*0.75 k9.append(k) bz5=az-135 if bz5<0: bz5=bz5+360 bz6=az+135 if bz6>360: bz6=bz6-360 if g>bz5 and g<bz6: k=h*0.5 k9.append(k) bz7=az-135 if bz7<0: bz7=bz7+360 bz8=az+135 if bz8>360: bz8=bz8-360 if g<bz7 and g>bz8: k=h*0.25 k9.append(k) break ll=len(k9) print ll print k9 def highestNumber(k9): myMax = k9[0] for num in k9: if myMax < num: myMax = num return myMax print highestNumber (k9) smer=k9.index(highestNumber (k9)) print smer czk=k1[smer]
What is az, is it defined by the user?
Is the goal to determine how far the angle of the item in k8 is from az?
Check out the trig functions within the math module
9.2. math — Mathematical functions — Python v2.7.8 documentation
Mark,
az is one angle calculated in previous part of the script, it could be any value between 0 and 360. K8s are not angles but speed values As As go towards opposite side of the crircle (az+180), the corresponding k8s are reduced by factor (0.75->0.25).
Here is an image if what I'm trying to achieve if it helps to understand:
In this situation elements of k8 (h) that corresponds to element of A(45) and A(90) will be multiplied by 1, elements that correspond with 0/360 and 135 will be multiplied by 0.75 and so on.
Aleš
Also, line 53 is going to stop the for h in k8: on the first iter.
would be the same as replacing the "for h in k8:" with "h = 4.729216146562631" so k9 shoud only have one value for each g in A.
R_
Rhett,
thanks for advice but if I don't break the loop then it appends 64 elements to the k9 while it should be 8. I've tried first with the form of for loop that evaluates lists elements simultaneously:
for g,h in zip(A,k8):
....
but it returns an empty list.
Aleš
Ok, I edited the code and indentified the real preoblem. The new code is:
for g in A: bz1=az-45 if bz1<=0: bz1=bz1+360 bz2=az+45 if bz2>=360: bz2=bz2-360 if g>=bz1 and g<=bz2: k=A.index(g) # I changed this part l=k8*1.0 k9.append(l) bz3=az-90 if bz3<=0: bz3=bz3+360 bz4=az+90 if bz4>=360: bz4=bz4-360 if bz1>=g>=bz3 and bz2<=g<=bz4: k=A.index(g) # I changed this part l=k8 bz5=az-135 if bz5<=0: bz5=bz5+360 bz6=az+135 if bz6>=360: bz6=bz6-360 if bz3>=g>=bz5 and bz4<=g<=bz6: k=A.index(g) # I changed this part l=k8*0.75 k9.append(l) *0.5 k9.append(l) bz7=az-135 if bz7<=0: bz7=bz7+360 bz8=az+135 if bz8>=360: bz8=bz8-360 if g<=bz7 and g>=bz8: k=A.index(g) # I changed this part l=k8*0.25 k9.append(l)
The real preoblem is that the first element of A is 0 but while 0 is for most azs (let's say 30°) really smaller than 30°+45,..., 30°+135, it can never be larger than 30°-45,..., 30°-135 as this results 345°,..., 225°.
Anyone knows the solution for this? How to define "circularity" for this check?
Aleš
If I am understanding what you are trying to do, then maybe this will work:
A=[0, 45, 90, 135, 180, 225, 270, 315, 360]
k8=[4.729216146562631, 4.979995034716688, 5.83433020080749, 5.834682335428627, 5.555339121638964, 4.292788277464533, 5.875322012861815, 5.214309700178062]
octantScales = [1.0, 0.75, 0.5, 0.25]
def octant(az1, az2):
''' return 0, 1, 2, or 3 based on the angle between az1 and az2 '''
return min(3, int((abs(az1 - az2) % 180.0)/45.0))
def func(az):
''' Compute angle between az and values in A. Scale values in
k8 based which octant the corresponding value of A falls in.
'''
return [octantScales[octant(a, az)] * k for a,k in zip(A, k8)]
Call func() with your az value, and it will return an array with 8 elements.
The circularity problem is handled using the mod (%) function.
The triple quote that starts each doc string gets displayed as five quotes by the code formatter , so remember to fix that if you copy the code.
strange behaviour...it doesn't exist in the original copy and it can't be fixed or deleted within GeoNet...
A very similar post to this allows you to determine the index numbers between ordered and unordered lists to permit classification as to the index number that an unordered list falls with respect to the ordered list. From here you can follow the logic to see if it applies to your case....
"""
ClassifyData.py
Source: http://stackoverflow.com/questions/25081644/check-between-which-floats-in-a-list-a-given-float-falls
"""
# Ordered list of class breaks
a = [0.1, 0.3, 0.4, 0.5, 0.6, 0.7, 0.9]
# Unordered list or values to put into classes
b = [0.12, 0.53, 0.30, 0.03, 0.77, 0.62, 0.98, 0.01, 0.42, 0.33, 1.3]
#two options: bisect module and numpy module
#option 1
import bisect
indices = [bisect.bisect(a, x) for x in b] #should return [1, 4, 2, 0, 6, 5, 7, 0, 3, 2, 7]
print "bisect: ", indices
#option 2
import numpy as np
indices = np.searchsorted(a, b, side='right') #should return array([1, 4, 2, 0, 6, 5, 7, 0, 3, 2, 7], dtype=int64)
print "numpy: ", indices