Indexed Dictionary

This is the place for queries that don't fit in any of the other categories.

Indexed Dictionary

Postby dday9 » Wed Oct 16, 2013 4:09 pm

I'm looking for an indexed dictionary in Python. I'm currently making a slot machine program and pretty much my idea is to store a few entries that have a string and an integer. Then get a random entry and print that out. Basically this is how I'd do it in vb.net:
Code: Select all
    Private r As New Random
    Sub Main()
        Dim payout As New Dictionary(Of String, Integer)
        payout.Add("Cherry | Cherry | Cherry", 5)
        payout.Add("Bar | Bar | Bar", 10)
        payout.Add("7 | 7 | 7", 15)
        payout.Add("Cherry | Bar | 7", 0)
        payout.Add("Cherry | 7 | Bar", 0)
        payout.Add("7 | Cherry | Bar", 0)
        payout.Add("7 | Bar | Cherry", 0)
        payout.Add("Bar | Cherry | 7", 0)
        payout.Add("Bar | 7 | Cherry", 0)

        Dim i As Integer = r.Next(0, payout.Count - 1)
        Console.WriteLine(payout.Keys.ToList()(i))
        Console.ReadLine()
    End Sub


Grant it I use LINQ which I don't know if Python supports or not, but that's basically what I had in mind.
dday9
 
Posts: 17
Joined: Fri Oct 11, 2013 8:55 pm

Re: Indexed Dictionary

Postby stranac » Wed Oct 16, 2013 4:29 pm

If you really need an indexable dict(for whatever reason), I'm sure searching the web would give you some results.
But there is usually no need for a thing like that.

I don't really know exactly what that code does, but there's a better way to do what you want - you can use random.choice() with the appropriate dict method(if needed).
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1093
Joined: Thu Feb 07, 2013 3:42 pm

Re: Indexed Dictionary

Postby dday9 » Wed Oct 16, 2013 6:43 pm

Basically what the dictionary does is store a String that represents what the slot machine spinned and an Integer that represents the payout. What I do is call a random integer from 0 to the dictionaries count(minus one because dictionaries are 0 based) and get a random item in the dictionary. After that I just print out what the slot machine spinned and increase the amount of coins the user has.

After I typed it out like that, I'm thinking that I will probably just define a class and have an array of that class. The class would be pretty much the equivalent of the dictionary I used in vb.net. I'll probably post back here with my solution.
dday9
 
Posts: 17
Joined: Fri Oct 11, 2013 8:55 pm

Re: Indexed Dictionary

Postby micseydel » Wed Oct 16, 2013 7:20 pm

I don't understand what need you have that isn't being fulfilled here. Could you maybe show what you'd like to do in Python, granted the classes/behavior doesn't exist yet?
Join the #python-forum IRC channel on irc.freenode.net!
User avatar
micseydel
 
Posts: 1179
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: Indexed Dictionary

Postby dday9 » Wed Oct 16, 2013 10:05 pm

So far this is what I've come up with:
Code: Select all
import random

coins = 100
r = random
reels = []

class reel():
   reel = ""
   payout = 0

def set_dic():
   reel1 = reel()
   reel1.reel = "Cherry | Cherry | Cherry"
   reel1.payout = 5
   reel2 = reel()
   reel2.reel = "Bar | Bar | Bar"
   reel2.payout = 10
   reel3 = reel()
   reel3.reel = "7 | 7 | 7"
   reel3.payout = 15
   reel4 = reel()
   reel4.reel = "Cherry | Bar | 7"
   reel4.payout = 0
   reel5 = reel()
   reel5.reel = "Cherry | 7 | Bar"
   reel5.payout = 0
   reel6 = reel()
   reel6.reel = "7 | Cherry | Bar"
   reel6.payout = 0
   reel7 = reel()
   reel7.reel = "7 | Bar | Cherry"
   reel7.payout = 0
   reel8 = reel()
   reel8.reel = "Bar | Cherry | 7"
   reel8.payout = 0
   reel9 = reel()
   reel9.reel = "Bar | 7 | Cherry"
   reel9.payout = 0

   return [reel1, reel2, reel3, reel4, reel5, reel6, reel7, reel8, reel9]

def balance():
   print ("Your current coin balance is: " + str(coins))
   print ()

def instructions():
   print ("Instructions:")
   print ("To view your balance type: b")
   print ("To view these instructions type: d")
   print ("To spin the slot machine type: p")
   print ()
   
def pull():
   i = r.randint(0, len(reels))
   spinned_reel = reels[i]
   print (spinned_reel.reel)
   coins += spinned_reel.payout
   
reels = set_dic()
instructions()
while coins > 0:
   response = input()
   if response == "b":
      balance()
   elif response == "d":
      instructions()
   elif response == "p":
      coins -= 5
      pull()
   else:
      print ("Invalid Input")


That gives me this error:
UnboundLocalError: local variable 'coins' referenced before assignment


At first I tried to declare a class like this:
Code: Select all
class reel():
   reel = ""
   payout = 0
   
   def __init__(msg, pay):
      reel = msg
      payout = int(pay)


But that gives me this error:
TypeError: __init__() takes 2 positional arguments but 3 were given


So apparently I'm doing a few things wrong. But basically that's what I'm wanting to do if I could figure out why I'm getting the UnboundLocalError.
dday9
 
Posts: 17
Joined: Fri Oct 11, 2013 8:55 pm

Re: Indexed Dictionary

Postby dday9 » Wed Oct 16, 2013 10:14 pm

I guess what I'm expecting the msg and pay in init is to be like parameters, I know I keep referring back to vb.net, but that's because that's what I know and how I can explain myself. I'm wanting the class to be like this:

Code: Select all
Public Class Reel
   Public Property Reel As String
   Public Property Payout As Integer

   Private Sub New(ByVal msg As String)
      Me.Reel = msg
   End Sub

   Private Sub New(ByVal pay As Integer)
      Me.Payout = pay
   End Sub

   Private Sub New(ByVal msg As String, ByVal pay As Integer)
      Me.Reel = msg
      Me.Payout = pay
   End Sub

End Class
dday9
 
Posts: 17
Joined: Fri Oct 11, 2013 8:55 pm

Re: Indexed Dictionary

Postby Marbelous » Wed Oct 16, 2013 10:47 pm

Dictionaries are inherently un-ordered so you can't index per se, but you can still pull random selections with little effort. Even if I was going to make a class I might still use a dictionary to hold my pairs of data. Here is a quick example game which might show you some useful techniques:
Code: Select all
my_keys = ['LOSE 10', 'LOSE 5', 'TIE', 'WIN 5', 'WIN 10']
my_values = [-10, -5, 0, 5, 10]

my_dict = dict(zip(my_keys, my_values)) # Use dict and zip functions to build the dictionary.

def spinner(dictionary, spins, money=0):
    from random import choice # Import just the choice function from the random module.
    for i in range(spins):
        spin_key = choice(dictionary.keys()) # Get a randomized key with the random.choice function.
        spin_value = dictionary[spin_key]  # Get the dictionary value associated with the random key.
        print 'You spun a %s which is worth %d' % (spin_key, spin_value)
        money += spin_value
        print 'Your money is now = ', money

if __name__ == '__main__':
    spinner(my_dict, 10, 100)  # Runs 10 spins using my_dict and 100 starting money
Marbelous
 
Posts: 110
Joined: Fri May 31, 2013 8:12 pm

Re: Indexed Dictionary

Postby micseydel » Wed Oct 16, 2013 10:48 pm

dday9 wrote:So far this is what I've come up with:
Code: Select all
import random

coins = 100
r = random
reels = []

class reel():
   reel = ""
   payout = 0

def set_dic():
   reel1 = reel()
   reel1.reel = "Cherry | Cherry | Cherry"
   reel1.payout = 5
   reel2 = reel()
   reel2.reel = "Bar | Bar | Bar"
   reel2.payout = 10
   reel3 = reel()
   reel3.reel = "7 | 7 | 7"
   reel3.payout = 15
   reel4 = reel()
   reel4.reel = "Cherry | Bar | 7"
   reel4.payout = 0
   reel5 = reel()
   reel5.reel = "Cherry | 7 | Bar"
   reel5.payout = 0
   reel6 = reel()
   reel6.reel = "7 | Cherry | Bar"
   reel6.payout = 0
   reel7 = reel()
   reel7.reel = "7 | Bar | Cherry"
   reel7.payout = 0
   reel8 = reel()
   reel8.reel = "Bar | Cherry | 7"
   reel8.payout = 0
   reel9 = reel()
   reel9.reel = "Bar | 7 | Cherry"
   reel9.payout = 0

   return [reel1, reel2, reel3, reel4, reel5, reel6, reel7, reel8, reel9]

def balance():
   print ("Your current coin balance is: " + str(coins))
   print ()

def instructions():
   print ("Instructions:")
   print ("To view your balance type: b")
   print ("To view these instructions type: d")
   print ("To spin the slot machine type: p")
   print ()
   
def pull():
   i = r.randint(0, len(reels))
   spinned_reel = reels[i]
   print (spinned_reel.reel)
   coins += spinned_reel.payout
   
reels = set_dic()
instructions()
while coins > 0:
   response = input()
   if response == "b":
      balance()
   elif response == "d":
      instructions()
   elif response == "p":
      coins -= 5
      pull()
   else:
      print ("Invalid Input")

It looks to me like you should just use a list (or tuple) of tuples (or lists).
Code: Select all
import random

REELS = [
    ("Bar | Bar | Bar", 10),
    ("7 | 7 | 7", 15),
    # ...
]

result, payout = random.choice(REELS)


That gives me this error:
UnboundLocalError: local variable 'coins' referenced before assignment

Always post the full traceback, verbatim and in code tags, instead of just the error message. The traceback includes a line number, and typically that line too.

At first I tried to declare a class like this:
Code: Select all
class reel():
   reel = ""
   payout = 0
   
   def __init__(msg, pay):
      reel = msg
      payout = int(pay)


But that gives me this error:
TypeError: __init__() takes 2 positional arguments but 3 were given

All instance methods have a required first argument which is the instance itself. So change the initializer to
Code: Select all
   def __init__(self, msg, pay):

and you won't get that message. This is because
Code: Select all
instance.method(arg1, arg2)

is equivalent to
Code: Select all
Class.method(instance, arg1, arg2)

So when you do the first one, it's pass three arguments, but you only defined your initializer as accepting two.

You also have to prepend instance variables with self.,
Code: Select all
   def __init__(self, msg, pay):
      self.reel = msg
      self.payout = int(pay)

But again, I think a tuple is a more reasonable solution here.

Also: spaces are recommended over tabs for indentation, and I would advise against global variables (coins in your code) in any language.
Join the #python-forum IRC channel on irc.freenode.net!
User avatar
micseydel
 
Posts: 1179
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: Indexed Dictionary

Postby Kebap » Wed Oct 16, 2013 10:55 pm

dday9 wrote:I'm currently making a slot machine program and pretty much my idea is to store a few entries that have a string and an integer. Then get a random entry and print that out.


From what you wrote initially in visual basic, I don't see any need for classes, dictionaries, etc. Try this using python lists or tuples:

Code: Select all
import random
reems = [("Cherry | Cherry | Cherry", 5),
  ("Bar | Bar | Bar", 10),
  ("7 | 7 | 7", 15),
  ("Cherry | Bar | 7", 0),
  ("Cherry | 7 | Bar", 0),
  ("7 | Cherry | Bar", 0)]
getlucky = random.choice(reems)

>>> print getlucky
('7 | 7 | 7', 15)
>>> print getlucky[0]
7 | 7 | 7

Hope it helps! :mrgreen:
Learn: How To Ask Questions The Smart Way
Join the #python-forum IRC channel on irc.freenode.net and chat with uns directly!
Kebap
 
Posts: 377
Joined: Thu Apr 04, 2013 1:17 pm
Location: Germany, Europe


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 3 guests

cron