Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #58933 > unrolled thread

New user's initial thoughts / criticisms of Python

Started byJohn von Horn <j.h69@btinternet.com>
First post2013-11-09 07:08 -0600
Last post2013-11-12 01:53 +0000
Articles 6 on this page of 46 — 23 participants

Back to article view | Back to comp.lang.python


Contents

  New user's initial thoughts / criticisms of Python John von Horn <j.h69@btinternet.com> - 2013-11-09 07:08 -0600
    Re: New user's initial thoughts / criticisms of Python Ned Batchelder <ned@nedbatchelder.com> - 2013-11-09 05:22 -0800
    Re: New user's initial thoughts / criticisms of Python Joshua Landau <joshua@landau.ws> - 2013-11-09 13:27 +0000
      Re: New user's initial thoughts / criticisms of Python Jonathan <jtcegh@gmail.com> - 2013-11-09 14:44 -0800
        Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-10 10:29 +1100
        Re: New user's initial thoughts / criticisms of Python MRAB <python@mrabarnett.plus.com> - 2013-11-10 00:50 +0000
        Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-10 11:54 +1100
        Re: New user's initial thoughts / criticisms of Python Neil Cerutti <neilc@norwich.edu> - 2013-11-11 15:30 +0000
      Re: New user's initial thoughts / criticisms of Python Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2013-11-10 13:24 +0100
    Re: New user's initial thoughts / criticisms of Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-11-09 13:41 +0000
    Re: New user's initial thoughts / criticisms of Python Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-11-09 16:24 +0200
    Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-10 01:27 +1100
      Sandboxing Python [was Re: New user's initial thoughts / criticisms of Python] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-09 15:25 +0000
        Re: Sandboxing Python [was Re: New user's initial thoughts / criticisms of Python] Chris Angelico <rosuav@gmail.com> - 2013-11-10 02:32 +1100
      Re: New user's initial thoughts / criticisms of Python Jorgen Grahn <grahn+nntp@snipabacken.se> - 2013-11-10 08:47 +0000
        Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-10 20:22 +1100
        Re: New user's initial thoughts / criticisms of Python Ian Kelly <ian.g.kelly@gmail.com> - 2013-11-10 04:39 -0700
        Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-10 22:43 +1100
        Re: New user's initial thoughts / criticisms of Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-11-10 12:12 -0500
        Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-11 10:29 +1100
        Re: New user's initial thoughts / criticisms of Python Terry Reedy <tjreedy@udel.edu> - 2013-11-10 19:13 -0500
    Re: New user's initial thoughts / criticisms of Python rusi <rustompmody@gmail.com> - 2013-11-09 07:38 -0800
      Re: New user's initial thoughts / criticisms of Python Roy Smith <roy@panix.com> - 2013-11-09 10:56 -0500
        Re: New user's initial thoughts / criticisms of Python rusi <rustompmody@gmail.com> - 2013-11-09 08:30 -0800
          Re: New user's initial thoughts / criticisms of Python Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-10 21:36 -0800
            Re: New user's initial thoughts / criticisms of Python Roy Smith <roy@panix.com> - 2013-11-11 09:01 -0500
              Re: New user's initial thoughts / criticisms of Python rusi <rustompmody@gmail.com> - 2013-11-11 07:14 -0800
              Re: New user's initial thoughts / criticisms of Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-11-11 21:05 -0500
              Re: New user's initial thoughts / criticisms of Python Ethan Furman <ethan@stoneleaf.us> - 2013-11-12 14:38 -0800
    Re: New user's initial thoughts / criticisms of Python John von Horn <j.h69@btinternet.com> - 2013-11-09 14:19 -0600
    Re: New user's initial thoughts / criticisms of Python Tim Chase <python.list@tim.thechases.com> - 2013-11-09 14:39 -0600
    Re: New user's initial thoughts / criticisms of Python Mark Janssen <dreamingforward@gmail.com> - 2013-11-09 12:33 -0800
      Re: New user's initial thoughts / criticisms of Python Ned Batchelder <ned@nedbatchelder.com> - 2013-11-09 12:54 -0800
        Re: New user's initial thoughts / criticisms of Python Mark Janssen <dreamingforward@gmail.com> - 2013-11-09 13:21 -0800
    Re: New user's initial thoughts / criticisms of Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-11-09 21:01 +0000
    Re: New user's initial thoughts / criticisms of Python Tim Chase <python.list@tim.thechases.com> - 2013-11-09 15:20 -0600
    Re: New user's initial thoughts / criticisms of Python lorenzo.gatti@gmail.com - 2013-11-11 02:09 -0800
      Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-11 21:39 +1100
        Re: New user's initial thoughts / criticisms of Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-11 11:17 +0000
          Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-11 22:32 +1100
          Re: New user's initial thoughts / criticisms of Python Mark Janssen <dreamingforward@gmail.com> - 2013-11-11 14:29 -0800
      Re: New user's initial thoughts / criticisms of Python Robert Kern <robert.kern@gmail.com> - 2013-11-11 11:53 +0000
      Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-11 23:07 +1100
      Re: New user's initial thoughts / criticisms of Python Joshua Landau <joshua@landau.ws> - 2013-11-11 20:50 +0000
      Re: New user's initial thoughts / criticisms of Python Chris Angelico <rosuav@gmail.com> - 2013-11-12 09:21 +1100
      Re: New user's initial thoughts / criticisms of Python Joshua Landau <joshua@landau.ws> - 2013-11-12 01:53 +0000

Page 3 of 3 — ← Prev page 1 2 [3]


#59106

FromMark Janssen <dreamingforward@gmail.com>
Date2013-11-11 14:29 -0800
Message-ID<mailman.2402.1384208960.18130.python-list@python.org>
In reply to#59064
On Mon, Nov 11, 2013 at 3:32 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Mon, Nov 11, 2013 at 10:17 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Mon, 11 Nov 2013 21:39:27 +1100, Chris Angelico wrote:
>>> denormalizes it into a lookup table by creating 70 entries quoting the
>>> first string, 15 quoting the second, 5, and 10, respectively.
>>
>> Ewww :-(
>>
>> Imagine having to print out the dict looking for an error in the lookup
>> table. Or imagine the case where you have:
>>
>> 0...20000: do this
>> 20001...890001: do that
>> 890001...890003: do something else
>>
>> Don't get me wrong, it's a clever and reasonable solution for your
>> specific use-case. But I'd much rather have a lookup table variant that
>> matches on intervals.
>
> Of course it's "Ewww" in isolation :) But just imagine there are piles
> and piles of these tables, themselves keyed by keyword, and I want to
> be able to let untrusted people create tables (which means they
> basically have to be data, not code). Also, bear in mind, all the
> tables are based around dice that can be physically rolled, so none
> has more than 100 entries after denormalization. Quite a lot of the
> tables actually have unique entries per value (eg it's a d10 roll,
> with ten unique outputs), so it's simplest to just turn all the tables
> into that format; that way, the main code needs worry about one type
> only, and the preprocessor handles the denormalization.

Hmm, I automatically think of creating a hash function, but then
that's how Python implements keys in dicts, so a dict is fine
solution.

-- 
MarkJ
Tacoma, Washington

[toc] | [prev] | [next] | [standalone]


#59068

FromRobert Kern <robert.kern@gmail.com>
Date2013-11-11 11:53 +0000
Message-ID<mailman.2373.1384170873.18130.python-list@python.org>
In reply to#59060
On 2013-11-11 10:39, Chris Angelico wrote:

> A 'minor weapon' is based on a roll of a 100-sided dice. If it's 01 to
> 70, "+1 weapon: 2,000gp [weapon]"; if it's 71 to 85, "+2 weapon:
> 8,000gp [weapon]"; if 86 to 90, "Specific weapon [minor specific
> weapon]"; and if 91 to 100, "Special ability [minor special weapon]
> and roll again".
>
> My code to handle that starts out with this array:
>
> "minor weapon":({
>      70,"+1 weapon: 2,000gp [weapon]",
>      85,"+2 weapon: 8,000gp [weapon]",
>      90,"Specific weapon [minor specific weapon]",
>      100,"Special ability [minor special weapon] and roll again",
> }),
>
> (that's Pike; in Python it'd be a list, or maybe a tuple of tuples),
> and denormalizes it into a lookup table by creating 70 entries quoting
> the first string, 15 quoting the second, 5, and 10, respectively. So,
> with a bit of preprocessing, a lookup table (which in this case is an
> array (list), but could just as easily be a dict) can be used to
> handle inequalities. But this is because lookup tables can be treated
> as data, where if/elif/else blocks have to be code; there are roughly
> 42 million such lookup tables in the code I snagged that from, and
> having code for each one would work out far less manageable. Normally,
> you'll want to render inequalities with code as if/elif.

Heh. I've done pretty much exactly the same thing to implement an engine[1] to 
draw from the random tables on Abulafia[2] which have nearly the same structure. 
It scales up reasonably well beyond d100s. It's certainly not a technique I 
would pull out to replace one-off if-elif chains that you literally write, but 
it works well when you write the generic code once to apply to many tables.

[1] http://rollmeup.mechanicalkern.com/
[2] http://www.random-generator.com/index.php?title=Main_Page

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco

[toc] | [prev] | [next] | [standalone]


#59072

FromChris Angelico <rosuav@gmail.com>
Date2013-11-11 23:07 +1100
Message-ID<mailman.2375.1384171657.18130.python-list@python.org>
In reply to#59060
On Mon, Nov 11, 2013 at 10:53 PM, Robert Kern <robert.kern@gmail.com> wrote:
> Heh. I've done pretty much exactly the same thing to implement an engine[1]
> to draw from the random tables on Abulafia[2] which have nearly the same
> structure. It scales up reasonably well beyond d100s. It's certainly not a
> technique I would pull out to replace one-off if-elif chains that you
> literally write, but it works well when you write the generic code once to
> apply to many tables.

I'd trust my current code for several orders of magnitude beyond where
I'm currently using it, but as Steven said, you really don't want to
be manually looking at the denormalized tables. Since all the strings
are referenced anyway, having a lookup array of (say) 1,000,000 object
pointers is fairly cheap.

>>> lst = ["Low" if i<500000 else "High" for i in range(1000000)]
>>> sys.getsizeof(lst)
4348736

That's pretty close to four bytes per entry, which would be the
cheapest you could hope for on a 32-bit system. 10% overhead is quite
acceptable. And this is a fairly extreme example :)

ChrisA

[toc] | [prev] | [next] | [standalone]


#59100

FromJoshua Landau <joshua@landau.ws>
Date2013-11-11 20:50 +0000
Message-ID<mailman.2398.1384203083.18130.python-list@python.org>
In reply to#59060
On 11 November 2013 10:39, Chris Angelico <rosuav@gmail.com> wrote:
> On Mon, Nov 11, 2013 at 9:09 PM,  <lorenzo.gatti@gmail.com> wrote:
>> Regarding the "select" statement, I think the most "Pythonic" approach is using dictionaries rather than nested ifs.
>> Supposing we want to decode abbreviated day names ("mon") to full names ("Monday"):
>
> You can't [normally], for instance, build up a
> dictionary that handles inequalities, but you can do that with elif.
> [...] Consider the following logic:
>
> A 'minor weapon' is based on a roll of a 100-sided dice. If it's 01 to
> 70, "+1 weapon: 2,000gp [weapon]"; if it's 71 to 85, "+2 weapon:
> 8,000gp [weapon]"; if 86 to 90, "Specific weapon [minor specific
> weapon]"; and if 91 to 100, "Special ability [minor special weapon]
> and roll again".
>
> My code to handle that starts out with this array:
>
> "minor weapon":({
>     70,"+1 weapon: 2,000gp [weapon]",
>     85,"+2 weapon: 8,000gp [weapon]",
>     90,"Specific weapon [minor specific weapon]",
>     100,"Special ability [minor special weapon] and roll again",
> }),
>
> (that's Pike; in Python it'd be a list, or maybe a tuple of tuples),
> and denormalizes it into a lookup table by creating 70 entries quoting
> the first string, 15 quoting the second, 5, and 10, respectively. So,
> with a bit of preprocessing, a lookup table (which in this case is an
> array (list), but could just as easily be a dict) can be used to
> handle inequalities.

The obvious way to me is a binary search:

    from bisect import bisect_left

    class FloorMap:
        def __init__(self, dct):
            self.indexes = sorted(list(dct))
            self.dct = dct

        def __getitem__(self, itm):
            index = self.indexes[bisect_left(self.indexes, itm)]
            return self.dct[index]


    minor_weapon = FloorMap({
        70:  "+1 weapon: 2,000gp [weapon]",
        85:  "+2 weapon: 8,000gp [weapon]",
        90:  "Specific weapon [minor specific weapon]",
        100: "Special ability [minor special weapon] and roll again"
    })

    minor_weapon[63]
    #>>> '+1 weapon: 2,000gp [weapon]'

The precise details of the wrapper class here are just to make
initialisation pretty; it could be done straight from a pair of lists
too:

    from bisect import bisect_left

    minor_weapon_indexes = 70, 85, 90, 100
    minor_weapon_descriptions = (
        "+1 weapon: 2,000gp [weapon]",
        "+2 weapon: 8,000gp [weapon]",
        "Specific weapon [minor specific weapon]",
        "Special ability [minor special weapon] and roll again"
    )

    minor_weapon_descriptions[bisect_left(minor_weapon_indexes, 80)]
    #>>> '+2 weapon: 8,000gp [weapon]'

Compare to

    if 80 <= 70:
        res = "+1 weapon: 2,000gp [weapon]"

    elif 80 <= 85:
        res = "+2 weapon: 8,000gp [weapon]"

    elif 80 <= 90:
        res = "Specific weapon [minor specific weapon]"

    elif 80 <= 100:
        res = "Special ability [minor special weapon] and roll again"

which although shorter¹ is a lot less data-driven and much less reusable.

¹ Longer if you ignore the import and class declaration.

[toc] | [prev] | [next] | [standalone]


#59104

FromChris Angelico <rosuav@gmail.com>
Date2013-11-12 09:21 +1100
Message-ID<mailman.2401.1384208527.18130.python-list@python.org>
In reply to#59060
On Tue, Nov 12, 2013 at 7:50 AM, Joshua Landau <joshua@landau.ws> wrote:
> The obvious way to me is a binary search:

Which makes an O(log n) search where I have an O(1) lookup. The
startup cost of denormalization doesn't scale, so when the server
keeps running for two years or more, it's definitely worth processing
it that way.

ChrisA

[toc] | [prev] | [next] | [standalone]


#59134

FromJoshua Landau <joshua@landau.ws>
Date2013-11-12 01:53 +0000
Message-ID<mailman.2417.1384221253.18130.python-list@python.org>
In reply to#59060
On 11 November 2013 22:21, Chris Angelico <rosuav@gmail.com> wrote:
> On Tue, Nov 12, 2013 at 7:50 AM, Joshua Landau <joshua@landau.ws> wrote:
>> The obvious way to me is a binary search:
>
> Which makes an O(log n) search where I have an O(1) lookup. The
> startup cost of denormalization doesn't scale, so when the server
> keeps running for two years or more, it's definitely worth processing
> it that way.

log 4 is tiny so I'd expect constant factors to be far more
significant here. Then you add on the better asymptotic behaviours for
large n, space wise, and the simplicity of implementation. This just
seems like a premature optimisation to me, I guess.

I agree that your way is faster; I just don't see a single case in
which I'd care. I do see several circumstances (large or floating
numbers) in which I'd probably prefer my way.

Feel free to disagree, I'm not really trying to convince you.

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.python


csiph-web