Skip to first unread message

Alan Isaac

unread,
May 23, 2014, 9:11:08 AM5/23/14
to au-ec...@googlegroups.com
Use this thread to discuss the Gambler's Ruin, your first collected programming assignment. 

Please read the syllabus for guidelines for discussion posts for collected assignments.

For pure programming questions related to this assignment, please use the NetLogo Programming thread.

Kevin Carrig

unread,
May 28, 2014, 12:08:07 PM5/28/14
to au-ec...@googlegroups.com
For a Python implementation of the Gambler's Ruin assignment, are there any additional directions/steps beyond those listed here: https://subversion.american.edu/aisaac/notes/gamblers_ruin.xhtml ? For the plotting portions of the assignment, will pyplot suffice?


Alan Isaac

unread,
May 28, 2014, 6:07:52 PM5/28/14
to au-ec...@googlegroups.com
Using Python

The homeworks are constructed assuming you have access to the facilities in NetLogo.  Consider for example the instruction you will quickly encounter: "If you know how, display updates to this plot as your simulation runs."  Doing this requires a substantial understanding of Python, but is almost trivial in NetLogo.

Let me qualify that: I wrote gridworld (http://econpy.googlecode.com/svn/trunk/abm/gridworld/gridworld.py) to make such things easy for Python users.  But I am not asking you to learn gridworld for this class.  (Note that, as you suggested, the graphics functionality in gridworld is provided by Matplotlib.)

So ... I am not going to insist that you use NetLogo, but I think that you will find it profitable, interesting, and easier to use NetLogo.


Alan Isaac

unread,
May 29, 2014, 12:48:17 PM5/29/14
to au-ec...@googlegroups.com
Remember to use this thread for the Gambler's Ruin questions.  I had expected many questions by now!

Alan Isaac

Amanda Saville

unread,
May 29, 2014, 9:35:10 PM5/29/14
to au-ec...@googlegroups.com
Hi everyone,

Maybe it's me, but I'm feeling a little frustrated/confused with the project.  I'm not sure what the pound sign does in code, and I tried to look it up in the Netlogo dictionary, but it wasn't there.  I was going to just accept the pound sign in the lecture notes code for the playonce procedure, but I am getting an error that #player1 has not been defined.  Clearly I am missing something...

Any direction/advice would be helpful, even if it is just to say that you too are having this issue (so I know I'm not alone).

Natalie Chambers

unread,
May 29, 2014, 9:46:33 PM5/29/14
to au-ec...@googlegroups.com

Amanda you shouldn't be getting an issue with the #player1, double check your syntax. You shouldn't need to define #player1 or #player2 before hand like you would with a global variable. Did you add anything additional between your setup and the playonce command?

Amanda Saville

unread,
May 29, 2014, 10:11:29 PM5/29/14
to au-ec...@googlegroups.com
Just a very simple "to go" procedure:

to go
  playonce [#player1 #player2]
end

Dongping Xie

unread,
May 30, 2014, 5:39:04 AM5/30/14
to au-ec...@googlegroups.com
Hi Amada,

I think your code has a couple problems. 

First, the go procedure should take two inputs: #player1 and #player2. You pass along them to playonce when you call it within go. If go takes no inputs, an error will show that #player1 is not defined. As Natalie suggested, you do not need to define #player1 and #player2 as globals. Instead, you only need to take them as inputs to go

Second, inside go, when you call playonce, you do not need the brackets because you are not defining the procedure playonce.

So your code should look like this.

to playonce [#player1 #player2]
  ...
end

to transfer [#player1 #player2 n]
  ...
end

to go [#player1 #player2]
  playonce #player1 #player2
end

Dongping

Alan Isaac

unread,
May 30, 2014, 10:05:23 AM5/30/14
to au-ec...@googlegroups.com
Pound (Hash) Sign

The pound sign does not "do" anything.  It is just part of the variable name.  It can be a useful convention to use the pound sign to start the names of all local variables that are introduced as *arguments* to procedures and reporters.  This is just a convention, but it helps you remember where the variables come from.

In the required reading, this convention was introduced in the discussion of parameters for procedures:
https://subversion.american.edu/aisaac/notes/netlogo-intro.xhtml#parameters-for-procedures

Similarly, it can be a useful convention to prefix a percentage sign to all local variables that are introduced inside procedures and reporters.  (By "inside" I mean they are not arguments but rather are introduced in the body of the procedure or reporter.)

Message has been deleted

Adaora Isichei

unread,
May 30, 2014, 2:28:15 PM5/30/14
to au-ec...@googlegroups.com

For this assignment, when asked to set the wealth, is it correct to assign any random positive integer?

Alan Isaac

unread,
May 30, 2014, 2:38:50 PM5/30/14
to au-ec...@googlegroups.com
Initial Wealth

The instructions for the 2-player gambler's ruin exercise include this line:

   Use an initial wealth of 100 (and thus do at most 100*100 iterations).

Is this the answer to your question?

Adaora Isichei

unread,
May 30, 2014, 2:59:46 PM5/30/14
to au-ec...@googlegroups.com
Yes, thanks

Adin Dobkin

unread,
May 30, 2014, 3:40:54 PM5/30/14
to au-ec...@googlegroups.com
For some strange reason, my 'playonce' procedure is preventing a proper check from occurring.  Currently, it's more or less the standard code offered, but when I check the procedure, it says that 1 is an expected command (from the transfer #player1 #player2 1 line of code).  Does anyone have an idea where the source of this problem might be?  The only thing that I can think of is that I messed up the order of things somewhere.


On Friday, May 23, 2014 9:11:08 AM UTC-4, Alan Isaac wrote:

Natalie Chambers

unread,
May 30, 2014, 3:52:22 PM5/30/14
to au-ec...@googlegroups.com
I am wondering if anyone has gotten the __includes command to work. I have looked up in the netlogo dictionary the way to properly input the __includes command but I keep receiving an error message that says "expected string or ]". Perhaps this is a silly error but I have tried many variations of the includes command and file name but haven't had any luck with successfully replacing the playonce command without an error. 

Adin if you copied it straight from the notes then the playcode procedure shouldn't give you any problems. Did you put in in directly after your setup procedure?

Adin Dobkin

unread,
May 30, 2014, 3:54:55 PM5/30/14
to au-ec...@googlegroups.com
Nevermind, figured this out.

Alan Isaac

unread,
May 30, 2014, 7:23:33 PM5/30/14
to au-ec...@googlegroups.com
__includes

The __includes command takes as its argument a list of strings.  You make a list with brackets.  You make a string with quotes ("a string").  Don't forget to name the file to be included with the .nls extension!
http://ccl.northwestern.edu/netlogo/5.0/docs/dictionary.html#includes

Ask again if that does not get you there:

Natalie Chambers

unread,
May 31, 2014, 1:11:14 PM5/31/14
to au-ec...@googlegroups.com
Yes I read about the __include before posting. 

I have:
__includes [ ruin.nls ] 

Which I tried using now spaces around the brackets and a couple of other variations but haven't been successful. 

Alan Isaac

unread,
May 31, 2014, 3:44:10 PM5/31/14
to au-ec...@googlegroups.com
Strings

Question: what does a list of strings look like?  (Hint: see my previous post on __includes.)

Natalie Chambers

unread,
May 31, 2014, 4:14:39 PM5/31/14
to au-ec...@googlegroups.com
I was able to get it to work. Thanks.

Amanda Saville

unread,
May 31, 2014, 4:23:33 PM5/31/14
to au-ec...@googlegroups.com
Hi all, 

I'm working on GR static-pairs, and I am SURE I am missing something, but I've been on a hunt for about 20 minutes and it is really holding me up... 

Does anyone know where I can find the idxpairs01 procedure?  Is it right in front of me and I'm not seeing it? 

 Or if idxpairs is just code to put the players in static pairs, can I use a different name for the procedure I have written for this step?

Alan Isaac

unread,
Jun 1, 2014, 12:07:20 AM6/1/14
to au-ec...@googlegroups.com
idxpairs01

It does not matter what you name this, but you are asked to develop a procedure that accepts as input a list and returns a list of list of lists, where each inner list is a pair of elements from the input list. (As the assignment says: "Write the code needed to 'pair up' items in a list.")  You want to define

to-report idxpairs01 [#lst]
 
...
end

This is a challenging part of the assignment!  It requires that you use all that you have learned about NetLogo programming to date.  Here is one approach.  First, shuffle the list. (This is not important for the static pair problem but is important when you do random repairing.)  Next, divide the list into two sublists (using sublist). Then use map on the two sublists to produce the list of lists that you need.

Dongping Xie

unread,
Jun 1, 2014, 2:12:35 AM6/1/14
to au-ec...@googlegroups.com


On Saturday, May 31, 2014 3:40:54 AM UTC+8, Adin Dobkin wrote:
For some strange reason, my 'playonce' procedure is preventing a proper check from occurring.  Currently, it's more or less the standard code offered, but when I check the procedure, it says that 1 is an expected command (from the transfer #player1 #player2 1 line of code).  Does anyone have an idea where the source of this problem might be?  The only thing that I can think of is that I messed up the order of things somewhere.


How many inputs did you include in the transfer procedure? You should have 3 inputs for transfer: the first two are two agents, #player1 and #player2, and the third agent is an amount of wealth transfer. So you transfer procedure should look like:

to transfer [ #player1 #player2 n ]
...
end

If this is not your problem, please ask again and try to be more specific about the problem of your code. 

Amanda Saville

unread,
Jun 1, 2014, 3:49:12 PM6/1/14
to au-ec...@googlegroups.com
I'm sorry again I keep posting on this thread...

Thank you, Dr. Isaac, for clearing up the part about idxpairs01.  Natalie and I had discussed how to derive code from the sample code you posted for static pairs, but then I was concerned that you had provided the code somewhere that we should be using.

I'm not sure how everyone else is fairing in this assignment, but I have found it very challenging.  I am working on ruin03 now, but I seem to be stuck on how to change the transfer function from a function using arrays.  I keep re-reading the dictionary on "map" and "talking-to patches," but I don't seem to be getting anywhere.  Ideally, I would like a list item (1 wealth) to transfer to the wealth of another patch...

Hopefully that makes sense without actually posting my code and going into more detailed questions.  Any advice or suggestions or hints would be extremely helpful!

Thank you!

Alan Isaac

unread,
Jun 1, 2014, 4:44:34 PM6/1/14
to au-ec...@googlegroups.com
Transfer Between Patches

First of all, more questions in this thread is a good thing!

Second, help me understand why writing a new transfer procedure seems challenging.  You will again play between two players, but now the players will be patches (instead of array indexes).  Did you give your patches a wealth attribute?   If so, you can change it like you change any other attribute (using set).

Amanda Saville

unread,
Jun 1, 2014, 5:09:28 PM6/1/14
to au-ec...@googlegroups.com
It may be that I am just over-thinking it (in which case, it may be best for me to just walk away from my code for a few hours).  I have already given my patches a wealth attribute, and set the attribute to initial wealth.  

I suppose my trouble has more to do with the logic of programming the transfer procedure to locate a list, and transfer 1 wealth value from one patch's list to another.  This may also be complicated by me thinking about whether or not I need to define #player1 #player2 differently in some of my other procedures now that we are dealing with patches.

And if this question seems like it doesn't totally make sense, then it may just be because I need a break for a bit, and I will hopefully have an "aha!" moment. 

Thank you, Dr. Isaac, for your fast response, and I appreciate the open-door policy for questions (I just didn't want to seem like I was abusing the privilege)!

Alan Isaac

unread,
Jun 1, 2014, 5:16:19 PM6/1/14
to au-ec...@googlegroups.com
Transfer Between Patches

One thing you want to take away from the other parts of the assignment is the usefulness of breaking a task into small, manageable parts.  In this case, the transfer procedure should almost identical to the one you have already used.  It should take 3 arguments: a patch, a patch, and an amount.

I suspect your real question is, how do I get a list of the patches.

Please let me know if that is not enough of a hint.

Alan Isaac

Sebastien Lundby-Thomas

unread,
Jun 1, 2014, 8:38:39 PM6/1/14
to au-ec...@googlegroups.com
I am running into the same exact types of issues, I have been trying to find some examples of other codes that have lists where they store and reuse the data for comparison. I will look up the links again and place them up here if I can. That said it has gotten me a little bit further along, but I am still running into issues of my own.

Natalie Chambers

unread,
Jun 1, 2014, 9:19:27 PM6/1/14
to au-ec...@googlegroups.com
Thank you Dr. Issac for the responses and Amanda for posing this important question. I am also having issues with this because it seems like the transfer function needs to be in terms of x and y coordinates instead of a value from the array but I am having difficulty getting the right code to use coordinates. 

Alan Isaac

unread,
Jun 1, 2014, 10:28:33 PM6/1/14
to au-ec...@googlegroups.com
Issues

You need to be *very specific* about the kinds of issues you are having, or I cannot provide any useful feedback.

Natalie Chambers

unread,
Jun 1, 2014, 10:30:40 PM6/1/14
to au-ec...@googlegroups.com
When passing patches into the transfer procedure how do you get the pxcor and the pycor values from them?

Alan Isaac

unread,
Jun 1, 2014, 10:31:11 PM6/1/14
to au-ec...@googlegroups.com
Transfer Between Patches

You do NOT need to use the x and y coordinates.  You just need a list of all the patches.  See my previous hints about using self and of!

You want to change your previous code as little as possible!


Alan Isaac

unread,
Jun 2, 2014, 7:38:28 AM6/2/14
to au-ec...@googlegroups.com
Patch Attribute Access

The pxcor and pycor attributes are accessed like any other attributes, with of:
http://ccl.northwestern.edu/netlogo/5.0/docs/dictionary.html#of

In fact this is one of the example in the documentation.

But you do not need these attributes.  Please help me understand why you think you need them.

Kevin Carrig

unread,
Jun 2, 2014, 7:59:30 AM6/2/14
to au-ec...@googlegroups.com
For a python implementation of the random- repairing phase, can you expand on the use of global? I believe my reassignments are not correct. Please see the snippet below:

#Create Ruin2Player Function

'''Our simulation is bounded by a maximum number of iterations (100*100) for the entire game'''
'''Our simulation is bounded by one simulation per pairings before regrouping the pairs'''
 
itr2=0
def ruin2player(pairs):
  global itr2
  for q in pairs:
itr=0
larger_itr=10000
  while (itr<maxitr) and (itr2<larger_itr):
    play_once(q[0],q[1])
itr += 1
itr2 = itr2+1

'''An alternative is to allow players who still have wealth to continue playing until the maximum number of iterations is reached.'''

def resampling(pairs):
ruin2player(pairs)
while (all(a != 0 for a in wealths.values())):
pairs=pairup(list_of_players)
resampling(pairs)
else:
for k,v in wealths.items():
    if v == 0:
        del wealths[k]
for i in list_of_players:
if i==k:
del i
pairs=pairup(list_of_players)
resampling(pairs)

#Run Simulation
resampling(pairs)

Alan Isaac

unread,
Jun 2, 2014, 8:38:26 AM6/2/14
to au-ec...@googlegroups.com
Use of global in Python

When you post code, please use the Google's code formatting option ({}).

First of all, note that the code I posted for ruin2player does not need to be changed.  It will work fine once you correctly define playonce, and I also posted code for that.  For the two-player code, you pretty much just need to assemble the pieces.  But it looks like you are probably reusing the name ruin2player for a new purpose: to have each pair play once.  If so, that is a bit confusing.  So let us rename it playround.

Ordinarily in Python one does not need to use global. All variables introduced at the top ("module") level are global to the module.  (Of course they must be introduced before they are used.) So your use of global in this function is not actually doing anything.  Furthermore, we in any case do not want to increment each time a player plays, since we want *every* player to be able to play up to 10,000 times.  So don't test for the number of iterations in your playround function, but rather in what you called resampling.  Finally, there is no need to use a dictionary.  For our purposes, you can just use a list of wealth numbers.  In the Classic case, you can just keep shuffling the list.  In the other case, you are going to have to weed out the wealths that go to zero.  You want to program those two cases separately.  Related to this, usually you will want to avoid recursive constructs unless there is a darn good reason, as each recursion will add to the call stack (http://www.programmerinterview.com/index.php/recursion/explanation-of-recursion/).  So move your stopping test into your resampling function and get rid of the recursion.

Alan Isaac

Kevin Carrig

unread,
Jun 2, 2014, 10:00:55 AM6/2/14
to au-ec...@googlegroups.com
The recursion documentation was helpful-I was encountering several 'recursion depth' errors when running the program. I have updated the stop case as you suggested, but there are still a few bugs I am trying to sort through. Any insight?


#Create Play Once Function
# Based on the results of the coin flip, transfer payments are made from/to each player

def play_once(player1,player2):
  if random.uniform(0,1) < 0.5: #flip coin
    transfer(player1, player2, 1)
  else:
    transfer(player2, player1, 1)

#Create Ruin2Player Function

'''Our simulation is bounded by a maximum number of iterations (100*100) for the entire game'''
'''Our simulation is bounded by one simulation per pairings before regrouping the pairs'''
'''Removed the minimum wealth condition as this is taken care of in the resampling function to follow'''
maxitr=1
def ruin2player(pairs):
  itr = 0
  while (itr<maxitr):
    itr += 1
    play_once(pairs[0], pairs[1])

'''An alternative is to allow players who still have wealth to continue playing until the maximum number of iterations is reached.'''

def resampling(pairs):
for _ in range(1,10000,1):
while (all(a != 0 for a in wealths.values())):
pairs=pairup(list_of_players)
for q in range(0,len(pairs)-1,1):
ruin2player(pairs[q])
else:
for k,v in wealths.items():
    if v == 0:
try:
        del wealths[k]
except KeyErrror:
pass
del list_of_players[int(k.split('_')[1])]
pairs=pairup(list_of_players)
for q in range(0,len(pairs)-1,1):
ruin2player(pairs[q])

#Run Simulation
resampling(pairs)


Message has been deleted

Kevin Carrig

unread,
Jun 2, 2014, 10:26:18 AM6/2/14
to au-ec...@googlegroups.com
Some additional debugging shows the source of the error in the else-clause below. The while function takes care of one of the approaches to the random re-sampling (stop the simulation when any one players wealth falls to zero). The else clause is removing those players from the simulation whose wealth falls to zero (And thus allows the remaining winners to keep playing).

def resampling(pairs):
for _ in range(1,10000,1):
while (all(a != 0 for a in wealths.values())):
pairs=pairup(list_of_players)
for q in range(0,len(pairs)-1,1):
ruin2player(pairs[q])
else:
for k,v in wealths.items():
    if v == 0:
        del wealths[k]

Alan Isaac

unread,
Jun 2, 2014, 10:27:18 AM6/2/14
to au-ec...@googlegroups.com
Dealing with Bugs

When you run into bugs in your code, as is sure to happen, you have to decide how to investigate them.  This is one of the things explored in the required readings on verification.

Recall the following suggestions:

- use lots of print statements ("scaffolding") to test your program logic
- use lots of assertions (using assert in Python or error in NetLogo) to test your program logic
- use program bisection to isolate bugs (e.g., put a new print our assert that tests for the bug halfway through your program, then keep moving it by halves to isolate the bug)
- use empty (or trivial) procedures/functions to test the code structure

When you report a bug, do not just say that you encountered a bug.  Give a precise statement of the error statement (or other problem) that you encountered.

One other Python hint: if you find yourself using an else clause with while, there is usually a better way.


Alan Isaac

unread,
Jun 2, 2014, 10:38:30 AM6/2/14
to au-ec...@googlegroups.com
Dealing with Bugs

Remember to only format the code as code (using {}), not the rest of your comment.

Don't try to put the two approaches to the Gambler's Ruin in a single function.  They are two separate experiments.

Kevin Carrig

unread,
Jun 2, 2014, 10:59:49 AM6/2/14
to au-ec...@googlegroups.com
In the bottom half of the Gambler's Ruin notes, it reads: "With random re-pairing, we need a stopping condition for the simulation as a whole. The classical condition is to stop when any one player’s wealth goes to zero. An alternative is to allow players who still have wealth to continue playing until the maximum number of iterations is reached."

The histogram that follows the code below looks much like the last, normally distributed plot in the notes. However, my thought was that I was implementing the random repairing and that the histogram should look like the one before it (where we see accumulation by the lucky). In the code below, as long as all of the players wealth are greater than zero and we are below our maximum number of iterations (10,000), we reassign the pairs (this is the random element) and run the ruin2player function. Does my 'classical' implementation below satisfy the criteria for the random reassignment part of the project, or am I misreading the lecture notes?

def resampling(pairs):
 for _ in range(1,10000,1):
             while (all(a != 0 for a in wealths.values())):
                 pairs=pairup(list_of_players)
                  for q in range(0,len(pairs)-1,1):
                              ruin2player(pairs[q])
          print _



Alan Isaac

unread,
Jun 2, 2014, 11:38:15 AM6/2/14
to au-ec...@googlegroups.com
Dealing with Bugs

Use a single argument for range.  Python uses 0-based indexing (as does NetLogo).

In the code, it looks like you are going back and forth between list_of_players and a wealths dict.

The basic idea is sound: keep playing rounds until any one player has wealth 0.  But note that your while loop is inside your for loop!

Again: use many more print statements and assertions to check your program logic.

Alan Isaac

unread,
Jun 6, 2014, 1:39:55 PM6/6/14
to au-ec...@googlegroups.com
In general, students did pretty well on this assignment. A common problem was that some students did not setup and update the dynamic plot and histogram properly. Another problem is that some students did not recognize that random re-pairing requires all agents with positive wealths to be regrouped and re-paired after each round.

The Gambler's Ruin assignment familiarized you with the core programming features of NetLogo.  You should now have the programming skills needed for your term project.  The next assignment will focus on doing experiments with your models.  We will use the famous Schelling Segregation model for this.

Adaora Isichei

unread,
Jun 7, 2014, 9:56:02 AM6/7/14
to au-ec...@googlegroups.com
Does the Gambler’s Ruin shed light on the role of institutions?
My understanding of Gambler's Ruin is that an institutions chance of going bankrupt depends on the amount of money another institution (opponent)starts with. The more money your opponent start off with the high your chance of going bankrupt. This concept is applicable to casinos and the stock market.

Alan Isaac

unread,
Jun 9, 2014, 8:30:36 AM6/9/14
to au-ec...@googlegroups.com
Institutions

Thank you for taking up this topic, which I had hoped would receive more discussion.  Your focus on the role of relative initial wealth is interesting and important.  However, I was looking for a comment on how the rules (instittutions) under which the game is played affect the final wealth distribution.  While the rules of the various "Gambler's Ruin" exercises do not of course map directly to our social institutions, the assignment does seem to suggest that we should scrutinize our institutions if we care about distributional outcomes.
Reply all
Reply to author
Forward
0 new messages