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))
\$\endgroup\$
  • \$\begingroup\$ Any idea? Anybody has any suggestion? \$\endgroup\$ – pyring Dec 30 '16 at 16:56
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)
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.