Rock Papers Scissors in Python I am a newbie to Python and have started object-oriented programming recently. I have implemented a "Rock Paper Scissors" application in OOP. I would like for you to evaluate my code, and tell me where can I improve my code and how I can better organize the functionality.

import random

class RockPaperScissors(object):        
    def setUserOption(self,val):
        self.__option = val

    def getValueFromList(self,option):
        l = ['rock','scissors','paper']
        return l[option]

    def __getRandomValue(self,max):
        val = random.randint(1,max)
        return self.getValueFromList(val-1)

    def __getResult(self,t):
        self.__d = {('rock','scissors'):'rock breaks scissors - User has won',('rock','paper'):'rock is captured by paper - User has won',('scissors','paper'):'Scissors cut paper - User has won',
                    ('scissors','rock'):'rock breaks scissors - Computer won',('paper','rock'):'rock is captured by paper - Computer won',('paper','scissors'):'Scissors cut paper - Computer won'}
        return self.__d[t]

    def __computeResult(self,computerOption):
        if computerOption == self.__option:
            return 'The user and computer choose the same option'
        else:
            return self.__getResult((self.__option,computerOption))

    def printResult(self):
        computerOption = self.__getRandomValue(3)
        print 'User choice: ',self.__option
        print 'Computer choice: ',computerOption
        print self.__computeResult(computerOption)

if __name__ == "__main__":
    print 'Welcome to rock paper scissors'
    print '1. Rock, 2. Paper, 3. Scissor'
    val = int(raw_input('Enter your choice Number: '))
    if val &gt;=1 and val &lt;= 3:
        obj = RockPaperScissors()
        obj.setUserOption(obj.getValueFromList(val-1))
        obj.printResult()
    else:
        raise ValueError('You are supposed to enter the choice given in the menu')
These answers are fantastic, but seem to be focusing on one side of your question.  I'm going to focus on object orientation.

I reviewed your code with a couple basic concepts in mind, namely polymorphism and encapsulation.

Polymorphism

Where are your objects?  A rock, paper, and scissors could all be objects, could they not?  And, most importantly, they are all the same kind of object.  They are all "pieces" of the game.

Here's a pseudo-example:

class Rock inherits from Element
    type = 'rock'
    def compare(Element)
        if type == 'paper'
            return 'LOSE'
        elsif type == 'scissors'
            return 'WIN'
        else
            return 'TIE'


Although this is a potential solution, my example is going to go in a different direction simply for the fact that if you wanted to add more elements then you'd have to touch the existing code (re: Chris' example of RPSLS).

Encapsulation

A great programming muscle to exercise is encapsulation.  The two main areas, in this example, are to hide the user interface from the game code.  

The user interface shouldn't care about the inner-workings of the game.  The game shouldn't care how it's displayed.  What if you wanted to change the interface to something more graphical?  Right now, your code relies on the console to know about the pieces of the game and how it works.

Example

So, let's return to Chris' example again.  The elements of this game are something that may change quite often.  How can you handle this to make future programming easier?

One solution is to store the "data" of the game elsewhere and dynamically create objects.

The following is Python code to materialize the ideas I've written about here.

Here's code for an abstracted piece of the game, an element:

# The goal for an element is to just know when it wins, when it loses, and how to figure that out.
class Element:
    _name = ""
    _wins = {}
    _loses = {}

    def get_name(self):
        return self._name

    def add_win(self, losingElementName, action):
        self._wins[losingElementName] = action

    def add_loss(self, winningElementName, action):
        self._loses[winningElementName] = action

    def compare(self, element):
        if element.get_name() in self._wins.keys():
            return self._name + " " + self._wins[element.get_name()] + " " + element.get_name()
        elif element.get_name() in self._loses.keys():
            return None
        else:
            return "Tie"

    def __init__(self, name):
        self._name = name
        self._wins = {}
        self._loses = {}


Games have players:

# The player's only responsibility is to make a selection from a given set. Whether it be computer or human.
class Player:
    _type = ''
    _selection = ''

    def make_selection(self, arrayOfOptions):
        index = -1
        if (self._type == 'Computer'):
            index = random.randint(0, len(arrayOfOptions) - 1)
        else:
            index = int(raw_input('Enter the number of your selection: ')) - 1
        self._selection = arrayOfOptions[index]
        return self._type + ' selected ' + self._selection + '.'

    def get_selection(self):
        return self._selection

    def __init__(self, playerType):
        self._type = playerType
        self._selection = ''


Game code:

# A game should have players, game pieces, and know what to do with them.
class PlayGame:
    _player1 = Player('Human')
    _player2 = Player('Computer')

    _elements = {}

    def print_result(self, element1, element2):
        val = element1.compare(element2)
        if (val != None):
            print "YOU WIN! (" + val + ")" # win or tie
        else:
            print "You lose. (" + element2.compare(element1) + ")"


    def fire_when_ready(self):
        counter = 1
        for e in self._elements.keys():
            print str(counter) + ". " + e
            counter = counter + 1
        print ""
        print "Shoot!"
        print ""

        print self._player1.make_selection(self._elements.keys())
        print self._player2.make_selection(self._elements.keys())

        element1 = self._elements[self._player1.get_selection()]
        element2 = self._elements[self._player2.get_selection()]

        self.print_result(element1, element2)


    def load_element(self, elementName1, action, elementName2):
        winningElementObject = None
        newElementObject = None

        if (elementName1 in self._elements):
            winningElementObject = self._elements[elementName1]
            winningElementObject.add_win(elementName2, action)
        else:
            newElementObject = Element(elementName1)
            newElementObject.add_win(elementName2, action)
            self._elements[elementName1] = newElementObject

        if (elementName2 in self._elements):
            losingElementObject = self._elements[elementName2]
            losingElementObject.add_loss(elementName1, action)
        else:
            newElementObject = Element(elementName2)
            newElementObject.add_loss(elementName1, action)
            self._elements[elementName2] = newElementObject


    def __init__(self, filepath):
        # get elements from data storage
        f = open(filepath)
        for line in f:
            data = line.split(' ')
            self.load_element(data[0], data[1], data[2].replace('\n', ''))


The console code, the user interface:

if __name__ == "__main__":
    print "Welcome"
    game = PlayGame('data.txt')
    print ""
    print "Get ready!"
    print ""
    game.fire_when_ready()


And the data file, data.txt:

scissors cut paper
paper covers rock
rock crushes lizard
lizard poisons spock
spock smashes scissors
scissors decapitates lizard
lizard eats paper
paper disproves spock
spock vaporizes rock
rock crushes scissors


The goal for my answer was to show you how you can use some object oriented concepts in solving your problem.  In doing so I also left some unresolved problems.  One big one is that the player and game objects are still coupled to the user interface.  One way to nicely resolve this would be through the use of delegates.