3
\$\begingroup\$

The following code simulates a game of signals in which four participants (playing in pairs) show (muestra) and see (observan) signals. Signals are randomly assigned in the first round. Signals in the second round are assigned depending on a probability equation that takes into account memory dictionaries.

The final output is (sorted by participant):

  1. Signals shown in the first round
  2. Signals shown in the second round
  3. Memory dictionary of shown signals
  4. Memory dictionary of observed signals

I would like to simplify and optimise my code.

import random
emparejamientos= ([[1,2],[3,4], #round 1 (participant 1 plays with 2, and 3 with 4)
 [1,3],[2,4]]) #round 2 (1 with 3 and 2 with 4)
s1=1
s2=0
s3=0
s4=0
b=0.5
x=0.5
m=0.02
Muestra_part1 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Observa_part1 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Muestra_part2 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Observa_part2 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Muestra_part3 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Observa_part3 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Muestra_part4 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
Observa_part4 = {"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0}
#ROUND 1
#Shown signals by each participant in round 1
S1, S2, S3, S4 = random.sample("ABCDEFGH", 4) #assignment of signals
print "Shown signals in round 1 \n {0}".format((S1, S2, S3, S4))
#Storing signals in the dictionaries (record of shown signals)
for n in range(1):
 Muestra_part1[S1] += 1
for n in range(1):
 Muestra_part2[S2] += 1
for n in range(1):
 Muestra_part3[S3] += 1
for n in range(1):
 Muestra_part4[S4] += 1
#Storing signals in the dictionary (record of observed signals)
if emparejamientos[0]==[1,2]:
 Observa_part1[S2] +=1
 Observa_part2[S1] +=1
if emparejamientos[1]==[3,4]:
 Observa_part3[S4] += 1
 Observa_part4[S3] += 1
#ROUND 2
#Probability of production of each signal by participant
def with_b(muestra, observa, s):
 result = ((0.98) * (1.0 - 0) * (1.0 - x) * muestra) + ((0.98) * (1.0 - 0) * (x) * observa) + ((0.98) * 0 * s) + ((m / 8))
 if not (muestra == observa == 0):
 result = ((0.98) * (1.0 - b) * (1.0 - x) * muestra) + ((0.98) * (1.0 - b) * (x) * observa) + ((0.98) * b * s) + ((m / 8))
 return result
Prob_S1_part1 = with_b(Muestra_part1[S1], Observa_part1[S1], s1)
Prob_S2_part1 = with_b(Muestra_part1[S2], Observa_part1[S2], s2)
Prob_S3_part1 = with_b(Muestra_part1[S3], Observa_part1[S3], s3)
Prob_S4_part1 = with_b(Muestra_part1[S4], Observa_part1[S4], s4)
Prob_S1_part2 = with_b(Muestra_part2[S1], Observa_part2[S1], s1)
Prob_S2_part2 = with_b(Muestra_part2[S2], Observa_part2[S2], s2)
Prob_S3_part2 = with_b(Muestra_part2[S3], Observa_part2[S3], s3)
Prob_S4_part2 = with_b(Muestra_part2[S4], Observa_part2[S4], s4)
Prob_S1_part3 = with_b(Muestra_part3[S1], Observa_part3[S1], s1)
Prob_S2_part3 = with_b(Muestra_part3[S2], Observa_part3[S2], s2)
Prob_S3_part3 = with_b(Muestra_part3[S3], Observa_part3[S3], s3)
Prob_S4_part3 = with_b(Muestra_part3[S4], Observa_part3[S4], s4)
Prob_S1_part4 = with_b(Muestra_part4[S1], Observa_part4[S1], s1)
Prob_S2_part4 = with_b(Muestra_part4[S2], Observa_part4[S2], s2)
Prob_S3_part4 = with_b(Muestra_part4[S3], Observa_part4[S3], s3)
Prob_S4_part4 = with_b(Muestra_part4[S4], Observa_part4[S4], s4)
#Assignment of signals in round 2, taking into account the record
opciones = [S1, S2, S3, S4]
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]
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]
eleccion1 = choice(opciones, probabilidades1) #shown signal by part 1 in round 2
eleccion2 = choice(opciones, probabilidades2) #shown signal by part 2 in round 2
eleccion3 = choice(opciones, probabilidades3) #shown signal by part 3 in round 2
eleccion4 = choice(opciones, probabilidades4) #shown signal by part 4 in round 2
print "Shown signals in round 2 \n {0}".format((eleccion1, eleccion2, eleccion3, eleccion4))
#Storing signals in the dictionary (record of shown signals)
if eleccion1 == S1:
 Muestra_part1[S1] +=1
if eleccion1 == S2:
 Muestra_part1[S2] +=1
if eleccion1 == S3:
 Muestra_part1[S3] +=1
if eleccion1 == S4:
 Muestra_part1[S4] +=1
if eleccion2 == S1:
 Muestra_part2[S1] +=1
if eleccion2 == S2:
 Muestra_part2[S2] +=1
if eleccion2 == S3:
 Muestra_part2[S3] +=1
if eleccion2 == S4:
 Muestra_part2[S4] +=1
if eleccion3 == S1:
 Muestra_part3[S1] +=1
if eleccion3 == S2:
 Muestra_part3[S2] +=1
if eleccion3 == S3:
 Muestra_part3[S3] +=1
if eleccion3 == S4:
 Muestra_part3[S4] +=1
if eleccion4 == S1:
 Muestra_part4[S1] +=1
if eleccion4 == S2:
 Muestra_part4[S2] +=1
if eleccion4 == S3:
 Muestra_part4[S3] +=1
if eleccion4 == S4:
 Muestra_part4[S4] +=1
print "Record of shown signals \n {0}".format ((Muestra_part1, Muestra_part2, Muestra_part3, Muestra_part4))
#Storing signals in the dictionary (record of observed signals)
if emparejamientos[2]==[1,3]:
 Observa_part1[eleccion3] +=1
 Observa_part3[eleccion1] +=1
if emparejamientos[3]==[2,4]:
 Observa_part2[eleccion4] += 1
 Observa_part4[eleccion2] += 1
print "Record of observed signals \n {0}".format ((Observa_part1, Observa_part2, Observa_part3, Observa_part4))
asked Dec 29, 2016 at 23:40
\$\endgroup\$
1
  • \$\begingroup\$ Any idea? Anybody has any suggestion? \$\endgroup\$ Commented Dec 30, 2016 at 16:56

1 Answer 1

3
\$\begingroup\$

Group your data together, so that you can mutate it better. Which of the following examples is simpler?

  1. a = [1, 2, 3, 4, 6]
    b = [6, 3, 1, 4, 2]
    c = [i + j for i, j in zip(a, b)]
    
  2. a1 = 1
    a2 = 2
    a3 = 3
    a4 = 4
    a5 = 6
    b1 = 6
    b2 = 3
    b3 = 1
    b4 = 4
    b5 = 2
    c1 = a1 + b1
    c2 = a2 + b2
    c3 = a3 + b3
    c4 = a4 + b4
    c5 = a5 + b5
    

As you're doing the second, rather than the first, I'd recommend that you change your code to use the first.

You should also make a couple more functions. Even if the function looks like it is simple, it can move some of the complexity of your code to a different position. And at this point you need to remove as much complexity from your code as possible.

I didn't do anything than the above to your code and got the following. I suggest you learn how to do the same. I also don't know Spanish or Portuguese and so I don't know what your variables mean, and so I wrote mine in English. Please pick one language and name them better than S1. And I didn't check if my code works, as it's only intended as a guide, not a solution.

import random
from random import random
from bisect import bisect
emparejamientos= [
 [[0, 1], [2, 3]],
 [[0, 2], [1, 3]]
]
ss = [1, 0, 0, 0]
b=0.5
x=0.5
m=0.02
muestra = [
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
]
observa = [
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
 {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0},
]
def with_b(muestra, observa, s):
 result = ((0.98) * (1.0 - 0) * (1.0 - x) * muestra) + ((0.98) * (1.0 - 0) * (x) * observa) + ((0.98) * 0 * s) + ((m / 8))
 if not (muestra == observa == 0):
 result = ((0.98) * (1.0 - b) * (1.0 - x) * muestra) + ((0.98) * (1.0 - b) * (x) * observa) + ((0.98) * b * s) + ((m / 8))
 return result
def choice(signals, probs):
 probAcumuladas=[]
 aux = 0
 for p in probs:
 aux += p
 probAcumuladas.append(aux)
 r = random() * probAcumuladas[-1]
 op = bisect(probAcumuladas, r)
 return signals[op]
def add_matches(dictionary, move, indexes):
 a, b = indexes
 dictionary[a][move[b]] += 1
 dictionary[b][move[a]] += 1
def rename(muestra, observa, signals, matches):
 for d, i in zip(muestra, signals):
 d[i] += 1
 for match in matches:
 add_matches(observa, signals, match)
 add_matches(observa, signals, match)
signals = random.sample("ABCDEFGH", 4)
rename(muestra, observa, signals, emparejamientos[0])
eleccion = [
 choice(signals,
 [
 with_b(m[s1], o[s1], s2)
 for s1, s2 in zip(signals, ss)
 ]
 )
 for m, o in zip(muestra, observa)
]
rename(muestra, observa, eleccion, emparejamientos[1])
print "Shown signals in round 1 \n {0}".format(signals)
print "Shown signals in round 2 \n {0}".format(eleccion)
print "Record of shown signals \n {0}".format (muestra)
print "Record of observed signals \n {0}".format (observa)
answered Dec 31, 2016 at 17:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.