LST-2020
LST-2020

Reputation: 57

Cycling through a list of strings

I have the following exercise where I have a list directions = ["N", "E", "S", "W"] for each of the directions on a compass. I have to make a function where if you input "N" it returns the next one in clockwise direction "E". When you have input "W" it should go back to the start and return "N". When the input is not on the list e.g. "F" it should return none. This is what I have come up with:

def turn_clockwise(direction):
    directions = ["N", "E", "S", "W"]
    for i in range(3):
        if direction == directions[i]:
            result = directions[i+1]
            print(result)
        else:
            return(None)

This works only when I give input "N". When I remove the else it works for the other items as well however then it doesn't cycle back to the start when the input is "W". I wonder how I can make the code fit the assignment or if there is an easier way to do this.

Upvotes: 1

Views: 266

Answers (2)

Patrick Artner
Patrick Artner

Reputation: 51653

You can also use the prefabricated cycle from itertools.cycle:

from itertools import cycle

directions = cycle(["N", "E", "S", "W"])

for _ in range(10):
    print(next(directions), end = " -> ")
print(next(directions))

Output:

N -> E -> S -> W -> N -> E -> S -> W -> N -> E -> S

or simply create a lookup dict.

Both versions in a usable method:

from itertools import cycle

def next_dir(what):
    d = "NESW"
    directions = cycle(d)
    if what in d:   
        while next(directions) != what:
            pass
        return next(directions)
    else:
        raise ValueError(what + " not possible")


def next_lookup(what):
    d = {"N":"E", "E":"S", "S":"W", "W":"N"}
    r = d.get(what)
    if r: 
        return r
    raise ValueError(what+" not possible")

for l in "NESW":
    print(l, next_dir(l)) 
    print(l, next_lookup(l)) 

try:
    print(next_dir("q"))
except Exception as e:
    print(e)

try:
    print(next_lookup("q"))
except Exception as e:
    print(e)

Output:

N E  # next_dir
N E  # next_lookup  .. etc ..
E S
E S
S W
S W
W N
W N
q not possible
q not possible

Upvotes: 0

Banana
Banana

Reputation: 2533

def turn_clockwise(direction):
    directions = ["N", "E", "S", "W"]
    if direction in directions:
        return directions[(directions.index(direction) + 1) % len(directions)]
    else:
        return None

To wrap things around a specific number the modulo % operator is used.


Here with @AKX suggestion:

def cycle(values, current): 
    try:
        return values[(values.index(current) + 1) % len(values)]
    except ValueError:
         print(f"{current} not in {values}")

def turn_clockwise(direction):
    directions = ["N", "E", "S", "W"]
    if direction in directions:
        return cycle(directions, direction]
    else:
        return None

Upvotes: 6

Related Questions