Could someone check if this is correct, please?

2938
10
07-31-2014 02:49 PM
GrljAles
Occasional Contributor

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]

0 Kudos
10 Replies
MarkZito
New Contributor III

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

0 Kudos
GrljAles
Occasional Contributor

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:

AZ.png

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š

0 Kudos
RhettZufelt
MVP Frequent Contributor

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_

0 Kudos
GrljAles
Occasional Contributor

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š

0 Kudos
GrljAles
Occasional Contributor

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*0.75
            k9.append(l)




        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.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š

0 Kudos
ElleryChan
New Contributor II

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.

0 Kudos
ElleryChan
New Contributor II

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.

0 Kudos
DanPatterson_Retired
MVP Emeritus

strange behaviour...it doesn't exist in the original copy and it can't be fixed or deleted within GeoNet...

0 Kudos
DanPatterson_Retired
MVP Emeritus

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

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍