Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I asked about a pytest plugin to watch my test folders and automatically run a test if the files get modified and someone suggested pytest-xdist. It works great but it has the side effect of making "all tests passed" not green when I'm using the follow (-f) option. It does mark things as red though when things go wrong. Is there a way to make it also do green when good?

Also are there any other neat pytest plugins I should know about? I just started using pytest so this is the first one I've used.

Adbot
ADBOT LOVES YOU

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Why not environment module files? They're pretty neat.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Why doesn't this work?

https://repl.it/GMLO/1
code:
class Widget(object):
  def __init__(self):
    self._foo1 = 10
    self._foo2 = {'a_key': 20, 'b_key': 30}

  @property
  def foo(self):
    try:
      return self._foo1
    except TypeError:
      return self._foo2

thing = Widget()

print(thing.foo)
>> 10  # as expected

print(thing.foo['a_key']) 
>> TypeError  # raises TypeError but should return 20, from the dict foo2.
Basically I want a dict/container object that has a default return value when I don't give it an index or key or whatever. If I do then I want it to return the value of that key, which internally in my class is saved as a dictionary.

I guess I could just remove the property decorator and it would work, kind of. I don't want to type "thing.foo()", I just want to type "thing.foo". I could make two properties i guess, but I don't want that either. I want a single "foo" property that could return either things.

What the hell is the point of the property anyway? When I google I only see tutorials for making getters and setters and none of that explains to me why I should even bother.

At the moment I use @property on a class method when I want that docstring to show up in the help/pydoc for that class.

Boris Galerkin fucked around with this message at 12:27 on Mar 8, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

QuarkJets posted:

Thanks for the Miniconda recommendation, it's nice knowing that there is a minimalist version of anaconda out there. But for some reason I'm still having trouble with cmake; it claims to be using the HDF5 libraries and headers in my miniconda area, but it's apparently grabbing my system headers because when I launch my application I get a big gently caress-off warning about a library/header version mismatch (HDF5 at least gives a very thorough warning, as it specifies all of the paths and shows that system headers were used and that miniconda libraries are what is being linked against). This is probably going to require getting a lot more intimate with cmake and/or moc than I'd like

I have this same problem with cmake and HDF5. I'm not sure why but I've heard from others with similar problems as well.

I was able to "fix" the issue with compiling one thing by just exporting HDF5_ROOT with the cmake command: $ HDF5_ROOT=/path/to/hdf5/root cmake ... Hope that helps.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

Dominoes posted:

You're catching the TypeError before it occurs; ie once you've gotten thing.foo, you have no more error checking, and 10 doesn't have any keys.

I figured that might be the reason. I guess the interpreter looks to see if I have a 'thing.foo' and it finds it and returns it, and for all purposes the try part has succeeded (well it technically did succeed)?

Dominoes posted:

@property makes methods look like properties; I think they're for writing Java-style code. I wouldn't use them, since they mask that calculations are being run.

Oh okay. This made me reconsider about using properties to begin with. It just seems a bit weird that Python is "a consenting adults language" where nothing is private and everything can be accessed and used, yet @property exists to seemingly make things read-only.

Dominoes posted:

I'm not sure this is a good idea - you're trying to treat it as two different types of objects based on context. Here's a snippet that does what you ask, although as a function rather than a class.

[snip]

Not sure if this helps, but are you familiar with dict's get method? It'll return a default of your choice if it can't find the key.

Thanks for the effort but that wasn't what I was trying to accomplish. I was thinking more on the lines of having a default answer/response with the option to transparently get a more detailed/specific answer.

Like for example Belgium is also called België, Belgique, or Belgien depending on the language. These are official names that their government recognizes since they speak all of those languages listed, and not "unofficial" names that have been translated into other languages (like London and Londres for Spanish and some other languages).

I don't see any harm or why it's a bad idea to be able to do this:

code:
country = Belgium()

country.name
>> Belgium

country.name['german']
# or country.name('german')
# or country.name.german
>> Belgien
I know I can make "name" a method and my problem would be "solved", but then I'd have to type "country.name()" to get the response "Belgium". Those extra empty parenthesis there are exactly what I'm trying to avoid.

If it's not possible to do this then it's whatever, it's not a big deal. But making name a method isn't the answer I'm looking for.

Boris Galerkin fucked around with this message at 08:38 on Mar 10, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Because you write code to do things for you, not the other way around. Here's my lovely jumping through the hoops example:

https://repl.it/GP2U/0

code:

class Belgium(object):

    _names = {'en': 'Belgium',
             'de': 'Belgien',
             'nl': 'Belgie',
             'fr': 'Belgique',
             'default': 'Belgium'}

    def __init__(self):

        class Name(dict):
            def __repr__(self):
                return self['default']

        self.name = Name(self._names)

country = Belgium()

print('My name is {}'.format(country.name))
# >>> My name is Belgium

print('My name is also {}'.format(country.name['de']))
# >>> My name is also Belgien

I can understand if this isn't something that exists in Python. I can understand that this isn't "pythonic." But I want to understand why it's a bad idea to do this? I mean ignore the fact that I defined Name inside the init or whatever. I have no idea what __repr__ does but from a quick search it seems to be the thing that gets called when I just type the name of the class.

Typing "country.name_in_german" sounds like more of a hoop, and honestly making it a method and having to call "country.name()" is just ugly when 99% of the times I just need the default value. Plus the () implies function so isn't it semantically wrong? I'm not computing anything, I'm just getting something that already exists.

e: nevermind this only half works. __repr__ returns an actual Name object so I can't do things like "country.name+country.name['de']". Sad.

Boris Galerkin fucked around with this message at 09:23 on Mar 10, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Because it was just an example.

e: And also because I come from a procedural/imperative programming background (my first language was Fortran back when it was still FORTRAN [77]) and I've never learned anything else other than modern versions of Fortran and MATLAB so honestly I have no clue what the point of objects are or when and why I should use them.

I just think it's pretty neat to be able to do:

code:

new_tensor = old_tensor.rotate()

Instead of

code:

new_tensor = rotate_tensor(old_tensor, rotation_matrix)

But honestly the only reason I think the first one is neat is because it looks better to me. I really wasn't joking when I said I liked "foo.thing" better than "foo.thing()" because it looks better without the parenthesis (but mostly because I don't think it's semantically correct to call a function to return a value that I've already computed).

Boris Galerkin fucked around with this message at 17:49 on Mar 10, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

QuarkJets posted:

Your points on the first codeblock are very good, and indeed that does look better and work better and it makes sense. But then consider this:

code:
new_tensor = old_tensor.rotate
new_tensor2 = old_tensor.rotate(rotation_matrix2)

For reasons that I can't seem to articulate, this example doesn't make sense to me as something I would do. In my mind it's pretty clear that "rotate" is a function that does the rotation. It's a function, so I would be 100% fine with calling it like a function, eg old_tensor.rotate().

code:
# Call old_tensor to rotate itself against a rotation matrix and return the rotated tensor.
new_tensor = old_tensor.rotate()

# Call old_tensor to retrieve an already rotated tensor and return it.
# ... Maybe I pre-computed the rotated tensor in __init__ for better memory management.
# ... Maybe when I called the rotate() method it also saved a copy of it for retrieval later.
new_tensor2 = old_tensor.rotated
I appreciate all the help guys. It looks like my way of thinking about things might be wrong. If anything the insight is really helpful to me and I'm learning about things outside of my familiar box so that's not a bad thing at least.

Thermopyle posted:

Anyway, do you ever split your code into different files for reasons other than language-mandated reasons? The general reason you'd do that is one of the general reasons you'd use objects.

Yep of course. I split my code/functions into separate files/modules in a way that makes sense (e.g., functions that act on tensors go in tensors.py). I'm just having a hard time seeing the practical difference between these two though:

code:
def rotate_tensor(tensor, rotation_matrix):
    A = tensor
    Q = rotation_matrix
    return Q*A*transpose(Q)

new_tensor = rotate_tensor(old_tensor, some_matrix)
vs

code:
class Tensor(object):

    def __init__(self, tensor, rotation_matrix):
    self.A = tensor
    self.Q = rotation_matrix

    def rotate(self, rotation_matrix=None):
    Q = rotation_matrix or self.Q
    return Q*self.A*transpose(Q)

old_tensor = Tensor(a_numpy_ndarray, rotmat)
new_tensor = old_tensor.rotate()
They both do the same thing. It's just more elegant looking to be able to call a rotate() method I think, but at the end of the day all I really care about is that the rotate method or rotate_tensor function gives me back a properly rotated tensor. Plus it's neat that I can assign the rotation matrix to the object already and not have to worry about passing the rotation matrix around anymore. That's the really cool part for me.

quote:

You talking about your background makes me think you might like learning Elm, as it's completely different from what you'res used to for completely different purposes, and it'll really expand your mind about what you can do with Python as you can implement a lot of the same functional ideas in Python.

Neat, I'll check it out.

e:

quote:

Of course, OOP is full of stupid ideas as well. It's a good idea to become familiar with different paradigms like OOP, functional, etc so you don't end up just using what you know and missing out on better ways to solve problems.

Yep this is what I'm trying to do as well. I'm not making any claims about one way being better or whatever. I'm just drawing from experience: this is how I learned to do things, this is how I've always done things. I had to pick up Python to work on a project, and I'm honestly trying my best to learn how to do things "properly" with Python instead of trying to shoehorn in how I'd do things with C. So basically all of my questions are probably a mixture of "how do I do this in Python" and "why do I need to do it like this in OOP". I try to keep the OOP specific things out of here though.

Boris Galerkin fucked around with this message at 12:37 on Mar 12, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Is it okay to do something like this:

code:
class Beer(object):

  def __new__(type, *args, **kwargs):
    BEERS = {'ipa': BeerIPA, 'stout': BeerStout}
    return BEERS[type.lower()](*args, **kwargs)

  def some_shared_beer_methods(...):
    # do things

class BeerIPA(Beer):

  def __init__(self, *args, **kwargs):
    pass

  def ipa_specific_methods(self):
    # do other things

class BeerStout(Beer):
  pass
I think the proper term is using the __new__ constructor as a factory function? Is this an accepted way to do something or is this one of these things I shouldn't do in python?

e: Silly example aside in the real case I wrote the base class as an interface layer to other classes. It's not actually meant to be instanced directly but I have a few subclasses deriving from it that implement actual functionality. At the moment I have a module level getter function that's just more or less the __new__ method shown above. It's just more convenient and user friendly though I think to be able to instance an object by doing "beer = Beer('ipa', args)" instead of "beer = get_beer('ipa', args)". I want to avoid instancing the actual subclasses directly.

e: vvv What's the proper way to do it then?

Boris Galerkin fucked around with this message at 12:40 on Mar 18, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Thanks guys, I'll just stick with having a separate get_class_thing(...) function. It's what I had before but then I found out about __new__ and thought maybe I could just overwrite it.

Another question: I'm using sphinx to document things and in some of my methods I have latex math syntax, e.g
code:
def foo(self):
"""Returns foo.

Foo is defined as:

.. math::

    \mathbf{A} \cdot \mathbf{v} = \bar{\mathbf{x}}_\mathrm{text} + \nabla^2(\mathbf{y})
In the html versions of my docs this gets turned into mathjax so it looks nice. When I do 'pydoc foo' at the command line I get exactly what you see above. I want it to show this instead though:

code:
A*v = x_text + (nabla(y))^2
So I guess what I'm asking for is if there's some kind of preprocessor for pydoc that will rewrite math directives for me. I imagine there would be some kind of mapping involved, i.e., in the above I basically say "strip the mathbf, bar, and mathrm commands, turn cdot in *, keep _ literally, and somehow logic that \nabla^2(y) means raise my nabla operator to the power 2."

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
https://github.com/python/cpython/blob/3.6/Lib/collections/__init__.py

code:

    def __init__(*args, **kwds):

        [snip]

        self, *args = args

Is there a reason ever to write code this way like the init method of OrderedDict? Why wouldn't you explicitly write out "self" as the first argument?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
So if I'm understanding this right, it lets me use self as a keyword argument and nothing more?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Thanks for the responses guys. It was interesting to read about.


I just downloaded PyCharm to give it a try because the refactoring tools looked really cool. How do I get it to work nicely with both .rst and .py files? I think it's treating my .rst files in my ./docs/source folder as Python files because the inspector keeps giving me warnings about missing docstrings or encodings etc.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I need to be able to inject a function into a class when the object gets created, and I've found two ways of doing it: 1) I could play around with meta classes and make my metaclass do it for me (possible since I have all the inputs), or 2) I could use the "MethodType" class from the types module.

I kinda like the second choice because it seems much easier and way more intuitive to be able to just do

code:

self.foo = types.MethodType(module.foo, self)

But a lot of what I'm finding on the web suggest to use metaclasses without really saying why. Is there any practical differences to either way?

e: I want the method injected to be bound to the object so I can't just assign it as an attribute.

Boris Galerkin fucked around with this message at 22:10 on Apr 17, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

breaks posted:

You should probably just write a method that calls whatever you want to call instead unless you have a really good reason not to.


I have a class that represents this equation:



In this equation the nu (Greek v looking thing) is a mathematical function, and there are different ways you can mathematically define it. The simplest mathematical function/model would be a constant value for it. More complex models use a varying amount of arbitrary parameters and it also depends on other parts of that equation that I showed.

For example one model might need access to that "u" variable in the equation. Another model might need access to that "p" in the equation. Another one might need both. I know at runtime what model to use because I define it, but until then the class doesn't know what to pre-compute (I use lazy evaluation a lot here), what it needs to pass into the function, etc.

The class representing that equation I showed knows all the methods to compute these things, though. So that's why I want to inject said function for nu into the object at runtime based on a single kwarg, so that it can access all of the class's methods.


If there's a better way I'm all ears. I'd like to avoid creating a subclass of that equation class for every model I implement, because in actuality some of those other terms in the equation canare represented by arbitrary mathematical functions.

Boris Galerkin fucked around with this message at 15:04 on Apr 18, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

SurgicalOntologist posted:

can you do something like this:


Python code:

class NavierStokes:
    def __init__(self, ..., nu_method='constant'):
        ...
        self.nu = getattr(self, '_nu_' + nu_method)

    def _nu_constant(self, ...):
        ...

    def _nu_full(self, ...):
        ...

although I still don't understand the logic behind not wanting to assign it as an attribute. Because otherwise you could just pass it to __init__.

I mean I could do this I guess. Your way looks like my way, except that in your way you would define every single model for "nu" inside of that class, and in my way I would define every model for "nu" inside a separate file called viscosity.py.

I honestly thought I was being more clever by splitting those functions into their own file.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

SurgicalOntologist posted:

That's reasonable too. In that case I would just do

Python code:

def __init__(self, ..., nu_func=default_nu_func):
    self.nu = nu_func

If I did this I wouldn't be able to do "self.u" inside nu_func if I pass it in from outside the class right? I guess theoretically I could just call "self.nu(self)" inside the class to mimic a real method but that sounds weird.

[quote]
The only reason I didn't suggest that is this:


which I don't follow. With the above it is bound to the object.

Maybe I got my terminology wrong. I thought bound meant the thing where it implicitly gets "self" passed to it.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
You guys are right. I just tried that too and it works. The only problem is that then all Test objects would have access to that foo method. What I want to do is have foo he defined per object so that I could do something like

code:

problems = (Test('foo_bar', ...), Test('foo_baz', ...), Test('foo_baz2'))
results = [a.foo() for a in problems]

Dex posted:

keep in mind what you're actually doing - assigning an object that exists outside the class to a value within the class:

Python code:

def outer_func():
    pass


class RefClass(object):
    def __init__(self, func):
        self.func = func


print(outer_func) 
print(RefClass(func=outer_func).func)

is just going to print out the same object, which makes sense really

The way I thought of it was that everything is being passed around by reference/pointer. So when I assign test.foo = foo what I'm actually doing is saying "hey test object, your memory location corresponding to "foo" is now pointing to this other memory location which happens to have information on how to execute the foo function.

I'm not sure if that's right or not but from a Fortran background it made perfect sense …

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

Nippashish posted:

This is sort of weird, but what you want is also sort of weird. "I want a function that does different things depending on which instance I call it on" really screams "I want a base class with a bunch of different subclasses" to me.

You're not wrong, but I wanted to avoid having to explicitly make new subclasses and instead just have them all represented by one class called "NavierStokes" in this case. So that's why I asked about metaclass vs methodtypes.

Dex posted:

code:
import types

class Example(object):
    def __init__(self, value):
        self.value = value

    def bind_function(self, myfunc):
        return setattr(self, myfunc.__name__, types.MethodType(myfunc, self))

This is essentially what I had in my first post:

Boris Galerkin posted:

code:
self.foo = types.MethodType(module.foo, self)

The question was just: should I metaclass or use the types.MethodType module? I didn't really see or understand a practical difference.

shrike82 posted:

Which is a roundabout way of saying that Boris was right with his initial solution.

From Hettinger's Descriptor HowTo
code:
class Function(object):
    . . .
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        return types.MethodType(self, obj, objtype)
I think everyone here, including me, just found out that attaching a function to an instance doesn't automatically bind it, which is an interesting quirk.

I'm not sure I understand what this one is doing.

Thanks for all the help and discussion. I don't want to sound dismissive, but it looks like the original method I proposed works and Dex's solution is more or less the same, so I'm just going to stick with what I have.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

breaks posted:

The guy doesn't seem interested because it's not "injecting a method."

No.

I wasn't interested in passing in a literal function into the constructor of the class because I wanted the class constructor to do it for me.

I understand that I could have still written my class to "attach" the proper function to itself and then call it with explicitly passing in "self" into the function to replicate the same thing.

But my "there has to be a better way" lightbulb lit up since it seemed silly and I found metaclass and MethodType.

And also

breaks posted:

If you don't care you don't care but do enough of this stuff and it will eventually bite you in the rear end in a very painful way unless you are really taking pains to exactly replicate the normal behavior. It is genuine Bad Python to drop a MethodType on an instance like that because it is subverting the expectations of the language implementation. I'll stop harping on it because I think I've said it too many times already.

This is literally the first response from anybody with substantial information on why what I'm doing may be considered "bad." Everyone else was either helpful and suggested methods to do what I wanted to do or tell me "no don't" without offering why.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

dougdrums posted:

code:

$ pip3 search make sandwich

pysandwich (0.1.2) 		python sandwiches.
panini (2.4.6) 	 		The Simple Sandwich Maker. ([url]https://panini.io[/url])
libsandwich (0.1)  		Wrapper for libsandwich
sandwich-python (3.13.2) 	Python module for crossway multi-aspect production patterns.
yasm (1.4) 			Yet Another Sandwich Maker
pysw (1) 			makes yto samwitch!!!
sandwichmaker (2.0) 		easy to use sandwich maker
...

How come when I search pip it always shows me like a list of 648383628 packages, most of which don't even have what I searched for in the title or short description? Or maybe it does and I just don't see it because the list is just so huge that I gloss over everything.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
PyCharm question: I have it set to automatically type two ' symbols so it's really convenient. But what's a bit silly is that there doesn't seem to be a "exit" the quotation level if that makes sense, without actually pressing ' again. This gets kind of annoying when I'm trying to use something from a dict because what's the point of it automatically closing the [ and ' symbols if I still need to press those two buttons.

Is there a shortcut I'm missing? I would have guessed alt/ctrl enter or something but that doesn't work.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I don't have that key on my keyboard.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I'm just learning about anaconda/conda and it seems kinda of great. So I have a few questions about it:

1. How do I pre-download all of the necessary files to create a conda environment? I need to "deploy" on a system that has no internet access so if I could just upload a tarball with all the packages already downloaded that would be great.

2. For one of the environments I want to set up it uses two libraries that need to be compiled. There are conda build scripts that do this so that's great, but package #2 requires package #1 to build.

So I was thinking of doing something like this:

code:

# build package #1
conda build package1/

# create conda env with package1 to build package2
conda create -n foo --use-local package1
source activate foo
conda build package2/
source deactivate foo

# create new env with both packages
conda create -n bar --use-local package1 package2

Is there a better way to do this?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

QuarkJets posted:

Miniconda should have everything that you need to create a conda environment. If you have an internet-connected system with similar hardware, then you could just fully build your environment there and then move the whole anaconda directory to your not-connected system, saving you some time if anything goes wrong.

You should be able to just build both of the packages, in the right order, without creating multiple environments. Create the environment, build package1, build package2

To the first point, on my laptop anaconda was installed to $HOME/anaconda3. I can just upload this entire folder up to the other machine and add it to the PATH?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
What's the canonical way to include/make available a binary file in my Python package that can be used by unit tests and user tutorials? I could drop it into a "resources" folder at the project root but then to access it I need to use a lot of relative paths unless there's some kind of shortcut I'm missing?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I've never heard of Mayavi before but you might want to also check out Paraview. Both of them are built using the VTK library so should be quite similar. I'm pretty sure that everybody I know (including me) that would use a visualization software would use Paraview though.

This might help:

https://pyscience.wordpress.com/2014/09/06/numpy-to-vtk-converting-your-numpy-arrays-to-vtk-arrays-and-files/

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

Cingulate posted:

I thought that's a thing people do to imply point zero is what you should have done already in the first place or something like that. Like, utter basics.

That's how I'd use a 0th level bullet list too. I translate it in my head as "this is the pre requisite."

Rocko Bonaparte posted:

Has anybody dabbled with dependency injection with Python? I have reason to implement something like an API for getting implementations of APIs, and DI sounds like the way to go. I especially think back to how Angular managed stuff like this.

I feel like people are gonna jump in and say "no don't do that," based on responses to other things I've asked about. But I don't really understand what you're asking though.

LochNessMonster posted:

So I've been messing around with Python for a few months but I feel I'm stuck at a level slightly above complete beginner. I know how to work with lists/dicts/tuples and create loops/conditions.

What would be a good resource to gain knowledge on working with concepts that are new to me? Things I regularly see and don't understand are __init__ or __main__ funtions, when I should use classes or how to create a decent structure in my code. Currently I create a few functions and below them I write loops/conditions which use them. When looking at code from others I usually see them split over multiple files.

I'm working with python3.

Sup me from the past.

Re: code organization, i think starting off with everything in a single file is the best way to go. That way everything is right there and easy to jump around to (I'm aware IDES and ctags makes this a nonissue but there's a physiological factor of knowing everything is right here that helps I think), and then splitting things off into their own files when the need arises.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I've been asking (and see other people asking as well) my docker questions in the Linux thread so maybe try there. It's more active than this one as well.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
My first instinct was that conda isn't in your $PATH or whatever the Windows equivalent is, but I just popped open a PowerShell (I don't have conda installed on this computer) and typed 'conda list' and it complained to me about conda not being a recognized command. So unless you trimmed that out of your post then I dunno.

By the way I think PyCharm is the best thing ever as well, coming from vim for approximately 10 years now (gently caress I'm old). I just started using it though and yeah I could definitely see where it might be confusing and intimidating.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I'm just curious, if you run power she'll in administrative mode (hit the windows key, type powers, right click and choose admin mode) and then type "conda list" does it still show you no output?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I'm using PyCharm and a remote interpreter inside a Docker image. It's neat but it looks like PyCharm spawns a new container each time I run some code. Is it possible to tell PyCharm to use a persistent container instead?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Obviously there's something wrong with your megahurts, so you'll need a new processing unit.



It's because of floating point numbers:

http://floating-point-gui.de

e: You'll want to change the logic of that loop so that it counts by integers instead of floats. When you do the division part your integers are turning into floats.

e2: The overly simplified gist of it is that your computer does not know how to represent a value like 0.3 exactly, so it needs to approximate. That's what that extra 0.0...4 is coming from, and that's why some of your other values are actually less than what you are expecting. This is why the general wisdom is to never compare floating point numbers if the result is critical, e.g.:

code:

# this is bad
if a == b:
    foo()

# this is better
eps = 1e-8
if abs(a - b) < eps:
    foo()

Boris Galerkin fucked around with this message at 11:44 on Jun 10, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

LochNessMonster posted:

Never knew floating points behave like this, learning something knew everyday.

It's more of a hardware limitation than an actual thing. In real life 0.3 is exactly 0.3, but we lose some accuracy when we represent it in a computer.

I imagine for most people none of this has any direct relevance, but if you're doing any sort of numerical/computational work then this type of stuff comes up all the time. Doing simulations for example we already accept that there is an inherent error from the actual math equations and simplifications to them, but we also accept that there are errors from discretization (dividing the problem up into multiple smaller parts), and we also must be aware of problems in roundoff/precision due to the computer. Lots of fields use 64 bit floats for example because it gives us more precision (more decimals).

I remember one of my earliest courses in this field our professor intentionally misled us to use MATLAB to write our first finite difference solver to solve a problem that produced nonsense results because the default floating point precision in MATLAB (at that time? not sure if it's the case still) was 32bit. Due to error propagation these errors eventually ruined the solution. Telling MATLAB (or using C/Fortran double precision numbers) to use 64 bit reals on the other hand fixed the problem because these errors never had a chance to propagate.

Boris Galerkin fucked around with this message at 12:03 on Jun 10, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I think it's important to know why you should never do

code:

if 0.1 + 0.2 == 0.3:
    do_stuff()

And that the reason is because floating point numbers are something like approximations of the actual real number.

I think it's important to know the proper way of doing this comparison is

code:

eps = 1e-8
if abs(a - b) < eps:
    do_stuff()

And that the difference between this and the first one is that you're now comparing the residual between the computed value against the expected value, and that eps should be chosen to be small enough for your application/hardware.

I think for most people this is fine yeah. This is what I told the guy who asked and he seemed to appreciate it.

Boris Galerkin fucked around with this message at 12:10 on Jun 12, 2017

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

LochNessMonster posted:

Just read some stuff on the Floating-Point Guide that was linked earlier as well as the official docs and it makes some more sense now. At leas now I know to round my floats when using them for basic calculations!

(and to use decimals if I want to do something with currency)

Actually no you don't want to round your floats. Let the computer handle the precision of your floats, and let yourself handle what an acceptable cutoff for "the answer" is. Unless you're talking about printing values purely for human eyes to look at them truncate/round away.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

Philip Rivers posted:

Yeah, I'm currently having efficiency issues. The naive implementation is pulling the endpoint positions from a list of the line objects but it's not fast enough. I don't know if a numpy array would be useful because since the positions are always updating I would need to rebuild the array every timestep.

Have you actually profiled your code and determined that the slowdown is what you think it is? Since it sounds like you're new to this type of stuff I don't get the impression that you profiled it and are just going by gut feeling. And although I don't know what exactly you are trying to do with your code I'm having a hard time imagining that pulling essentially coordinate locations of the nodes in 2D would be a significant cause of slowdown unless there's much more going on under the hood that you've not mentioned.

Anyway it sounds like a fun problem though and got me thinking:

1. You could implement/use some kind of sparse matrix storage scheme if your problem size was on the order of like hundreds of thousands.
2. You could take advantage of the fact that the lines connecting each node obeys the same formula y = mx + b and build some kind of system of equations which numpy could easily solve.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I want to make flow charts and it looks like GraphViz is the library I want. Does anyone have experience with the various Python bindings to it? I've seen recommendations for graphviz, pygraphviz, and pydot.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Well I just had a frustrating time figuring out what was wrong with a part of my code when it turns out it was numpy being weird.

So I have a numpy array where some values are inf and some values are nan. I create a Boolean list of where these values in the array are inf/nan, and then I use these indices to do something to another array.

Like so:

code:

import numpy as np

a = np.array([1, np.sqrt(-1), np.nan, np.inf])  # [1, nan, nan, inf]

print(a == np.inf)
# F, F, F, T, as expected

print(a == np.nan)
# F, F, F, F, which is wrong

print(np.isnan(a))
# F, T, T, F

Is there a reason it does this? Does np.nan has an actual numerical value or something? I would have thought it would be treated in the same way as None where it just "is" or "isn't."

Adbot
ADBOT LOVES YOU

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Ok cool thanks for the info. I figured it was a spec related thing but I guess this is the first time I've ever used a thing where nan or dividing by zero doesn't crash your program.

Eela6 posted:

NaN == n is False, even if n is NaN. It's in the IEEE specificiations for floating point numbers. This is occasionally inconvenient but it's the way it is - the spec is older than Python!

This is true both for numpy and Python's built-in float type, though you're unlikely to encounter NaN in that case, since most operations that produce it will raise an exception first.

Yep I explicitly used numpy arrays here cause I figured it was easier to just handle the nan/inf values of they ever arose rather than pre-checking.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply