A few days ago I was asked in the comments of another question to upload my code and rephrase the question. Here it goes.
The following code contains a series of variables and functions, which define a set of signals according to a certain model. The output gives us the signals that each player shows in each round.
I need to know how:
Simulate this game x times (for example 1000). I have managed to do it with execfile("Mymodule.py"), but it is not useful for storing the results.
Store in a csv file (rows (signals) and columns (players)), the results. That is, the csv file contains at the end of the 1000 simulations the amount of each type of signal that each player has produced in each round. This is useful for later statistical analysis. I've only managed to open and close a CSV file, but I'm afraid I'm stuck.
Here is the code:
import random
##### Variables ######
emparejamientos= ([[1,2],[3,4], #ronda 1 (participante 1 juega con 2 y 3 con 4)
[1,3],[2,4], #ronda 2 (1 con 3 y 2 con 4)
[1,4],[2,3]]) #ronda 3 (1 con 4 y 2 con 3)
#Parejas de cada participante en cada ronda (empezando por la ronda 1).
pareja_part1= [2,3,4]
pareja_part2= [1,4,3]
pareja_part3= [4,1,2]
pareja_part4= [3,2,1]
#Parametros del modelo
s1=1
s2=0
s3=0
s4=0
b=0.5
x=0.5
m=0.02
round=[0,1,2,3,4,5,6] #rounds
#Senales
S1="S1"
S2="S2"
S3="S3"
S4="S4"
opciones = [S1, S2, S3, S4]
#Diccionarios de memoria
Muestra_part1 = {"S1":0,"S2":0,"S3":0,"S4":0}
Observa_part1 = {"S1":0,"S2":0,"S3":0,"S4":0}
Muestra_part2 = {"S1":0,"S2":0,"S3":0,"S4":0}
Observa_part2 = {"S1":0,"S2":0,"S3":0,"S4":0}
Muestra_part3 = {"S1":0,"S2":0,"S3":0,"S4":0}
Observa_part3 = {"S1":0,"S2":0,"S3":0,"S4":0}
Muestra_part4 = {"S1":0,"S2":0,"S3":0,"S4":0}
Observa_part4 = {"S1":0,"S2":0,"S3":0,"S4":0}
##### Funciones #####
#Almacen de senales mostradas en el diccionario de memoria Muestra_partx
def mem_mostradas(e, memoria):
if e == S1:
memoria[S1] +=1
if e == S2:
memoria[S2] +=1
if e == S3:
memoria[S3] +=1
if e == S4:
memoria[S4] +=1
return memoria
#Almacen de senales observadas en el diccionario de memoria Observa_partx
def mem_observadas(pareja_part, memoria):
if pareja_part == 1:
memoria[eleccion1] +=1
if pareja_part == 2:
memoria[eleccion2] +=1
if pareja_part == 3:
memoria[eleccion3] +=1
if pareja_part == 4:
memoria[eleccion4] +=1
return memoria
#Probabilidad para cada participante de mostrar una senal determinada en una ronda
def with_b(muestra, observa, s, r):
result = ((0.98) * (1.0 - 0) * (1.0 - x) * muestra/r) + ((0.98) * (1.0 - 0) * (x) * observa/r) + ((0.98) * 0 * s) + ((m / 8))
if not (muestra == observa == 0):
result = ((0.98) * (1.0 - b) * (1.0 - x) * muestra/r) + ((0.98) * (1.0 - b) * (x) * observa/r) + ((0.98) * b * s) + ((m / 8))
return result
#Funcion que arroja la opcion que cada participante elige para mostrar
from random import random
from bisect import bisect
def choice(opciones, probs):
probAcumuladas=[]
aux = 0
for p in probs:
aux += p
probAcumuladas.append(aux)
r = random() * probAcumuladas[-1]
op = bisect(probAcumuladas, r)
return opciones[op]
##### Juego #####
#RONDA 1
#Senales mostradas por cada participante en ronda 1
eleccion1=S1
eleccion2=S2
eleccion3=S3
eleccion4=S4
print "Senales mostradas en la generacion 1 \n jugador1: {0}, jugador2: {1}, jugador3: {2}, jugador4: {3}".format(S1, S2, S3, S4)
#Almacen de senales mostradas en el diccionario (memoria de senales mostradas)
Muestra_part1=mem_mostradas(eleccion1,Muestra_part1)
Muestra_part2=mem_mostradas(eleccion2,Muestra_part2)
Muestra_part3=mem_mostradas(eleccion3,Muestra_part3)
Muestra_part4=mem_mostradas(eleccion4,Muestra_part4)
#Almacen de senales observadas en el diccionario (memoria de senales observadas)
Observa_part1=mem_observadas(pareja_part1[0], Observa_part1)
Observa_part2=mem_observadas(pareja_part2[0], Observa_part2)
Observa_part3=mem_observadas(pareja_part3[0], Observa_part3)
Observa_part4=mem_observadas(pareja_part4[0], Observa_part4)
#RONDA 2
#Probabilidad para cada participante de mostrar una senal determinada en 2a ronda
Prob_S1_part1 = with_b(Muestra_part1[S1], Observa_part1[S1], s1, round[1])
Prob_S2_part1 = with_b(Muestra_part1[S2], Observa_part1[S2], s2, round[1])
Prob_S3_part1 = with_b(Muestra_part1[S3], Observa_part1[S3], s3, round[1])
Prob_S4_part1 = with_b(Muestra_part1[S4], Observa_part1[S4], s4, round[1])
Prob_S1_part2 = with_b(Muestra_part2[S1], Observa_part2[S1], s1, round[1])
Prob_S2_part2 = with_b(Muestra_part2[S2], Observa_part2[S2], s2, round[1])
Prob_S3_part2 = with_b(Muestra_part2[S3], Observa_part2[S3], s3, round[1])
Prob_S4_part2 = with_b(Muestra_part2[S4], Observa_part2[S4], s4, round[1])
Prob_S1_part3 = with_b(Muestra_part3[S1], Observa_part3[S1], s1, round[1])
Prob_S2_part3 = with_b(Muestra_part3[S2], Observa_part3[S2], s2, round[1])
Prob_S3_part3 = with_b(Muestra_part3[S3], Observa_part3[S3], s3, round[1])
Prob_S4_part3 = with_b(Muestra_part3[S4], Observa_part3[S4], s4, round[1])
Prob_S1_part4 = with_b(Muestra_part4[S1], Observa_part4[S1], s1, round[1])
Prob_S2_part4 = with_b(Muestra_part4[S2], Observa_part4[S2], s2, round[1])
Prob_S3_part4 = with_b(Muestra_part4[S3], Observa_part4[S3], s3, round[1])
Prob_S4_part4 = with_b(Muestra_part4[S4], Observa_part4[S4], s4, round[1])
probabilidades1 = [Prob_S1_part1, Prob_S2_part1, Prob_S3_part1, Prob_S4_part1]
probabilidades2 = [Prob_S1_part2, Prob_S2_part2, Prob_S3_part2, Prob_S4_part2]
probabilidades3 = [Prob_S1_part3, Prob_S2_part3, Prob_S3_part3, Prob_S4_part3]
probabilidades4 = [Prob_S1_part4, Prob_S2_part4, Prob_S3_part4, Prob_S4_part4]
#Senales que muestran los participantes en la RONDA 2. Asignadas segun las probabilidades dadas por la ecuacion de memorias
eleccion1 = choice(opciones, probabilidades1) #senal mostrada por participante 1 en ronda 2
eleccion2 = choice(opciones, probabilidades2) #senal mostrada por participante 2 en ronda 2
eleccion3 = choice(opciones, probabilidades3) #senal mostrada por participante 3 en ronda 2
eleccion4 = choice(opciones, probabilidades4) #senal mostrada por participante 4 en ronda 2
print "Senales mostradas en la generacion 2 \n jugador1: {0}, jugador2: {1}, jugador3: {2}, jugador4: {3}".format(eleccion1, eleccion2, eleccion3, eleccion4)
#Almacen de senales mostradas en el diccionario (memoria de senales mostradas)
Muestra_part1=mem_mostradas(eleccion1,Muestra_part1)
Muestra_part2=mem_mostradas(eleccion2,Muestra_part2)
Muestra_part3=mem_mostradas(eleccion3,Muestra_part3)
Muestra_part4=mem_mostradas(eleccion4,Muestra_part4)
#Almacen de senales observadas en el diccionario (memoria de senales observadas)
Observa_part1=mem_observadas(pareja_part1[1], Observa_part1)
Observa_part2=mem_observadas(pareja_part2[1], Observa_part2)
Observa_part3=mem_observadas(pareja_part3[1], Observa_part3)
Observa_part4=mem_observadas(pareja_part4[1], Observa_part4)
#RONDA 3
#Probabilidad para cada participante de mostrar una senal determinada en 3a ronda
Prob_S1_part1 = with_b(Muestra_part1[S1], Observa_part1[S1], s1, round[2])
Prob_S2_part1 = with_b(Muestra_part1[S2], Observa_part1[S2], s2, round[2])
Prob_S3_part1 = with_b(Muestra_part1[S3], Observa_part1[S3], s3, round[2])
Prob_S4_part1 = with_b(Muestra_part1[S4], Observa_part1[S4], s4, round[2])
Prob_S1_part2 = with_b(Muestra_part2[S1], Observa_part2[S1], s1, round[2])
Prob_S2_part2 = with_b(Muestra_part2[S2], Observa_part2[S2], s2, round[2])
Prob_S3_part2 = with_b(Muestra_part2[S3], Observa_part2[S3], s3, round[2])
Prob_S4_part2 = with_b(Muestra_part2[S4], Observa_part2[S4], s4, round[2])
Prob_S1_part3 = with_b(Muestra_part3[S1], Observa_part3[S1], s1, round[2])
Prob_S2_part3 = with_b(Muestra_part3[S2], Observa_part3[S2], s2, round[2])
Prob_S3_part3 = with_b(Muestra_part3[S3], Observa_part3[S3], s3, round[2])
Prob_S4_part3 = with_b(Muestra_part3[S4], Observa_part3[S4], s4, round[2])
Prob_S1_part4 = with_b(Muestra_part4[S1], Observa_part4[S1], s1, round[2])
Prob_S2_part4 = with_b(Muestra_part4[S2], Observa_part4[S2], s2, round[2])
Prob_S3_part4 = with_b(Muestra_part4[S3], Observa_part4[S3], s3, round[2])
Prob_S4_part4 = with_b(Muestra_part4[S4], Observa_part4[S4], s4, round[2])
probabilidades1 = [Prob_S1_part1, Prob_S2_part1, Prob_S3_part1, Prob_S4_part1]
probabilidades2 = [Prob_S1_part2, Prob_S2_part2, Prob_S3_part2, Prob_S4_part2]
probabilidades3 = [Prob_S1_part3, Prob_S2_part3, Prob_S3_part3, Prob_S4_part3]
probabilidades4 = [Prob_S1_part4, Prob_S2_part4, Prob_S3_part4, Prob_S4_part4]
#Senales que muestran los participantes en la RONDA 3. Asignadas segun las probabilidades dadas por la ecuacion de memorias
eleccion1 = choice(opciones, probabilidades1) #senal mostrada por participante 1 en ronda 3
eleccion2 = choice(opciones, probabilidades2) #senal mostrada por participante 2 en ronda 3
eleccion3 = choice(opciones, probabilidades3) #senal mostrada por participante 3 en ronda 3
eleccion4 = choice(opciones, probabilidades4) #senal mostrada por participante 4 en ronda 3
print "Senales mostradas en la generacion 3 \n jugador1: {0}, jugador2: {1}, jugador3: {2}, jugador4: {3}".format(eleccion1, eleccion2, eleccion3, eleccion4)
#Almacen de senales mostradas en el diccionario (memoria de senales mostradas)
Muestra_part1=mem_mostradas(eleccion1,Muestra_part1)
Muestra_part2=mem_mostradas(eleccion2,Muestra_part2)
Muestra_part3=mem_mostradas(eleccion3,Muestra_part3)
Muestra_part4=mem_mostradas(eleccion4,Muestra_part4)
#Almacen de senales observadas en el diccionario (memoria de senales observadas)
Observa_part1=mem_observadas(pareja_part1[2], Observa_part1)
Observa_part2=mem_observadas(pareja_part2[2], Observa_part2)
Observa_part3=mem_observadas(pareja_part3[2], Observa_part3)
Observa_part4=mem_observadas(pareja_part4[2], Observa_part4)
The output in an example simulation is as follows:
Senales mostradas en la generacion 1
jugador1: S1, jugador2: S2, jugador3: S3, jugador4: S4
Senales mostradas en la generacion 2
jugador1: S1, jugador2: S1, jugador3: S3, jugador4: S4
Senales mostradas en la generacion 3
jugador1: S2, jugador2: S1, jugador3: S1, jugador4: S1
Therefore, it is sought to store in a CSV file, during 1000 simulations, the signals that each player has generated in each round.
An example of how it would be useful to store the results in a CSV for later statistical analysis is as follows. In the example, the RONDAX columns show the number of times each signal has been chosen (the numbers in this image do not correspond to any simulation with the program, and therefore the summations are inconsistent, since it is only an example to illustrate table format).
Edition (11.01.2016):
Starting from the latest version of the code shared by @FJSevilla, I would like to be able to go a little further. With regard to the statistical analysis of the data, it would be interesting to obtain not only 1,000 simulations, but x samples of 1,000 simulations.
Using the same code, the table of results that is intended to be obtained in this case is as follows (exemplifying what a CSV would look like that would store the results of 3 samples of 1000 simulations of the complete game):
Where in "sample" the number 1 refers to the first 1,000 simulations, 2 refers to the second 1,000 simulations, and so on. Where "round" refers to the round number within the game. Where "player" refers to the player number.
Note that in this case the parameters b, x and m are included in the table, and that the numbers in the "Senalx" columns refer to the times each signal has been chosen in each round.
It is a different data order configuration than the one we had, but it would facilitate statistical comparison. Any helping hand with this?
I have been looking at the previous questions and based on this I leave you an approximation using OOP. In this way the code is reduced and easily scalable since it allows the use of an indeterminate number of signals, players and rounds. Some clarifications:
I have removed the variable
round
since, I think, you only use the list to number the round you are in, that is, it is always of the form:If not, it can be easily modified so that the constructor accepts the list as a variable.
The operation of the method
generar_senales()
is:In round 1, the signals of each participant are determined by the order of the player and signal parameters that we pass to the constructor. For example:
In the first round player 1 shows the 'a' signal, 2 the 'b' signal, 3 the 'r' signal and 4 the 'n' signal.
In the second round and later it uses the signals from the first round to generate each signal randomly and according to the probabilities for each player and signal (using the
with_b
and functionschoise
).The method
generar_senales()
is a generator (yield
) and returns a dictionary with the random signal of each player, in the form:This same dictionary is the one used to create the corresponding row of the
csv
The variables
s1
,s2
,s3
, Is4
pass inside a list calleds
, in this way we can define any number of players and signals.I have also modified the way of passing the pairings, now each round is a list that contains the pairings inside. This way it is more intuitive. However, your form could still be used with some modifications.
The
csv
header (first row) has the names of the players. The rest of the rows are the rounds (sign shown by each player).As shown in the following execution we simulate a game of 4 rounds with 6 players:
This generates an
csv
open with LibreOffice (to see more visually how the data is left) is:In this case the csv has 6 columns (1 per player) and 4001 rows (the first is the header and the other 4000 corresponds to the thousand simulations of the 4-round game). To adapt it to other parameters you only have to modify them in the function
main()
There are many ways to do this, in this case what I do is that I save
self.memoria
the choices of each round in a list of dictionaries ( ) and then use it to create the csv. To handle the csv itself I use thecsv
Python standard library.Edition:
Si deseas obtener las frecuencias con que cada jugador a mostrado cada señal a partir del
csv
puedes hacer algo así:csv.reader
crea un generador que itera sobre las filas delcsv
, si lo que quiereses obtener las columnas, una solución es tratarlo como una matriz y usar su transpuesta (descartando la primera fila que es la cabecera con los nombres), para ello podemos usaritertools.izip
. Para contar las frecuencias es muy útilcollections.Counter
.Este código lo puedes usar dentro de la función
main
anterior, para ello mueve los import al inicio del módulo. Unas salida ejemplo sería:If you are going to work a lot with files
csv
and data, I recommend that you look atpandas
Edition 2: I leave you the code with the
main
modified function so that it generates thecsv
one you want according to the edition of your question.Simulating your example we get something
csv
like the following:As pointed out in a comment, you can simply wrap the game part in a loop and save the information you need the way you need it. For example, it could be like this:
I have moved the
import
s to the beginning of the program and removed unnecessary parts. The lines that do the job you ask for are the lines that end with hashes, example: