473,789 Members | 2,781 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Dice gen and analyser script for RPGs: comments sought

Hi fellow Pythonistas,

I've been using Python in anger for some time, and I must say, as I
wrote in <http://macprang.source forge.net/>:

"It's refreshing beyond words to use a language that so freely combines
such a small, clean syntax with such a powerful synthesis of
procedural, object-oriented and functional techniques."

My (hardcore C++) workplace is now very much converted to Python for
scripting tasks! We have completely abandoned Unix and DOS
shell-script, and Perl. We drive our entire "build-for-QA" process,
including code-signing, with Python and also use it for all our
automated nightly builds and unit tests.

So, inspired by the Python cookbook article 17.13, and because the
subject interests me, I've bashed out a module in my own time that can
do brute force and monte carlo analysis of dice under various RPG
rulesets:

* vanilla rolls of n x-sided dice, the result being multiplied by y
(usual d20 system ndx*y)
* as above, but the lowest m rolls are discarded
(optional d20 char gen rules)
* dice beating a threshold (Storyteller-style system),
with optional roll again
* opposed sorted rolls (Risk-style system).

The 1.0 version is at http://www.sailmaker.co.uk/newfiles/dice.py and
is public domain.

Before you ask, yes I'm fully aware of Newton's binomial theorem and
its generaliziation s. The point of this code is to however to
generalise, exercise and accumulate the brute force and Monte Carlo
methods across various evaluatuon rules.

All comments welcomed, cc to email preferred merely because it shows up
sooner for me and is less likely to be missed.

Comments, insights and overall evaluations are especially welcomed re:
* Cleanliness of design
* Pythonicity of design
* Pythonicity of code
* Efficiency of code
* Quality of docstrings
* Conformance with modern docstring standards
* Conformance with coding standards e.g. PEP 8

I look forward to receiving your comments and criticisms.

Regards,
Richard.
Sep 5 '06 #1
4 1767
Richard Buckle <ri******@sailm aker.co.nospam. ukwrites:
Comments, insights and overall evaluations are especially welcomed re:
* Cleanliness of design
* Pythonicity of design
* Pythonicity of code
* Efficiency of code
* Quality of docstrings
* Conformance with modern docstring standards
* Conformance with coding standards e.g. PEP 8

I look forward to receiving your comments and criticisms.
I looked at this for a minute and found it carefully written but
somewhat hard to understand. I think it's maybe more OOP-y than
Python programs usually are; perhaps it's Java-like. There are some
efficiency issues that would be serious if the code were being used on
large problems, but probably no big deal for "3D6" or the like. In
particular, you call histogram.numSa mples() in a bunch of places and
each call results in scanning through the dict. You might want to
cache this value in the histogram instance. Making histogram a
subclass of dict also seems a little bit peculiar.

You might find it more in the functional programming spirit to use
gencomps rather than listcomps in a few places:

return sum([freq * val for val, freq in self.items()])
becomes
return sum((freq * val) for val, freq in self.iteritems( ))

etc.
Sep 6 '06 #2
Paul Rubin <http://ph****@NOSPAM.i nvalidwrote

(re <http://www.sailmaker.c o.uk/newfiles/dice.py>)
I looked at this for a minute
Thanks for taking the time to look over it; I greatly appreciate it!
and found it carefully written but somewhat hard to understand.
Obviously, as the author, I have a blind spot about others
understanding it, but I always strive for my code to be self-commenting
and understandable at first sight, so I would genuinely welcome
feedback on which parts are difficult to understand and need more
commenting.

Perhaps it is insufficient commenting of the implementations of the
various subclasses of class Dice? I admit /they/ get a but funky in
places.
I think it's maybe more OOP-y than
Python programs usually are; perhaps it's Java-like.
That's interesting: while my background is certainly more OO than
functional, Java is the language I use least. Certainly I relish the
freedom to mix OO, functional and procedural paradigms that you get
with Python, so if there are ways in which that mixture can improve
dice.py, please enlighten me!

On the other hand, is "being more OOP-y than Python programs usually
are" a bad thing in itself, if the object analysis is cleanly designed?
There are some
efficiency issues that would be serious if the code were being used on
large problems, but probably no big deal for "3D6" or the like. In
particular, you call histogram.numSa mples() in a bunch of places and
each call results in scanning through the dict.
A good point which I did consider, however after practical tests I
ruled in favour of code simplicity for the case in hand, while being
careful to leave the Histogram class open to optimisations such as you
describe via subclassing.

An earlier draft of the Histogram class did indeed have each method do
a single pass through the dict, accumulating what is now numSamples(),
sigma() and sigmaSquared() in local variables. But in practice I found
that for my problem domain, even a 'large' problem would have
relatively few histogram buckets, and computing the summary statistics
for the histogram took a /miniscule/ amount of time compared to the
time taken by generating the data.

On that basis I refactored the Histogram class to follow the "once and
only once" coding principle, resulting in a much clearer and more
concise Histogram class, with very simple and natural code that any
high-school statisician can immediately see is correct. I found no
measurable perfomance hit.
You might want to cache this value in the histogram instance.
On the same basis as above, I decided against caching any results in
the Histogram class, preferring simplicity of code to the additional
logic that would be required to manage cache invalidation upon arrival
of new samples.

I've learned the hard way that caching, while a dramatic optimisation
in the right place, introduces a lot of complexity and pitfalls (even
more so in multi-threaded scenarios), so these days I only do it when
performance analysis reveals the need.

Of course, for histograms with huge numbers of buckets, there may well
be mileage in subclassing the Histogram class to implement the above
optimisations, and I think the class is sufficiently cleanly designed
to facilitate that.
Making histogram a subclass of dict also seems a little bit peculiar.
Why? Genuine question. Keep in mind that I might want to re-use the
Histogram class for cases where the buckets may be floating point, so I
can't just use a vector.

I wanted a mapping of bucket->frequency with an easy way to add a new
sample by incrementing the frequency, so dict seemed a natural choice.
I am of course open to better ideas!
You might find it more in the functional programming spirit to use
gencomps rather than listcomps in a few places:

return sum([freq * val for val, freq in self.items()])
becomes
return sum((freq * val) for val, freq in self.iteritems( ))
Nice: thanks for making me aware of gencomps!

I agree that they're better, but when at home I'm on Mac OS X and so
stuck with Python 2.3 unless I engage in the necessary shenanigans to
slap Python 2.4 onto Mac OS X 10.4.7. Yes, I know how to do it, I've
done it before, but it's a PITA and I don't want to deal with it any
more.

Moreover I want my code to run on vanilla installations of Mac OS X
10.4.x, so I just put up with it and code to Python 2.3.

I'm on Apple's developer program, so if anyone has a Radar bug number I
can cite while requesting they pull their socks up and ship Python 2.4
with the OS, just let me know and I'll cite it to Apple.

Richard.
Sep 13 '06 #3
Richard Buckle wrote:
Comments, insights and overall evaluations are especially welcomed re:
* Cleanliness of design
* Pythonicity of design
* Pythonicity of code
* Efficiency of code
* Quality of docstrings
* Conformance with modern docstring standards
* Conformance with coding standards e.g. PEP 8

I look forward to receiving your comments and criticisms.
Here are some random (and less random) comments in no particular order,
with minimal or no justification; if you're not sure why some point is
good advice, simply ask :) I did just a "shallow parsing", meaning I
didn't attempt to understand what it's actually doing, check for
correctness, algorithm optimizations or major refactorings.

* Instead of importing sets, have the following snippet to be able to
use the builtin set (available since 2.4):
try: set
except NameError: from sets import Set as set

* Prefer new-style classes unless you have a good reason not to. The
change is minimal; just replace "class Dice" with "class Dice(object)".

* Replace most occurences of dict.keys, dict.values, dict.items with
dict.iterkeys, dict.itervalues , dict.iteritems respectively (unless you
write code with Py3K in mind ;-)).

* Avoid mutable default function arguments unless necessary. Instead of
a default empty list, use either an empty tuple or None (in which case
you may assign an empty list in the function's body when the argument
is None).

* Raising LookupError when a sanity check of function arguments fails
looks strange. ValueError (or a a specialised subclass of it) would be
more appropriate. 'assert' statements should also not be used for
arguments checking because they may be turned off when running the
program with '-O'.

* reduce() is discouraged; it's almost always more readable to unroll
it in a for loop.

* Are all the methods public, i.e. useful to a client of the classes ?
If not, the convention is to start the non-public methods' name with a
single underscore (or double underscore sometimes, but name mangling
often causes more problems than it solves in my experience, especially
when inheritance is involved).

* Several snippets can be condensed with list comprehensions, though
one-liners are not to everyone's taste. E.g. I'd write
histograms = []
maxDice = 10
for i in xrange(maxDice) :
dice = StoryTellerDice (i)
histogram = dice.bruteforce ()
histograms.appe nd(histogram)
as histograms = [StoryTellerDice (i).bruteforce( ) for i in xrange(10)]

* [personal preference]: Don't leave space between *every* operator in
expressions, group them based on precedence. E.g. instead of "(n *
sigmaSq - sigma * sigma) / (n * n)", I read it easier as "(n*sigmaSq -
sigma*sigma) / (n*n).
HTH,
George

Sep 13 '06 #4
George Sakkis wrote:
* [personal preference]: Don't leave space between *every* operator in
expressions, group them based on precedence. E.g. instead of "(n *
sigmaSq - sigma * sigma) / (n * n)", I read it easier as "(n*sigmaSq -
sigma*sigma) / (n*n).
The spaced-out version is more `PEP 8`_ compliant. Under "Whitespace in
Expressions and Statements -Other Recommendations " it says "Use spaces
around arithmetic operators" and gives a few examples of "Yes" usage
that look much like the OP's usage.

That said, I also tend to omit the spaces around multiplicative
operators (though I'm slowly training myself out of that). As you say,
in the end, this is really a matter of personal preference.

... _PEP 8: http://www.python.org/dev/peps/pep-0008/
STeVe
Sep 13 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
7827
by: lawrence | last post by:
Suppose I create dynamic web pages with 3 functions (which call other functions to make everything happen, but these 3 you might think of as being the top layer): registerSessions(); sendHtmlToBrowsers(); incrementPageViews(); Is there any chance that incrementPageViews() will be executed? Or, to
15
2033
by: kpp9c | last post by:
I am kind of in a bit of a jam (okay a big jam) and i was hoping that someone here could give me a quick hand. I had a few pages of time calculations to do. So, i just started in on them typing them in my time calculator and writing them in by hand. Now i realize, that i really need a script to do this because: 1. It turns out there are hundreds of pages of this stuff. 2. I have to do something similar in again soon. 3. By doing it by...
4
1996
by: Angelos Devletoglou | last post by:
Hello everybody, I am trying to find if there is any simple Documentation tool or PHP file analyser. I am going to confess that I started designing my project but at some point my timeframe did alow me to spend more time on design so I started developing and I ended up having a crap OO code. So I am looking for a quick way to get all my files and actually output on a paper the function/methods of each Class.
11
4993
by: Tomi Lindberg | last post by:
Hi, I'm trying to find a way to calculate a distribution of outcomes with any combination of dice. I have the basics done, but I'm a bit unsure how to continue. My main concern is how to make this accept any number of dice, without having to write a new list comprehension for each case? Here's a piece of code that shows the way I'm doing things at the moment.
1
3692
by: db55 | last post by:
This script doesn't work. Why? UPDATE SET = LTRIM(SUBSTRING(, 1, convert(bigint, CHARINDEX(',', Comments)-1))) WHERE NOT( IS NULL) AND LEN() > 8 Basically, I'm trying to move everything before a comma into and everything after the comma into . The comments 2 script works. See below.
101
6424
by: Elijah Cardon | last post by:
Let's say I have m dice having n sides, such that n^m is not going to bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1, 2}. What is a good way to represent this in c so that I can check cases by brute force? EC
0
2351
by: Bree | last post by:
The game requires it not to accept negative numbers. At the moment it isnt, and it is urgent I find the solution asap. So if anyone can help I would much appreciate it. Thanks Bree This is the code so far. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head>
4
4130
by: vegtard | last post by:
simple question. is it possible to write a script that rolls a six sided dice? if this is possible, is it possible to tell it to roll the six sided dice 4 times and ignore the dice that rolled the lowest score? if you want to know, i am working on a script to create a dungeons and dragons character :)
1
1801
by: clairelee0322 | last post by:
I am a c++ beginner and i am working on a dice loop lab. This program should roll two dice (each dice is from 1 to 6) and then total them together. The user should be able to input how many times they would like to have the dice rolled. Your program should output the rolls and once the rolls are done, it should output how many of each number had been rolled. //this program will run forever and never stops expect i input the number than is...
0
9666
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9511
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10200
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10139
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9984
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5418
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5551
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3701
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2909
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.