1

I am trying to create a program that returns a position on a board (starting from position 0) for each roll of a dice.

My dictionary contains keys, which are the positions on the board and values, which are the

displacements that should take place.

dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

For example, when I land on position 64, I find key 64 in the dictionary and from 64 I move -4 on the board, resting on 60.

I have my current code below.

def location(rolls):
dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

    position = 0
    list_position = []
    for roll in rolls:
        position = position + roll

        if position not in dictionary:
            pass
        if position in dictionary:
            position = position + dictionary.get(roll)
            list_position.append(position)
        print(position)

I am getting partial positions and I believe some iterations are returning a type error.

>>> location([1, 4, 5])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 12, in location
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
38
42

# desired output
[38, 42, 26]

From the first roll of the dice, we land on position 1. We located 1 in my dictionary and learned that I

have to move by 37, resting on 38. From the second roll of the dice, we move 4 from 38 and land

on 42. 42 is not in my dictionary, so we rest on 42. Then from the third roll of the dice, we move 5

from 42, landing on 47. 47 is in my dictionary and I move -21 from 47, landing on 26.

So I am actually getting the first two positions in the list. I have not a single clue why the third

position is not being printed and returning this type error.

4
  • Please fix the indentation. It is not possible to see what location was intended to do Commented Nov 16, 2018 at 14:05
  • 1
    well 5 isn't in the dict so dictionary.get(roll) returns None, which can't be added to an integer Commented Nov 16, 2018 at 14:06
  • @Ayxan I have fixed the indentation. Commented Nov 16, 2018 at 14:11
  • @Chris_Rands Oh I see. 4 and 1 are in dict, but 5 is not. Haven't I cleared the case with pass statement? Commented Nov 16, 2018 at 14:14

3 Answers 3

2

Your code have some structuring issue:

  1. The checks should be one big if block instead of 2 separate ones:

    if position not in dictionary:
        pass
    else:   # <-- use else instead
        position = position + dictionary.get(roll)
        list_position.append(position)
    print(position)
    

Since the two conditions are polar opposites there's no point for you to do another position in dictionary check.

Better yet - since you don't even need to do anything if position not in dictionary, just do this:

if position in dictionary:
    position = position + dictionary.get(roll)
    list_position.append(position)
# you don't need an else because you don't intend to do anything
  1. The dictionary.get(roll) is not controlled by the condition. You would check if position in dictionary but you do not ensure that roll is also in dictionary. Therefore when it's not in there, dict.get() returns None by default.

You can either set a default value like dictionary.get(roll, 0), or fill your dictionary with all the possible rolls you want to define, or do a check for roll in dictionary.

Sign up to request clarification or add additional context in comments.

Comments

1
  1. I think list_position and position_list were meant to be the same lists
  2. 5 isn't in the dictionary (since you are not checking for roll, you are only checking for position), so it returns None and you definitely cannot add None to an integer. Add a default value for non-existent keys.
  3. A minor suggestion; the if case with pass you used there does almost nothing. You might only check for the case the key is in the dictionary.

EDIT: Looks like what OP meant to do was dictionary.get(position). In that case we don't need to check for anything.

Here's what I mean:

def location(rolls):
  dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

  position = 0
  list_position = []
  for roll in rolls:
    position = position + roll
    # if position not in dictionary:  # commented out
    #     pass                        # 
    # if position in dictionary:      # no need to check anything since default is 0
    position = position + dictionary.get(position, 0)
    list_position.append(position)    # fixed the name
    print(position)

Run it:

location([1, 4, 5])

Output:

38
42
26

3 Comments

The last output should be 26, not 47 btw. Why would this be returning 42 + 5 and not 26?
@VAnon Well, in that case what you meant to do was dictionary.get(position, 0) instead of dictionary.get(roll, 0). Edited and fixed that.
@VAnon in that case, you don't need the if cases at all
1

The problem is position = position + dictionary.get(roll). On the 3rd iteration where the roll is = 5, dictionary.get(roll) evaluates to None.

EDIT: Also, if you want to skip to the next iteration of the for loop, the proper syntax is continue, not pass.

I added a check for this below:

def location(rolls):
    dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43,
                  95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}
    position = 0
    list_position = []
    for roll in rolls:
        position = position + roll
        if position not in dictionary:
            continue # pass does nothing here
        if position in dictionary:
            if dictionary.get(roll):
                position = position + dictionary.get(roll)
            list_position.append(position)
        print(position)

location([1, 4, 5])

1 Comment

Just use position = position + dictionary.get(roll, 0) and remove the extra if dictionary.get(roll):: not necessary to fetch the same key twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.