How to randomize the card selection

I wanted to create a 3 card spread utilizing the dictionary concept. Initially I did not include the deck size variable, however once I ran it about 30x, it threw an error so I subtracted 1 card from the present and future.

A fun challenge would be to let the user choose input of a 1, 3 or 5 card spread. I feel like we could do this with a few loops!

import random tarot = {1:"The Magician",2:"The High Priestess",3:"The Empress", 4:"The Emperor",5:"The Hierophant",6:"The Lovers",7:"The Chariot", 8:"Strength",9:"The Hermit",10:"Wheel of Fortune",11:"Justice", 12:"The Hanged Man",13:"Death",14:"Temperance",15:"The Devil",16:"The Tower", 17:"The Star",18:"The Moon",19:"The Sun",20:"Judgement",21:"The World", 22:"The Fool",23:"Ace of Clubs",24:"2 of Clubs",25:"3 of Clubs",26:"4 of Clubs", 27:"5 of Clubs", 28:"6 of Clubs",29:"7 of Clubs",30:"8 of Clubs",31:"9 of Clubs", 32:"10 of Clubs",33:"Ace of Hearts",34:"2 of Hearts",35:"3 of Hearts", 36:"4 of Hearts",37:"5 of Hearts",38:"6 of Hearts",39:"7 of Hearts", 40:"8 of Hearts",41:"9 of Hearts",42:"10 of Hearts",43:"Ace of Swords", 44:"2 of Swords",45:"3 of Swords",46:"4 of Swords",47:"5 of Swords", 48:"6 of Swords",49:"7 of Swords",50:"8 of Swords",51:"9 of Swords", 52:"10 of Swords",53:"Ace of Pentacles",54:"2 of Pentacles",55:"3 of Pentacles", 56:"4 of Pentacles",57:"5 of Pentacles",58:"6 of Pentacles",59:"7 of Pentacles", 60:"8 of Pentacles",61:"9 of Pentacles",62:"10 of Pentacles"} spread = {} decksize = len(tarot) spread["past"] = tarot.pop(random.randint(1, decksize)) spread["present"] = tarot.pop(random.randint(1, decksize -1)) spread["future"] = tarot.pop(random.randint(1, decksize -2)) for key, value in spread.items(): print("Your "+key+" is the "+value+" card. ")

Something to consider…

def draw_spread(n=3):
  deck = [*tarot.values()]
  return [deck.pop(random.randrange(len(deck))) for _ in range(n)]
>>> draw_spread()
['8 of Hearts', 'The Hanged Man', '2 of Swords']
>>> 
1 Like

Fun to read this thread. I see many was thinking the same thing, including me. I was a bit surprised to see so many different solutions though!

Mine was like this. I’m perfectly aware i could eliminate the three extra variables and just write it out directly into .update() but yea, just find it a bit cleaner and easier to read.

import random tarot = {1: "The Magician", 2: "The High Priestess", 3: "The Empress", 4: "The Emperor", 5: "The Hierophant", 6: "The Lovers", 7: "The Chariot", 8: "Strength", 9: "The Hermit", 10: "Wheel of Fortune", 11: "Justice", 12: "The Hanged Man", 13: "Death", 14: "Temperance", 15: "The Devil", 16: "The Tower", 17: "The Star", 18: "The Moon", 19: "The Sun", 20: "Judgement", 21: "The World", 22: "The Fool"} card_one = random.randint(0, len(tarot)) card_two = random.randint(0, len(tarot)) card_three = random.randint(0, len(tarot)) spread = {} spread["past"] = tarot.pop(card_one) # just testing both wayt to update spread spread.update({"present": tarot.pop(card_two)}) spread.update({"future": tarot.pop(card_three)}) for time, card in spread.items(): print("Your " + time + " is the " + card + " card.")

Hi this is my solution

I used random.randint

And I carefully made sure that the same random number is not picked twice by running an inner condition based while loop inside the for loop

Here is the code:

import random
tarot = { 1:	"The Magician", 2:	"The High Priestess", 3:	"The Empress", 4:	"The Emperor", 5:	"The Hierophant", 6:	"The Lovers", 7:	"The Chariot", 8:	"Strength", 9:	"The Hermit", 10:	"Wheel of Fortune", 11:	"Justice", 12:	"The Hanged Man", 13:	"Death", 14:	"Temperance", 15:	"The Devil", 16:	"The Tower", 17:	"The Star", 18:	"The Moon", 19:	"The Sun", 20:	"Judgement", 21:	"The World", 22: "The Fool"}

spread = {}
rand = []
for i in range(3):
  integer = random.randint(1, 22)
  rand.append(integer)
  while rand.count(integer) > 1:
    rand.remove(integer)
    integer = random.randint(1, 22)
    rand.append(integer)

spread["past"] = tarot.pop(rand[0], 0)
spread["present"] = tarot.pop(rand[1], 0)
spread["future"] = tarot.pop(rand[2], 0)

for key, value in spread.items():
  print("Your {} is the {} card.".format(key, value))

Please explain your code…

My go at it:

# Used to generate random number
import random

# Provided tarot dictionary
tarot = { 1:	"The Magician", 2:	"The High Priestess", 3:	"The Empress", 4:	"The Emperor", 5:	"The Hierophant", 6:	"The Lovers", 7:	"The Chariot", 8:	"Strength", 9:	"The Hermit", 10:	"Wheel of Fortune", 11:	"Justice", 12:	"The Hanged Man", 13:	"Death", 14:	"Temperance", 15:	"The Devil", 16:	"The Tower", 17:	"The Star", 18:	"The Moon", 19:	"The Sun", 20:	"Judgement", 21:	"The World", 22: "The Fool"}

# Empty dictionary for the reading
spread = {}

# Type of spread (reading) we are doing. Anything with less than 23 values would work here
three_spread = ["past", "present", "future"]

# To give an example, I (lazily) came up with this reading format that uses 6 cards with new meanings instead of the classic one
crazier_spread = ["love", "hate", "fear", "enemy", "ally", "destiny"]

# Function that puts a random card into spread connected to a meaning ("domain")
def take_a_card(domain):
  # Get a random number in the dictionary's range
  random_card = random.randint(1, 22)
  # Bool used to make sure our while loop doesn't last forever
  card_pulled = False
  # Debugging int used to figure out if we're stuck in an eternal loop and kill the whole proccess if we are
  error_sieve = 0
  # Loop that will keep trying to find a card until it does or something goes wrong
  while not card_pulled:
    # Honestly, only created this because it's less of a hassle to do than refreshing the page if a while loop goes terribly wrong
    if error_sieve >= 50000:
      print("Eternal While Loop Error")
      break
    # Removes card from deck and adds it as the value to the "domain" key in spread
    if random_card in tarot:
      spread[domain] = tarot.pop(random_card)
      card_pulled = True # Lets the while loop end
    # If the card had already been taken out, comes up with a new random card before the loop restarts
    else:
      random_card = random.randint(1, 22)
    # Lastly before restarting the loop, increments the error detector
    error_sieve += 1

# Function that "does" the reading. It requires the desired type of reading (AKA the list of meanings the cards will have) as an argument
def tarot_reading(spread_configuration):
  # Simply runs the take_a_card function once for every meaning we gave to our reading
  for subject in spread_configuration:
    take_a_card(subject)

# Printer function
def tarot_reading_printer(spread_deck):
  # Iterates through presumably populated spread dictionary and prints the results
  for subject, card in spread_deck.items():
    print("Your {} is the {} card.".format(subject, card))

# Finally, calling the reading function with the spread you decided to use
tarot_reading(crazier_spread)
# And, after a reading has been done, the printer can be used
tarot_reading_printer(spread)

I was refreshing on the subject of functions today, and it might have influenced my approach a little bit

I came with this:

import random tarot = { 1:"The Magician", 2:"The High Priestess", 3:"The Empress", 4:"The Emperor", 5:"The Hierophant", 6:"The Lovers", 7:"The Chariot", 8:"Strength", 9:"The Hermit", 10:"Wheel of Fortune", 11:"Justice", 12:"The Hanged Man", 13:"Death", 14:"Temperance", 15:"The Devil", 16:"The Tower", 17:"The Star", 18:"The Moon", 19:"The Sun", 20:"Judgement", 21:"The World", 22: "The Fool"} def tarot_play(tarot): cards=[] while len(cards) < 3: selected_card = random.choice(list(tarot.keys())) if selected_card not in cards: cards.append(selected_card) print(f'Your past is the {tarot[cards[0]]} card.\nYour present is the {tarot[cards[1]]} card.\nAnd you future is the {tarot[cards[2]]} card.')