Suite

ERREUR 000989 Problème avec le script Python et le champ Calcul de la distance entre deux points de latitude longs

ERREUR 000989 Problème avec le script Python et le champ Calcul de la distance entre deux points de latitude longs


très nouveau dans les scripts et j'ai du mal avec mon script depuis un certain temps. Je ne sais pas pourquoi cela ne fonctionne pas dans la calculatrice de champ. J'essaie de calculer une liste de distance entre deux longs points de latitude. Ce qui suit est le code que j'ai implémenté dans le code de script pré-logique pour FieldName1. J'utilise actuellement ArcGIS 10.1

def Distance(Latitude, Latitude2, Longitude, Longitude2) Longitude, Latitude, Longitude2, Latitude2 = map(math.radians, [Longitude, Latitude, Longitude2, Latitude2]) dlong = Longitude2-Longitude dlat = Latitude2 - Latitude a = math.sin (dlat/2)**2 + math.cos(Latitude * math.cos(Latitude2) * math.sin(dlong/2)**2 c = 2 * math.asin(math.sqrt(a)) Distance = 6371 * C * 1000

Voici des exemples de points de référence : Latitude :48,5761 Longitude : -124,31111 Latitude 2 : 48,57611 Longitude 2 : -124,31111

J'ai continué à obtenir l'erreur 000989 : Erreur de syntaxe Python : erreur d'analyse SyntaxError : syntaxe invalide (ligne1). Il ajoute également que les paramètres ne sont pas valides.


D'après ce tutoriel, la fonction map renvoie une liste :

>>> items = [1, 2, 3, 4, 5] >>> >>> def sqr(x): return x ** 2 >>> list(map(sqr, items)) [1, 4, 9, 16, 25] >>>

Votre code devrait donc ressembler à ceci :

def Distance(Latitude, Latitude2, Longitude, Longitude2) pList = map(math.radians, [Longitude, Latitude, Longitude2, Latitude2]) Longitude = pList[0] Latitude = pList[1] Longitude2 = pList[2] Latitude2 = pList [3] dlong = Longitude2-Longitude dlat = Latitude2 - Latitude a = math.sin(dlat/2)**2 + math.cos(Latitude * math.cos(Latitude2) * math.sin(dlong/2)** 2 c = 2 * math.asin(math.sqrt(a)) Distance = 6371 * C * 1000

Ce qui reviendrait à écrire :

def Distance(Latitude, Latitude2, Longitude, Longitude2) Longitude = math.radians(Longitude) Latitude = math.radians(Latitude) Longitude2 = math.radians(Longitude2) Latitude2 = math.radians(Latitude2) dlong = Longitude2-Longitude dlat = Latitude2 - Latitude a = math.sin(dlat/2)**2 + math.cos(Latitude * math.cos(Latitude2) * math.sin(dlong/2)**2 c = 2 * math.asin(math .sqrt(a)) Distance = 6371 * C * 1000

Comment simuler l'interaction entre deux atomes ?

Je veux construire un simulateur d'interaction d'atomes grossier, où poussent deux (ou plus) atomes l'un vers l'autre et ils devraient se comporter physiquement correctement : attirer, lier ou repousser avec une certaine force. C'est donc ce que je dois calculer.

J'ai étudié la théorie des liaisons ioniques et covalentes et cela m'aide.

Mais je ne comprends toujours pas comment calculer le résultat final en fonction des types et des forces des atomes en collision avec lesquels ils sont poussés les uns vers les autres.


11 réponses 11

Le meilleur endroit pour ces calculs est le site Web "Great Circle Mapper".

Pour trouver la distance entre deux aéroports ou plus, entrez-les simplement avec des tirets entre eux. par exemple, JFK-DFW ou SFO-IAD-LHR

Vous pouvez effectuer plusieurs trajets à la fois en les séparant par des virgules. JKF-DFW, OFS-IAD-LHR

À tous les répondeurs recommandant les mathématiques du Grand Cercle, vous n'avez qu'en partie raison.

La distance entre deux points sur une sphère est trouvée par GC Maths, mais le PO a spécifiquement demandé la distance aérienne. Ceci est trouvé en trouvant d'abord tous les points visités en route vers la destination, puis en calculant les distances GC pour toutes les paires de routes.

Par exemple, un vol de Londres à New York ne suit pas la trajectoire orthodromique entre les deux points. Il suit un ensemble de points, qui peuvent inclure des aides à la navigation, des points de cheminement, des voies aériennes, des routes de départ, des routes d'arrivée, des repères lat/long et des points de relèvement. voir Plan de vol pour plus d'informations.

Il faudrait donc contacter la compagnie aérienne concernée et lui demander gentiment le plan de vol utilisé, et trouver les lat longs pour chacun des points visités.

De nombreuses compagnies aériennes incluent ces informations dans leurs horaires. Par exemple, Air Canada vous permet de télécharger un PDF de leur horaire complet. En voici un extrait :

Je suggère de rechercher le site Web de la compagnie aérienne que vous avez l'intention d'utiliser. Tout outil basé sur la distance réelle entre les villes peut être jusqu'à 20-30 miles différent de la distance aérienne.

Si vous voulez le calculer vous-même, alors la loi sphérique des cosinus est probablement le moyen le plus simple de procéder. Il sera probablement assez précis pour vos besoins et est vraiment simple. Si vous le voulez en python, essayez ce code (vous voudriez calculer_distance_and_bearing )

Vous voudrez probablement également les informations de localisation des différents aéroports d'intérêt. J'ai eu tendance à utiliser la base de données Global Airport dans le passé pour ce genre de chose.

Si vous voulez faire ce calcul pour les vols, vous devrez utiliser la loi sphérique des cosinus comme l'a mentionné Gagravarr. Cependant, si vous voulez écrire votre propre petit outil et tracer une ligne sur une carte, cela devient un peu délicat. Vous devrez utiliser une carte de projection Lambert pour tracer une ligne droite de A à B dessus. Le problème avec la projection conique conforme de Lambert est que ces cartes ne sont précises que le long des deux parallèles de référence, et plus vous vous en éloignez, moins elles sont précises. Ce n'est généralement pas le cas et cela pose problème sur les petites cartes qui ne couvrent que 100x100 km, mais plus la carte est grande, plus la marge d'erreur est grande. Cela a quelque chose à voir avec le fait que la terre est ronde, et vous ne pouvez pas faire une cartographie exacte 1:1 d'une surface ronde à une surface plane.

Google maps (et toutes les cartes nautiques) utilise une projection de carte cylindrique, cela signifie que vous devrez tracer des courbes sur la carte pour obtenir le même itinéraire que vous le feriez avec une ligne droite sur une projection Lambert.

Vous pouvez également tracer de telles lignes (appelées géodésiques) dans Google Maps en utilisant ce site.


3 réponses 3

Ceci est une excellente question. Vous marchez sur les traces d'Archimède et commencez à inventer le calcul intégral et l'idée d'une limite.

Je vais essayer d'aborder (brièvement !) les problèmes mathématiques et philosophiques ici, pas la question de programmation.

Vous avez raison de vous inquiéter d'un processus qui doit durer éternellement. La façon dont les mathématiciens traitent cette question est de remplacer les opérations infiniment nombreuses qu'il faudrait pour « atteindre une limite » par une infinité d'inégalités dont chacune peut être justifiée en un nombre fini prévisible d'étapes. Si dans votre image vous calculez la surface totale des tranches inscrites tout comme vous avez calculé la surface des tranches circonscrites, vous pouvez montrer (avec une logique, pas un programme) que la différence entre ces deux zones est aussi petite que vous le souhaitez aussi longtemps car vous êtes prêt à utiliser des rectangles suffisamment fins. Ensuite, vous pouvez argumenter (bien que ce ne soit pas facile) qu'il n'y a qu'un chiffre de moins que toutes les surestimations et plus que toutes les sous-estimations. Pour un cercle de rayon $1$ nous appelons ce nombre $pi$ .

Le travail suivant consiste à surestimer et sous-estimer la circonférence du cercle unité avec le même type d'argument, en utilisant des polygones circonscrits et inscrits. Là aussi, vous pouvez montrer qu'ils vous indiquent un nombre pour la circonférence.

La dernière étape consiste à montrer que ce nombre est exactement le double du $pi$ que vous avez trouvé pour la zone.

Pour un cercle de rayon $r$ la circonférence sera $r$ fois plus grande, donc $2pi r$ , et l'aire sera $r^2$ fois plus grande, donc $pi r^2$ . (Pour prouver soigneusement ces proportionnalités pour les formes courbes comme les cercles, il faut des estimations et des limites.)


2 réponses 2

La marge de fondu est la différence de niveaux de puissance entre le signal réel qui frappe le récepteur et le signal minimal minimal requis par le récepteur pour fonctionner. Il donne par exemple une indication des taux d'erreurs binaires probables.

Il existe une formule standard pour calculer le niveau de signal théorique minimum nécessaire à un récepteur pour un débit de données donné. C'est -154dBm + 10$log_<10>$(débit binaire). Si le débit de données est de 1 Mbps, un récepteur aura besoin de -94 dBm pour avoir une chance d'obtenir raisonnablement des données décentes.

Si le signal reçu est en fait de -84 dBm, la marge d'évanouissement est de 10 dB, c'est-à-dire qu'elle peut permettre un évanouissement du signal reçu jusqu'à 10 dB.

Pour appliquer cela à votre situation, vous devez comprendre le débit de données afin de pouvoir calculer la puissance de réception minimale acceptable. Parce que Fm = Pr - Pm (où Pm est le niveau de puissance minimum du récepteur calculé à partir du débit binaire ou peut-être marqué sur la boîte), je pense que vous devriez pouvoir le résoudre en vous basant sur le RSSI équivalent à Pr.

Si vous regardez dans le lien que vous avez fourni, vous verrez ceci : -

Sensibilité de réception : 802.11b : [email protected]

En d'autres termes, à 11 Mbps, en utilisant la formule de ma réponse, vous obtenez une puissance de réception minimale requise de -154 dBm + 10$ log_<10>$(11 000 000) dBm = -154dBm + 70,4dBm = -83,59dBm.

J'ai jeté un coup d'œil à ce sujet et il existe une formule plus simple que vous pouvez utiliser sur la base de ce document. La formule est #19 à la page 3 et fondamentalement c'est ceci : -

Où A est la force du signal reçu en dBm à 1 mètre - vous devez l'étalonner sur votre système. Parce que vous calibrez à une distance connue, vous n'avez pas besoin de prendre en compte la fréquence de votre transmission et cela simplifie l'équation.

d est la distance en mètres et n est la constante de propagation ou l'exposant de perte de trajet comme vous l'avez mentionné dans votre question, c'est-à-dire 2,7 à 4,3 (l'espace libre a n = 2 pour référence).

Votre formule d'origine - si vous pouviez fournir une source pour cela, je peux la comparer aux données dont je dispose.


Oui, mais fais-le évident.

Ce que je trouve étrange à propos de ce Q&A jusqu'à présent, c'est que personne n'a réellement tenté de définir clairement le "code en dur" ou, plus important encore, les alternatives.

tldr : Oui, il est parfois une bonne idée de coder en dur les valeurs, mais il n'y a pas de règle simple pour lorsque cela dépend complètement du contexte.

La question se réduit à valeurs, que je considère comme des nombres magiques, mais la réponse à la question de savoir s'ils sont ou non une bonne idée est relative à à quoi ils servent réellement !

Voici plusieurs exemples de valeurs « codées en dur » :

Valeurs de configuration

Je grince des dents chaque fois que je vois des instructions comme command.Timeout = 600 . Pourquoi 600 ? Qui a décidé ça ? Était-ce un délai avant, et quelqu'un a-t-il évoqué le délai d'expiration comme un piratage au lieu de résoudre le problème de performances sous-jacent ? Ou s'agit-il en fait d'une attente connue et documentée en matière de temps de traitement ?

Ce ne devrait pas être des nombres magiques ou alors constantes, elles doivent être externalisées dans un fichier de configuration ou une base de données quelque part avec un nom significatif, car leur valeur optimale est déterminée en grande partie ou entièrement par l'environnement dans lequel l'application s'exécute.

Formules mathématiques

Les formules ont généralement tendance à être assez statiques, de sorte que la nature des valeurs constantes à l'intérieur n'est pas vraiment particulièrement importante. Le volume d'une pyramide est (1/3)b*h. Nous soucions-nous de l'origine du 1 ou du 3 ? Pas vraiment. Un intervenant précédent a souligné à juste titre que diamètre = rayon * 2 est probablement meilleur que diamètre = rayon * RADIUS_TO_DIAMETER_CONVERSION_FACTOR - mais c'est une fausse dichotomie.

Ce que vous devriez faire pour ce type de scénario est de créer un une fonction. Je n'ai pas besoin de savoir comment tu est venu avec la formule mais j'ai encore besoin de savoir à quoi ça sert. Si, au lieu de l'une des bêtises écrites ci-dessus, j'écris volume = GetVolumeOfPyramid(base, height) alors tout devient soudainement beaucoup plus clair, et il est parfaitement normal d'avoir des nombres magiques à l'intérieur la fonction ( return base * height / 3 ) car il est évident qu'elles ne font qu'une partie de la formule.

La clé ici est bien sûr d'avoir court et Facile les fonctions. Cela ne fonctionne pas pour les fonctions avec 10 arguments et 30 lignes de calcul. Utilisez la composition de fonction ou des constantes dans ce cas.

Domaine/règles métier

Celui-ci est toujours la zone grise car cela dépend de la valeur exacte. Plus du temps, ce sont ces nombres magiques particuliers qui sont candidats à la transformation en constantes, car cela rend le programme plus facile à comprendre sans compliquer la logique du programme. Considérez le test si Age < 19 vs. si Age < Legal DrinkingAge vous avez probablement pouvez comprendre ce qui se passe sans la constante, mais c'est plus facile avec le titre descriptif.

Ceux-ci peuvent également deviennent des candidats pour l'abstraction de fonction, par exemple la fonction isLegalDrinkingAge(age) < return age >= 19 >. La seule chose est que souvent votre logique métier est beaucoup plus alambiquée que cela, et il n'est peut-être pas logique de commencer à écrire des dizaines de fonctions avec 20 à 30 paramètres chacune. S'il n'y a pas d'abstraction claire basée sur des objets et/ou des fonctions, alors le recours à des constantes est acceptable.

La mise en garde est que si vous travaillez pour le service des impôts, cela devient vraiment, vraiment fastidieux et honnêtement inutile d'écrire AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR) . Vous n'allez pas faire ça, vous allez AttachForm("B-46") ​​parce que chaque développeur qui a déjà travaillé ou travaillera là-bas saura que "B-46" est le code de formulaire pour un seul contribuable déclarant blah blah blah - les codes de formulaire font partie du domaine lui-même, ils ne changent jamais, donc ce ne sont pas vraiment des nombres magiques.

Vous devez donc utiliser les constantes avec parcimonie dans la logique métier. En gros, vous devez comprendre si ce "nombre magique" est en fait un nombre magique ou s'il s'agit d'un aspect bien connu du domaine. S'il s'agit d'un domaine, vous ne le codez pas à moins qu'il n'y ait de très bonnes chances qu'il change.

Codes d'erreur et indicateurs d'état

Ceux-ci sont jamais OK pour coder en dur, comme tout pauvre bâtard qui a déjà été touché par l'échec de l'action précédente en raison du code d'erreur 46 peut vous le dire. Si votre langue le prend en charge, vous devez utiliser un type d'énumération. Sinon, vous aurez généralement un fichier/module entier plein de constantes spécifiant les valeurs valides pour un type d'erreur particulier.

Ne me laisse jamais voir le retour 42 dans un gestionnaire d'erreurs, capiche ? Pas d'excuses.

J'ai probablement omis plusieurs scénarios, mais je pense que cela couvre la plupart d'entre eux.

Donc, oui, c'est parfois une pratique acceptable de coder des choses en dur. Ne soyez pas paresseux à ce sujet, cela devrait être une décision consciente plutôt qu'un simple vieux code bâclé.


3 réponses 3

Considérons les deux vecteurs vers les points de la sphère, $<f v>_i=(rsin heta_icosvarphi_i,rsin heta_isinvarphi_i,rcos heta_i)$ avec $i =1,2$. Utilisez le produit scalaire pour obtenir l'angle $psi$ entre eux : $<f v>_1cdot <f v>_2=r^2left(cos heta_1cos heta_2+sin heta_1 sin heta_2cosleft(varphi_1-varphi_2 ight) ight)=r^2cospsi.$

Alors la longueur de l'arc est $s=rpsi=rcos^<-1>left(cos heta_1cos heta_2+sin heta_1sin heta_2cosleft(varphi_1-varphi_2 ight )droit).$

Je compare deux formules dans Matlab, en termes de précision et de temps d'exécution.

Considérons la sphère, en coordonnées cartésiennes :

ou en coordonnées sphériques :

$x = ho sin( heta) cos(varphi) y = ho sin( heta) sin(varphi) z = ho cos( heta)$

Choisissez un tas de points sur la sphère, par exemple :

Calculez maintenant la distance entre chaque couple de points (1,2), (2,3), . (N-1, N).

La première formule est considérée comme plus précise, mais elle est plus lente, la seconde est moins précise aux pôles, mais elle est beaucoup plus rapide. Sinon les deux solutions sont pratiquement équivalentes :


5 réponses 5

L'idée principale est de couvrir tout l'espace occupé par les points avec une grille régulière rectangulaire.

Chaque cellule de la grille contient un petit sous-ensemble de points situés à l'intérieur de la cellule.

Le maillage étant régulier, pour un point donné on peut facilement calculer son indice de cellule (I, J) .

Ensuite, nous recherchons le point le plus proche dans la plage I-1 <= i <= I+1, J-1 <= j <= J+1 .

Si aucun point n'est trouvé, itérer pour tous les index de la plage I-n <= i <= I+n, J-n <= j <= J+n pour n = 2, 3, . , à l'exception des index des étapes précédentes.

Il n'est pas nécessaire d'utiliser la méthode Math.Pow, pensez à utiliser la méthode Pow2 à la place :

Il n'est pas nécessaire de calculer la distance, pensez à utiliser le carré de la distance :

Il n'est pas nécessaire de supprimer des points de la liste source, vous pouvez itérer

Voici le code complet :

Temps d'exécution sur mon PC (en Debug) :

Je n'aime aucune de ces réponses. En particulier, la réponse acceptée est tout simplement fausse.

Commençons par critiquer l'interface :

Le contrat est : la liste doit contenir au moins un élément, la liste est détruite (. ) par la méthode, le premier élément est spécial, et le résultat est une liste mutable. Je n'aime rien de tout cela, cela ressemble à une boule de bugs potentiels. Le bon contrat est :

Regardez combien de problèmes cela résout. Avons-nous besoin que l'ensemble contienne au moins un point ? Non. Nous avons déjà le point de départ. Détruisons-nous l'ensemble des points ? Non, c'est immuable. Etc.

Maintenant que nous avons la signature correcte, l'algorithme est simple :

Maintenant, tout ce que vous avez à faire est d'implémenter efficacement Closest, ce que vous devriez être capable de faire compte tenu des conseils précédents sur le calcul des distances à moindre coût, etc.

Si vous voulez un algorithme plus sophistiqué pour Closest , alors vous devez faire quelques recherches sur ce problème bien étudié :


Les variables de drapeau sont nulles et doivent être évitées. De plus, les variables ne doivent pas être nommées dans ALL_CAPS pour ressembler à des constantes. Tout ce dont vous avez besoin pour sortir de la boucle est une pause.

Vous avez codé en dur les parties du menu à trois endroits :

Toutes les informations du menu doivent être définies au même endroit. Vous pouvez générer par programme la table ASCII à l'aide du package astropy.io.ascii, mais j'ai mis en place une implémentation rapide et simple ci-dessous.

Les instructions if dans la boucle doivent être remplacées par une recherche dans le dictionnaire. De plus, c'est le mauvais opérateur pour utiliser la comparaison de chaînes doit être effectuée en utilisant == . En fait, entrer "done" ne termine pas correctement la boucle, à cause de cela.

Vous avez utilisé + str(0) comme hack pour obtenir un prix se terminant par "0" pour s'afficher correctement. Pour représenter des nombres à virgule fixe, vous devez utiliser une décimale à la place.

Ce programme est suffisamment long pour que ce soit une bonne idée de créer une fonction main().

Les instructions ne doivent généralement pas se terminer par des points-virgules en Python. De plus, PEP 8, le guide de style officiel, spécifie que l'indentation doit être de quatre espaces. Il s'agit d'une convention importante en Python, où l'indentation compte beaucoup.


Voir la vidéo: Invalid syntax error while running scripts solved in Python