Suite

Calculer la valeur à partir d'une équation à l'aide de Field Calculator Python/VB Script


Je voulais calculer une valeur de résultat à partir de 3 champs à l'aide d'une équation.

Les codes VBScript ou Python sont également acceptés… :-)

l'équation est RESULTAT= [(R^2/3)(S^1/2)]/n…


Votre expression semble incomplète mais je suppose que la première partie essaie de trouver le carré de la racine cubique.

Mon test ci-dessous sur celui où R avait une valeur de 8 a renvoyé la valeur attendue de 4 au champ RESULTAT

RÉSULTAT =

[R] ^ ( 2 / 3 )

Ce qui précède a fonctionné lorsque l'analyseur est défini sur VBScript.

Avec Python, il existe, espérons-le, un moyen plus simple, mais je l'ai fait fonctionner avec :

RÉSULTAT =

math.pow(!R!,( float(2) / float(3) ))

Mes tests ont utilisé ArcGIS 10.2.2 for Desktop sur une classe d'entités de géodatabase fichier.

Peut-être que votre expression entière en VBScript est :

([R]^(2/3))*([S]^(1/2))/[n]

Calculatrice GUI utilisant tkinter

Ceci est mon programme python pour une calculatrice graphique réalisée à l'aide du module tkinter. Cela m'a pris environ 2 jours pour terminer. Cependant, je pense toujours qu'il y a place à amélioration. Il me manque quelques autres boutons et je prévois de les ajouter plus tard. De plus, je ne savais pas si je devais utiliser le style par défaut de tkinter ou utiliser le style ttk (ce qui est mieux à mon avis). Néanmoins, j'avais l'habitude d'utiliser le style par défaut juste pour le tester, mais ce style est-il meilleur ou le style ttk est-il meilleur ? S'il vous plaît donnez-moi tous les conseils et astuces que vous pouvez sur ce sujet.


Comment créer une calculatrice d'entrée pour une équation personnalisée? [fermé]

Vous voulez améliorer cette question ? Mettez à jour la question afin qu'elle se concentre sur un seul problème en éditant ce message.

J'ai l'équation : ((A x B) - (C x D)) / (C - B)

Je veux faire une calculatrice qui ressemble à ceci :

Cette capture d'écran est quelque chose que j'ai modifié à partir d'un autre site Web et que j'ai ajusté à ce que je veux que le produit final ressemble également. Fondamentalement, l'utilisateur tape ses numéros dans les cases et appuie sur le bouton de réponse pour révéler la réponse. (à droite du bouton de réponse)

Je ne veux pas nécessairement que quelqu'un le fasse pour moi, car cela peut être difficile, mais je veux apprendre comment c'est fait. Comme je l'ai dit, j'ai modifié un code d'un autre site Web : edit : je ne peux pas poster plus de 2 liens, mais cela ressemble beaucoup à la capture d'écran.

Je ne sais vraiment pas comment faire autrement et je veux apprendre à faire une "calculatrice" comme celle-ci. Vous tapez "A,B,C,D" dans les cases et il résout le problème pour vous. J'ai créé ce programme en Python mais je ne sais pas comment le transformer en ce à quoi je veux qu'il ressemble. Voici un lien vers le code python que j'ai créé avec un ami : https://repl.it/FQJu/2

Je vais essayer de répondre aux commentaires, merci ! aussi s'il vous plaît noter, je suis un novice à ce genre de choses.


Le compilateur interne de Python peut analyser cela, si vous utilisez la notation Python.

Si vous changez légèrement la notation, vous serez plus heureux.

Vous obtenez un arbre de syntaxe abstrait avec lequel vous pouvez travailler.

Vous pouvez utiliser l'analyseur Python :

Il fonctionne mieux qu'un eval pur et, bien sûr, évite l'injection de code !

Où l'analyseur peut être défini à l'aide de PLY, pyparsing, tokenizer intégré, analyseur, ast.

N'utilisez pas eval sur la saisie de l'utilisateur.

pyparsing peut faire ce que vous voulez (http://pyparsing.wikispaces.com/) surtout si les chaînes proviennent d'une source non fiable.

Voir aussi http://pyparsing.wikispaces.com/file/view/fourFn.py pour une calculatrice assez complète construite avec.

Pour souligner les conseils de J.F. Sebastian, les solutions « eval » et même « compilateur » peuvent être ouvertes à de subtiles failles de sécurité. Quelle est la fiabilité de l'entrée ? Avec 'compiler', vous pouvez au moins filtrer des choses comme les recherches getattr de l'AST, mais j'ai trouvé qu'il est plus facile d'utiliser PLY ou pyparsing pour ce genre de chose que de sécuriser le résultat de laisser Python aider.

De plus, le « compilateur » est maladroit et difficile à utiliser. Il est obsolète et supprimé dans la version 3.0. Vous devez utiliser le module 'ast' (ajouté en 2.6, disponible en 2.5 en tant que '_ast').

En accord avec vartec. J'utiliserais SymPy - en particulier, la fonction lambdify devrait faire exactement ce que vous voulez.

pour une très belle explication de cela.

Sage est destiné à remplacer matlab et dans les vidéos d'introduction, il est démontré à quel point les cas similaires au vôtre sont traités. Ils semblent soutenir un large éventail d'approches. Étant donné que le code est open-source, vous pouvez parcourir et voir par vous-même comment les auteurs gèrent de tels cas.


Procédure

Pour calculer les valeurs MSL et stocker les valeurs dans le champ d'une classe d'entités, suivez les instructions fournies ci-dessous.

  1. Préparez la carte pour la collecte de données dans ArcMap. Pour plus d'informations, reportez-vous à Collector for ArcGIS : préparez vos données dans ArcGIS Desktop.
  2. Configurez une classe d'entités pour stocker les champs du système mondial de navigation par satellite (GNSS). Ajoutez les champs manuellement à l'aide du workflow recommandé par Esri. Pour plus d'informations, reportez-vous à Collector for ArcGIS : Configurer un service d'entités pour stocker les métadonnées GPS. Vous pouvez également utiliser le script de GitHub : Add GNSS Metadata Fields .
  3. Collectez les données de terrain souhaitées à l'aide de Collector for ArcGIS. Pour un exemple de workflow sur la collecte de données de terrain, l'enregistrement et le partage des données, reportez-vous à Collector for ArcGIS : Collecter des données.
  4. Ajoutez les données collectées à l'étape 3 à ArcMap.
  5. Pour transférer les valeurs d'altitude aux valeurs z de la géométrie, ajoutez les données collectées en tant qu'entrée pour le ProjetZ outil.
    1. Téléchargez la boîte à outils CollectorUtils.
    2. Du Catalogue fenêtre, connectez-vous au dossier contenant la boîte à outils.
    3. Ouvrez le ProjetZ outil.
    1. Saisissez les paramètres requis, comme indiqué ci-dessous, et cliquez sur d'accord.
      • Fonctionnalités d'entrée
      • Système de coordonnées en entrée (des valeurs x, y, z)
      • Coordonnées de la valeur X
      • Coordonnées de la valeur Y
      • Coordonnées de la valeur Z
      • Jeu de données ou classe d'entités en sortie
      • Système de coordonnées en sortie

    L'image ci-dessous montre les champs de paramètres pour la saisie.

    1. Téléchargez le fichier le*binaire GEOID12B correspondant ici. Déterminez la grille appropriée à l'aide de cette image.
    2. Ajoutez le fichier GEOID12B .bin téléchargé à ArcMap en créant une connexion au fichier dans le Catalogue fenêtre et en faisant glisser le fichier .bin vers la fenêtre cartographique.

    1. Projetez le fichier GEOID12B .bin dans le même système de coordonnées que les données à l'aide du Raster de projet outil. Le fichier .bin se projette à la volée lorsqu'il est ajouté à la carte, ce qui peut ajouter un certain degré d'imprécision à la hauteur du géoïde si la couche n'est pas reprojetée.
    1. Utilisez le Extraire des valeurs en points outil pour générer des valeurs de géoïde spécifiques pour les données collectées avec Collector for ArcGIS.
    1. Ouvrez le Ajouter le champ et ajoutez un champ avec les informations suivantes pour stocker les valeurs MSL dans la classe d'entités en sortie de l'étape 9. Reportez-vous à ArcMap : Ajout de champs pour plus d'informations.

    • Nom du champ : MSL_Elevation
    • Type : Double
    • Précision : 50
    • Échelle : 10
    1. Utilisez les expressions suivantes dans Calculateur de champ pour sortir les valeurs MSL dans le champ créé à l'étape 10.
    • En utilisant Python (et la hauteur d'antenne donnée = 1 mètre):
    • En utilisant VB Script (et la hauteur d'antenne donnée = 1 mètre):


    Compte tenu de la mauvaise indentation du code d'origine, je suppose que vous vouliez publier un code qui ressemble à ceci

    Je vous suggère d'utiliser un IDE ou un linter, qui signaleront tous deux les problèmes de syntaxe dans le code.

    L'idée derrière le code peut être résumée comme

    C'est une bonne structure à avoir. Vous avez trois limites claires et vous avez réparti le travail de manière appropriée. Vous pouvez rendre cela explicite avec des fonctions bien nommées. je le présenterais comme ça

    L'avantage de ceci est que votre code pour calculer le montant de la taxe à payer est facile à utiliser dans un autre module python.

    Si nous regardons comment l'impôt est calculé, le schéma est très clair. À chaque tranche d'imposition, nous soustrayons un montant, multiplions par un pourcentage et rajoutons un montant

    Nous pourrions modifier le code pour déterminer d'abord la tranche d'imposition dans laquelle se situe le revenu, puis calculer le montant de l'impôt. Bien que cela ne semble pas mieux maintenant, il sera bénéfique d'explorer cette voie.

    Puisque ce code répété semble maintenant un peu plus facile à gérer, transformons-le en boucle. Je vais laisser les détails de côté car il y a quelques fonctionnalités de python qui pourraient être nouvelles pour vous et qui valent la peine de chercher vous-même.

    Nous devrions probablement inclure des vérifications de cohérence au cas où quelqu'un changerait les valeurs de manière incorrecte. À titre d'exemple, nous pourrions vérifier que chaque coupure est plus grande que la précédente.

    Notez que ce code est un peu plus dense que l'original, et je ne sais pas si je recommanderais d'utiliser une boucle. Si le code d'origine devient un jour plus complexe, c'est ainsi que j'essaierais de le simplifier. Mais jusque-là, je laisserais les déclarations explicites if/elif/else dans la suggestion précédente.

    La logique ici est assez solide. J'hésiterais beaucoup à changer. La seule chose que je n'aime pas, c'est l'int, car il est parfaitement raisonnable de gagner une fraction d'unité de la monnaie.

    Il existe de nombreuses façons de coder ce type de fonction. Voici une alternative qui supprime quelques pièces inutiles.

    Bonjour @AMG_ et bienvenue dans la revue de code.

    Une bonne chose ici est de vérifier que l'entrée de l'utilisateur est un nombre. C'est une bonne habitude de toujours supposer que la saisie de l'utilisateur est interrompue et de lui donner une indication de ce qui ne va pas. Vous pouvez également effectuer d'autres validations à ce stade. Que se passe-t-il si, par exemple, ils entrent un nombre négatif ? Au fait, bien que python prenne en charge try . sauf . sinon, l'autre est un peu une fonctionnalité de niche. C'est plus courant, et donc plus facile pour les programmeurs python de voir que c'est correct, si vous mettez le break à la fin de la section try.

    Une cause de préoccupation est les nombres magiques dans ce code. Si, disons, le gouvernement change le seuil de 0,19 de 37k à 38k, vous devez vous rappeler de changer le 37000 dans sa propre bande et dans la bande 90000. De plus, parce que je connais l'idée derrière les taux marginaux d'imposition, je sais à quoi 20797 est censé faire référence. Même si j'en suis conscient maintenant, je ne vérifie pas si le calcul est exact. Si le gouvernement changeait la tranche d'imposition de 37000, tous ces chiffres devraient changer et il serait terriblement facile d'en manquer un.

    Ce code serait plus facile à gérer s'il y avait une liste de seuils en un seul endroit et que la contribution des tranches d'imposition inférieures était calculée par le code plutôt que codée en dur.

    Je diviserais le morceau de code qui calcule la taxe en une fonction. Il est généralement considéré comme une bonne pratique de séparer le code qui effectue l'interaction de l'utilisateur (affichage et analyse au clavier) du code qui effectue les calculs. Le comportement serait le même, mais il est beaucoup plus facile de suivre ce qui se passe.


    1 réponse 1

    Tu y es presque. Pour l'argument de symétrie : notez d'abord que la loi de Faraday, $oint extbf cdot d extbf=-frac

    $, ressemble à la loi d'Ampère de l'électrostatique : $oint extbfcdot d extbf=mu_0 I$.

    Considérons maintenant un courant (ou une densité de courant homogène) pointant dans la direction $x_3$ positive. Quelle est la direction du champ magnétique qu'un tel courant produirait ? En effet, en utilisant la règle de la main droite (ou l'un de vos arguments de symétrie préférés), il s'ensuit facilement que le $ extbfLe champ $ entoure le courant, c'est-à-dire qu'il est symétrique autour de l'axe $x_3$ et pointe dans le sens inverse des aiguilles d'une montre. J'espère que vous connaissez les symétries des champs magnétiques produits par des courants constants.

    Comparez maintenant la forme des lois de Faraday et d'Ampère. Parce que les lois se ressemblent exactement, il est facile de voir que le champ électrique dû à une diminution du flux dans la direction $x_3$ aura la même symétrie qu'un champ magnétique dû à un courant (densité) dans la $x_3$ - direction. D'où ici le $fLe champ $ sera également symétrique autour de l'axe $x_3$ et pointera dans la direction azimutale ! (Il pointera dans le sens des aiguilles d'une montre si le flux augmente, mais cela découlera du calcul.)

    Par conséquent, nous pouvons effectuer le calcul exactement comme vous l'avez fait, ce qui donne

    $ extbf=-frac<2>frac

    hat$ comme vous l'avez noté. (Ici $ extbf(t)=B(t) hat_3$.)

    Notez que dans votre calcul, vous aviez déjà supposé que $ extbf$ est dans la direction $hat$ quand vous avez dit que $2pi r |vec| = int_ vec dvec$, puisque cela suppose que $f$ et $df$ sont parallèles.

    La dernière chose à noter est que votre calcul est valable lorsque votre contour $gamma$ est dans le cercle $A$ où le flux change. Soit $R$ le rayon de $A$. Si $gamma$ est en dehors de $A$, alors il enferme tout le flux, donc $frac

    =pi R^2frac
    $ de sorte que pour $r>R$ nous obtenons

    qui disparaît joliment sous la forme $r ightarrow infty$.

    Enfin, notez que si nous calculions le champ magnétique produit par une densité de charge volumique $ extbf=J_0chapeau_3$ avec $J_0$ constant, et remplacé dans notre réponse $J_0$ par $-frac<1>frac

    $, nous obtiendrions exactement le champ électrique ci-dessus.


    5 réponses 5

    Si l'ellipse est centrée à l'origine, l'équation de l'ellipse est $frac+frac=1$. L'équation de la droite est $y=x an heta $ Donc vous avez $frac+frac<(x an heta )^2>=1$ ou $x=pm frac>$ où le signe est + si $ -pi/2 lt heta lt pi/2$

    Vous pouvez également utiliser des équations paramétriques :

    Où $a$ est le rayon sur l'axe horizontal et $b$ est le rayon sur l'axe vertical.

    Si l'ellipse est centrée sur $(0,0)$, $2a$ de large dans la direction $x$, $2b$ de haut dans la direction $y$ et l'angle que vous voulez est de $ heta$ à partir du axe $x$ positif, les coordonnées du point d'intersection sont $left(frac>,frac> ight) ext< if >0le heta< 90° ext< ou >270°< hetale360°$ ou $left(-frac>,-frac> ight) ext< if >90°< heta< 270°.$

    Je travaille sur celui-ci depuis un certain temps maintenant parce que j'essayais de tester une coordonnée pour le chevauchement avec une ellipse, et j'ai trouvé quelque chose de beaucoup plus facile pour trouver le point sur une ellipse étant donné un angle par rapport au centre. Si vous utilisez une équation générale du premier degré pour la ligne et que vous la remplacez par une ellipse dans l'équation, vous pouvez résoudre x et y (les points où la ligne intercepte l'ellipse).

    Pour trouver l'équation générale du premier degré d'une droite, vous pouvez utiliser cette formule : $(y_1 - y_2)*x + (x_2 - x_1)*y + (x_1*y_2 - x_2*y_1) = 0$

    Puisque l'ellipse est centrée sur l'origine et que la ligne la traverse également, vous pouvez simplifier l'équation de la ligne en substituant $x_1 = 0$ et $y_1 = 0$ et vous obtenez : $-y_2*x + x_2*y = 0$

    Résolvez pour x et y et vous obtenez $x = frac , y = frac$

    Ensuite, utilisez l'équation pour une ellipse $frac + frac = 1$ et remplacez en x et y et résolvez pour $y^2$ et $x^2$ respectivement. Vous obtenez ces deux équations : $y^2 = frac <(b^2*x_2^2 + a^2*y_2^2)>, x^2 = frac$ Si vous connaissez le point sur la droite, vous pouvez le remplacer par $x_2$ et $y_2$, mais puisque tout ce que nous avons est un angle, nous devrons re-dériver notre équation de droite. Ce n'est pas difficile cependant. Pour trouver les coordonnées x et y d'un point à l'aide d'un rayon (dont nous n'aurons pas besoin) et d'un angle, il suffit d'utiliser un peu de trigonométrie. La valeur x du triangle est $r*cos< heta>$ et la valeur y est $r*sin< heta>$. Remplacez-les par $x_2$ et $y_2$ ci-dessus et vous obtenez $-rsin< heta>*x + rcos< heta>*y = 0$. Notez que vous pouvez maintenant diviser par le rayon pour le supprimer de l'équation, nous laissant avec $-sin< heta>*x + cos< heta>*y = 0$. Re-substituez dans l'équation précédente et vous obtenez $y = sin< heta>$ et $x = cos< heta>$. Remplacez-les dans les équations pour $y^2$ et $x^2$ et vous obtenez les équations suivantes. $y = pmfrac>)^2 + (asin< heta>)^2>> , x = pmfrac>)^2 + (asin< heta>)^2>>$

    Vous connaissez maintenant une autre formule pour trouver les coordonnées d'un point sur une ellipse étant donné qu'un angle par rapport au centre, ou pour déterminer si un point est à l'intérieur d'une ellipse ou non en comparant les rayons. )


    Vous devriez réfléchir davantage à la façon dont vous organisez et stylisez votre code. De plus, vous devez connaître la méthodologie DRY et éviter de répéter le code dans la mesure du possible.

    J'ai apporté quelques modifications à votre code. Principalement, j'ai nettoyé l'arrangement et le style. Après cela, j'ai ajouté une classe Ohm - qui place toutes vos fonctions liées à Ohm en tant que méthodes (encore une fois pour la propreté du code):

    Après cela, j'ai changé la façon dont vous générez le bloc de texte à partir d'un ensemble d'instructions d'impression en 1 instruction d'impression multiligne :

    Après cela, j'ai ajouté un appel à int() sur l'appel choice = raw_input(. ) afin que toutes les entrées soient dérivées vers un entier. Après cela, nous initialisons notre classe Ohm sur une variable Ohm. Ensuite, au lieu d'avoir plusieurs définitions pour i , r , v et w - nous demandons si le choix est dans une liste, définissons i/r/v/w. Cela réduit la quantité de code dupliqué :

    Après cela, nous continuons avec un bloc if/else qui appelle la fonction en fonction de l'entrée utilisateur. Notre i/v/r/w devrait déjà être défini dans le bloc ci-dessus. Un changement majeur ici est que nous n'imprimons plus directement à partir d'ici. Au lieu de cela, nous définissons la sortie dans une variable de sortie, que nous utiliserons plus tard pour imprimer.

    Enfin, nous vérifions si la variable de sortie est None. Si ce n'est pas None, alors nous l'imprimons, sinon nous imprimons une erreur. Quant à votre erreur "drôle", rappelez-vous que les messages d'erreur doivent être informatifs (c'est-à-dire qu'ils doivent indiquer à l'utilisateur final où l'erreur s'est produite et/ou pourquoi elle s'est produite) :


    3 réponses 3

    Pour créer la table avec un seul appel à awk :

    Comment ça fonctionne

    Les données du fichier sont fournies comme argument pour awk deux fois. Par conséquent, il sera lu deux fois, la première fois pour obtenir le total, qui est stocké dans la variable s , et la seconde pour imprimer la sortie. En regardant les commandes plus en détail :

    NR est le nombre total d'enregistrements (lignes) que awk a lus et FNR est le nombre d'enregistrements lus jusqu'à présent depuis le fichier actuel. Par conséquent, lorsque FNR==NR , nous lisons le premier fichier. Lorsque cela se produit, la variable s est incrémentée de la valeur de la deuxième colonne. Ensuite, next dit à awk d'ignorer le reste des commandes et de recommencer avec l'enregistrement suivant.

    Notez qu'il n'est pas nécessaire d'initialiser s à zéro. Dans awk , toutes les variables numériques sont, par défaut, initialisées à zéro.

    Si nous atteignons cette commande, alors nous traitons le deuxième fichier. Cela signifie que s contient maintenant le total de la colonne 2. Ainsi, nous imprimons la colonne 1, la colonne 2 et le pourcentage, 100*$2/s .

    Options de format de sortie

    Avec printf , un contrôle détaillé du format de sortie est possible. La commande ci-dessus utilise le spécificateur de format %s qui fonctionne pour les chaînes, les entiers et les flottants. Trois autres options qui pourraient être utiles ici sont :

    %d formate les nombres sous forme d'entiers. Si le nombre est en fait à virgule flottante, il sera tronqué en un entier

    %f formate les nombres en virgule flottante. Il est également possible de spécifier des largeurs et des décimales comme, par exemple, %5.2f .

    %e fournit une notation exponentielle. Cela serait utile si certains nombres étaient exceptionnellement grands ou petits.

    Faire une fonction shell

    Si vous comptez l'utiliser plus d'une fois, c'est un inconvénient de taper une longue commande. Au lieu de cela, créez une fonction ou un script pour percer la commande.

    Pour créer une fonction appelée totaux , exécutez la commande :

    Avec cette fonction définie, les pourcentages pour un fichier de données appelé data peuvent être trouvés en exécutant :