You get a "text" and have to shift the vowels by "n" positions to the right.
(Negative value for n should shift to the left.)
"Position" means the vowel's position if taken as one item in a list of all vowels within the string.
A shift by 1 would mean, that every vowel shifts to the place of the next vowel.
Shifting over the edges of the text should continue at the other edge.

Example:

text = "This is a test!"
n = 1
output = "Thes is i tast!"

text = "This is a test!"
n = 3
output = "This as e tist!"

If text is null or empty return exactly this value.
Vowels are "a,e,i,o,u".



Have fun coding it and please don't forget to vote and rank this kata! :-)

I have created other katas. Have a look if you like coding and challenges.

Difficulty: EASY
Starter code: def vowel_shift(text, n):
	

Solutions:
import re
from collections import deque

def vowel_shift(text, n):
	try:
		tokens = re.split('([aeiouAEIOU])', text)
		if len(tokens) > 1:
			vowels = deque(tokens[1::2])
			vowels.rotate(n)
			tokens[1::2] = vowels
		return ''.join(tokens)
	except TypeError:
		return None


def vowel_shift(text, n):
	if text in (None, ''):
		return text
	vwl = [x for x in text if x in 'aeiouAEIOU']
	if len(vwl) == 0:
		return text
	n %= len(vwl)
	vwl = list(vwl[-n:] + vwl[:-n])
	return ''.join([x if x not in 'aeiouAEIOU' else vwl.pop(0) for x in text])


import re

def vowel_shift(text, n):
	if not text:
		return text
	vowels = [v for v in text if v in 'aeiouAEIOU']
	n = n % len(vowels) if len(vowels) else n
	shifted_vowels = vowels[-n:] + vowels[:-n]
	return re.sub('[aeiouAEIOU]', lambda _: shifted_vowels.pop(0), text)


import re

def vowel_shift(s, n):
	vow = re.sub('[^aeiouAEIOU]', '', s or '')
	if not s or n == 0 or (not vow):
		return s
	n %= len(vow)
	vow = iter(vow[-n:] + vow[:-n])
	return ''.join((i if i not in 'aeiouAEIOU' else next(vow) for i in s))


is_vowel = lambda c: c in 'aeiouAEIOU'

def vowel_shift(text, n):
	if not text or not n:
		return text
	vowels = [c for c in text if is_vowel(c)]
	n = -n % (len(vowels) or 1)
	vowels = iter(vowels[n:] + vowels[:n])
	return ''.join((c if not is_vowel(c) else next(vowels) for c in text))


from itertools import chain
vowel = set('aeiouAEIOU').__contains__

def vowel_shift(text, n):
	if not (text and n):
		return text
	L = list(filter(vowel, text))
	if not L:
		return text
	n %= len(L)
	it = chain(L[-n:], L[:-n])
	return ''.join((next(it) if vowel(c) else c for c in text))


from itertools import cycle, islice

def vowel_shift(text, n):
	chrs = [c for c in text or '' if c.lower() in 'aeiou']
	if text and chrs:
		it = islice(cycle(chrs), -n % len(chrs), None)
		text = ''.join((next(it) if c.lower() in 'aeiou' else c for c in text))
	return text


import re

def vowel_shift(text, n):
	if not text:
		return text
	vowels = [c for c in text if c in 'AEIOUaeiou']
	if not vowels:
		return text
	vowels = iter(vowels[-n % len(vowels):] + vowels)
	return re.sub('[AEIOUaeiou]', lambda m: next(vowels), text)


from re import split

def vowel_shift(text, n):
	if text == None:
		return None
	parts = split('([aeiouAEIOU])', text)
	return ''.join((parts[i if i % 2 == 0 else (i - 2 * n) % (len(parts) - 1)] for i in range(len(parts))))


def vowel_shift(text, n):
	if text is None or text is '':
		return text
	text = [n for n in text]
	vowels = []
	for x in range(len(text)):
		if text[x].lower() in 'aeuoi':
			vowels.append(text[x])
			text[x] = None
	if len(vowels) == 0:
		return ''.join(text)
	while n != 0:
		if n > 0:
			vowels.insert(0, vowels.pop(-1))
			n -= 1
		else:
			vowels.insert(len(vowels) - 1, vowels.pop(0))
			n += 1
	while len(vowels) != 0:
		text[text.index(None)] = vowels.pop(0)
	return ''.join(text)