You have to write two methods to *encrypt* and *decrypt* strings.
Both methods have two parameters:
```
1. The string to encrypt/decrypt
2. The Qwerty-Encryption-Key (000-999) 
```

The rules are very easy:
```
The crypting-regions are these 3 lines from your keyboard:
1. "qwertyuiop"
2. "asdfghjkl"
3. "zxcvbnm,."

If a char of the string is not in any of these regions, take the char direct in the output.
If a char of the string is in one of these regions: Move it by the part of the key in the 
region and take this char at the position from the region. 
If the movement is over the length of the region, continue at the beginning.
The encrypted char must have the same case like the decrypted char! 
So for upperCase-chars the regions are the same, but with pressed "SHIFT"!

The Encryption-Key is an integer number from 000 to 999. E.g.: 127

The first digit of the key (e.g. 1) is the movement for the first line.
The second digit of the key (e.g. 2) is the movement for the second line.
The third digit of the key (e.g. 7) is the movement for the third line.

(Consider that the key is an integer! When you got a 0 this would mean 000. A 1 would mean 001. And so on.)
```

You do not need to do any prechecks. The strings will always be not null 
and will always have a length > 0. You do not have to throw any exceptions.

An Example:
```
Encrypt "Ball" with key 134
1. "B" is in the third region line. Move per 4 places in the region. -> ">" (Also "upperCase"!)
2. "a" is in the second region line. Move per 3 places in the region. -> "f"
3. "l" is in the second region line. Move per 3 places in the region. -> "d"
4. "l" is in the second region line. Move per 3 places in the region. -> "d"
--> Output would be ">fdd"
```

*Hint: Don't forget: The regions are from an US-Keyboard!*
*In doubt google for "US Keyboard."*



This kata is part of the Simple Encryption Series:
Simple Encryption #1 - Alternating Split
Simple Encryption #2 - Index-Difference
Simple Encryption #3 - Turn The Bits Around
Simple Encryption #4 - Qwerty

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

Difficulty: introductory

Starter code:

def encrypt(text, encryptKey):
	

Solutions:
from collections import deque
KEYBOARD = ['zxcvbnm,.', 'ZXCVBNM<>', 'asdfghjkl', 'ASDFGHJKL', 'qwertyuiop', 'QWERTYUIOP']

def encrypt(text, encryptKey): return converter(text, encryptKey, 1)
def decrypt(text, encryptKey): return converter(text, encryptKey, -1)
    
def converter(text, encryptKey, sens):
    deques = list(map(deque, KEYBOARD))
    for i, deq in enumerate(deques):
        deq.rotate(-sens * (encryptKey // 10**(i//2) % 10) )
    return text.translate(str.maketrans(''.join(KEYBOARD), ''.join(''.join(deq) for deq in deques)))

encrypt = lambda s, k: code(s, k)
decrypt = lambda s, k: code(s, k, -1)
    
def code(text, key, m=1):
    keys, r = [int(e) * m for e in str(key).rjust(3, '0')], []
    for c in text:    
        for i, a in enumerate(['qwertyuiop', 'asdfghjkl', 'zxcvbnm,.']):
            if c in a: c = a[(a.index(c) + keys[i]) % len(a)]            
        for i, a in enumerate(['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM<>']):
            if c in a: c = a[(a.index(c) + keys[i]) % len(a)]
        r.append(c)
    return ''.join(r)

def code(mode, text, key):
    alphabet = "qwertyuiop asdfghjkl zxcvbnm,. QWERTYUIOP ASDFGHJKL ZXCVBNM<>"
    idxs = [mode * int(d) for d in '%03d' % key * 2]
    table = ' '.join(w[i:] + w[:i] for i, w in zip(idxs, alphabet.split()))
    return text.translate(str.maketrans(alphabet, table))

from functools import partial
encrypt, decrypt = partial(code, 1), partial(code, -1)

rs=("qwertyuiop","asdfghjkl","zxcvbnm,.","QWERTYUIOP","ASDFGHJKL","ZXCVBNM<>")

def encrypt(t,k):
    k=[k//100,k//10%10,k%10]
    return t.translate(str.maketrans(''.join(rs),''.join(rs[i][k[i%3]:]+rs[i][:k[i%3]] for i,r in enumerate(rs))))
    
def decrypt(t,k):
    k=[k//100,k//10%10,k%10]
    return t.translate(str.maketrans(''.join(rs),''.join(rs[i][-k[i%3]:]+rs[i][:-k[i%3]] for i,r in enumerate(rs))))


from operator import add, sub
from functools import partial

keyboard = ("qwertyuiop", "asdfghjkl", "zxcvbnm,.", "QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM<>")
D = {c:(i,j,len(row)) for i,row in enumerate(keyboard) for j,c in enumerate(row)}
key = "{:03}".format

def trans(L, f, c):
    if c in D:
        i, j, l = D[c]
        return keyboard[i][f(j, L[i%3])%l]
    return c

def encrypt(text, encryptKey, f=add):
    return ''.join(map(partial(trans, list(map(int, key(encryptKey))), f), text))
    
def decrypt(text, encryptKey):
    return encrypt(text, encryptKey, sub)

def encrypt(text, key):
    r1,r2,r3 = 'qwertyuiop','asdfghjkl','zxcvbnm,.'
    R1,R2,R3 = 'QWERTYUIOP','ASDFGHJKL', 'ZXCVBNM<>' 
    key = str(key).zfill(3)
    mx = ''
    for x in text:
        if x in r1:
            mx += r1[(r1.index(x)+int(key[0]))%10]
        elif x in R1:
            mx += R1[(R1.index(x)+int(key[0]))%10]
        elif x in r2:
            mx += r2[(r2.index(x)+int(key[1]))%9]
        elif x in R2:
            mx += R2[(R2.index(x)+int(key[1]))%9]
        elif x in r3:
            mx += r3[(r3.index(x)+int(key[2]))%9]
        elif x in R3:
            mx += R3[(R3.index(x)+int(key[2]))%9]
        else:
            mx += x
    return mx
def decrypt(text, key):
    r1,r2,r3 = 'qwertyuiop','asdfghjkl','zxcvbnm,.'
    R1,R2,R3 = 'QWERTYUIOP','ASDFGHJKL', 'ZXCVBNM<>' 
    key = str(key).zfill(3)
    mx = ''
    for x in text:
        if x in r1:
            mx += r1[(r1.index(x)-int(key[0]))%10]
        elif x in R1:
            mx += R1[(R1.index(x)-int(key[0]))%10]
        elif x in r2:
            mx += r2[(r2.index(x)-int(key[1]))%9]
        elif x in R2:
            mx += R2[(R2.index(x)-int(key[1]))%9]
        elif x in r3:
            mx += r3[(r3.index(x)-int(key[2]))%9]
        elif x in R3:
            mx += R3[(R3.index(x)-int(key[2]))%9]
        else:
            mx += x
    return mx

def crypt(s, key, to_encrypt=True):
    keys = []
    for key in '{:0>3}'.format(key):
        keys.extend([int(key)] * 2)
    rows = ('qwertyuiop', 'QWERTYUIOP',
            'asdfghjkl', 'ASDFGHJKL',
            'zxcvbnm,.', 'ZXCVBNM<>')
    original = ''.join(rows)
    shifted = ''.join(r[k:] + r[:k] for r, k in zip(rows, keys))
    table = str.maketrans(*(
        (original, shifted) if to_encrypt else (shifted, original)))
    return s.translate(table)


def decrypt(s, key):
    return crypt(s, key, to_encrypt=False)


def encrypt(s, key):
    return crypt(s, key, to_encrypt=True)


region1="qwertyuiop" #10
region2="asdfghjkl" #9
region3="zxcvbnm,." #9

def encrypt(text, encryptKey):
    print(text)
    print(encryptKey)
    s=str(encryptKey)
    if len(s) == 1: s=['0', '0', encryptKey]
    elif len(s) == 2: s=['0', s[0], s[1]]
    else: s=str(encryptKey)
    
    ntext=''
    for c in text:
        if c.lower() in region1:
            ind=region1.find(c.lower())
            if c == c.lower(): ntext+=region1[(ind+int(s[0]))%10]
            else: ntext+=region1[(ind+int(s[0]))%10].upper()
        elif c.lower() in region2:
            ind=region2.find(c.lower())
            if c == c.lower(): ntext+=region2[(ind+int(s[1]))%9]
            else: ntext+=region2[(ind+int(s[1]))%9].upper()
        elif c.lower() in region3+'<>':
            if c.lower() in region3:
                ind=region3.find(c.lower())
                if c == c.lower(): ntext+=region3[(ind+int(s[2]))%9]
                else: 
                    if region3[(ind+int(s[2]))%9] == ',': ntext+='<' 
                    elif region3[(ind+int(s[2]))%9] == '.': ntext+='>'
                    else: ntext+=region3[(ind+int(s[2]))%9].upper()
            if c == '<':
                ind=region3.find(',')
                q=region3[(ind+int(s[2]))%9]
                if q == ',': ntext+='<'
                elif q == '.': ntext+='>'
                else: ntext+=q.upper()
            if c == '>':
                ind=region3.find('.')
                q=region3[(ind+int(s[2]))%9]
                if q == ',': ntext+='<'
                elif q == '.': ntext+='>'
                else: ntext+=q.upper()
                
        else: ntext+=c
    print(ntext)
    return ntext
    
def decrypt(text, encryptKey):
    print(text)
    print(encryptKey)
    
    s=str(encryptKey)
    if len(s) == 1: s=['0', '0', encryptKey]
    elif len(s) == 2: s=['0', s[0], s[1]]
    else: s=str(encryptKey)
    
    ntext=''
    for c in text:
        if c.lower() in region1:
            ind=region1.find(c.lower())
            if c == c.lower(): ntext+=region1[(ind-int(s[0]))%10]
            else: ntext+=region1[(ind-int(s[0]))%10].upper()
        elif c.lower() in region2:
            ind=region2.find(c.lower())
            if c == c.lower(): ntext+=region2[(ind-int(s[1]))%9]
            else: ntext+=region2[(ind-int(s[1]))%9].upper()
        elif c.lower() in region3+'<>':
            if c.lower() in region3:
                ind=region3.find(c.lower())
                if c == c.lower(): ntext+=region3[(ind-int(s[2]))%9]
                else: 
                    if region3[(ind-int(s[2]))%9] == ',': ntext+='<' 
                    elif region3[(ind-int(s[2]))%9] == '.': ntext+='>'
                    else: ntext+=region3[(ind-int(s[2]))%9].upper()
            if c == '<':
                ind=region3.find(',')
                q=region3[(ind-int(s[2]))%9]
                if q == ',': ntext+='<'
                elif q == '.': ntext+='>'
                else: ntext+=q.upper()
            if c == '>':
                ind=region3.find('.')
                q=region3[(ind-int(s[2]))%9]
                if q == ',': ntext+='<'
                elif q == '.': ntext+='>'
                else: ntext+=q.upper()
                
        else: ntext+=c
    print(ntext)
    return ntext

keyboard = ['qwertyuiop', 'QWERTYUIOP', 'asdfghjkl','ASDFGHJKL','zxcvbnm,.','ZXCVBNM<>']

def encrypt(text, encryptKey): return crypt(text, encryptKey, 1)
def decrypt(text, encryptKey): return crypt(text, encryptKey, -1)
    
def crypt(text, encryptKey, dir):
    encryptKey = str(encryptKey).zfill(3)
    # rotate all rows of keyboard
    new_keyboard = [row[int(encryptKey[i//2])*dir:]+row[:int(encryptKey[i//2])*dir] for i,row in enumerate(keyboard)]
    # join the rows of keyboard together to make a full translation and translate
    return ''.join([char.translate(str.maketrans(' '.join(keyboard), ' '.join(new_keyboard))) for char in text])

top = 'qwertyuiop'
top_caps = 'QWERTYUIOP'
mid = "asdfghjkl"
mid_caps = 'ASDFGHJKL'
bot = 'zxcvbnm,.'
bot_caps = 'ZXCVBNM<>'


def encrypt(text, encryptKey):
    encryptKey = str(encryptKey).zfill(3)
    res = ''
    for char in text:
        for i, row in enumerate([top, top_caps, mid, mid_caps, bot, bot_caps]): 
            if char in row:
                shift = int(encryptKey[i//2])
                res += char.translate(str.maketrans(row, row[shift:]+row[:shift]))
                break
        else: res += char
    return res
        
    
def decrypt(text, encryptKey):
    encryptKey = str(encryptKey).zfill(3)
    res = ''
    for char in text:
        for i, row in enumerate([top, top_caps, mid, mid_caps, bot, bot_caps]): 
            if char in row:
                shift = int(str(encryptKey)[i//2])
                res += char.translate(str.maketrans(row, row[-shift:]+row[:-shift]))
                break
        else: res += char
    return res