I want to create a simple cipher.
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
def main():
while True:
plain = raw_input("text to be encoded: ")
print encode(plain)
def encode(plain):
length = len(plain)
plain = plain.upper()
for c in plain:
encoded = _______
return encoded
Input : CAT , Output : MXU
I have this template in mind but What is the best way to do this ? If I have to use dictionary, how do I use it in given set up?
A very efficient way of doing this is to make use of the .translate() method of strings:
import string
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
cipher = string.maketrans(alpha, key)
def encode(plaintext):
return plaintext.translate(cipher)
With your two strings:
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
Create a dictionary using zip():
mydict = {k:v for k, v in zip(alpha, key)} # Or dict(zip(alpha, key))
Then in your encode() function, you can just do:
def encode(plain):
return ''.join([mydict.get(i, i) for i in plain])
[mydict.get(i, i) for i in plain] Is equivalent to:
newlist = []
for i in plain:
newlist.append(mydict.get(i, i))
mydict.get(i, i) is equivalent to mydict[i], but if there is no key i, then i (the second parameter) is returned (instead of raising a KeyError)
Note that the list will return something like ['M', 'X', 'U'], so the ''.join() will print it as 'MXU'
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "XPMGTDHLYONZBWEARKJUFSCIQV"
inp = 'CAT'
_d = {e[0]: e[1] for e in zip(alpha, key)}
print _d
print ''.join([_d[ele] for ele in inp if ele in _d])
Related
am trying to get the name of a list (type list) if it contain the needed value:
def f(Value):
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']
w = next(n for n,v in filter(lambda t: isinstance(t[1],list), locals().items()) if value in v)
return(w)
f()
well this code will return the name of the list but type string so i will be not able to use it later. thank you in advance
You got several errors in your code - if you want the list, then return it and not it's name:
def f(value): # capitalization not correct
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']
# set w to v not n - n is the local name, v is the value
w = next(v for n,v in filter(lambda t: isinstance(t[1],list),
locals().items()) if value in v)
return w
# needs to be called with parameter
what_list = f("h")
print( what_list )
Output:
['g', 'h', 'i']
I don't see the point why using locals().items() in this minimal example, you could do
for li in [a,b,c,d]: # simply add more lists if needed, no need to inspect locals
if value in li:
return li
instead.
I've got this code that translates a string (that starts out as a list) using a dictionary. I wanted the code to translate the string, then un-translate it back to the original.
This is the code that I've got so far:
words = ['Abra', ' ', 'cadabra', '!']
clues = {'A':'Z', 'a':'z', 'b':'y', 'c':'x'}
def converter(words, clues):
words = ''.join(words)
for item in words:
if item in clues.keys():
words = words.replace(item, clues[item])
return words
def reversal(clues):
clues = {v: k for k, v in clues.items()}
print(clues)
x = converter(words, clues)
print(x)
reversal(clues)
x = converter(words, clues)
print(x)
Only, this will print
"Zyrz xzdzyrz!"
"Zyrz xdzyrz!"
I'm not sure why it's not printing:
"Zyrz xzdzyrz!"
"Abra cadabra!"
Is there an error in my code that is causing it to act this way? I checked clues and it IS reversed properly after it goes through the function. What am I doing wrong?
Python already has the translate method on all strings, just call it!
def converter(text, clues, reverse=False):
if reverse:
clues = {v: k for k, v in clues.items()}
table = str.maketrans(clues)
return text.translate(table)
Usage:
words = ['Abra', ' ', 'cadabra', '!']
clues = {'A':'Z', 'a':'z', 'b':'y', 'c':'x'}
# join the text into a single string:
x = ''.join(words)
# convert first
x = converter(x, clues)
print(x) # -> you get `Zyrz xzdzyrz!`
#back to original
x = converter(x, clues, reverse=True)
print(x) # -> you get `Abra cadabra!`
Looks like you're trying to do a dictionary operation in place within a function. Your function needs to return the reversed version of the dictionary which you then need to pick up in your main:
# Your stuff here
def reversal(clues):
return {v: k for k, v in clues.items()}
x = converter(words, clues)
print(x)
clues_reversed = reversal(clues)
x = converter(words, clues_reversed)
print(x)
say for example I have the word dictionary,
how do I code so that it produces
dictionar
dictiona
diction
dictio
dicti
dict
dic
di
d
(every last character is removed)
I currently have:
def generate_letter_removed(word):
return_list4 = []
for i in range(1, len(word)):
q = word[:-1]
return_list4.append(q)
return return_list4
letter_removed = generate_letter_removed(word)
print(letter_removed)
but this produces "dictionar"
Use string slicing:
word = "dictionary"
for i in range(len(word), 0, -1):
print(word[:i])
Output:
dictionary
dictionar
dictiona
diction
dictio
dicti
dict
dic
di
d
As a function:
def slice_output(w):
print('\n'.join(w[:i] for i in range(len(w), 0, -1)))
Corrected your code
def generate_letter_removed(word):
return_list4 = [word]
for i in range(1, len(word)):
q = word[:-i]
return_list4.append(q)
return return_list4
word=input("Enter A Word: ")
letter_removed = generate_letter_removed(word)
print(letter_removed)
Output
Enter A Word: Dictionary
['Dictionary', 'Dictionar', 'Dictiona', 'Diction', 'Dictio', 'Dicti', 'Dict', 'Dic', 'Di', 'D']
I have a dictionary containing the following key-value pairs: d={'Alice':'x','Bob':'y','Chloe':'z'}
I want to replace the lower case variables(values) by the constants(keys) in any given string.
For example, if my string is:
A(x)B(y)C(x,z)
how do I replace the characters in order to get a resultant string of :
A(Alice)B(Bob)C(Alice,Chloe)
Should I use regular expressions?
re.sub() solution with replacement function:
import re
d = {'Alice':'x','Bob':'y','Chloe':'z'}
flipped = dict(zip(d.values(), d.keys()))
s = 'A(x)B(y)C(x,z)'
result = re.sub(r'\([^()]+\)', lambda m: '({})'.format(','.join(flipped.get(k,'')
for k in m.group().strip('()').split(','))), s)
print(result)
The output:
A(Alice)B(Bob)C(Alice,Chloe)
Extended version:
import re
def repl(m):
val = m.group().strip('()')
d = {'Alice':'x','Bob':'y','Chloe':'z'}
flipped = dict(zip(d.values(), d.keys()))
if ',' in val:
return '({})'.format(','.join(flipped.get(k,'') for k in val.split(',')))
else:
return '({})'.format(flipped.get(val,''))
s = 'A(x)B(y)C(x,z)'
result = re.sub(r'\([^()]+\)', repl, s)
print(result)
Bonus approach for particular input case A(x)B(y)C(Alice,z):
...
s = 'A(x)B(y)C(Alice,z)'
result = re.sub(r'\([^()]+\)', lambda m: '({})'.format(','.join(flipped.get(k,'') or k
for k in m.group().strip('()').split(','))), s)
print(result)
I assume you want to replace the values in a string with the respective keys of the dictionary. If my assumption is correct you can try this without using regex.
First the swap the keys and values using dictionary comprehension.
my_dict = {'Alice':'x','Bob':'y','Chloe':'z'}
my_dict = { y:x for x,y in my_dict.iteritems()}
Then using list_comprehension, you replace the values
str_ = 'A(x)B(y)C(x,z)'
output = ''.join([i if i not in my_dict.keys() else my_dict[i] for i in str_])
Hope this is what you need ;)
Code
import re
d={'Alice':'x','Bob':'y','Chloe':'z'}
keys = d.keys()
values = d.values()
s = "A(x)B(y)C(x,z)"
for i in range(0, len(d.keys())):
rx = r"" + re.escape(values[i])
s = re.sub(rx, keys[i], s)
print s
Output
A(Alice)B(Bob)C(Alice,Chloe)
Also you could use the replace method in python like this:
d={'x':'Alice','y':'Bob','z':'Chloe'}
str = "A(x)B(y)C(x,z)"
for key in d:
str = str.replace(key,d[key])
print (str)
But yeah you should swipe your dictionary values like Kishore suggested.
This is the way that I would do it:
import re
def sub_args(text, tosub):
ops = '|'.join(tosub.keys())
for argstr, _ in re.findall(r'(\(([%s]+?,?)+\))' % ops, text):
args = argstr[1:-1].split(',')
args = [tosub[a] for a in args]
subbed = '(%s)' % ','.join(map(str, args))
text = re.sub(re.escape(argstr), subbed, text)
return text
text = 'A(x)B(y)C(x,z)'
tosub = {
'x': 'Alice',
'y': 'Bob',
'z': 'Chloe'
}
print(sub_args(text, tosub))
Basically you just use the regex pattern to find all of the argument groups and substitute in the proper values--the nice thing about this approach is that you don't have to worry about subbing where you don't want to (for example, if you had a string like 'Fn(F,n)'). You can also have multi-character keys, like 'F(arg1,arg2)'.
So i have (below) which cleans up my list
def cleanGpaList(gpalist):
mylist = []
for i in gpalist:
b = i.strip()
c = b.split()
mylist.append(c)
return mylist
And (below) which sums up the values of keys that repeat. For example ['Bob','1.0'] and ['Bob', '2.1'] and gives me ['Bob', '3.1']
def dictGpa(cleanList):
diction = {}
for item in cleanList:
if item[0] in diction:
diction[item[0]] += float(item[1])
else:
diction[item[0]] = float(item[1])
diction2 = ', '.join(map(str,diction.keys()))
return (diction2)
Now I am trying to write a final function that prints from the dictionary line by line and the keys and the values.
'Bob' '3.1'
'xname' 'xnumber'
I have this, but it keeps giving me TypeError: string indices must be integers
def printCumulative(myDict):
for x in myDict:
print(x)
for y in myDict[x]:
print(y,' ',myDict[x][y])
To print keys and values you can use simple for:
for k,v in myDict.items():
print(k,v)