[HN Gopher] Doing Symbolic Math with SymPy
___________________________________________________________________
Doing Symbolic Math with SymPy
Author : signa11
Score : 112 points
Date : 2021-01-08 10:50 UTC (12 hours ago)
(HTM) web link (lwn.net)
(TXT) w3m dump (lwn.net)
| ivan_ah wrote:
| +100 this; SymPy is the best!
|
| One of the coolest things about SymPy is the Live Shell, that
| let's you try basic calculations (without plotting) in the
| browser: https://live.sympy.org
|
| There is even an option to send the entire session encoded as URL
| querystring which makes it tweetable, emailable, etc. e.g.
| https://live.sympy.org/?evaluate=factor(x**2%2B5*x%2B6)%0A%2...
| (to generate the session-as-querystring for your current
| live.sympy.org session, use the thumbtack button below the
| prompt)
|
| I use this very often to send calculations and solutions--not
| only do you get the answer, but you see all the calculations.
| ivan_ah wrote:
| Here is a short tutorial of the SymPy APIs that are relevant
| for high school math (equations, algebra, functions, etc.) and
| first-year university (mechanics/calculus/linear algebra):
| https://minireference.com/static/tutorials/sympy_tutorial.pd...
| jupdarter wrote:
| I've had similar problems as others posting here have. To be
| honest when I've had to do symbolic math at work (usually some
| combination of computational geometry and PDEs), I typically fall
| back to maxima or Mathematica (if my collaborators also have
| licenses). Those systems are quite solid and very mature when it
| comes to symbolic work, and I never saw any value in using SymPy
| since I can get to maxima from Python via Sage. I will admit
| though: I tend to not do that since I'm usually pretty happy in
| maxima or Mathematica directly and don't see a reason to
| complicate things with a layer of Python. I taught a course a
| couple years back where I tried to use sympy since we were using
| a bunch of other Python tools (numpy, scipy, etc...), and the
| sympy part felt very awkward. I think I remember showing the
| students maxima and Mathematica to convince them that computers
| really could do complex symbolic work and not to get too turned
| off by the Python tools.
| prof-dr-ir wrote:
| SymPy is fantastic and impressive and I am a fan. It however does
| few things better than the program it is directly trying to
| compete with, namely Mathematica. This gives me scary flashbacks
| to the early 'Linux on the desktop' advocates, whose main
| argument was that it was all 'free' in every sense of the word.
| As we know now, that simply was not enough to switch the majority
| of users.
|
| Do people see a space where SymPy can realistically flourish?
| prionassembly wrote:
| It runs on a google colab tab that you can spin up pressing
| "ctrl-T" in any available computer.
| svantana wrote:
| Sure, but if you want fast easy math, it's hard to beat
| wolfram alpha, where you can just enter something like "solve
| x^2+5a=y for x" and get the answer right away.
| prionassembly wrote:
| It's really not. WA is good at getting natural language
| questions but gives you next to no control on the outputs.
|
| Last time I used sympy I had a complicated function on many
| variables and wanted to plot certain specific 2D contours.
| I was distant from any computer with numerical/programming
| tools and needed to add them to a PPT deck last minute.
| kavalg wrote:
| Maybe as a basis for something like an open source
| Photomath[1]. I noticed that kids use it a lot in my community.
| And it is not only to cheat at homeworks :)
|
| [1] https://photomath.app/en/
| xvilka wrote:
| Maxima plus Sage Math wrappers works more appropriately, I
| think. Though I would prefer a faster language than Python for
| such systems. Something like Sage but with Julia.
| fdej wrote:
| Nemo (http://nemocas.org/) and Oscar
| (https://oscar.computeralgebra.de/) are such projects.
| However, they are focused on algebra and have no support for
| expression manipulation, symbolic integration and the like.
| ChrisRackauckas wrote:
| For symbolic manipulation and all of that,
| ModelingToolkit.jl (https://mtk.sciml.ai/dev/) is the
| project, and it's getting SymEngine-like speeds in about a
| day or so. There's still more to do, but where this shines
| is the connection to numerical computing, i.e. partially
| solving models and then spitting out optimized parallelized
| code for the ODE solver for the other half of the model.
| Qem wrote:
| As SymPy is pure Python, if you need speed, you can run it
| under Pypy just-in-time compiled implementation of Python.
| fdej wrote:
| I think SymPy already flourishes in its space: it's a great
| tool for users who need some computer algebra functionality
| with the ability to glue that together with other code (thanks
| to Python). It's fine as long as you don't need high efficiency
| or specialized functionality.
|
| Mathematica has no serious competition as a general-purpose
| symbolic system. I guess Maple is the closest runner-up, but
| it's more narrowly focused on computer algebra. Most people
| only need a fraction of Mathematica to get their work done,
| though.
| Enginerrrd wrote:
| I use it in Jupyter notebooks for civil and structural
| engineering calcs. The reason is simple: I can print
| expressions and manipulate the expression with a guarantee that
| my calcs conform to the pretty printed ones. This allows non-
| programmers (senior engineers) to check the work on the
| engineering side with some additional assurances that the
| calculation is going to be correct compared to just inputting
| the expression in python seperately from the pretty printing
| process.
| rwlincoln wrote:
| Andes, a Python package for power system simulation, uses SymPy
| now. In previous versions, computing the derivatives for dynamic
| models was done using complex equations written out manually.
| SymPy greatly simplifies the process of adding custom device
| models, which power companies often wish to do.
|
| https://andes.readthedocs.io/
| jbarrs wrote:
| I'd like to give an alternative perspective on SymPy. Whilst I'm
| not familiar with Mathematica, and therefore cannot draw
| parallels between the two, I've used SymPy for a number of years
| and found it to be really useful. I was initially introduced to
| it as part of a first year programming module in a Physics
| degree, and it was more than sufficient for that use-case; for
| that use-case, it absolutely wasn't worth paying for something
| like Mathematica. When combined with a graphical REPL (some may
| use Spyder, I personally use jupyter-qtconsole) or a Jupyter
| Notebook, it becomes really quite useful as it incorporates LaTeX
| rendering to make its outputs more readable and a little less
| daunting. Whilst the syntax may not be optimal for the
| mathematical way of working, for many problems like simple
| rearrangements, automatic simplification, checking equivalences,
| etc. it is almost always the first tool I reach for. The syntax
| is just cosmetic, and I use Python enough that the syntax doesn't
| even bother me, either. It does its job well, and it's helped me
| solve and verify solutions for a number of mathematical problems
| during my degree. Admittedly, I do run into the occasional
| problem here and there where there are obviously better tools
| available, but that's the same with any gratis vs paid solution.
| In most cases, SymPy does a sufficiently good job.
| spuz wrote:
| The article mentions qtconsole interface. Does anyone know how to
| install and run this interface? I could not find such information
| either on the linked page or the SymPy docs.
| thatcherc wrote:
| Worth noting that Julia's SymPy binding [1] is pretty pretty nice
| to work with too. If anyone's looking for big Julia project, I
| think a symbolic math package written fully in Julia would be a
| really exciting development. As far as I know, there isn't one
| yet. The better-known symbolic math packages for Julia still use
| bindings to C++ (SymEngine.jl [2]) or Python (SymPy.jl, Symata.jl
| [3]).
|
| [1] - https://github.com/JuliaPy/SymPy.jl
|
| [2] - https://github.com/symengine/SymEngine.jl
|
| [3] - https://github.com/jlapeyre/Symata.jl
| ChrisRackauckas wrote:
| ModelingToolkit.jl is a symbolic math package written fully in
| Julia (with a bunch of extra symbolic-numerics features)
|
| https://github.com/SciML/ModelingToolkit.jl
|
| https://mtk.sciml.ai/dev/tutorials/symbolic_functions/
|
| It's more like SymEngine in terms of completeness right now,
| though there's a good amount of simplification and equation
| solving built in. It's still growing, it's not at SymPy yet,
| but it's moving fast.
| carapace wrote:
| I did a fun thing with Sympy for Advent of Code 2017 December
| 3rd, here's a Jupyter notebook if anyone's interested:
| https://osdn.net/projects/joypy/scm/hg/Joypy/blobs/tip/docs/...
|
| The puzzle involves a weird "spiral" RAM:
|
| > You come across an experimental new kind of memory stored on an
| infinite two-dimensional grid.
|
| > Each square on the grid is allocated in a spiral pattern
| starting at a location marked 1 and then counting up while
| spiraling outward.
|
| The problem is to compute "the Manhattan Distance between the
| location of the data and square 1" for any given square.
|
| While working on this I came up with the following equation:
| from sympy import floor, lambdify, solve, symbols k
| = symbols('k') E = 2 + 8 * k * (k + 1) / 2
|
| Sympy figures out that this reduces to E = 4k(k + 1) + 2
|
| I needed a function to solve for k given some n... Sympy can do
| that. Take a new symbol `n`, subtract it from the equation `E`, 0
| = 4k(k + 1) + 2 - n and solve for `k`. There are two solutions
| because the equation is quadratic so it has two roots.
| n = symbols('n') g, f = solve(E - n, k)
|
| In the context of the puzzle we only care about the larger root:
| (sqrt(n - 1) / 2 - 0.5) + 1
|
| For reasons, I need to take the _floor_ and add 1. Then Sympy can
| _lambdify_ it and create a fast Python function to compute `k`,
| given `n`: F = lambdify(n, floor(f) + 1)
| for n in (9, 10, 25, 26, 49, 50): print(n, int(F(n)))
| 9 1 10 2 25 2 26 3 49 3
| 50 4
|
| I'm sorry that it's hard to follow, I'm just excited to share how
| cool it was to let the computer do the symbolic math for me.
| stochastician wrote:
| I want to encourage people to think of sympy not just as a
| competitor to Mathematica but additionally as an incredibly
| valuable library that can be used _inside_ of other projects.
| Sometimes, you just want to compute an antiderivative, or you
| want user-supplied functions that you can manipulate easily, or
| you want to do some actual algebra.
|
| Think of it less as a Mathematica replacement (like "Linux on the
| Desktop") and more as a crucial library enabling a lot of fun new
| creative things (like "embedded linux running on your toaster").
|
| For example, in some of my computational chemistry work we use it
| to allow users to specify certain functionals, which we can then
| manipulate symbolically, do expression reduction and elimination
| on, and prove certain properties about. It's great!
| adenozine wrote:
| This may be a stretch, but can you point to any examples or
| articles about using SymPy outside of a strictly mathematical
| context?
| dang wrote:
| If curious see also
|
| a few weeks ago https://news.ycombinator.com/item?id=25254648
|
| 2020 https://news.ycombinator.com/item?id=23747133
|
| 2019 https://news.ycombinator.com/item?id=20287486
|
| Lots in 2014:
|
| https://news.ycombinator.com/item?id=8243452
|
| https://news.ycombinator.com/item?id=8109265
|
| https://news.ycombinator.com/item?id=7214783
|
| https://news.ycombinator.com/item?id=7145219
|
| 2012 https://news.ycombinator.com/item?id=4463471
|
| 2011 https://news.ycombinator.com/item?id=3141699
| mehrdadn wrote:
| The trouble with SymPy is it's, well, buggy. I tried it a few
| years ago, and as soon as I got serious, I quite quickly ran into
| problems that I reported, some of which I now see they apparently
| still haven't gotten around to addressing. [1] [2]
|
| Symbolic math is _hard_ ; they have my sympathies. I don't think
| I could do better. But as long as bugs like these exist, it's
| going to be hard to convince people to switch away from better
| tools like Mathematica.
|
| [1] https://github.com/sympy/sympy/issues/12561
|
| [2] https://github.com/sympy/sympy/issues/12562
| BeetleB wrote:
| Yikes those are bad. As a non-user interested in it, I must
| confess that seeing those issues (especially the 2nd one) makes
| me not want to use it!
|
| I do get that it is a hard problem, but I would then recommend
| they not have an option for "real" if they can't get it right.
| Users will expect it to work (unless the docs point out it is
| unreliable).
| ogogmad wrote:
| > I would then recommend they not have an option for "real"
| if they can't get it right. Users will expect it to work
| (unless the docs point out it is unreliable).
|
| You should be suspicious of using floats and expecting the
| solver to detect if a solution is real. Consider the
| polynomial $x^2 + C$ for $C \approx 0$. Are all of its roots
| real or complex? The problem is that even a very small change
| in C, maybe caused by rounding errors, can easily change a
| root from real to not real.
|
| When solving polynomials, either use complex numbers
| throughout or insist on _exact_ solutions and don 't use
| floats.
| mehrdadn wrote:
| > You should be suspicious of using floats and expecting
| the solver to detect if a solution is real. Consider the
| polynomial $x^2 + C$ for $C \approx 0$. Are all of its
| roots real or complex? The problem is that even a very
| small change in C, maybe caused by rounding errors, can
| easily change a root from real to not real.
|
| C \approx 0?
|
| The imaginary parts in the first bug are nowhere close to
| zero.
| ogogmad wrote:
| I was actually responding to the following claim:
|
| > I would then recommend they not have an option for
| "real" if they can't get it right. Users will expect it
| to work (unless the docs point out it is unreliable).
|
| It can't work reliably if the coefficients of the
| polynomial consist of floats. At least not in general.
| This point is a more fundamental one than your example.
|
| Also, regarding your particular example: When solving
| cubics using the cubic formula, it is often the case that
| you will end up computing with complex numbers even if
| the result ends up real. If you introduce floats into
| this, it's impossible to guarantee that the imaginary
| parts will cancel out completely. Instead, they may
| cancel up to 10^-21 or something like that, which is
| precisely what happens in your example.
| mehrdadn wrote:
| You're missing my point entirely. They _don 't need_ to
| solve this by keeping the variable real at every step or
| anything like that. What they need to do is to ensure the
| final solutions are real. Which means they need to solve
| it in the complex domain entirely and then filter out
| non-real solutions at the end, where they have the final
| magnitudes of the real and imaginary components. The only
| place that would run into trouble is where the imaginary
| components are small but nonzero, where you'd just expect
| it to use some tolerance threshold as the cutoff, but
| that obviously isn't the case in the first example (hence
| my comment).
|
| There's no reason that the algorithm _must_ fail on
| univariate real polynomials if it can 't work equally
| well on arbitrary functions with arbitrary domains. It's
| trivial for a symbolic engine to recognize a univariate
| polynomial. And practically speaking it's _the_ job of a
| computer algebra system to recognize different well-known
| classes of functions and treat them as well as it can.
| What I suspect likely happened here is they 've been just
| so busy dealing with the more general problems (which are
| far more difficult) that they haven't gotten around to
| implementing many better methods for the special cases
| (like polynomials). Which I sympathize with, as I'd have
| virtually no clue how to solve some of the more general
| problems to begin with.
| mehrdadn wrote:
| Yeah. For what it's worth (not sure if it makes you feel
| better or worse...) I've found similarly bad bugs in SciPy
| too.
| BeetleB wrote:
| Curious what those were.
| mehrdadn wrote:
| Here's the one I can find (might not have
| reported/written others so I don't recall them):
| https://github.com/scipy/scipy/issues/7332
|
| I can't tell if I'm just exceptionally good at making
| bugs explode in my face or something, but these are so
| simple that it boggles my mind when I'm the first person
| to report them...
| fractionalhare wrote:
| That's not really a bug, it's just behavior explained by
| numerical analysis. A very small change in the initial
| guess can be the difference between success and a blowup
| for numerical algorithms; particularly rootfinding
| algorithms.
|
| Sometimes this is implementation specific, and is
| numerical instability. Sometimes this is endemic to the
| algorithm regardless of implementation, like Runge's
| phenomenon. Often there is no fix, or the fix would be
| inordinately complicated or only generalize poorly, etc.
|
| In this situation scipy should probably just pop a
| warning.
| mehrdadn wrote:
| I know how numerical stuff works, but no, this is pretty
| inexcusable. See my other comment:
| https://news.ycombinator.com/item?id=25689916
| BeetleB wrote:
| That one seems a bit more reasonable, though. When doing
| numerical computation (as opposed to symbolic), you
| should never assume the algorithm "just works". You need
| to know the quirks of the underlying method, etc. And I
| believe most root finding numerical algorithms will be
| sensitive to the initial guess.
|
| Surprised they haven't added the warning and closed the
| bug.
| mehrdadn wrote:
| Not at all. I've worked on numerical stuff myself; unlike
| the symbolic bugs, I have little sympathy for these
| particular numerical errors. It would be far more
| reasonable if it was convoluted composition of functions,
| or some kind of bizarre numerical edge case. However:
|
| (a) Univariate quadratics are _extremely_ well-understood
| and _extremely_ important. For example, the convergences
| of optimization algorithms (this is root-finding, and
| there are some differences, but they 're not unrelated,
| and this is beside my point) are often proven on
| quadratics first, and _then_ they 're applied to other
| functions.
|
| (b) (x - 1)^2 - 1 is just about the simplest quadratic
| you can possibly imagine that isn't outright lacking in
| other terms (like x^2), and quadratics are pretty much
| the simplest nonlinear functions.
|
| (c) No matter how good or bad your algorithm is, it is
| absolutely trivial to do a few quick tests afterward to
| sanity-check the result, and to return some kind of error
| if it looks wrong.
|
| This isn't some kind of quibbling over a solver that has
| an error of 0.0001 or something. We're feeding in the
| most basic quadratic you can imagine, and the solver is
| telling you with _confidence_ that the solution is 1.01
| when in fact it 's supposed to be 2. It's just
| inexcusable. At the _very_ least (and even this would
| honestly still be woefully lacking), it should be able to
| do the dumbest thing possible, which is to plug that back
| in, and maybe plug in a couple close numbers (maybe + /-
| some epsilon) and see if results change sign or land
| anywhere _near_ zero. In reality there are all kinds of
| tests they could and should be doing to check things like
| concavity and switch to better algorithms, but that 's
| kind of moot when they're not doing the most basic check.
|
| Edit: Actually I could probably say something similar
| about one of the SymPy bugs too (they really shouldn't
| have trouble telling if 0.66 + 0.56I is a real number),
| but one key difference is at least their problem is in
| filtering out _correct_ solutions, not in returning
| completely _wrong_ solutions with full confidence.
| [deleted]
| bee_rider wrote:
| Have you tried out SageMath? It seemed to work pretty well when
| I tried it out, but I never got serious really. My needs for
| symbolic math programming are pretty limited.
| mehrdadn wrote:
| I haven't, though I did download it. I was trying to work on
| an algorithm rather than solve specific problem instances, so
| I ended up just working around it by using different problem
| instances that didn't result in these errors.
| abdullahkhalids wrote:
| SymPy's problem is that it is based on an object-oriented
| language. This results in SymPy (and friends) demanding that
| users abandon hundreds of years of math notation, to conform to
| the whims of a programming language.
|
| In SymPy you do M.diagonalize(), which makes no sense. The matrix
| M does not have a property diagonalize. Rather, you should apply
| a choosen diagonalization algorithm like Diagonalize(M) to
| produce a new matrix.
|
| Mathematica wins, and will continue to win, because the language
| is functional and conforms to how Mathematicians think, rather
| than how (EDIT: certain) programmers like to code.
| vanderZwan wrote:
| > _Mathematica wins, and will continue to win, because the
| language is functional and conforms to how Mathematicians
| think, rather than how programmers like to code._
|
| Or maybe Python "will win" because it conforms to how
| programmers think, rather than forcing them to think like
| mathematicians (also, why capitalize "mathematicians" in your
| sentence?), letting _them_ get _their_ shit done.
|
| More importantly, "win" what exactly? It makes no sense to talk
| about "winning" if you don't even properly define a victory
| condition and context first.
| joshuaissac wrote:
| It depends on who the intended users of SymPy are. If they
| are programmers, then conforming to how programmers would
| think would be useful. If it is targeted at mathematicians,
| then confirming to how programmers think would just be
| another unnecessary hurdle to using the library, and would
| hurt adoption (which is what "win" means here).
| Koshkin wrote:
| > _conforms to how programmers think_
|
| Python is an important tool in general, it allows to automate
| many tasks that otherwise would have to be done manually. I
| wish more _non-programmers_ knew how to use it.
| billfruit wrote:
| May be the way mathematicians notate is frankly ambiguous and
| confusing, and recent decades of programming experience have
| given good insight into more expressive methods of notation.
| enriquto wrote:
| > recent decades of programming experience
|
| as opposed to recent millennia of mathematical experience?
| Koshkin wrote:
| To be fair, the mathematical notation that is familiar to
| us today is just a few hundred years old.
| whimsicalism wrote:
| Let's not pretend math notation has remained constant for
| millennia.
| snakeboy wrote:
| Exactly, it has been _refined_ over millennia.
| creata wrote:
| Right, and it's important to remember that mathematics is
| sharply optimized for _human_ understanding, whereas
| programming languages strike a careful compromise between
| human understanding and efficient execution by machines.
| I don 't think anyone could seriously argue that
| programming languages are "more expressive" than
| mathematical notation, which has the powers of ambiguity
| and hand-drawn graphics.
| Koshkin wrote:
| You are not wrong. Replace 'efficient execution by
| machines' with 'efficient processing by a compiler' and
| you will be even more correct.
| enriquto wrote:
| Of course it has evolved. But some landmarks of it (e.g.,
| using single letters for "variables") have been used
| since 2500 years ago. Now I laugh when programmers tell
| me to be "civilized" and name my matrices with full
| words.
| fn-mote wrote:
| I think this would be a more compelling thread if people
| discussed particulars of ambiguity in notation and how to
| resolve it.
|
| Structure and Interpretation of Classical Mechanics [1] walks
| through ambiguity in physics and math. The first interesting
| note I found was footnote 2 in the preface [2], citing the
| ambiguity in the statement of the chain rule.
|
| I am ignorant about some of the insight coming from recent
| decades of programming and would love to hear it.
|
| [1]: https://mitpress.mit.edu/sites/default/files/titles/cont
| ent/...
|
| [2]: https://mitpress.mit.edu/sites/default/files/titles/cont
| ent/...
| leephillips wrote:
| This is problem I have with Python in general; that even if you
| prefer to use it in a functional style, most libraries are
| written by real Python programmers, and using them will force
| you to grapple with the object-oriented inversion of common
| sense (https://lee-phillips.org/pythonhate/).
|
| My favorite example is: ','.join(['a', 'b'])
| eli_gottlieb wrote:
| You tried Coconut? http://coconut-lang.org/
| leephillips wrote:
| I had not heard of that; it's an interesting project. But
| of course it doesn't address the issue I was talking about,
| which is the OO nature of existing libraries.
| fantod wrote:
| Yeah, the Python language favors an imperative style due to
| the absence of features necessary for writing more
| functionally, like lambdas that can do more than return an
| expression, tail call optimization, and lexical scope. This
| last one, additionally, tends to make people use classes for
| essentially no other reason than that closures don't work
| natively.
|
| > My favorite example is: ','.join(['a', 'b'])
|
| I've always found the discrepancy between this example
| (instance method call), list(('a', 'b')) (technically a
| method call, but resembles a functional call), and
| str.lower('AB') (class method call) to be quite maddening.
| NoThisIsMe wrote:
| Closures do work natively in Python though. Lexical scope
| does not prevent that. Most languages, including functional
| languages, use lexical scope these days.
| creata wrote:
| What's wrong with (','.join(['a', 'b']))? If it's the order
| of arguments, then I want to point out that the order has two
| big advantages:
|
| * partial application is actually useful: I've actually used
| (','.join) before, but (lambda sep: sep.join(['a', 'b']))
| seems relatively useless. That's why Haskell also uses this
| order with (intercalate sep listOfStrings).
|
| * it accepts any iterable, rather than just lists.
| leephillips wrote:
| What strikes me as weird about this is that our intent is
| to do something to the array of strings, so we are looking
| for a function that takes this array and transforms it into
| something else. But we are obligated to invert our
| intuition here, and write this as if we are doing something
| to the punctuation that we want to insert between the array
| elements. It's backwards, and causes us (me, anyway) to
| keep forgetting how to use this method. I must have gotten
| this wrong a dozen times. The sensible way would be
| something like join(array, separator). That is
| straightforward, and would be hard to get wrong. It could
| even be written in a way where the order of arguments
| didn't matter, so you wouldn't even have to remember that.
| Why is the separator privileged as the implicit first
| argument of `join`?
|
| I accept that you've identified some advantages of the
| Python version; it's always possible to find cases where
| object.method() notation gets you something.
| hakuseki wrote:
| > It could even be written in a way where the order of
| arguments didn't matter
|
| Well, 'hello'.join(', ') does not produce the same output
| as ', '.join('hello'), so the order of the arguments does
| matter.
| creata wrote:
| Perhaps they want named arguments so that join(sep=', ',
| strings='hello') and join(strings='hello', sep=', ') are
| equivalent.
| leephillips wrote:
| OK, but I was thinking along the lines of how easy it is
| in (for example) Julia to make methods that dispatch on
| types, so that your function could examine the arguments,
| and if one of them happens to be a single character, and
| the other a string or array, do the sensible thing,
| regardless of the order in which you typed in the
| arguments.
| blt wrote:
| OOP interface is wrong for this functionality. It should be
| a free function. There is no reason it should be restricted
| to strings -- "join" makes sense on any sequence-like
| objects. We should be able to join(Iter1, Iter2[Iter3])
| where Iter* are all arbitrary iterable data types.
| ByteJockey wrote:
| There's no reason you can't do this. Python has free functions.
| It was an intentional style choice to do it this way.
|
| You can also make a diagonalize function that just calls the
| method if you like that style better, half of python's generic
| functions (e.g. len) just call methods anyways.
| [deleted]
| [deleted]
| unionpivo wrote:
| Sympy is great for people who occasionally need such programs.
| Any serious mathematician will have his or her preferred
| software that he uses daily anyway.
|
| Sympy works for people who know programming (not just
| programmers, but researchers in general) who need to use it
| occasionally.
___________________________________________________________________
(page generated 2021-01-08 23:01 UTC)