Программа для имитации одновременного подбрасывания 2 монет

Мое задание - создать программу, которая имитирует подбрасывание двух монет одновременно. Если оба решают, то очко получает Группа А; если оба решки, то Группа B получает очко. Если монеты разные, Проф получает балл. Программа должна принимать 2 входа: количество игр и количество бросков за игру. Вот 2 отдельных прогона для иллюстрации:

How many games? 1
How many coin tosses per game? 100
Game 0:
 Group A: 25 (25.0%); Group B: 19 (19.0%); Prof: 56 (56.0%)
Wins: Group A=0 (0.0%); Group B=0 (0.0%); Prof=1 (100.0%)

How many games? 5
How many coin tosses per game? 10
Game 0:
 Group A: 3 (30.0%); Group B: 1 (10.0%); Prof: 6 (60.0%)
Game 1:
 Group A: 6 (60.0%); Group B: 1 (10.0%); Prof: 3 (30.0%)
Game 2:
 Group A: 4 (40.0%); Group B: 1 (10.0%); Prof: 5 (50.0%)
Game 3:
 Group A: 4 (40.0%); Group B: 1 (10.0%); Prof: 5 (50.0%)
Game 4:
 Group A: 5 (50.0%); Group B: 3 (30.0%); Prof: 2 (20.0%)
Wins: Group A=2 (40.0%); Group B=0 (0.0%); Prof=3 (60.0%)

Мой код (хотя и неуклюжий) работает для ввода входных данных, имитации подбрасывания монет, а также вычисления и отображения количества баллов на группу и процентов. Однако моя проблема заключается в подсчете и сохранении количества побед во всех сыгранных играх. Вот мой код на данный момент:

import random

def coinFlip():
    games = input("How many games? ")
    tosses = input("How many coin tosses per game? ")

    for i in range(games):
        gA = 0
        gAW = 0
        gB = 0
        gBW = 0
        prof = 0
        profW = 0

        for j in range(tosses):
            flip1 = random.randint(0, 1)
            flip2 = random.randint(0, 1)

            if (flip1 == 0 and flip2 == 0):
                gA += 1
            elif (flip1 == 1 and flip2 == 1):
                gB += 1
            else:
                prof += 1

            gAper = ((gA * 1.0) / tosses) * 100
            gBper = ((gB * 1.0) / tosses) * 100
            profper = ((prof * 1.0) / tosses) * 100

        if (gA > gB and gA > prof):
            gAW += 1
        elif (gB > gA and gB > prof):
            gBW += 1
        elif ( prof > gA and prof > gB):
            profW += 1

        gAWper = ((gAW * 1.0) / games) * 100
        gBWper = ((gBW * 1.0) / games) * 100
        profWper = ((profW * 1.0) / games) * 100

        print "Game {}:".format(i)
        print " Group A: {} ({}%); Group B: {} ({}%); Prof: {} ({}%)".format(gA, gAper, gB, gBper, prof, profper)
        print "Wins: Group A = {} ({}%); Group B = {} ({}%); Prof: {} ({}%)".format(gAW, gAWper, gBW, gBWper, profW, profWper)

Думаю, мне стоит записать победы в список, но здесь я заблудился.

Почему это помечено как chaos?

user3483203 01.05.2018 18:37

@chrisz Не уверен. OP, вероятно, не знал, что тег chaos имеет конкретное значение и не предназначен для использования просто, когда ваш код «хаотичный». Я удалил.

Christian Dean 01.05.2018 18:38

Почему вы хотите сохранить список побед, а не просто счет, как вы это уже делаете? Похоже, единственное, что вам нужно сделать с этими списками, - это взять их len, так зачем они? (Если вам нужно передать их в statistics.pstdev или что-то в этом роде, это может быть другая история, но это не похоже на требование.)

abarnert 01.05.2018 18:40

Проще говоря, вам нужно создать переменные счетчика для общего количества побед за пределами каждой группы обоих циклов for в области видимости функции coinFlip. В противном случае вы будете продолжать сбрасывать их каждую итерацию, теряя данные. Кроме того, в качестве дополнительного примечания, вам нужно подумать о переименовании имен переменных в более понятное. Такие загадочные имена, как gB и profWper, только вызовут путаницу в дальнейшем при разработке ваших программ.

Christian Dean 01.05.2018 18:47

Сделайте так, чтобы ваша функция возвращала значение (или значения) из каждого запуска моделирования и сохраняла их в списке. Когда все запуски будут выполнены, вы сможете рассчитать нужную статистику по всем играм, в которые играли, из того, что указано в списке.

martineau 01.05.2018 18:48
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
87
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Критическая проблема заключается в том, что вы сбрасываете долгосрочные счетчики в начале каждой игры. Таким образом, никто не может зафиксировать более одной победы. Это отлично подходит для моих игр во фрисби по понедельникам, но неэффективно для вашего задания.

Вернитесь к своему псевдокоду и посмотрите, где совпадают циклы и инициализации. Вот версия кода:

def coinFlip ():

# Set-up you do only once per program execution
games = input("How many games? ")
tosses = input("How many coin tosses per game? ")
games_won_A = 0
games_won_B = 0
games_won_prof = 0

for i in range(games):
    # Set-up things you do once per game
    tosses_won_A = 0
    tosses_won_B = 0
    tosses_won_prof = 0

    for j in range(tosses):
        # Things you do every toss
        flip1 = random.randint(0, 1)
        flip2 = random.randint(0, 1)
        ...

    # Summary things you do every game
    # ... such as compute percentages

# Summary things you do at the end of the program execution
# ... such as print the overall totals

Это заставляет вас двигаться?

Кстати, обратите внимание, что это становится много короче, если вы помещаете счетчики в список. Например, подсчет победителя каждого подбрасывания сводится к одной строке:

win_count[flip1 + flip2] += 1

win_count может быть списком из трех элементов, в котором в указанном порядке записываются выигрыши для A, prof и B.

Спасибо! Как я уже сказал, я все еще новичок, и это действительно была ошибка отступа внутри функции.

setho14 01.05.2018 21:21

Вероятно, это не то, что искал OP, но в целом генерация случайных чисел с помощью numpy может сделать это быстро и просто.

import numpy as np

# get these from input or wherever
games = 5
tosses = 10
n_coins = 2

experiment = np.random.randint(2,size=(games, tosses, n_coins))
flip_results = experiment.sum(axis=2) # 0 means group A wins, 1 Prof, 2 group B
game_results = np.stack((flip_results == 0, flip_results == 1, flip_results == 2))
game_results = game_results.sum(axis=2)
total_results = game_results.sum(axis=1)
print(game_results, total_results)

Я недоволен битом np.stack. Если кто-нибудь знает более чистый способ подсчитать количество 0s 1 и 2 за игру, меня это интересует. Обратите внимание, что np.unique не будет работать с каждым значением по отдельным осям.

Him 01.05.2018 19:26

Другие вопросы по теме