Как я могу различать значения звезд по вертикали, а не по горизонтали?

#python #list

Вопрос:

У меня есть программа, которая «бросает» 2 кубика 100 раз и добавляет значения каждого броска в список. Затем я подсчитываю, сколько раз 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, и в этом списке появляется 12, и именно столько раз комбинация появлялась в бросках. Прямо сейчас я отображаю свои данные, объединяя строку с номером, количество раз, когда он появляется, а затем новую строку для следующего номера.(смотрите изображение) https://i.stack.imgur.com/qxUGr.png Однако я хочу отобразить свой «график» вертикально, как на втором прикрепленном изображении: https://i.stack.imgur.com/5KvzU.png

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

 def q6():
c = 0
c1 = 0
results = []
for x in range(100):
    c = random.randint(1, 6)
    c1 = random.randint(1, 6)
    sum = c   c1
    results.append(sum)
num2 = results.count(2)
num3 = results.count(3)
num4 = results.count(4)
num5 = results.count(5)
num6 = results.count(6)
num7 = results.count(7)
num8 = results.count(8)
num9 = results.count(9)
num10 = results.count(10)
num11 = results.count(11)
num12 = results.count(12)
display = "2: "   (num2 * "*")   "n"   "3: "   (num3 * "*")   "n"  "4: "   (num4 * "*")   "n"  "5: "   (num5 * "*")   "n"  "6: "   (num6 * "*")   "n"  "7: "   (num7 * "*")   "n"  "8: "   (num8 * "*")   "n"  "9: "   (num9 * "*")   "n"  "10: "   (num10 * "*")   "n"  "11: "   (num11 * "*")   "n"  "12: "   (num12 * "*") 
return display
#below is a loop I tried to do by printing the stars in a row and printing a space if the value was 0. the variable called "big" is the largest number in the list of values, variable "layers" was the layer the loop was printing at the time. "string" is of course the display.
"""while layers < big:
    for x in counts[x]:
        y = 0
        if x > 0:
            string  = " * "
            counts[y] = counts[y] - 1
        if x == 0:
            string  = "  "
        y  = 1
    string  = "n" 
    layers  = 1
    
return string"""
 

До сих пор это мой код.

Ответ №1:

Попробуйте выполнить следующие действия:

 import random

def q6():
    d = {k: 0 for k in range(2, 13)}
    for _ in range(100):
        d[random.randint(1, 6)   random.randint(1, 6)]  = 1 # random draw

    output = ' '.join(f'{k:2}' for k in d) # header

    while any(d.values()): # while there are any remaining stars to be drawn
        line = '' # begin with an empty string
        line = ' '.join(' *' if v else '  ' for v in d.values())
        for k in d: # loop over d to reduce the number of remaining stars
            if d[k] > 0:
                d[k] -= 1
        output  = 'n'   line # append the line to the output

    return output

print(q6())
 

Как вы можете заметить, идея состоит в том, чтобы уменьшать количество звезд на 1 на каждом шаге, пока их количество не истощится.

Обратите внимание, что количество звезд, т. е. диктант d , не будет сохранено в неизменном виде. В случае, если вы хотите сохранить это, используйте что-то вроде d_copy = d.copy() перед while циклом.

Также в этом подходе используется тот факт, что dict сохраняет порядок элементов (на основе вставки) начиная с python 3.7.

Выход:

  2  3  4  5  6  7  8  9 10 11 12
 *  *  *  *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *  *  *  *
 *  *  *  *  *  *  *  *  *  *  *
    *  *  *  *  *  *  *  *  *
    *  *  *  *  *  *  *  *
       *  *  *  *  *  *  *
       *  *  *  *  *  *  *
          *  *  *  *  *  *
          *  *  *  *  *  *
          *  *  *  *  *
             *  *  *  *
             *     *
             *     *
             *
             *
             *
             *
             *
             *
             *
             *
             *
             *
             *
 

Согласно запросу ОП,

 line = ' '.join(' *' if v else '  ' for v in d.values())
 

использует условное выражение. Например, output = 'a' if x else 'b' устанавливает output , как 'a' если x есть True , и 'b' если x есть False .

В этом случае python видит v . Если v не равно нулю, это «правдиво», поэтому ' *' if v else ' ' for v равно ' *' . Если v равно нулю, то v является «ложным», поэтому оно равно ' ' . Другими словами, строка эквивалентна

 temp = []
for v in d.values():
    if v != 0:
        temp.append(' *')
    else:
        temp.append('  ')

line = ' '.join(temp)
 

Комментарии:

1. Большое вам спасибо за ваш ответ. Можно ли было бы объяснить строку с кодом: строка = ‘ ‘.join(‘ *’ если v еще » для v в d.значения()) для меня? Я могу понять все остальное, что происходит в коде, за исключением того, что там происходит. Большое спасибо!

2. @saul212 Конечно, я добавлю это к ответу.

Ответ №2:

Чтобы сделать его вертикальным, вам нужно проверить каждое число отдельно, сделать цикл for, который насчитывает от 1 до 100 (которые являются минимальными и максимальными перспективами), чтобы проверить каждое число, если это число достигнет этого значения, и вложенный цикл for, чтобы проверить каждое число, если оно достигнет его….что-то вроде:

 list = [num2, num3, num4, num5, num6, num7, num8, num9, num10, num11, num12]
for i in range(1,100):
  line = []
  for x in list:
    if x >= i:
      line.append("*")
    else:
      line.append(" ")
  for element in line:
    print(element, end="")
 

Комментарии:

1. Не составляйте свой список по имени list

2. Вы также можете просто сделать print("".join(line)) вместо последнего цикла

3. Кроме того, диапазон должен быть range(1, 101) , так как конец является эксклюзивным

4. Я бы также рекомендовал установить проверку, которая прерывает цикл, если не было написано ни одной звезды, у вас нет ведер пустых строк и бессмысленных вычислений

5. Когда вы вносите имя в свой список list , вы лишаете себя доступа к встроенной функции. Кроме того, в python нет компилятора