Praful
Praful

Reputation: 31

New to Python: Getting TypeError: unhashable type: 'list'

So I have a class assignment I have to make a rock paper scissors game and stop cheating. I keep getting TypeError: unhashable type: 'list'

I have no idea what is causing this; could someone help me to fix this?

import random
import re

def MatchAssess(): 
    if userThrow == compThrow:
        print("Draw")
    elif userThrow == "r" and compThrow == "p":
        print("Computer chose paper; you chose rock - you lose")
    elif userThrow == "p" and compThrow == "s":
        print("Computer chose scissors; you chose paper - you lose!")
    elif userThrow == "r" and compThrow == "p":
        print("Computer chose paper; you chose rock - you lose!")
    elif userThrow == "s" and compThrow == "r":
        print("Computer chose rock; you chose scissors - you lose!")
    else:
        print("you win")



CompThrowSelection = ["r","p","s"]
ThrowRule = "[a-z]"

while True:
    compThrow = random.choice(CompThrowSelection)
    userThrow = input("Enter Rock [r] Paper [p] or Scissors [s]")
    if not re.match(CompThrowSelection,userThrow) and len(userThrow) > 1:
        MatchAssess()
    else:
        print("incorrect letter")
        userThrow = input("Enter Rock [r] Paper [p] or Scissors [s]")

Upvotes: 2

Views: 881

Answers (3)

bharadhwaj
bharadhwaj

Reputation: 2129

I noticed some fault with your logic on the code.

One is that re.match() is to be applied on a pattern rather than on a list. For list we can use something like,

if element in list:
    # Do something

Next is that len(userThrow) > 1 will never be satisfied if user makes a valid input. So make len(userThrow) >= 1 or even == 1.

Last I added a continue statement on the conditional branch for catching wrong input, rather than reading input again from there.


So finally, this is the working code!

while True:
    compThrow = random.choice(CompThrowSelection)
    userThrow = raw_input("Enter Rock [r] Paper [p] or Scissors [s]")
    if userThrow in CompThrowSelection and len(userThrow) >= 1:
        MatchAssess()
    else:
        print("incorrect letter")
        continue

Hope this helps! :)

Upvotes: 4

Mohammad Yusuf
Mohammad Yusuf

Reputation: 17044

You can implement it like this:

import random

cts = ["r","p","s"]

def match_assess(ut):
    ct = random.choice(cts)
    if ut == ct:
        print('Draw. You threw:'+ut+' and computer threw:'+ct)
    elif (ut=="r" and ct == "p") or (ut == "p" and ct == "s") or (ut == "r" and ct == "p") or (ut == "s" and ct == "r"):
        print ('You Loose. You threw:'+ut+' and computer threw:'+ct)
    else:
        print ('You Win. You threw:'+ut+' and computer threw:'+ct)
a = 0
while a<5: #Play the game 5 times.
    ut = raw_input("Enter Rock [r] Paper [p] or Scissors [s]")
    if ut in cts and len(ut) == 1:
        match_assess(ut)
    else:
        print("incorrect letter")
    a+=1

Upvotes: 0

Marlon Abeykoon
Marlon Abeykoon

Reputation: 12465

It should be corrected as

if  userThrow in CompThrowSelection and len(userThrow) == 1: # this checks user's input value is present in your list CompThrowSelection and check the length of input is 1
    MatchAssess()

and

    userThrow = raw_input("Enter Rock [r] Paper [p] or Scissors [s]") # raw_input() returns a string, and input() tries to run the input as a Python expression (assumed as python 2)

Upvotes: 0

Related Questions