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
VikingofRock
Aug 24, 2008




Dominoes posted:

Objects are nice if you're defining something that can be thought of as a datatype, or if you're using a collection of similar items.

I prefer to use namedtuples for this personally.

E: which, I suppose, is actually a class, but people tend to treat them differently in their mental model of how things work.

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




ynohtna posted:

Here's my common snippet to convert an iterable into natural sort order:
Python code:
import re
def sorted_nicely(iter):
    """ Sort the given iterable in the way that humans expect."""
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
    return sorted(iter, key=alphanum_key)
Usage is:
Python code:
    for p in sorted_nicely(seen_paths):
        print(p)

It took me a little bit to prove to myself that you would never end up comparing a string and an int with this, but yeah, you never do so this is totally valid. Nice!

VikingofRock
Aug 24, 2008




huhu posted:

What would be the best way to take:

[{u'amt': 10.0}, {u'amt': 0.1}, {u'amt': 1.0}, {u'amt': 3.0}, {u'amt': 5.0}]

and turn it into

[10.0, 0.1, 1.0, 3.0, 5.0]

I'd do

Python code:

[val for dict in list for val in dict.values()]

Edit: the difference between Thermopyle's solution and mine is that if there are other items in the dictionaries, his will select out the values with 'amt' keys, whereas mine will just give all the values regardless of key.

VikingofRock fucked around with this message at 15:51 on Jun 14, 2017

VikingofRock
Aug 24, 2008




So I've been doing more python lately, and while I feel like I have a decent grasp on the language itself, I struggle with a lot of the idioms for structuring a program. For example, how should I layout the directory structure of my program, what is __init__.py, where do I list my dependencies, stuff like that. Does anyone have a good resource for learning that sort of stuff? Like the things that are necessary to use python effectively, but which are outside of the scope of the language itself.

edit: I often don't really know what various tools are, either, which falls into the same category. Like what is virtualenv / venv / pyvenv, etc? Is there a standard python code formatter? What other tools should I know about?

VikingofRock fucked around with this message at 03:24 on Jun 23, 2017

VikingofRock
Aug 24, 2008




accipter posted:

Here is the official documentation: https://docs.python.org/3/tutorial/modules.html#packages , and this is pretty good guide on how to package a Python module: https://python-packaging.readthedocs.io/en/latest/index.html . I would also recommend the setuptools documentation: https://setuptools.readthedocs.io/en/latest/index.html . However, it is a more focused on setuptools, rather than the organization of a package. How to organize a package depends on the scale of the package. If it is small enough, you can put everything in __init__.py.

PEP8 is the recommended standard format for Python code. I use it because it is a standard, but there are people that complain about it (then again people always find something to complain about). I have also been used YAPF. When I am developing a package, I use py.test with flake8. This checks the format for all of my code, and if it violates PEP8 then I fix the code by hand.

Depending on what you are working on and the OS, Python dependencies can be in conflict. A virtual environment is a way to create a project specific collection of Python packages. I used miniconda to develop packages that simultaneously support Python 2.7 and 3.6. I do this by having conda environmental for 2.7 and 3.6 installed simultaneously, and test against each one.

Thank you for all the information, this is very helpful. I'm worried that there are more questions like this that I don't even know to ask, though. Is there a book or something that covers these topics for python?

Edit: I'm looking at Effective Python. Does anyone have any experience with that book? If so, would you recommend it?

VikingofRock fucked around with this message at 03:59 on Jun 24, 2017

VikingofRock
Aug 24, 2008




Thermopyle posted:

Say i have a routine that searches for and gets a thing. You can search for a thing via a regex, via an int, or via a tuple. Which of the following do you prefer?

one
Python code:
 
def find_thing(filter):
  # code that type checks 'filter' and does the right thing.
two
Python code:
 
def find_thing_regex(regex):
def find_thing_int(an_int):
def find_thing_tuple(a_tuple):
three
Python code:
def find_thing(regex=None, an_int=None, a_tuple=None):

Python code:
def find_thing(predicate):

where predicate is a function/callable which takes as input elements of the space you are searching over and which returns true if a match is found.

If you don't want to do that though, I think the first function you posted has the cleanest interface so I would prefer that.

VikingofRock
Aug 24, 2008




Thermopyle posted:

I don't know why I didn't even think of using a predicate since most of my time is spent doing JS nowadays and thats a very common pattern there. Thanks for reminding me.

Now I accept a predicate, or build a predicate for you if you provide the other types I mentioned above.

Nice, that sounds like an excellent, convenient interface.

VikingofRock
Aug 24, 2008




Why does this happen? (Python 3.6.3)

Python code:
letters = {'a': 1.0, 'b': 2.0, 'c': 3.0}
fns = {key: lambda x: x / val for key, val in letters.items()}
for key in fns:
    print(key, fns[key](1))

# output:
# 
# a 0.3333333333333333
# b 0.3333333333333333
# c 0.3333333333333333

VikingofRock
Aug 24, 2008




VikingofRock posted:

Why does this happen? (Python 3.6.3)

Python code:
letters = {'a': 1.0, 'b': 2.0, 'c': 3.0}
fns = {key: lambda x: x / val for key, val in letters.items()}
for key in fns:
    print(key, fns[key](1))

# output:
# 
# a 0.3333333333333333
# b 0.3333333333333333
# c 0.3333333333333333

Okay, so I asked a friend and he said that it's because the lambda is storing a reference to val, and so when val is updated throughout the dictionary comprehension it changes the val "pointed to" by all the lambdas. And this works:

Python code:
def over(val):
    return lambda x: x / val

letters = {'a': 1.0, 'b': 2.0, 'c': 3.0}
fns = {key: over(val) for key, val in letters.items()}
for key in fns:
    print(key, fns[key](1))
# output:
#
# a 1.0
# b 0.5
# c 0.3333333333333333
So I guess the real problem is that I don't understand variable assignment in python. Does anyone know of a good resource for understanding how that really works? In most of the languages that I'm used to, either variables are very explicitly copies or references (C, C++, Rust) or are immutable (Haskell), so the assignment model of python is pretty confusing to me.

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




QuarkJets posted:

Is there a reason that you're returning a lambda instead of just x/val?

This question actually came from me helping someone else with some python (and getting stumped), but presumably the answer is "because you don't know x at the time when this dictionary is created".

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