问:
Wrong result for best fit plane to set of points with scipy.linalg.lstsq?
I have a set of (x, y, z) points for which I need to find the plane that best fits them. A plane is defined by its coefficients as:

```<code>a*x + b*y + c*z + d = 0
</code>```

or equivalently:

```<code>A*X +B*y + C = z
</code>```

The second equation is just a re-write of the first.

I'm using the method developed in this gist, which is a translation to Python from the Matlab code given in this answer. The method finds the coefficients to define the plane equation that best fits the set of points.

The issue is that I am able to come up with a set of coefficients that gives a better fit to that set of points.

To define "better", I calculate the sum of absolute distances of each point to the given plane, following the math given here. A smaller value, means a "better" fit, since the points are then on average closer to the plane.

The MWE is below. As can be seen, the hand-picked coefficients result in a smaller sum of absolute distance values (~155.89), than using the "best" coefficients found by the method described above (~158.78).

What am I missing here?

MWE

```<code>import numpy as np
import scipy.linalg

def sum_dist_2_plane(x, y, z, a, b, c, d):
    """
    Sum of the absolute values of the distances to a plane, given by the
    a,b,c,d coefficients, for the set of points defined by x,y,z.
    """
    return np.sum(abs(a*x + b*y + c*z + d)/np.sqrt(a**2+b**2+c**2), axis=0)

# Some xyz points.
xyz = np.array([[1.1724546888698482, 0.67037911349217505, 1.6014525241637045], [2.0029440384631063, 1.2163076402918147, -1.1082409593302032], [-0.87863180025363918, 1.261853987259635, 1.1598532675831237], [0.42789396045777467, 0.67325845732274703, 1.1421266649135475], [1.366142552248496, 1.0959456367043121, -1.6046393305927751], [-2.1595534005011485, -2.2582441035518794, -1.0663372184011806], [2.1104543583371633, -2.3711560770628917, 0.33077589412150843], [1.1974640975387107, 1.2100068141421523, 0.71395322259985505], [0.44492797840962123, 0.51098686422493145, 0.23383900276620295], [-2.0810094204638281, -2.11327958929372, -1.0758230448163033], [1.1655230345226737, 2.3777304002844968, -1.5663228128649394], [0.90952208156596781, 0.84978064084217519, 1.5986081506274985], [1.2951624720758836, 1.2231899029278033, 1.6154291293114866], [0.97545563477882025, 1.1844143994262264, 0.25292733170194026], [2.0281659385206012, 1.3370146330231019, 1.1961575550766028], [-1.9843445684092424, -0.012247402159192651, -2.0732736152121092], [1.0852175044560746, 1.8083916604163963, 0.27402181385868829], [-0.97983337631837208, 1.1032503818628847, 1.1579341604311182], [2.5033961310304029, 1.5628354191569325, -0.60785250636200061], [0.84123393662217383, 1.6169587554844618, -0.66116704633280676], [-1.8572657771039134, 0.043103553120073364, -2.0779545355975415], [2.6979128603518787, 1.70987170366249, -0.59306759275995091], [1.898614831265683, -2.9411794973775129, 1.7095862940118209], [0.81052668401212824, 0.89107411631439926, 1.597589407046101], [-2.0466083174114331, 0.14841369250699468, -1.120794708199135], [2.7004384737959648, 1.3616954868011328, 1.2294957766312749], [2.5373220833750385, 1.7067484497548233, 0.32345763726774379], [0.42025310188487158, 0.25762913945011717, -2.5899822318304473], [1.0425582222020597, 1.2902156453507225, 1.1638276333984123], [1.8492329386150801, 1.369745208770941, -1.1101559957041474], [-1.9685282554587256, -0.053725287173628226, 0.26827797508054374], [2.1798881190450285, 1.2454661605758286, -1.5732113885771071], [2.097212096433736, -2.9271738140601462, -0.56568133063870363], [-4.0108387171254396, -0.95559594599890008, 1.7588521192455815], [1.1558287640906737, 0.84330421357278096, 1.1565989504480143], [-2.9571643443632118, -2.847346163285049, 1.3087401683271338], [1.8592900784537116, 1.3952561066549967, 0.28365423946831214], [-3.4841441062982867, -3.0501496018162109, -0.48161393173162992], [2.5524429115550777, 0.62723764313314334, 0.29882336571990464], [2.2267279436912251, -3.8561674586606758, 1.3393813829669483], [2.1214758016437449, -0.20203416631090113, -1.5903243997743601], [0.14882165322179747, 0.4127883227210779, 0.23115527212661391], [1.2042041122995621, 1.2013226392201846, -0.2014020012510187], [-0.91807770884292583, 1.1176994160488214, -2.5723612427329385], [1.910565457302241, 1.1857852625952567, -1.5853233609652335], [1.0660312416826301, 1.3594393638452948, 0.71483235729161265], [0.65109075860726373, 0.58395151990229632, 1.590486638605114], [2.0967121651174518, 3.5121496638531586, 0.85481080660772335], [1.1484000297535542, 0.93256813649663772, 0.25125672956252743], [-1.7670514601312102, 0.17479726844255272, 0.26097336908379276], [-0.38814151285133675, -1.36837872393391, -2.0916940966530149], [1.5825758742579219, -0.34854211056693962, 0.2556641250097158], [2.586881293405797, -4.371974479474976, -2.3458559556297445], [0.22496107684878977, 0.26917053206799602, -0.69280100767942088], [-0.92198332953292639, 5.3103622894708327, 1.4344469946544294], [1.5669967464035819, -0.13527817891479368, 1.6081806927677107], [-0.56872000311273319, -1.9823395333139691, -2.5517609300755879], [-3.7708737466313824, -3.2863308845331081, 1.3928734104180975], [0.26086111146896701, 0.91063726352187491, -2.1025221562973897], [4.3490818342473947, 1.7969605233982313, -0.94470942930075807], [0.8202509554992351, 1.6178074457637883, -0.66148472916848533], [-1.5947972211483237, 0.18933818654144918, -0.20453683465790107], [0.9736103155058905, 1.4905334895713331, -2.0806647444063202], [1.2838541958241105, 2.0842224244281931, -0.17045822168000058], [3.7985716232291624, 2.5292902540646183, -0.022070946178700979], [1.175697191763003, 0.70063646974704663, 0.24808027552254686], [1.7834118390535998, 1.2937296781793448, -0.1818232448888395], [1.1281441478154344, 0.89641394438231292, 1.6040641573676311], [-2.0118889302553362, 2.7916846393274373, -0.57683324778643197], [-0.5995803308341846, -2.2434949940054554, 0.2835440401850704], [0.32077033536702831, -0.95844872063257081, -1.6245015133016167], [0.81357199339193753, 1.5540883407880133, -0.19956720143058249], [0.62611590692268004, 2.5129849486626958, -0.62767513959140331], [1.3018663649626585, 0.92514176013041427, 0.71042211390030729], [-0.72715254964437737, -2.3705643250823436, -0.63320562968051775], [1.9172742234794142, -2.8680592171367834, -1.9965843559235594], [-0.7108415762295921, -2.2783943434144658, -0.63767826146936812], [1.968546542650037, -2.8305910089272146, -0.11154135958968681], [-3.1492524087194655, -2.8503098024243823, -0.049957063615551078], [-4.0600431110777313, -0.97891479243488955, -0.055962425569617835], [-3.3752702254780629, 5.7587998072406652, 2.0459797674238658], [-1.9855135921592455, 2.7466682542750638, -0.58034791274582886], [2.033073141968945, 1.5208650449610079, -0.16592183863411947], [-1.0379089220195949, -4.7336396164389383, 0.0045652508195388464], [0.059579198580756186, 0.50654688886459498, -0.69144595015375643], [2.1785293390435458, -2.67576518666927, -2.4787451249989232], [2.1096278381494935, -0.41668256763302775, -2.5482230530414327], [2.898772426390924, 1.9762337520130302, 1.2619960149795091], [0.95620776766155502, 1.4639884373148864, -0.19976180368861662], [0.78751831482788348, 1.6888070662998231, -1.1280318812973462], [0.75574071441925506, -0.89893698883953688, -0.21651308186821439], [-0.26825101547751962, -3.4496728096007274, 1.7066486428460195], [1.6690385240329706, -0.49893224975237227, -0.66401176702524367], [-0.28877792353045606, 1.5139628395303639, 0.25314013342428154], [0.33435105972001761, 0.72567663189581422, -2.5862147225048417], [-0.29757422904759573, 1.5866751937867298, -0.6682501010682671], [2.7581055173587461, -3.973585217996157, 0.0036824743223959899], [-3.4344275379769509, -3.089933175898083, 0.44457796620464052], [-2.9394415977285413, -2.6122275577950083, 1.2944549102942418], [2.0038460695984823, 1.515512638618338, -1.5731231727332897], [2.206216953170296, 1.4688891052013793, -1.5661966567970254], [-1.035208468220836, 4.4666436487176657, 0.89858770640569929], [-2.0039938640838546, 0.24894412179006209, -1.1220951191237916], [-3.9104727661324539, -0.70689702779279451, 1.2978242803460915], [1.7290487193475563, 1.2850859351795931, -0.18395259620439219], [1.1198244545179541, 1.7335817969585154, -0.18776435816536718], [0.32239533364835676, 0.2896168073626299, -1.1602117002106667], [0.36649393980823192, 0.28244286109766281, -0.69190114531475189], [0.71629324271161154, 0.62574841994964003, 1.1448784055936088], [-0.65109499789331204, -1.3933343864454197, -2.0884024350786063], [0.97046822380567643, 1.5321191441287463, -0.19744980702830617], [-0.9585141324426697, 1.3494884330155692, 1.610936445675776], [0.9615111008482673, 2.4535668843530907, -1.0939899554364985], [-1.0667872216702354, 0.9585914740866075, 1.6038639420443772], [1.8021244106955299, 1.1320598433704154, 1.1820726259869971], [-0.060098920604716666, 0.46839599864404674, 2.0277692055269654], [0.1721690681247055, 0.33837718694053642, 1.137078044079125], [-1.5964760388322969, 0.29775223476696611, 1.1626558382504655], [2.233093222044507, -2.8349614127699461, 0.36052101139762271], [1.9257633093026034, -2.5325763598899247, -1.5360887301240496], [1.116293873468281, 0.82698434754975214, -2.5739062165349651], [1.1781306304855363, 0.67917370389645249, 1.6017135739225736], [-1.8600651472693519, 0.078727875114422086, 1.6184578422253679], [-1.43994317003447, 0.13431327308359137, 2.0472930703748276], [0.84521838040660946, 0.63970047924770745, -2.100345751420285], [1.7661749989776647, -0.37651847162651875, -2.0797840873592222], [0.83547092354865804, 1.7219104152802622, 0.2661115369175846], [1.8300570222025725, -0.28592323411250137, 1.6180934388285593], [-0.62076647836845089, -0.99191053757063119, -1.1486388713745725], [-1.6239006006253158, 0.41366361326031414, 0.2574990624750626], [0.89195815704237569, 2.2004172385784, -0.17400231396826626], [0.36791088305589931, 0.36096348396301231, -2.5897662606427687], [0.073648763901347059, 0.19675260582587464, -2.1107265203482299], [2.161140531872539, -2.842373820387067, 0.35775402140617274], [-2.0416416353442859, -4.4051625504298446, 0.0054589213454931951], [-2.0525396585901774, 3.6758248479033888, -2.4231570023949089], [-0.96441167578601306, -4.6667609706070516, -0.0032107139968431397], [-1.8689820843196163, 0.021432805852950151, 0.26440433366338567], [-0.15613351765730205, -1.0964152703770347, 1.5952653951331826], [-0.91084152695600051, 1.2388514346844914, 1.1598544561959656], [0.94699177145572266, 1.2276340276860185, 2.0505581774713733], [-0.8929399989505632, 1.2806485400811793, -0.20595242802870217], [1.2023125342023806, 2.3477287603163717, -1.5668539565738087], [1.1651535046949058, 1.3836371788871575, 0.26217241277176129], [-1.0929407572158512, 1.3887078738113698, -0.19910861560325088], [-0.76452840903206265, 1.4237410113821392, -1.6090659495628117], [-1.5594385646555604, 0.1455415355638911, 1.1607640518832483], [-0.59734981961340872, -1.2800366176149909, 1.6032259368271653], [1.2325774703556955, 0.80804053623212702, 0.25109224401040819], [1.177240124012167, 0.90163100927998241, -1.1405108476689563]])
x, y, z = xyz[:, 0], xyz[:, 1], xyz[:, 2]

# Best-fit linear plane, for the Eq: z = a*x + b*y + c.
# See: https://gist.github.com/amroamroamro/1db8d69b4b65e8bc66a6
A = np.c_[x, y, np.ones(xyz.shape[0])]
C, _, _, _ = scipy.linalg.lstsq(A, z)

# Coefficients in the form: a*x + b*y + c*z + d = 0.
a, b, c, d = C[0], C[1], -1., C[2]

# Sum of absolute distances of each point to this plane.
print sum_dist_2_plane(x, y, z, a, b, c, d)

# Hand-picked coefficients.
a, b, c, d = 0.28, -0.14, 0.95, 0.

# Sum of absolute distances of each point to this plane.
print sum_dist_2_plane(x, y, z, a, b, c, d)
</code>```

答:
The answer by unutbu is outstanding, the best I've seen online. I've tested it a lot.

To refine it a bit, for making an estimate of the initial guess for a plane, I found it useful to do so using just 3 points from the larger set. We can estimate the parameters a,b,c,d like so:

    def estimate_initial_parameters_with_first_three_points(points):
        # points is a list of lists [[x,y,z], [x,y,z], ...]
        p1 = points[0]
        p2 = points[1]
        p3 = points[2]
        a1 = p2[0] - p1[0]
        b1 = p2[1] - p1[1]
        c1 = p2[2] - p1[2]
        a2 = p3[0] - p1[0]
        b2 = p3[1] - p1[1]
        c2 = p3[2] - p1[2]
        a = b1 * c2 - b2 * c1
        b = a2 * c1 - a1 * c2
        c = a1 * b2 - b1 * a2
        d = (- a * p1[0] - b * p1[1] - c * p1[2])
        return [a,b,c,d]
```

<p>This is of course derived from the equation of a plane:</p>

```a(x-x0) + b*(y-y0) + c*(z-z0) = d
```

Body:
I have a set of (x, y, z) points for which I need to find the plane that best fits them. A plane is defined by its coefficients as:

a*x + b*y + c*z + d = 0

or equivalently:

A*X +B*y + C = z

The second equation is just a re-write of the first.

I'm using the method developed in this gist, which is a translation to Python from the Matlab code given in this answer. The method finds the coefficients to define the plane equation that best fits the set of points.

The issue is that I am able to come up with a set of coefficients that gives a better fit to that set of points.

To define "better", I calculate the sum of absolute distances of each point to the given plane, following the math given here. A smaller value, means a "better" fit, since the points are then on average closer to the plane.

The MWE is below. As can be seen, the hand-picked coefficients result in a smaller sum of absolute distance values (~155.89), than using the "best" coefficients found by the method described above (~158.78).

What am I missing here?

MWE

import numpy as np
import scipy.linalg

def sum_dist_2_plane(x, y, z, a, b, c, d):
    """
    Sum of the absolute values of the distances to a plane, given by the
    a,b,c,d coefficients, for the set of points defined by x,y,z.
    """
    return np.sum(abs(a*x + b*y + c*z + d)/np.sqrt(a**2+b**2+c**2), axis=0)

# Some xyz points.
xyz = np.array([[1.1724546888698482, 0.67037911349217505, 1.6014525241637045], [2.0029440384631063, 1.2163076402918147, -1.1082409593302032], [-0.87863180025363918, 1.261853987259635, 1.1598532675831237], [0.42789396045777467, 0.67325845732274703, 1.1421266649135475], [1.366142552248496, 1.0959456367043121, -1.6046393305927751], [-2.1595534005011485, -2.2582441035518794, -1.0663372184011806], [2.1104543583371633, -2.3711560770628917, 0.33077589412150843], [1.1974640975387107, 1.2100068141421523, 0.71395322259985505], [0.44492797840962123, 0.51098686422493145, 0.23383900276620295], [-2.0810094204638281, -2.11327958929372, -1.0758230448163033], [1.1655230345226737, 2.3777304002844968, -1.5663228128649394], [0.90952208156596781, 0.84978064084217519, 1.5986081506274985], [1.2951624720758836, 1.2231899029278033, 1.6154291293114866], [0.97545563477882025, 1.1844143994262264, 0.25292733170194026], [2.0281659385206012, 1.3370146330231019, 1.1961575550766028], [-1.9843445684092424, -0.012247402159192651, -2.0732736152121092], [1.0852175044560746, 1.8083916604163963, 0.27402181385868829], [-0.97983337631837208, 1.1032503818628847, 1.1579341604311182], [2.5033961310304029, 1.5628354191569325, -0.60785250636200061], [0.84123393662217383, 1.6169587554844618, -0.66116704633280676], [-1.8572657771039134, 0.043103553120073364, -2.0779545355975415], [2.6979128603518787, 1.70987170366249, -0.59306759275995091], [1.898614831265683, -2.9411794973775129, 1.7095862940118209], [0.81052668401212824, 0.89107411631439926, 1.597589407046101], [-2.0466083174114331, 0.14841369250699468, -1.120794708199135], [2.7004384737959648, 1.3616954868011328, 1.2294957766312749], [2.5373220833750385, 1.7067484497548233, 0.32345763726774379], [0.42025310188487158, 0.25762913945011717, -2.5899822318304473], [1.0425582222020597, 1.2902156453507225, 1.1638276333984123], [1.8492329386150801, 1.369745208770941, -1.1101559957041474], [-1.9685282554587256, -0.053725287173628226, 0.26827797508054374], [2.1798881190450285, 1.2454661605758286, -1.5732113885771071], [2.097212096433736, -2.9271738140601462, -0.56568133063870363], [-4.0108387171254396, -0.95559594599890008, 1.7588521192455815], [1.1558287640906737, 0.84330421357278096, 1.1565989504480143], [-2.9571643443632118, -2.847346163285049, 1.3087401683271338], [1.8592900784537116, 1.3952561066549967, 0.28365423946831214], [-3.4841441062982867, -3.0501496018162109, -0.48161393173162992], [2.5524429115550777, 0.62723764313314334, 0.29882336571990464], [2.2267279436912251, -3.8561674586606758, 1.3393813829669483], [2.1214758016437449, -0.20203416631090113, -1.5903243997743601], [0.14882165322179747, 0.4127883227210779, 0.23115527212661391], [1.2042041122995621, 1.2013226392201846, -0.2014020012510187], [-0.91807770884292583, 1.1176994160488214, -2.5723612427329385], [1.910565457302241, 1.1857852625952567, -1.5853233609652335], [1.0660312416826301, 1.3594393638452948, 0.71483235729161265], [0.65109075860726373, 0.58395151990229632, 1.590486638605114], [2.0967121651174518, 3.5121496638531586, 0.85481080660772335], [1.1484000297535542, 0.93256813649663772, 0.25125672956252743], [-1.7670514601312102, 0.17479726844255272, 0.26097336908379276], [-0.38814151285133675, -1.36837872393391, -2.0916940966530149], [1.5825758742579219, -0.34854211056693962, 0.2556641250097158], [2.586881293405797, -4.371974479474976, -2.3458559556297445], [0.22496107684878977, 0.26917053206799602, -0.69280100767942088], [-0.92198332953292639, 5.3103622894708327, 1.4344469946544294], [1.5669967464035819, -0.13527817891479368, 1.6081806927677107], [-0.56872000311273319, -1.9823395333139691, -2.5517609300755879], [-3.7708737466313824, -3.2863308845331081, 1.3928734104180975], [0.26086111146896701, 0.91063726352187491, -2.1025221562973897], [4.3490818342473947, 1.7969605233982313, -0.94470942930075807], [0.8202509554992351, 1.6178074457637883, -0.66148472916848533], [-1.5947972211483237, 0.18933818654144918, -0.20453683465790107], [0.9736103155058905, 1.4905334895713331, -2.0806647444063202], [1.2838541958241105, 2.0842224244281931, -0.17045822168000058], [3.7985716232291624, 2.5292902540646183, -0.022070946178700979], [1.175697191763003, 0.70063646974704663, 0.24808027552254686], [1.7834118390535998, 1.2937296781793448, -0.1818232448888395], [1.1281441478154344, 0.89641394438231292, 1.6040641573676311], [-2.0118889302553362, 2.7916846393274373, -0.57683324778643197], [-0.5995803308341846, -2.2434949940054554, 0.2835440401850704], [0.32077033536702831, -0.95844872063257081, -1.6245015133016167], [0.81357199339193753, 1.5540883407880133, -0.19956720143058249], [0.62611590692268004, 2.5129849486626958, -0.62767513959140331], [1.3018663649626585, 0.92514176013041427, 0.71042211390030729], [-0.72715254964437737, -2.3705643250823436, -0.63320562968051775], [1.9172742234794142, -2.8680592171367834, -1.9965843559235594], [-0.7108415762295921, -2.2783943434144658, -0.63767826146936812], [1.968546542650037, -2.8305910089272146, -0.11154135958968681], [-3.1492524087194655, -2.8503098024243823, -0.049957063615551078], [-4.0600431110777313, -0.97891479243488955, -0.055962425569617835], [-3.3752702254780629, 5.7587998072406652, 2.0459797674238658], [-1.9855135921592455, 2.7466682542750638, -0.58034791274582886], [2.033073141968945, 1.5208650449610079, -0.16592183863411947], [-1.0379089220195949, -4.7336396164389383, 0.0045652508195388464], [0.059579198580756186, 0.50654688886459498, -0.69144595015375643], [2.1785293390435458, -2.67576518666927, -2.4787451249989232], [2.1096278381494935, -0.41668256763302775, -2.5482230530414327], [2.898772426390924, 1.9762337520130302, 1.2619960149795091], [0.95620776766155502, 1.4639884373148864, -0.19976180368861662], [0.78751831482788348, 1.6888070662998231, -1.1280318812973462], [0.75574071441925506, -0.89893698883953688, -0.21651308186821439], [-0.26825101547751962, -3.4496728096007274, 1.7066486428460195], [1.6690385240329706, -0.49893224975237227, -0.66401176702524367], [-0.28877792353045606, 1.5139628395303639, 0.25314013342428154], [0.33435105972001761, 0.72567663189581422, -2.5862147225048417], [-0.29757422904759573, 1.5866751937867298, -0.6682501010682671], [2.7581055173587461, -3.973585217996157, 0.0036824743223959899], [-3.4344275379769509, -3.089933175898083, 0.44457796620464052], [-2.9394415977285413, -2.6122275577950083, 1.2944549102942418], [2.0038460695984823, 1.515512638618338, -1.5731231727332897], [2.206216953170296, 1.4688891052013793, -1.5661966567970254], [-1.035208468220836, 4.4666436487176657, 0.89858770640569929], [-2.0039938640838546, 0.24894412179006209, -1.1220951191237916], [-3.9104727661324539, -0.70689702779279451, 1.2978242803460915], [1.7290487193475563, 1.2850859351795931, -0.18395259620439219], [1.1198244545179541, 1.7335817969585154, -0.18776435816536718], [0.32239533364835676, 0.2896168073626299, -1.1602117002106667], [0.36649393980823192, 0.28244286109766281, -0.69190114531475189], [0.71629324271161154, 0.62574841994964003, 1.1448784055936088], [-0.65109499789331204, -1.3933343864454197, -2.0884024350786063], [0.97046822380567643, 1.5321191441287463, -0.19744980702830617], [-0.9585141324426697, 1.3494884330155692, 1.610936445675776], [0.9615111008482673, 2.4535668843530907, -1.0939899554364985], [-1.0667872216702354, 0.9585914740866075, 1.6038639420443772], [1.8021244106955299, 1.1320598433704154, 1.1820726259869971], [-0.060098920604716666, 0.46839599864404674, 2.0277692055269654], [0.1721690681247055, 0.33837718694053642, 1.137078044079125], [-1.5964760388322969, 0.29775223476696611, 1.1626558382504655], [2.233093222044507, -2.8349614127699461, 0.36052101139762271], [1.9257633093026034, -2.5325763598899247, -1.5360887301240496], [1.116293873468281, 0.82698434754975214, -2.5739062165349651], [1.1781306304855363, 0.67917370389645249, 1.6017135739225736], [-1.8600651472693519, 0.078727875114422086, 1.6184578422253679], [-1.43994317003447, 0.13431327308359137, 2.0472930703748276], [0.84521838040660946, 0.63970047924770745, -2.100345751420285], [1.7661749989776647, -0.37651847162651875, -2.0797840873592222], [0.83547092354865804, 1.7219104152802622, 0.2661115369175846], [1.8300570222025725, -0.28592323411250137, 1.6180934388285593], [-0.62076647836845089, -0.99191053757063119, -1.1486388713745725], [-1.6239006006253158, 0.41366361326031414, 0.2574990624750626], [0.89195815704237569, 2.2004172385784, -0.17400231396826626], [0.36791088305589931, 0.36096348396301231, -2.5897662606427687], [0.073648763901347059, 0.19675260582587464, -2.1107265203482299], [2.161140531872539, -2.842373820387067, 0.35775402140617274], [-2.0416416353442859, -4.4051625504298446, 0.0054589213454931951], [-2.0525396585901774, 3.6758248479033888, -2.4231570023949089], [-0.96441167578601306, -4.6667609706070516, -0.0032107139968431397], [-1.8689820843196163, 0.021432805852950151, 0.26440433366338567], [-0.15613351765730205, -1.0964152703770347, 1.5952653951331826], [-0.91084152695600051, 1.2388514346844914, 1.1598544561959656], [0.94699177145572266, 1.2276340276860185, 2.0505581774713733], [-0.8929399989505632, 1.2806485400811793, -0.20595242802870217], [1.2023125342023806, 2.3477287603163717, -1.5668539565738087], [1.1651535046949058, 1.3836371788871575, 0.26217241277176129], [-1.0929407572158512, 1.3887078738113698, -0.19910861560325088], [-0.76452840903206265, 1.4237410113821392, -1.6090659495628117], [-1.5594385646555604, 0.1455415355638911, 1.1607640518832483], [-0.59734981961340872, -1.2800366176149909, 1.6032259368271653], [1.2325774703556955, 0.80804053623212702, 0.25109224401040819], [1.177240124012167, 0.90163100927998241, -1.1405108476689563]])
x, y, z = xyz[:, 0], xyz[:, 1], xyz[:, 2]

# Best-fit linear plane, for the Eq: z = a*x + b*y + c.
# See: https://gist.github.com/amroamroamro/1db8d69b4b65e8bc66a6
A = np.c_[x, y, np.ones(xyz.shape[0])]
C, _, _, _ = scipy.linalg.lstsq(A, z)

# Coefficients in the form: a*x + b*y + c*z + d = 0.
a, b, c, d = C[0], C[1], -1., C[2]

# Sum of absolute distances of each point to this plane.
print sum_dist_2_plane(x, y, z, a, b, c, d)

# Hand-picked coefficients.
a, b, c, d = 0.28, -0.14, 0.95, 0.

# Sum of absolute distances of each point to this plane.
print sum_dist_2_plane(x, y, z, a, b, c, d)

Body:
The answer by unutbu is outstanding, the best I've seen online. I've tested it a lot.

To refine it a bit, for making an estimate of the initial guess for a plane, I found it useful to do so using just 3 points from the larger set. We can estimate the parameters a,b,c,d like so:

    def estimate_initial_parameters_with_first_three_points(points):
        # points is a list of lists [[x,y,z], [x,y,z], ...]
        p1 = points[0]
        p2 = points[1]
        p3 = points[2]
        a1 = p2[0] - p1[0]
        b1 = p2[1] - p1[1]
        c1 = p2[2] - p1[2]
        a2 = p3[0] - p1[0]
        b2 = p3[1] - p1[1]
        c2 = p3[2] - p1[2]
        a = b1 * c2 - b2 * c1
        b = a2 * c1 - a1 * c2
        c = a1 * b2 - b1 * a2
        d = (- a * p1[0] - b * p1[1] - c * p1[2])
        return [a,b,c,d]

This is of course derived from the equation of a plane:

a(x-x0) + b*(y-y0) + c*(z-z0) = d


来源: stackexchange

问:
Cluster work node not ready after server reboot
The work node change Ready to NotReady when I reboot master and work node.

The result of kubectl get nodes.

```<code>NAME                      STATUS     ROLES    AGE   VERSION
XXX                       NotReady   work     13d   v1.17.2
XXX                       Ready      master   13d   v1.17.2
</code>```

The result of kubectl get pod --all-namespaces.

```<code>NAMESPACE       NAME                                              READY   STATUS    RESTARTS   AGE
default         postgres                                          1/1     Running   0          20m
default         user-api                                          3/3     Running   0          20m
ingress-nginx   nginx-ingress-controller                          1/1     Running   3          10d
kube-system     coredns                                           1/1     Running   4          13d
kube-system     coredns                                           1/1     Running   4          13d
kube-system     etcd                                              1/1     Running   4          13d
kube-system     kube-apiserver                                    1/1     Running   4          13d
kube-system     kube-controller-manager                           1/1     Running   4          13d
kube-system     kube-flannel-ds-amd64                             1/1     Running   3          13d
kube-system     kube-flannel-ds-amd64                             1/1     Running   5          13d
kube-system     kube-proxy                                        1/1     Running   4          13d
kube-system     kube-proxy                                        1/1     Running   3          13d
kube-system     kube-scheduler                                    1/1     Running   4          13d
</code>```

How should I check this problem out?

答:
Try restarting kubelet of the node which is in notReady state and it may solve your problem.

The below command can help:

```<code>systemctl restart kubelet
</code>```

ContentLicense: CC BY-SA 4.0

Body:
The work node change Ready to NotReady when I reboot master and work node.

The result of kubectl get nodes.

NAME                      STATUS     ROLES    AGE   VERSION
XXX                       NotReady   work     13d   v1.17.2
XXX                       Ready      master   13d   v1.17.2

The result of kubectl get pod --all-namespaces.

NAMESPACE       NAME                                              READY   STATUS    RESTARTS   AGE
default         postgres                                          1/1     Running   0          20m
default         user-api                                          3/3     Running   0          20m
ingress-nginx   nginx-ingress-controller                          1/1     Running   3          10d
kube-system     coredns                                           1/1     Running   4          13d
kube-system     coredns                                           1/1     Running   4          13d
kube-system     etcd                                              1/1     Running   4          13d
kube-system     kube-apiserver                                    1/1     Running   4          13d
kube-system     kube-controller-manager                           1/1     Running   4          13d
kube-system     kube-flannel-ds-amd64                             1/1     Running   3          13d
kube-system     kube-flannel-ds-amd64                             1/1     Running   5          13d
kube-system     kube-proxy                                        1/1     Running   4          13d
kube-system     kube-proxy                                        1/1     Running   3          13d
kube-system     kube-scheduler                                    1/1     Running   4          13d

How should I check this problem out?

Body:
Try restarting kubelet of the node which is in notReady state and it may solve your problem.

The below command can help:

systemctl restart kubelet


问:
store input value which is in loop with javascript
I have a column input field in  which is in the loop due to this each Row has input field I got a javascript from which it storing local storage for input field but the issue is this javascript is working only for one input For Example :

I have five rows and due to loop input field generated for 5 rows automatically

What I am looking for is to store different values for each row..due to this script its not implementing for each row individually

Code

```<code><input type="text" id="txt_1" onkeyup='saveValue(this);'/>
</code>```

Javascript

```<code><script type="text/javascript">
        document.getElementById("txt_1").value = getSavedValue("txt_1");    // set the value to this input
        document.getElementById("txt_2").value = getSavedValue("txt_2");   // set the value to this input
        /* Here you can add more inputs to set value. if it's saved */

        //Save the value function - save it to localStorage as (ID, VALUE)
        function saveValue(e){
            var id = e.id;  // get the sender's id to save it .
            var val = e.value; // get the value.
            localStorage.setItem(id, val);// Every time user writing something, the localStorage's value will override .
        }

        //get the saved value function - return the value of "v" from localStorage.
        function getSavedValue  (v){
            if (!localStorage.getItem(v)) {
                return "";// You can change this to your defualt value.
            }
            return localStorage.getItem(v);
        }
</script>
</code>```

Image Showing

COde

```<code><table class="table table-hover table-striped table-bordered" id="input-group">
<thead ><tr >
 <th class="text-right"><?php echo "Contact No."; ?></th>
  <th><?php echo "Followup 1 Date"; ?>
    </th></tr></thead>
    <tbody>
    <?php
      if (empty($enquiry_list)) {
       ?>
       <?php
        } else {
        foreach ($enquiry_list as $key => $value) {
         $current_date = date("d/m/Y");
         $next_date = $value["next_date"];
         if (empty($next_date)) { $next_date = $value["follow_up_date"];
          }if ($next_date < $current_date) {
          $class = "class='danger'";} else {
           $class = ""; } ?>
           <td class="mailbox-name"><?php echo $value['contact']; ?> </td>
   <td class="mailbox-name" >
    <div  style="width:200px" style="height:200px" >
     <input id="txt_<?= $row[id] ?>" onkeyup='saveValue(this);'
      autocomplete="off" type="text" class="form-control"   /></div></td>
      </tr> </tr>
      <?php }}?> </tbody> </table>
</code>```

答:
var inputGroup = document.getElementById('input-group');
var inputs = inputGroup.getElementsByTagName('input');

for(i=0;i<inputs.length;i++)
{
 var id = inputs[i].getAttribute('id');
 inputs[i].value = getSavedValue(id);
}

//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e){
    var id = e.id;  // get the sender's id to save it .
    var val = e.value; // get the value.
    localStorage.setItem(id, val);// Every time user writing something, the localStorage's value will override .
}

//get the saved value function - return the value of "v" from localStorage.
function getSavedValue  (v){
    if (!localStorage.getItem(v)) {
        return "";// You can change this to your defualt value.
    }
    return localStorage.getItem(v);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="input-group">
  <tr>
   <th>Text 1</th>
   <th><input type="text" id="txt_1" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 2</th>
   <th><input type="text" id="txt_2" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 3</th>
   <th><input type="text" id="txt_3" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 4</th>
   <th><input type="text" id="txt_4" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 5</th>
   <th><input type="text" id="txt_5" onkeyup='saveValue(this);'/> </th>
  </tr>
</table> </code>```

Body:
I have a column input field in  which is in the loop due to this each Row has input field I got a javascript from which it storing local storage for input field but the issue is this javascript is working only for one input For Example :

I have five rows and due to loop input field generated for 5 rows automatically

What I am looking for is to store different values for each row..due to this script its not implementing for each row individually

Code

<input type="text" id="txt_1" onkeyup='saveValue(this);'/>

Javascript

Image Showing

COde

 <?php echo "Contact No."; ?>
  <?php echo "Followup 1 Date"; ?>

    <?php
      if (empty($enquiry_list)) {
       ?>
       <?php
        } else {
        foreach ($enquiry_list as $key => $value) {
         $current_date = date("d/m/Y");
         $next_date = $value["next_date"];
         if (empty($next_date)) { $next_date = $value["follow_up_date"];
          }if ($next_date < $current_date) {
          $class = "class='danger'";} else {
           $class = ""; } ?>
           <?php echo $value['contact']; ?>

     <input id="txt_<?= $row[id] ?>" onkeyup='saveValue(this);'
      autocomplete="off" type="text" class="form-control"   />

      <?php }}?>

Body:
var inputGroup = document.getElementById('input-group');
var inputs = inputGroup.getElementsByTagName('input');

for(i=0;i<inputs.length;i++)
{
 var id = inputs[i].getAttribute('id');
 inputs[i].value = getSavedValue(id);
}

//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e){
    var id = e.id;  // get the sender's id to save it .
    var val = e.value; // get the value.
    localStorage.setItem(id, val);// Every time user writing something, the localStorage's value will override .
}

//get the saved value function - return the value of "v" from localStorage.
function getSavedValue  (v){
    if (!localStorage.getItem(v)) {
        return "";// You can change this to your defualt value.
    }
    return localStorage.getItem(v);
}

<table id="input-group">
  <tr>
   <th>Text 1</th>
   <th><input type="text" id="txt_1" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 2</th>
   <th><input type="text" id="txt_2" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 3</th>
   <th><input type="text" id="txt_3" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 4</th>
   <th><input type="text" id="txt_4" onkeyup='saveValue(this);'/> </th>
  </tr>
  <tr>
   <th>Text 5</th>
   <th><input type="text" id="txt_5" onkeyup='saveValue(this);'/> </th>
  </tr>
</table>


问:
WinForms multi-threaded databinding scenario, best practice?
I'm currently designing/reworking the databinding part of an application that makes heavy use of winforms databinding and updates coming from a background thread (once a second on > 100 records).

Let's assume the application is a stock trading application, where a background thread monitors for data changes and putting them onto the data objects. These objects are stored in a BindingList<> and implement INotifyPropertyChanged to propagate the changes via databinding to the winforms controls.
Additionally the data objects are currently marshalling the changes via WinformsSynchronizationContext.Send to the UI thread.
The user is able to enter some of the values in the UI, which means that some values can be changed from both sides. And the user values shouldn't be overritten by updates.

So there are several question coming to my mind:

Is there a general design-guildline how to do that (background updates in databinding)?

When and how to marshal on the UI thread?

What is the best way of the background thread to interact with
binding/data objects?

Which classes/Interfaces should be used? (BindingSource, ...)

...

The UI doesn't really know that there is a background thread, that updates the control, and as of my understanding in databinding scenarios the UI shouldn't know where the data is coming from... You can think of the background thread as something that pushes data to the UI, so I'm not sure if the backgroundworker is the option I'm searching for.

Sometimes you want to get some UI response during an operation in the data-/business object (e.g. setting the background during recalculations). Raising a propertychanged on a status property which is bound to the background isn't enough, as the control get's repainted after the calculation has finished? My idea would be to hook on the propertychanged event and call .update() on the control...
Any other ideas about that?

答:
There is an MSDN article specific on that topic. But be prepared to look at VB.NET. ;)

Additionally maybe you could use System.ComponentModel.BackgroundWorker, instead of a generic second thread, since it nicely formalize the kind of interaction with the spawned background thread you are describing. The example given in the MSDN library is pretty decent, so go look at it for a hint on how to use it.

Edit:
Please note: No marshalling is required if you use the ProgressChanged event to communicate back to the UI thread. The background thread calls ReportProgress whenever it has the need to communicate with the UI. Since it is possible to attach any object to that event there is no reason to do manual marshalling. The progress is communicated via another async operation - so there is no need to worry about neither how fast the UI can handle the progress events nor if the background thread gets interruped by waiting for the event to finish.

If you prove that the background thread is raising the progress changed event way too fast then you might want to look at Pull vs. Push models for UI updates an excellent article by Ayende.

OwnerDisplayName: Martin Moser

ContentLicense: CC BY-SA 3.0

LastEditorDisplayName: Martin Moser


问:
How to clear a form?
For example I have a form like this:

```<code><form method='post' action='someaction.php' name='myform'>

<input type='text' name='text1'>
<input type='text' name='text2'>

<input type='checkbox' name="check1">Check Me

<textarea rows="2" cols="20" name='textarea1'></textarea>

<select name='select1'>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

<input type='reset' value='Reset' name='reset'>
<input type='submit' value='Submit' name='submit'>

</form>
</code>```

When I press Reset it empties all fields. But if I populate some fields using URL params and then press Reset, it only empties fields which I enter after form reload.

How can I empty all fields whether some fields are already populated at the time of form load.

答:
Using JavaScript give the form an ID of 'myform':

document.getElementById('myform').reset();

Title: How to clear a form?

Body:
For example I have a form like this:

<form method='post' action='someaction.php' name='myform'>

<input type='text' name='text1'>
<input type='text' name='text2'>

<input type='checkbox' name="check1">Check Me

<textarea rows="2" cols="20" name='textarea1'></textarea>

<select name='select1'>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

<input type='reset' value='Reset' name='reset'>
<input type='submit' value='Submit' name='submit'>

</form>

When I press Reset it empties all fields. But if I populate some fields using URL params and then press Reset, it only empties fields which I enter after form reload.

How can I empty all fields whether some fields are already populated at the time of form load.


问:
React axios api call: How can I return multiple parameters in a url?
Wasn't sure how to ask this..

How can I return, say, people/0-15? I don't want just people/0, I'd like to access people 0-15, etc

I want to return multiple people. What should I be doing here?

```<code>function getData() {
    return axios.get("https://www.blablahtest.com/api/orders");
  }

function getPerson() {
    return axios.get(`https://www.blablahtest.com/api/people/0`); <----
  }

  useEffect(() => {
    axios.all([getData(), getPerson()]).then(
      axios.spread(function(item, person) {
        setData(item.data);
        setPersonData(person.data);
      })
    );
  }, []);
</code>```

答:
You could make a function called getPeople to set up an array of Axios GET's, then execute them all in your axios.all? Not an ideal solution since you need to make many requests, but if you don't have the ability to modify the backend then it'll get you what you need...

```<code>    function getPeople(start, end) {
      const requestArray= [];
      for ( let i = start; i < end; i++ ) {
        peopleArray.push(() => axios.get(`https://www.blablahtest.com/api/people/${i}`))
      }
     return peopleArray;
}
</code>```

In useEffect:

```<code>  useEffect(() => {
    axios.all(...getPeople(0,15)).then(
      axios.spread(function(people) {
        setPersonData(people);
      })
    );
  }, []);
</code>```

Something like that.... Might need some tweaks as I didn't get a chance to test it. Good luck!

Body:
Wasn't sure how to ask this..

How can I return, say, people/0-15? I don't want just people/0, I'd like to access people 0-15, etc

I want to return multiple people. What should I be doing here?

function getData() {
    return axios.get("https://www.blablahtest.com/api/orders");
  }

function getPerson() {
    return axios.get(`https://www.blablahtest.com/api/people/0`); <----
  }

  useEffect(() => {
    axios.all([getData(), getPerson()]).then(
      axios.spread(function(item, person) {
        setData(item.data);
        setPersonData(person.data);
      })
    );
  }, []);

Body:
You could make a function called getPeople to set up an array of Axios GET's, then execute them all in your axios.all? Not an ideal solution since you need to make many requests, but if you don't have the ability to modify the backend then it'll get you what you need...

    function getPeople(start, end) {
      const requestArray= [];
      for ( let i = start; i < end; i++ ) {
        peopleArray.push(() => axios.get(`https://www.blablahtest.com/api/people/${i}`))
      }
     return peopleArray;
}

In useEffect:

  useEffect(() => {
    axios.all(...getPeople(0,15)).then(
      axios.spread(function(people) {
        setPersonData(people);
      })
    );
  }, []);

Something like that.... Might need some tweaks as I didn't get a chance to test it. Good luck!


问:
Getting the aspect ratio of any video
I want to get the aspect ratio of nay video in android like (1:1, 9:16 etc). Currently i get the height and width of a video but i want the aspect ratio. Is this task is possible with Ffmpeg or MediaMetadataRetriever? If yes, then please give me some example code. If no, then please suggest me the other solutions.</p>

答:
The aspect ratio is just the ratio of the height to the width* - as you can get those I think what you are looking for is simply a way to reduce them to the lowest ratio.

This is a common maths exercise - you divide each number by their greatest common divisor, which is the largest number which will divide into both numbers (https://en.wikipedia.org/wiki/Greatest_common_divisor).

There is a nice example in Java using a recursive modulus division here you can use: https://stackoverflow.com/a/4009247/334402

So in summary you:

get the height and width (e.g. 1500, 500)

get their greatest common divisor, gcd (500 in this example)

dived the gcd into both numbers and get your aspect ratio is its lowest terms (3:1 in this example)

(*) Update. Actually @llogan's very good answer includes both SAR and DAR aspect ratios. Sample Aspect ratio, SAR, is the original source aspect ratio and Display Aspect Ratio is the aspect ration of the video as it is intended to be displayed. There is a third term you may see sometimes also, Pixel aspect ratio which is the DAR divided by the SAR. I suspect it is still the DAR you are interested in so the height and width approach you used still applies.

Title: Getting the aspect ratio of any video


问:
Sharepoint Teamsite-calendar-webpart - save appointment to outlook
Is there a way to save a calendar entry by javascript to personal outlook-calendar within a sharepoint-calendar webpart ?

I want to save a created Entry in a sharepoint-calendar direkt to the personal outlook calendar of the user created it.

Any tip how to do this ?

答:
So, the answer is "kind of".

You technically don't have to write JavaScript to achieve this, as SharePoint has a built in service URL that will download an .ICS file to the user's machine, and whatever that user's default calendaring system (e.g. Outlook) will open that as a new Calendar item.

Although you can construct this link manually if you want to provide a calendar item download for one specific Event, you can certainly use JavaScript to dynamically fill in the parameter values in this URL, which may be easier that having to look up these values individually to manually construct a link.

The URL that you can provide a hyperlink to generate an .ics file is
https://**SITE_URL**/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={**LIST_GUID**}&CacheControl=1&ID=**EVENT_ID**&Using=event.ics

SITE_URL – The URL to the site where the calendar is hosted
LIST_GUID – The (guid) unique identifier of your calendar list
EVENT_ID – The (integer) ID of the calendar event

for example:

https://mysharepointserver/sites/myteamsite/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={B2E3EC57-9BA6-46A2-B072-578C9796A42E}&CacheControl=1&ID=26&Using=event.ics

As an example of who you can use JavaScript to generate this link per event, the following code can be put in a Script Editor WebPart on the same page as a Calendar View Web Part, and it will insert a down arrow character in front of every event link that will trigger the .ics file for that event.  This script assumes you have the jQuery library already loaded on your page, and you will need to replace the string "NameOfYourEventsList" below with the actual title of your Events list.

```<code>function lookupListBeforeAppendingCalendarLink() {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    list = web.get_lists().getByTitle("NameOfYourEventsList");
    context.load(list, 'Id');

    context.executeQueryAsync(Function.createDelegate(this,listIdSuccess), Function.createDelegate(this,error));

}

function listIdSuccess() {
    var listId = list.get_id();
    appendAddToCalendarLink(listId);
}

function error(sender, args) {
    console.log('Request failed. ' + args.get_message() +
        '\n' + args.get_stackTrace());
}

function appendAddToCalendarLink(listId) {
    jQuery('.ms-acal-rootdiv .ms-acal-item').each(function () {
            var currentCalendarAnchor = jQuery('a', jQuery(this));
            var itemId = currentCalendarAnchor.attr('href').split('?ID=')[1];

            currentCalendarAnchor.before("<a href='" + _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List=" + listId + "&CacheControl=1&ID=" + itemId + "&Using=event.ics'>↓</a>");
    });

}

function customizeCalendar() {
    //if you know the list id, you can hard code it here,
    // otherwise use function to look it up first by List title
    // var listId = 'B2E3EC57-9BA6-46A2-B072-578C9796A42E'
    // appendAddToCalendarLink(listId);
    lookupListBeforeAppendingCalendarLink();
}

ExecuteOrDelayUntilScriptLoaded(customizeCalendar, "sp.js")

</code>```

Body:
So, the answer is "kind of".

You technically don't have to write JavaScript to achieve this, as SharePoint has a built in service URL that will download an .ICS file to the user's machine, and whatever that user's default calendaring system (e.g. Outlook) will open that as a new Calendar item.

Although you can construct this link manually if you want to provide a calendar item download for one specific Event, you can certainly use JavaScript to dynamically fill in the parameter values in this URL, which may be easier that having to look up these values individually to manually construct a link.

The URL that you can provide a hyperlink to generate an .ics file is
https://**SITE_URL**/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={**LIST_GUID**}&CacheControl=1&ID=**EVENT_ID**&Using=event.ics

SITE_URL – The URL to the site where the calendar is hosted
LIST_GUID – The (guid) unique identifier of your calendar list
EVENT_ID – The (integer) ID of the calendar event

for example:

https://mysharepointserver/sites/myteamsite/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={B2E3EC57-9BA6-46A2-B072-578C9796A42E}&CacheControl=1&ID=26&Using=event.ics

As an example of who you can use JavaScript to generate this link per event, the following code can be put in a Script Editor WebPart on the same page as a Calendar View Web Part, and it will insert a down arrow character in front of every event link that will trigger the .ics file for that event.  This script assumes you have the jQuery library already loaded on your page, and you will need to replace the string "NameOfYourEventsList" below with the actual title of your Events list.

function lookupListBeforeAppendingCalendarLink() {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    list = web.get_lists().getByTitle("NameOfYourEventsList");
    context.load(list, 'Id');

    context.executeQueryAsync(Function.createDelegate(this,listIdSuccess), Function.createDelegate(this,error));

}

function listIdSuccess() {
    var listId = list.get_id();
    appendAddToCalendarLink(listId);
}

function error(sender, args) {
    console.log('Request failed. ' + args.get_message() +
        '\n' + args.get_stackTrace());
}

function appendAddToCalendarLink(listId) {
    jQuery('.ms-acal-rootdiv .ms-acal-item').each(function () {
            var currentCalendarAnchor = jQuery('a', jQuery(this));
            var itemId = currentCalendarAnchor.attr('href').split('?ID=')[1];

            currentCalendarAnchor.before("<a href='" + _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List=" + listId + "&CacheControl=1&ID=" + itemId + "&Using=event.ics'>&darr;</a>");
    });

}

function customizeCalendar() {
    //if you know the list id, you can hard code it here,
    // otherwise use function to look it up first by List title
    // var listId = 'B2E3EC57-9BA6-46A2-B072-578C9796A42E'
    // appendAddToCalendarLink(listId);
    lookupListBeforeAppendingCalendarLink();
}

ExecuteOrDelayUntilScriptLoaded(customizeCalendar, "sp.js")


问:
Iterate through objects in JSON
I am trying to iterate through the follow json file

[]

In order to access the rank of each item in api.standings[0] so I can create a new table cell with the rank key.

This is my my current code:

```<code>data.api.standings[0].forEach(elements => {

        var tr = document.createElement('tr');

        tr.innerHTML = '<td>' + data.api.standings[0].rank + '</td>';

        table.appendChild(tr);

    });
</code>```

However I am getting undefined in the cell.

答:
Assuming your data is correct, you are iterating through the array standings[0]. In which case, you need to adjust how you reference the objects in the innerHTML assignment statement.

```<code>data.api.standings[0].forEach(elements => {

    var tr = document.createElement('tr');

    tr.innerHTML = '<td>' + elements.rank + '</td>';

    table.appendChild(tr);

});
</code>```

Title: Iterate through objects in JSON

Body:
I am trying to iterate through the follow json file

[]

In order to access the rank of each item in api.standings[0] so I can create a new table cell with the rank key.

This is my my current code:

data.api.standings[0].forEach(elements => {

        var tr = document.createElement('tr');

        tr.innerHTML = '' + data.api.standings[0].rank + '	';

        table.appendChild(tr);

    });

However I am getting undefined in the cell.

Body:
Assuming your data is correct, you are iterating through the array standings[0]. In which case, you need to adjust how you reference the objects in the innerHTML assignment statement.

data.api.standings[0].forEach(elements => {

    var tr = document.createElement('tr');

    tr.innerHTML = '<td>' + elements.rank + '</td>';

    table.appendChild(tr);

});


问:
Retrieve photos on Azure
I have a task to do on Azure.

On Azure, I need to get photos with a link like this :

https://picture.blob.core.windows.net/datapicture

I was given this document.

https://learn.microsoft.com/en-us/powershell/module/azure.storage/get-azurestorageblobcontent?view=azurermps-6.13.0

The goal is to make a powershell script that allows you to retrieve photos in this path with Azure.

I don't have a key to login but a login user and password.

My connection model is, I think :

```<code>Login-AzureRmAccount

$SourceResourceGroupName = "...";
$SourceServerName = "...";
$Database = "...";
$ServerInstance =  "...";
$Username = "...";
$Password = "..."

$con.ConnectionString = "Server=$ServerInstance;
                        uid=$Username;
                        pwd=$Password;
                        Database=$Database;
                        Integrated Security=False;"
$con.Open();
</code>```

Thank you in advance for helping me.

答:
Seems that you are trying to download file from Azure Blob Storage. It is not working like a database.

Just as silent explained in comment, Azure Storage supports symmetric key and Azure AD authentication. Or, you can set your file to public in which way it can be accessed directly.

You used Login-AzureRmAccount command. So, you should be able to download a blob as following:

```<code>$ResourceGroup = "Jack"
$StorageAccount = "storagetest789"
$Container = "function"
Set-AzureRmCurrentStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccount
Get-AzureStorageBlobContent -Container $Container -Blob "User1.txt" -Destination 'D:\'
</code>```

Update

A normal storage blob URL should look like the following: https://{storage_account_name}.blob.core.windows.net/{container_name}/{blob_name}

So, you may get $StorageAccount, $Container and $Blob as following:

```<code>$UserName = '.......';
$Password = '.........';
$Secret = ConvertTo-SecureString -String $Password -AsPlainText -Force;
$PsCred = New-Object System.Management.Automation.PSCredential($UserName, $Secret);
Login-AzureRmAccount -Credential $PsCred;

$ResourceGroup = '';
$URL = 'https://{storage_account_name}.blob.core.windows.net/{container_name}/{blob_name}';

$StorageAccount = $URL.Substring('https://'.Length,$URL.IndexOf(".")-'https://'.Length);
$Path = $URL.Substring($URL.IndexOf('.blob.core.windows.net/')+'.blob.core.windows.net/'.Length);
$Container = $Path.Substring(0,$Path.IndexOf('/'));
$Blob = $Path.Substring($Container.Length+1);

Set-AzCurrentStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccount;
Get-AzStorageBlobContent -Container $Container -Blob $Blob -Destination 'D:\';
</code>```

Title: Retrieve photos on Azure

Body:
I have a task to do on Azure.

On Azure, I need to get photos with a link like this :

https://picture.blob.core.windows.net/datapicture

I was given this document.

https://learn.microsoft.com/en-us/powershell/module/azure.storage/get-azurestorageblobcontent?view=azurermps-6.13.0

The goal is to make a powershell script that allows you to retrieve photos in this path with Azure.

I don't have a key to login but a login user and password.

My connection model is, I think :

Login-AzureRmAccount

$SourceResourceGroupName = "...";
$SourceServerName = "...";
$Database = "...";
$ServerInstance =  "...";
$Username = "...";
$Password = "..."

$con.ConnectionString = "Server=$ServerInstance;
                        uid=$Username;
                        pwd=$Password;
                        Database=$Database;
                        Integrated Security=False;"
$con.Open();

Thank you in advance for helping me.

Body:
Seems that you are trying to download file from Azure Blob Storage. It is not working like a database.

Just as silent explained in comment, Azure Storage supports symmetric key and Azure AD authentication. Or, you can set your file to public in which way it can be accessed directly.

You used Login-AzureRmAccount command. So, you should be able to download a blob as following:

$ResourceGroup = "Jack"
$StorageAccount = "storagetest789"
$Container = "function"
Set-AzureRmCurrentStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccount
Get-AzureStorageBlobContent -Container $Container -Blob "User1.txt" -Destination 'D:\'

Update

A normal storage blob URL should look like the following: https://{storage_account_name}.blob.core.windows.net/{container_name}/{blob_name}

So, you may get $StorageAccount, $Container and $Blob as following:

$UserName = '.......';
$Password = '.........';
$Secret = ConvertTo-SecureString -String $Password -AsPlainText -Force;
$PsCred = New-Object System.Management.Automation.PSCredential($UserName, $Secret);
Login-AzureRmAccount -Credential $PsCred;

$ResourceGroup = '';
$URL = 'https://{storage_account_name}.blob.core.windows.net/{container_name}/{blob_name}';

$StorageAccount = $URL.Substring('https://'.Length,$URL.IndexOf(".")-'https://'.Length);
$Path = $URL.Substring($URL.IndexOf('.blob.core.windows.net/')+'.blob.core.windows.net/'.Length);
$Container = $Path.Substring(0,$Path.IndexOf('/'));
$Blob = $Path.Substring($Container.Length+1);

Set-AzCurrentStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccount;
Get-AzStorageBlobContent -Container $Container -Blob $Blob -Destination 'D:\';


问:
How to group RadioButton from different LinearLayouts?
I was wondering if is possible to group each single RadioButton in a unique RadioGroup
maintaining the same structure. My structure look like this:

LinearLayout_main

LinearLayout_1

RadioButton1

LinearLayout_2

RadioButton2

LinearLayout_3

RadioButton3

As you can see, now each RadioButton is a child of different LinearLayout. I tried using the structure below, but it doesn't work:

Radiogroup

LinearLayout_main

LinearLayout_1

RadioButton1

LinearLayout_2

RadioButton2

LinearLayout_3

RadioButton3

答:
You can use this simple RadioGroup extension code. Drop whatever layouts/views/images in it along with the RadioButtons and it will work.

It contains selection callback which returns the selected RadioButton with its index and you can set selection programatically by index or id:

```<code>import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.util.ArrayList;

public class EnhancedRadioGroup extends RadioGroup implements View.OnClickListener {

    public interface OnSelectionChangedListener {
        void onSelectionChanged(RadioButton radioButton, int index);
    }

    private OnSelectionChangedListener selectionChangedListener;
    ArrayList<RadioButton> radioButtons = new ArrayList<>();

    public EnhancedRadioGroup(Context context) {
        super(context);
    }

    public EnhancedRadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            getRadioButtons();
        }
    }

    private void getRadioButtons() {
        radioButtons.clear();
        checkForRadioButtons(this);
    }

    private void checkForRadioButtons(ViewGroup viewGroup) {
        if (viewGroup == null) {
            return;
        }
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View v = viewGroup.getChildAt(i);
            if (v instanceof RadioButton) {
                v.setOnClickListener(this);
                // store index of item
                v.setTag(radioButtons.size());
                radioButtons.add((RadioButton) v);
            }
            else if (v instanceof ViewGroup) {
                checkForRadioButtons((ViewGroup)v);
            }
        }
    }

    public RadioButton getSelectedItem() {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            if (radioButton.isChecked()) {
                return radioButton;
            }
        }
        return null;
    }

    public void setOnSelectionChanged(OnSelectionChangedListener selectionChangedListener) {
        this.selectionChangedListener = selectionChangedListener;
    }

    public void setSelectedById(int id) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            boolean isSelectedRadioButton = radioButton.getId() == id;
            radioButton.setChecked(isSelectedRadioButton);
            if (isSelectedRadioButton && selectionChangedListener != null) {
                selectionChangedListener.onSelectionChanged(radioButton, (int)radioButton.getTag());
            }
        }
    }

    public void setSelectedByIndex(int index) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        if (radioButtons.size() > index) {
            setSelectedRadioButton(radioButtons.get(index));
        }
    }

    @Override
    public void onClick(View v) {
        setSelectedRadioButton((RadioButton) v);
    }

    private void setSelectedRadioButton(RadioButton rb) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            radioButton.setChecked(rb == radioButton);
        }
        if (selectionChangedListener != null) {
            selectionChangedListener.onSelectionChanged(rb, (int)rb.getTag());
        }
    }
}
</code>```

Use it in you layout xml:

```<code>    <path.to.your.package.EnhancedRadioGroup>
       Layouts containing RadioButtons/Images/Views and other RadioButtons
    </path.to.your.package.EnhancedRadioGroup>
</code>```

To register to the callback:

```<code>        enhancedRadioGroupInstance.setOnSelectionChanged(new EnhancedRadioGroup.OnSelectionChangedListener() {
            @Override
            public void onSelectionChanged(RadioButton radioButton, int index) {

            }
        });
</code>```

Body:
You can use this simple RadioGroup extension code. Drop whatever layouts/views/images in it along with the RadioButtons and it will work.

It contains selection callback which returns the selected RadioButton with its index and you can set selection programatically by index or id:

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.util.ArrayList;

public class EnhancedRadioGroup extends RadioGroup implements View.OnClickListener {

    public interface OnSelectionChangedListener {
        void onSelectionChanged(RadioButton radioButton, int index);
    }

    private OnSelectionChangedListener selectionChangedListener;
    ArrayList<RadioButton> radioButtons = new ArrayList<>();

    public EnhancedRadioGroup(Context context) {
        super(context);
    }

    public EnhancedRadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            getRadioButtons();
        }
    }

    private void getRadioButtons() {
        radioButtons.clear();
        checkForRadioButtons(this);
    }

    private void checkForRadioButtons(ViewGroup viewGroup) {
        if (viewGroup == null) {
            return;
        }
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View v = viewGroup.getChildAt(i);
            if (v instanceof RadioButton) {
                v.setOnClickListener(this);
                // store index of item
                v.setTag(radioButtons.size());
                radioButtons.add((RadioButton) v);
            }
            else if (v instanceof ViewGroup) {
                checkForRadioButtons((ViewGroup)v);
            }
        }
    }

    public RadioButton getSelectedItem() {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            if (radioButton.isChecked()) {
                return radioButton;
            }
        }
        return null;
    }

    public void setOnSelectionChanged(OnSelectionChangedListener selectionChangedListener) {
        this.selectionChangedListener = selectionChangedListener;
    }

    public void setSelectedById(int id) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            boolean isSelectedRadioButton = radioButton.getId() == id;
            radioButton.setChecked(isSelectedRadioButton);
            if (isSelectedRadioButton && selectionChangedListener != null) {
                selectionChangedListener.onSelectionChanged(radioButton, (int)radioButton.getTag());
            }
        }
    }

    public void setSelectedByIndex(int index) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        if (radioButtons.size() > index) {
            setSelectedRadioButton(radioButtons.get(index));
        }
    }

    @Override
    public void onClick(View v) {
        setSelectedRadioButton((RadioButton) v);
    }

    private void setSelectedRadioButton(RadioButton rb) {
        if (radioButtons.isEmpty()) {
            getRadioButtons();
        }
        for (RadioButton radioButton : radioButtons) {
            radioButton.setChecked(rb == radioButton);
        }
        if (selectionChangedListener != null) {
            selectionChangedListener.onSelectionChanged(rb, (int)rb.getTag());
        }
    }
}

Use it in you layout xml:

    <path.to.your.package.EnhancedRadioGroup>
       Layouts containing RadioButtons/Images/Views and other RadioButtons
    </path.to.your.package.EnhancedRadioGroup>

To register to the callback:

        enhancedRadioGroupInstance.setOnSelectionChanged(new EnhancedRadioGroup.OnSelectionChangedListener() {
            @Override
            public void onSelectionChanged(RadioButton radioButton, int index) {

            }
        });


问:
The class is not in the trusted packages although appears in the list of trusted packages
I am trying to implement a simple Kafka communication between 2 different Spring Boot applications with out any special settings, this application has only one kafkalistener. My yml for the consumer is the following:

```<code>spring:
  kafka:
    bootstrap-servers: ip_here
    topic:
      json: topic_here
    consumer:
      group-id: group_id
      auto-offset-reset: earliest
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring:
          json:
            trusted:
              packages: 'com.example.kw.dtos.Classdata'
</code>```

The error I am receiving is the following:

Caused by: java.lang.IllegalArgumentException: The class
  'com.example.kw.dtos.Classdata' is not in the trusted packages:
  [java.util, java.lang, com.example.kw.dtos.Classdata]. If you believe
  this class is safe to deserialize, please provide its name. If the
  serialization is only done by a trusted source, you can also enable
  trust all (*).

The package is in the trusted packages but something is wrong.

My factory class:

```<code>@Configuration
@EnableKafka
public class MsgListener {

    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;

    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "json");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.example.kw.dtos.Classdata");
        return props;
    }

    @Bean
    public ConsumerFactory<String, Classdata> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(
                consumerConfigs(),
                new StringDeserializer(),
                new JsonDeserializer<>(Classdata.class));
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Classdata> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, Classdata> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}
</code>```

答:
The trick here is that you have to set it in two places

spring.json.trusted.packages - for any json deserializers created outside of kafka's influence

spring.kafka.consumer.properties.spring.json.trusted.packages - for kafka created deserializers

This was the only way i was able to make it work. Also, it does not accept wildcards, so it has to be exact package match

Body:
I am trying to implement a simple Kafka communication between 2 different Spring Boot applications with out any special settings, this application has only one kafkalistener. My yml for the consumer is the following:

spring:
  kafka:
    bootstrap-servers: ip_here
    topic:
      json: topic_here
    consumer:
      group-id: group_id
      auto-offset-reset: earliest
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring:
          json:
            trusted:
              packages: 'com.example.kw.dtos.Classdata'

The error I am receiving is the following:

Caused by: java.lang.IllegalArgumentException: The class
  'com.example.kw.dtos.Classdata' is not in the trusted packages:
  [java.util, java.lang, com.example.kw.dtos.Classdata]. If you believe
  this class is safe to deserialize, please provide its name. If the
  serialization is only done by a trusted source, you can also enable
  trust all (*).

The package is in the trusted packages but something is wrong.

My factory class:

@Configuration
@EnableKafka
public class MsgListener {

    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;

    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "json");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.example.kw.dtos.Classdata");
        return props;
    }

    @Bean
    public ConsumerFactory<String, Classdata> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(
                consumerConfigs(),
                new StringDeserializer(),
                new JsonDeserializer<>(Classdata.class));
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Classdata> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, Classdata> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}


问:
compute_totals returns the wrong total derivatives when approx_totals is not used
I noticed that prob.compute_totals() returns a wrong answer when prob.model.approx_totals() is not specified before. Having the partial derivative manually defined or computed by finite differences doesn't change anything, the answer remains wrong when not calling prob.model.approx_totals() before. Also, the call to compute_totals is actually faster when approx_totals is called before, compared to when it's not. This seems counter-intuitive with manually defined partials, since approx_totals is supposed to add an unnecessary finite-difference computation.

Here is a MWE with the Sellar example taken from the OpenMDAO documentation. I also noticed the same behaviour in OpenAeroStruct, even though the differences are smaller than in this example.

```<code>import openmdao.api as om
from openmdao.test_suite.components.sellar_feature import SellarMDA

prob = om.Problem()
prob.model = SellarMDA()

prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1e-8

prob.model.add_design_var('x', lower=0, upper=10)
prob.model.add_design_var('z', lower=0, upper=10)
prob.model.add_objective('obj')
prob.model.add_constraint('con1', upper=0)
prob.model.add_constraint('con2', upper=0)

prob.setup()
prob.set_solver_print(level=0)

prob.model.approx_totals() # Commenting this line gives the wrong result

prob.run_driver()
totals = prob.compute_totals(of=['obj'],wrt=['x','z'])

print("""
Obj = {}
x = {}
z = {}
y1 = {}
y2 = {}
Totals = {}""".format(prob['obj'][0],prob['x'][0],prob['z'][0],prob['y1'][0],prob['y2'][0],totals))
</code>```

The good result, with approx_totals :

```<code>Optimization terminated successfully.    (Exit mode 0)
            Current function value: 3.183393951729169
            Iterations: 6
            Function evaluations: 6
            Gradient evaluations: 6
Optimization Complete
-----------------------------------

Obj = 3.183393951729169
x = 0.0
z = 1.977638883487764
y1 = 3.1600000000897133
y2 = 3.755277766976125
Totals = OrderedDict([(('obj', 'x'), array([[0.94051147]])), (('obj', 'z'), array([[3.50849282, 1.72901602]]))])
</code>```

The wrong result, whithout approx_totals :

```<code>Optimization terminated successfully.    (Exit mode 0)
            Current function value: 3.1833939532752136
            Iterations: 11
            Function evaluations: 12
            Gradient evaluations: 11
Optimization Complete
-----------------------------------

Obj = 3.1833939532752136
x = 4.401421628747386e-15
z = 1.9776388839289216
y1 = 3.1600000016563765
y2 = 3.755277767857951
Totals = OrderedDict([(('obj', 'x'), array([[0.99341446]])), (('obj', 'z'), array([[3.90585351, 1.97002055]]))])
</code>```

答:
In this example, the problem is that you have a cycle in SellarMDA, but the model does not contain a linear solver that can compute the total derivatives across the cycle. One way you can check on this is to run "openmdao check myfilename.py" at the command-line.  I ran it on your model, and got the following warnings:

```<code>INFO: checking comp_has_no_outputs
INFO: checking dup_inputs
INFO: checking missing_recorders
WARNING: The Problem has no recorder of any kind attached
INFO: checking out_of_order
INFO: checking solvers
WARNING: Group 'cycle' contains cycles [['d1', 'd2']], but does not have an iterative linear solver.
INFO: checking system
</code>```

There are a couple of remedies for this. You could manually add a different linear solver such as DirectSolver or PETScKrylov to the "cycle" group.  You could also import SellarMDALinearSolver instead of SellarMDA.  SellarMDALinearSolver uses a Newton solver for converging the cycle, and a DirectSolver for computing the derivatives.  SellarMDA uses NonlinearBlockGS to converge the cycle, but unfortunately does not contain an appropriate linear solver to compute the derivatives.  These components are used in a variety of testing roles, but I think in retrospect, we should probably add a LinearBlockGS to SellarMDA in the future, so that total derivatives can be computed without modification.  For now though, you'll have to use SellarMDALinearSolver or add the solver yourself.

BTW, I suspect the optimization was slower because the derivatives were so bad.  It took twice as many iterations, though it still somehow managed to get pretty close to the answer.

You mentioned similar symptoms in your OpenAeroStruct model.  I would suspect that either 1) a subcomponent has an error in its analytical derivatives, or 2) the linear solvers are not set up correctly (maybe you have a cycle somewhere without a good linear solver in that group or parent group.)  I think that Problem.check_partials and Problem.check_totals will give you more insight on where the problem could be.  There is more info on these here.

Body:
I noticed that prob.compute_totals() returns a wrong answer when prob.model.approx_totals() is not specified before. Having the partial derivative manually defined or computed by finite differences doesn't change anything, the answer remains wrong when not calling prob.model.approx_totals() before. Also, the call to compute_totals is actually faster when approx_totals is called before, compared to when it's not. This seems counter-intuitive with manually defined partials, since approx_totals is supposed to add an unnecessary finite-difference computation.

Here is a MWE with the Sellar example taken from the OpenMDAO documentation. I also noticed the same behaviour in OpenAeroStruct, even though the differences are smaller than in this example.

import openmdao.api as om
from openmdao.test_suite.components.sellar_feature import SellarMDA

prob = om.Problem()
prob.model = SellarMDA()

prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1e-8

prob.model.add_design_var('x', lower=0, upper=10)
prob.model.add_design_var('z', lower=0, upper=10)
prob.model.add_objective('obj')
prob.model.add_constraint('con1', upper=0)
prob.model.add_constraint('con2', upper=0)

prob.setup()
prob.set_solver_print(level=0)

prob.model.approx_totals() # Commenting this line gives the wrong result

prob.run_driver()
totals = prob.compute_totals(of=['obj'],wrt=['x','z'])

print("""
Obj = {}
x = {}
z = {}
y1 = {}
y2 = {}
Totals = {}""".format(prob['obj'][0],prob['x'][0],prob['z'][0],prob['y1'][0],prob['y2'][0],totals))

The good result, with approx_totals :

Optimization terminated successfully.    (Exit mode 0)
            Current function value: 3.183393951729169
            Iterations: 6
            Function evaluations: 6
            Gradient evaluations: 6
Optimization Complete
-----------------------------------

Obj = 3.183393951729169
x = 0.0
z = 1.977638883487764
y1 = 3.1600000000897133
y2 = 3.755277766976125
Totals = OrderedDict([(('obj', 'x'), array([[0.94051147]])), (('obj', 'z'), array([[3.50849282, 1.72901602]]))])

The wrong result, whithout approx_totals :

Optimization terminated successfully.    (Exit mode 0)
            Current function value: 3.1833939532752136
            Iterations: 11
            Function evaluations: 12
            Gradient evaluations: 11
Optimization Complete
-----------------------------------

Obj = 3.1833939532752136
x = 4.401421628747386e-15
z = 1.9776388839289216
y1 = 3.1600000016563765
y2 = 3.755277767857951
Totals = OrderedDict([(('obj', 'x'), array([[0.99341446]])), (('obj', 'z'), array([[3.90585351, 1.97002055]]))])

Body:
In this example, the problem is that you have a cycle in SellarMDA, but the model does not contain a linear solver that can compute the total derivatives across the cycle. One way you can check on this is to run "openmdao check myfilename.py" at the command-line.  I ran it on your model, and got the following warnings:

INFO: checking comp_has_no_outputs
INFO: checking dup_inputs
INFO: checking missing_recorders
WARNING: The Problem has no recorder of any kind attached
INFO: checking out_of_order
INFO: checking solvers
WARNING: Group 'cycle' contains cycles [['d1', 'd2']], but does not have an iterative linear solver.
INFO: checking system

There are a couple of remedies for this. You could manually add a different linear solver such as DirectSolver or PETScKrylov to the "cycle" group.  You could also import SellarMDALinearSolver instead of SellarMDA.  SellarMDALinearSolver uses a Newton solver for converging the cycle, and a DirectSolver for computing the derivatives.  SellarMDA uses NonlinearBlockGS to converge the cycle, but unfortunately does not contain an appropriate linear solver to compute the derivatives.  These components are used in a variety of testing roles, but I think in retrospect, we should probably add a LinearBlockGS to SellarMDA in the future, so that total derivatives can be computed without modification.  For now though, you'll have to use SellarMDALinearSolver or add the solver yourself.

BTW, I suspect the optimization was slower because the derivatives were so bad.  It took twice as many iterations, though it still somehow managed to get pretty close to the answer.

You mentioned similar symptoms in your OpenAeroStruct model.  I would suspect that either 1) a subcomponent has an error in its analytical derivatives, or 2) the linear solvers are not set up correctly (maybe you have a cycle somewhere without a good linear solver in that group or parent group.)  I think that Problem.check_partials and Problem.check_totals will give you more insight on where the problem could be.  There is more info on these here.


问:
Show dialog box programmatically, then dispose it on dialog button press
I currently have a UserControl View and ViewModel which essentially gets some data back about the user. If the user does not have access rights to the system, the application should show a pop up box telling the user this information - the popup box has an "OK" button, which then disposes the dialog box and returns to the previous user control.

I am also using Material Design to do this, however implementation is not very clear from the documentation here: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/Dialogs#dialoghostshow

My implementation is as follows:

Dialog View:

```<code><UserControl x:Class="GiveUpRegister.Dialogs.MessageBoxView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:system="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d"
             Height="auto" Width="auto">

    <materialDesign:Card HorizontalAlignment="Center" materialDesign:ShadowAssist.ShadowDepth="Depth1">
        <DockPanel  Height="auto" Width="250">
            <TextBlock Text="{Binding TxtBlockTitle.Value}" FontWeight="Bold" DockPanel.Dock="Top" Margin="20,20,9,20">Example error title</TextBlock>
            <TextBlock Text="{Binding TxtBlockMessage.Value}" DockPanel.Dock="Top" Margin="20,5,20,10">Some error message.</TextBlock>
            <Button Margin="9,10,9,10" Style="{StaticResource MaterialDesignFlatButton}" DockPanel.Dock="Bottom">
                <Button.CommandParameter>
                    <system:Boolean>True</system:Boolean>
                </Button.CommandParameter>
                OK
            </Button>
        </DockPanel>
    </materialDesign:Card>
</UserControl>
</code>```

Dialog ViewModel:

```<code>public class MessageBoxViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool _isMessageBoxOpen;
    public bool IsMessageBoxOpen
    {
        get => _isMessageBoxOpen;
        set
        {
            if (_isMessageBoxOpen == value) return;
            _isMessageBoxOpen = value;
            OnPropertyChanged(nameof(IsMessageBoxOpen));
        }
    }

    private object _messageContent;
    public object MessageContent
    {
        get => _messageContent;
        set
        {
            if (_messageContent == value) return;
            _messageContent = value;
            OnPropertyChanged(nameof(MessageContent));
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
</code>```

How do I adapt this code to be able to initialise this from the following code:

StartupViewModel:

```<code>private async Task LoadUserDetails()
{
    try
    {
        await Task.Factory.StartNew(() => SystemUserService = SystemUserService.Instance);
        bool hasAccess = SystemUserService.CheckAccessPermission();
        if (hasAccess)
        {
             // Show the dialog box
        }
    }
    catch (Exception ex)
    {
        Logger.SendError("Could not retrieve user details", ex);
    }
}
</code>```

答:
I found a solution to wait for a dialogbox without blocking the calling UI thread.
It's far from the best solution but it works for me. If someone can enhance it...

You can try this solution :
Is there a mean to call Show DialogHost synchronously ?

It consist from code to call the following method

```<code>methodMessageDialog(string message, System.Windows.Forms.MessageBoxButtons messageBoxButtons = System.Windows.Forms.MessageBoxButtons.OK)).
</code>```

This method is async and waits for user button answer, it will block the current method without blocking the UI.

Body:
I currently have a UserControl View and ViewModel which essentially gets some data back about the user. If the user does not have access rights to the system, the application should show a pop up box telling the user this information - the popup box has an "OK" button, which then disposes the dialog box and returns to the previous user control.

I am also using Material Design to do this, however implementation is not very clear from the documentation here: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/Dialogs#dialoghostshow

My implementation is as follows:

Dialog View:

<UserControl x:Class="GiveUpRegister.Dialogs.MessageBoxView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:system="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d"
             Height="auto" Width="auto">

    <materialDesign:Card HorizontalAlignment="Center" materialDesign:ShadowAssist.ShadowDepth="Depth1">
        <DockPanel  Height="auto" Width="250">
            <TextBlock Text="{Binding TxtBlockTitle.Value}" FontWeight="Bold" DockPanel.Dock="Top" Margin="20,20,9,20">Example error title</TextBlock>
            <TextBlock Text="{Binding TxtBlockMessage.Value}" DockPanel.Dock="Top" Margin="20,5,20,10">Some error message.</TextBlock>
            <Button Margin="9,10,9,10" Style="{StaticResource MaterialDesignFlatButton}" DockPanel.Dock="Bottom">
                <Button.CommandParameter>
                    <system:Boolean>True</system:Boolean>
                </Button.CommandParameter>
                OK
            </Button>
        </DockPanel>
    </materialDesign:Card>
</UserControl>

Dialog ViewModel:

public class MessageBoxViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool _isMessageBoxOpen;
    public bool IsMessageBoxOpen
    {
        get => _isMessageBoxOpen;
        set
        {
            if (_isMessageBoxOpen == value) return;
            _isMessageBoxOpen = value;
            OnPropertyChanged(nameof(IsMessageBoxOpen));
        }
    }

    private object _messageContent;
    public object MessageContent
    {
        get => _messageContent;
        set
        {
            if (_messageContent == value) return;
            _messageContent = value;
            OnPropertyChanged(nameof(MessageContent));
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

How do I adapt this code to be able to initialise this from the following code:

StartupViewModel:

private async Task LoadUserDetails()
{
    try
    {
        await Task.Factory.StartNew(() => SystemUserService = SystemUserService.Instance);
        bool hasAccess = SystemUserService.CheckAccessPermission();
        if (hasAccess)
        {
             // Show the dialog box
        }
    }
    catch (Exception ex)
    {
        Logger.SendError("Could not retrieve user details", ex);
    }
}

Body:
I found a solution to wait for a dialogbox without blocking the calling UI thread.
It's far from the best solution but it works for me. If someone can enhance it...

You can try this solution :
Is there a mean to call Show DialogHost synchronously ?

It consist from code to call the following method

methodMessageDialog(string message, System.Windows.Forms.MessageBoxButtons messageBoxButtons = System.Windows.Forms.MessageBoxButtons.OK)).

This method is async and waits for user button answer, it will block the current method without blocking the UI.


问:
Restore from backup | MySQL
I have restored from a backup on a specific date to a test server database and I want to check if it restored all the data. How can I check or compare the data between the test database and the production database. </p>

答:
Welcome.

This would have become a good post (for several others) if you had added little more details.

Assumptions.

Original database at first server is bigger and the restored database in second server is a subset (backup on a specific date).

So many databases, so many tables, so many columns and so many rows.

Solutions.

Your backup (bet it through your own script or through a tool) should have an accompanying log file. Refer the same for any errors / warnings.

Refer the outcome of your restore too. And if both does not have any thing unusual, you can be sure of (may be 95%).

Prepare a script to have output from both servers having grouped sum values based on important criteria / categories / group heads / etc.

Also run this. https://dev.mysql.com/doc/refman/5.7/en/checksum-table.html on both servers.

Title: Restore from backup | MySQL


问:
How to expand height of containing view as TextField expands vertically with a newline
I have an array of Views that expand vertically in a scrollView.  The views are of equal width and lined up top to bottom.  Each View has a multiline text field that begins at a fixed height, and gets taller as lines are added.  How can I constrain the height of the parent view to the height of the text field?  Is it possible to do something like this (constraining a view within itself)?

```<code>Class DocCell: NSView {
    // removed unnecessary components

    var textField: NSTextField!

    override func updateConstraints() {
        NSLayoutConstraint.activate([
            heightAnchor.constraint(equalTo: textField.heightAnchor, constant: 10),
            // ..other constraints
        ])
    }
}
</code>```

The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.

答:
The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.

You have no choice. You need to update the height of the field each time a new line is added. You can, for example, override textDidChange: in the NSTextField subclass, and call invalidateInstrinsicContentSize (after calling super) and recalculate the size there:

```<code>override func textDidChange(_ note: Notification) {
    super.textDidChange(note)
    invalidateIntrinsicContentSize()
}

override var intrinsicContentSize: NSSize {
    let cell = self.cell as! NSTextFieldCell
    var boundingRect = frame
    boundingRect.size.height = CGFloat.max
    return cell.cellSize(for: boundingRect)
}
</code>```

This will let your other existing constraints do the right thing as long as you have the hugging and compression resistance set to 1000.

Body:
I have an array of Views that expand vertically in a scrollView.  The views are of equal width and lined up top to bottom.  Each View has a multiline text field that begins at a fixed height, and gets taller as lines are added.  How can I constrain the height of the parent view to the height of the text field?  Is it possible to do something like this (constraining a view within itself)?

Class DocCell: NSView {
    // removed unnecessary components

    var textField: NSTextField!

    override func updateConstraints() {
        NSLayoutConstraint.activate([
            heightAnchor.constraint(equalTo: textField.heightAnchor, constant: 10),
            // ..other constraints
        ])
    }
}

The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.

Body:
The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.

You have no choice. You need to update the height of the field each time a new line is added. You can, for example, override textDidChange: in the NSTextField subclass, and call invalidateInstrinsicContentSize (after calling super) and recalculate the size there:

override func textDidChange(_ note: Notification) {
    super.textDidChange(note)
    invalidateIntrinsicContentSize()
}

override var intrinsicContentSize: NSSize {
    let cell = self.cell as! NSTextFieldCell
    var boundingRect = frame
    boundingRect.size.height = CGFloat.max
    return cell.cellSize(for: boundingRect)
}

This will let your other existing constraints do the right thing as long as you have the hugging and compression resistance set to 1000.


问:
How to get the control that is clicked?
How can I get the name of control that was clicked in ASP.NET? (e.g., a LinkBottun)</p>

答:
How about

```<code>sender.Name;
</code>```

Place this inside the method which is called on the click event.

Title: How to get the control that is clicked?

Body:
How about

sender.Name;

Place this inside the method which is called on the click event.


问:
What are the benefits of sharing an IAM role instead of a IAM key?
I'm told sharing IAM roles with third parties is more secure than sharing IAM keys. Currently we limit IAM keys with IP filters, many conditions on access control.

Why would sharing IAM roles be better. My understanding is they can use their role to assume privilege for a time limited period from something like the boto3 api. But if they can assume the role without limit, how is there a security benefit over a key?

答:
To grant an external party access to the AWS resources owned by you, you have following options:

[WORST APPROACH] You create an IAM user (say, Foo) and grant it the required permissions and then share the same with the external parties. This is obviously the worst approach as now you have no segregation between who is making calls to your resources because in effect, it is always Foo who is calling you.

You let your clients create IAM users in their own accounts and then whitelist them in your resource's policy. This works, given that your resource supports resource-level policies (S3 and API Gatewaydo). Now, even if they do support resource-level policies, now it is an overhead for you to whitelist all such users created by all your clients, which can access the resource.

You create an IAM role, grant it capabilities (in terms of IAM policies) to access your resource and then whitelist your clients' IAM users to assume that role. This will be your way of saying that "this role is capable of accessing my resource and if you can assume this role, so do you". Moreover, this also prevents you from sharing the credentials as AWS STS  does all that work in generating the temporary credentials for you.