Ceci est la partie 2 de ma série de programmation sur le package Python swiftexpour écrire des mathématiques dans Jupyter aussi rapidement qu'avec un crayon et du papier. Suivez-moi tout au long du développement et n'hésitez pas à influencer son déroulement en commentant cet article ou tout autre article de la série.
Aujourd'hui, continuons avec les fondations, et bien sûr nous restons avec le style de développement piloté par les tests (TDD). Après cet article, le package doit nous permettre de faire des choses comme ceci :
>>> Int(-oo, oo) * f(x) * dx
Out: \int_{-\infty}^{\infty} f(x) dx
Vous pouvez vous demander pourquoi je n'utilise pas quelque chose comme Sympy pour cela ? Eh bien, le problème est que sympy m'oblige à utiliser une syntaxe fixe. Par exemple, dans sympy , je ne peux pas dire
Mais inverser l'ordre des intégrandes et des différentielles, c'est exactement ce que beaucoup de physiciens aiment écrire des intégrales ! sympy n'est tout simplement pas assez flexible dans l'écriture de la notation mathématique et oblige à pousser sa réflexion vers ce qui est possible avec sympy . C'est un tueur pour tout processus créatif. Donc, le but de mon package est d'avoir quelque chose pour écrire rapidement et facilement une syntaxe mathématique arbitraire .
Commençons par les fonctionnalités d'aujourd'hui. D'abord, prenez soin du signe intégral lui-même. Rédigez le test :
def test_integral_sign_with_limits(self):
expr = Int(-oo, oo)
self.assertEqual(r'\int_{-\infty}^{\infty}', expr)
class Symbol:
def __init__(self, latex_string):
self.latex_string = latex_string
[...]
def __neg__(self):
return Symbol('- %s' % self.latex_string)
class Int(Symbol):
def __init__(self, lower, upper):
super().__init__(
'\\int_{%s}^{%s}' % (str(lower),
str(upper)))
[...]
oo = Symbol(r'\infty')
Afin de rendre la chaîne LaTeX sous forme de formule dans Jupyter, nous devons implémenter deux méthodes dans notre Symbolclasse que Jupyter utilise comme crochets :
from IPython.display import Math, display
class Symbol:
def __init__(self, latex_string):
self.latex_string = latex_string
[...]
def __neg__(self):
return Symbol('- %s' % self.latex_string)
def _ipython_display_(self, **kwargs):
display(Math(str(self)))
def _repr_latex_(self):
return Math(str(self))
Occupons-nous maintenant de l'intégrande. Je dirais que la notion d'attacher simplement un symbole après l'autre est bien représentée par le symbole de multiplication, puisque lorsque vous multipliez deux variables, vous pouvez sauter le point. Inversant cela, nous pourrions dire qu'écrire un point signifie simplement attacher un symbole après l'autre. Nous devons donc implémenter l' *opérateur pour la Symbolclasse. Mais bien sûr, testez d'abord !
def test_attach_symbols(self):
actual = a * b * c
self.assertEqual('a b c', str(actual))
class Symbol:
def __init__(self, latex_string):
self.latex_string = latex_string
[...7
def __neg__(self):
return Symbol('- %s' % self.latex_string)
def __mul__(self, other):
return Symbol('%s %s' % (str(self), str(other)))
def _ipython_display_(self, **kwargs):
display(Math(str(self)))
[...]
Il y a trois autres améliorations que je souhaite apporter dans cet article :
swiftex.abcc'est bien, mais ce n'est pas pratique de devoir définir les différentiels séparément. Les différentiels sont très souvent nécessaires !f(x)comme intégrande. Le problème est la parenthèse, car Python l'interprète comme un appel de fonction Python.(da, db, dc, dd, de, df,
dg, dh, di, dj, dk, dl,
dm, dn, do, dp, dq, dr,
ds, dt, du, dv, dw, dx,
dy, dz) = tuple(
Symbol('d' + s) for s in 'abcdefghijklmnopqrstuvwxyz')
def test_integral_f_of_x(self):
expr = Int(a, b) * f(x) * dx
self.assertEqual(
r'\int_{a}^{b} f \left( x \right) ^{2} dx', expr)
def test_integral_f_of_x_and_y(self):
expr = Int(a, b) * f(x, y) * dx
self.assertEqual(
r'\int_{a}^{b} f \left( x, y \right) ^{2} dx', expr)
class Symbol:
[...]
def __call__(self, *args, **kwargs):
s = self.latex_string + '\\left( '
for i, arg in enumerate(args):
s += str(arg)
if i < len(args) - 1:
s += ', '
s += ' \\right)'
return Symbol(s)
[...]
def test_integral_only_upper_limit(self):
expr = Int('', b) * f(x, y) * dx
self.assertEqual(
r'\int_{}^{b} f \left( x, y \right) ^{2} dx', expr)
def test_integral_only_lower_limit(self):
expr = Int(a, '') * f(x, y) * dx
self.assertEqual(
r'\int_{}^{} f \left( x, y \right) ^{2} dx', expr)
def test_integral_no_limits(self):
expr = Int() * f(x, y) * dx
self.assertEqual(
r'\int f \left( x, y \right) ^{2} dx', expr)
class Int(Symbol):
def __init__(self, lower='', upper=''):
super().__init__(
'\\int_{%s}^{%s}' % (str(lower), str(upper)))
git checkout fb7852a39b095f
Lorsque vous faites une demande à facebook.com, votre ordinateur recherche le nom de domaine pour traduire ce nom de domaine en une adresse IP afin que votre ordinateur puisse établir cette connexion.
Vous devez avoir entendu parler de tous les nouveaux plugins ChatGPT puissants comme le navigateur, l'interpréteur de code, etc. Mais il y a un problème, l'accès aux plugins est limité à une liste d'attente et donc beaucoup n'y ont pas accès.
Ça me frappe tout à coup, comme c'est si souvent le cas C'est à nouveau le milieu du chemin <Non, pas celui du Pacifique, toi marron, celui du carnaval> Chaque gros titre fort… ..
Salut les cyber-amateurs ! Bienvenue à nouveau dans la série OSINT pour la chasse aux menaces. Dans le premier article, je vous ai donné un aperçu d'OSINT et de son importance dans la chasse aux menaces.
(Attention - Ceci est une satire, destinée à être joyeusement subversive - Certainement pas pour les enfants) Vous avez vu votre mère et votre père se cacher dans la cuisine et fumer ces cigarettes malodorantes. Ils vous disent.
Nous avons souvent du mal à mettre en œuvre ce que nous savons être bon pour nous. Qu'il s'agisse de dire à un proche que nous l'aimons ou de se rappeler de parler comme un pirate, il y aura toujours ceux qui prétendent qu'un jour, une semaine ou un mois d'événements ne sont pas nécessaires parce qu'ils font déjà ces choses.