

The 'ugliness' of Python - Ruby, Python, functions & objects - djacobs
http://allthingsprogress.com/posts/the-ugliness-of-python

======
jacobolus
The python code here is not very idiomatic. Better would be something like:

    
    
        import re
        with open('companies') as f:
            important_companies = set(f)
    
        articles = ['article1.md', 'article2.md', 'article3.md']
        http_regex = re.compile(r"https?:\/\/(\w+)?(\.(\w+))*\.(com|org|net)")
    
        def parse_article(a):
            with open(a, 'r') as f:
                words = f.read().split()
                urls = (http_regex.search(w) for w in words)
                companies = (match.group(0).capitalize() for match in urls if match)
                return (c for c in companies if c in important_companies)
    
        [c for a in articles for c in parse_article(a)]
    

(Note, I didn’t test this; I might be slightly misunderstanding some of what
the code is supposed to do; the basic idea should be clear though. I think the
original Python code posted might be broken: a regexp match object shouldn’t
be directly subscriptable, it’s not clear why he’s opening the file 'atp' for
each article, and I’m really not sure what’s supposed to happen when the url
regexp doesn’t match. One nice thing to notice: in Python a file object can be
iterated over, and will spit out its lines; passing a file into list() or
set() will turn its lines into the appropriate data structure. But if explicit
splitting is ever necessary, the author should use foo.splitlines() rather
than foo.split('\n'). Finally, compiling a regexp for each word in every file
is bad form, and he should really be using "raw" strings for regexps. My guess
is that the Python code in the original article was never actually tested.)

Or even better, use a generator:

    
    
        import re
        with open('companies') as f:
            important_companies = set(f)
    
        articles = ['article1.md', 'article2.md', 'article3.md']
        http_regex = re.compile(r"https?:\/\/(\w+)?(\.(\w+))*\.(com|org|net)")
    
        def parse_article(a):
            with open(a, 'r') as f:
                for word in f.read().split():
                    url = http_regex.search(word)
                    if url:
                        name = url.group(0).capitalize()
                        if name in important_companies:
                            yield name
        
        [c for a in articles for c in parse_article(a)]
    

In my opinion, either of these, but especially the second, makes control flow
much much clearer than either the ruby or python examples in the original
article.

~~~
djacobs
I'm not a fan of if statements (especially nested) or for loops (except for
side effects), which is why I coded like I did — in the style of a Lisp. That
said, thanks for the excellent code. I'm going to look it over.

I'll go back tomorrow and double-check the regex. I'm definitely not an expert
with those objects in Python.

------
davidmathers
_numbers.map &:to_s could give different values in the same code—even though
its argument doesn’t change_

It's a family of functions: <http://en.wikipedia.org/wiki/Indexed_family>

------
djacobs
Ruby for functional programming ... I realize lots of people don't swing that
way. Thoughts?

~~~
rbxbx
Unfortunately most professional Ruby work is still done within the Rails
framework these days, which more or less binds you to a more traditional OO
type style. I do find that in regards to everything other than class/object
abstraction my coding style gets more and more functional.

Especially when working in a team environment though it's important to stick
to some established standards and idioms...

That said, Ruby itself gets more functional with each release, but it would
seem unlikely that it'll ever completely shed it's OO-ness.

Rambling aside, some great links.

[http://moonbase.rydia.net/mental/writings/programming/monads...](http://moonbase.rydia.net/mental/writings/programming/monads-
in-ruby/00introduction.html)

<http://www.khelll.com/blog/ruby/ruby-currying/>

<http://nex-3.com/posts/43-fun-with-the-y-combinator-in-ruby>

------
vegas
This is a fantastic read!

~~~
thwarted
This is a terrible read. This is a rant about what the author is used to, and
anything else is different and hard.

 _Now, in my mind, these method names are decidedly ugly. They aren’t
friendly, short, clean, straightforward or simple. I don’t think anyone would
argue with me there. Certainly no one’s actually happy typing the extra
underscores._

 _That’s true, function passing is painless in Python and a little harder in
Ruby. But coll.map &f isn’t so bad, and for me, it’s definitely not a deal
breaker. I’ve actually gotten used to it. To me, the extra syntax is the price
we pay for internal consistency._

These two quotes above are on one hand poopooing some apparently arbitrary
naming convention in python and then praising the same kind of apparently
arbitrary syntax quirk in ruby.

(I find the double prefixing and suffixing underscores to make sense in
python: these methods are called _implicitly_ by other constructs, never
called directly.)

~~~
djacobs
I'm going to go ahead and guess that you didn't read the entire article. You
can disagree with what I say, but it's anything but a rant.

~~~
thwarted
Maybe rant was too strong of a word, but I don't think there much meat to this
write up, because there isn't much introspection into _why_ any of these
differences are the way they are, it's mainly just pointing them out and
favoring one over the other based on familiarity.

