Encoding string into numbers separated by dashes, decoding numbers separated by dashes into a string
Task: Write a program that gives the user a choice to encode or
decode. You will either encode letters into numbers separated by
dashes, or decode a series of numbers (also separated by dashes) into
letters.
I am learning python, and this Lab has proven extremely difficult because I don't yet know all the tools I need to make it function. I managed to get the encode portion to work, but my decode portion is crap. I think it is taking 2-digit numbers and treating them like individual numbers ("19" as "1" and "9", so returns "ai" instead of 's'). I have thought about switching from using indexing to trying to convert the numbers to letters using chr(), but not being familiar with that either, I keep getting type errors when trying to add 96 to get the correct number.
Then encode_letters function is a bit clumsy, but it works. However, the decode_numbers function is what is giving me fits.
Can anyone tell me what I am doing wrong?
def encode_letters():
global code_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g', '7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
msg_in = str(input("Enter the message you wish to encode:n"))
msg_in = msg_in.lower()
from_index = 0
to_index = 1
for i in msg_in:
letter_found = False
for e in encryption_key:
if ('a' <= i and i <= 'z') and i == e[from_index]:
code_out = code_out + e[to_index] + "-"
letter_found = True
if not letter_found:
code_out = code_out + i
return code_out
def return_encoded():
global code_out
code_out = code_out.rstrip("-")
print("Your secret code is:", code_out.replace('- ', ' '))
def decode_numbers():
global string_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g','7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
numbers_in = input("Enter the numbers separated by dashes that you wish to decode: ")
numbers_in = numbers_in.replace('-', ' ')
print(numbers_in)
from_index = 1
to_index = 0
for i in numbers_in:
number_found = False
for e in encryption_key:
if i == e[from_index]:
string_out = string_out + e[to_index]
number_found = True
if not number_found:
string_out = string_out + i
return string_out
def return_decoded():
global string_out
print("Your decoded string is: ", string_out.capitalize())
python python-3.x
add a comment |
Task: Write a program that gives the user a choice to encode or
decode. You will either encode letters into numbers separated by
dashes, or decode a series of numbers (also separated by dashes) into
letters.
I am learning python, and this Lab has proven extremely difficult because I don't yet know all the tools I need to make it function. I managed to get the encode portion to work, but my decode portion is crap. I think it is taking 2-digit numbers and treating them like individual numbers ("19" as "1" and "9", so returns "ai" instead of 's'). I have thought about switching from using indexing to trying to convert the numbers to letters using chr(), but not being familiar with that either, I keep getting type errors when trying to add 96 to get the correct number.
Then encode_letters function is a bit clumsy, but it works. However, the decode_numbers function is what is giving me fits.
Can anyone tell me what I am doing wrong?
def encode_letters():
global code_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g', '7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
msg_in = str(input("Enter the message you wish to encode:n"))
msg_in = msg_in.lower()
from_index = 0
to_index = 1
for i in msg_in:
letter_found = False
for e in encryption_key:
if ('a' <= i and i <= 'z') and i == e[from_index]:
code_out = code_out + e[to_index] + "-"
letter_found = True
if not letter_found:
code_out = code_out + i
return code_out
def return_encoded():
global code_out
code_out = code_out.rstrip("-")
print("Your secret code is:", code_out.replace('- ', ' '))
def decode_numbers():
global string_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g','7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
numbers_in = input("Enter the numbers separated by dashes that you wish to decode: ")
numbers_in = numbers_in.replace('-', ' ')
print(numbers_in)
from_index = 1
to_index = 0
for i in numbers_in:
number_found = False
for e in encryption_key:
if i == e[from_index]:
string_out = string_out + e[to_index]
number_found = True
if not number_found:
string_out = string_out + i
return string_out
def return_decoded():
global string_out
print("Your decoded string is: ", string_out.capitalize())
python python-3.x
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So3 + 's'
throws an error, butstr(3) + 's'
does not.
– duhaime
Nov 18 '18 at 19:44
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52
add a comment |
Task: Write a program that gives the user a choice to encode or
decode. You will either encode letters into numbers separated by
dashes, or decode a series of numbers (also separated by dashes) into
letters.
I am learning python, and this Lab has proven extremely difficult because I don't yet know all the tools I need to make it function. I managed to get the encode portion to work, but my decode portion is crap. I think it is taking 2-digit numbers and treating them like individual numbers ("19" as "1" and "9", so returns "ai" instead of 's'). I have thought about switching from using indexing to trying to convert the numbers to letters using chr(), but not being familiar with that either, I keep getting type errors when trying to add 96 to get the correct number.
Then encode_letters function is a bit clumsy, but it works. However, the decode_numbers function is what is giving me fits.
Can anyone tell me what I am doing wrong?
def encode_letters():
global code_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g', '7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
msg_in = str(input("Enter the message you wish to encode:n"))
msg_in = msg_in.lower()
from_index = 0
to_index = 1
for i in msg_in:
letter_found = False
for e in encryption_key:
if ('a' <= i and i <= 'z') and i == e[from_index]:
code_out = code_out + e[to_index] + "-"
letter_found = True
if not letter_found:
code_out = code_out + i
return code_out
def return_encoded():
global code_out
code_out = code_out.rstrip("-")
print("Your secret code is:", code_out.replace('- ', ' '))
def decode_numbers():
global string_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g','7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
numbers_in = input("Enter the numbers separated by dashes that you wish to decode: ")
numbers_in = numbers_in.replace('-', ' ')
print(numbers_in)
from_index = 1
to_index = 0
for i in numbers_in:
number_found = False
for e in encryption_key:
if i == e[from_index]:
string_out = string_out + e[to_index]
number_found = True
if not number_found:
string_out = string_out + i
return string_out
def return_decoded():
global string_out
print("Your decoded string is: ", string_out.capitalize())
python python-3.x
Task: Write a program that gives the user a choice to encode or
decode. You will either encode letters into numbers separated by
dashes, or decode a series of numbers (also separated by dashes) into
letters.
I am learning python, and this Lab has proven extremely difficult because I don't yet know all the tools I need to make it function. I managed to get the encode portion to work, but my decode portion is crap. I think it is taking 2-digit numbers and treating them like individual numbers ("19" as "1" and "9", so returns "ai" instead of 's'). I have thought about switching from using indexing to trying to convert the numbers to letters using chr(), but not being familiar with that either, I keep getting type errors when trying to add 96 to get the correct number.
Then encode_letters function is a bit clumsy, but it works. However, the decode_numbers function is what is giving me fits.
Can anyone tell me what I am doing wrong?
def encode_letters():
global code_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g', '7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
msg_in = str(input("Enter the message you wish to encode:n"))
msg_in = msg_in.lower()
from_index = 0
to_index = 1
for i in msg_in:
letter_found = False
for e in encryption_key:
if ('a' <= i and i <= 'z') and i == e[from_index]:
code_out = code_out + e[to_index] + "-"
letter_found = True
if not letter_found:
code_out = code_out + i
return code_out
def return_encoded():
global code_out
code_out = code_out.rstrip("-")
print("Your secret code is:", code_out.replace('- ', ' '))
def decode_numbers():
global string_out
encryption_key = (('a','1'), ('b','2'), ('c','3'), ('d','4'), ('e','5'), ('f','6'), ('g','7'), ('h','8'), ('i','9'), ('j','10'), ('k','11'), ('l','12'),
('m','13'), ('n','14'), ('o','15'), ('p','16'), ('q','17'), ('r','18'), ('s','19'), ('t','20'), ('u','21'), ('v','22'), ('w','23'), ('x','24'),
('y','25'), ('z','26'))
numbers_in = input("Enter the numbers separated by dashes that you wish to decode: ")
numbers_in = numbers_in.replace('-', ' ')
print(numbers_in)
from_index = 1
to_index = 0
for i in numbers_in:
number_found = False
for e in encryption_key:
if i == e[from_index]:
string_out = string_out + e[to_index]
number_found = True
if not number_found:
string_out = string_out + i
return string_out
def return_decoded():
global string_out
print("Your decoded string is: ", string_out.capitalize())
python python-3.x
python python-3.x
edited Nov 18 '18 at 19:34
Dionys
2,13711120
2,13711120
asked Nov 18 '18 at 19:17
LisaLisa
111
111
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So3 + 's'
throws an error, butstr(3) + 's'
does not.
– duhaime
Nov 18 '18 at 19:44
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52
add a comment |
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So3 + 's'
throws an error, butstr(3) + 's'
does not.
– duhaime
Nov 18 '18 at 19:44
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So
3 + 's'
throws an error, but str(3) + 's'
does not.– duhaime
Nov 18 '18 at 19:44
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So
3 + 's'
throws an error, but str(3) + 's'
does not.– duhaime
Nov 18 '18 at 19:44
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52
add a comment |
2 Answers
2
active
oldest
votes
I think you can simplify this quite a bit if you keep track of the type conversions:
def convert(s, method='encode'):
if method == 'encode':
return '-'.join([str(ord(i)) for i in s])
elif method == 'decode':
return ''.join([str(chr(int(i))) for i in s.split('-')])
s = 'cats on wheels'
encoded = convert(s, method='encode')
decoded = convert(encoded, method='decode')
print(encoded) # prints 99-97-116-115-32-111-110-32-119-104-101-101-108-115
print(decoded) # prints cats on wheels
As you said, one can use ord
to convert a string to an integer, then use chr
to convert an integer back into a string. This lets us flip a string into a sequence of hyphen separated integers, then flip that sequence back into the input string
add a comment |
Using a dictionary makes encryption, decription easier. Example for ceasar chiffre:
d = {}
# build the encode/decode dict
for k in range(26):
cha = chr(ord("a")+k)
d[cha] = k
d[cha.upper()] = k
d[k] = cha
print(d)
def encode(word,offset):
# dont use other things then a-zA-Z or else...
return ''.join(d[ (d[c]+offset)%26 ] for c in word)
def decode(word,offset):
return encode(word,-offset)
print(encode("abcdefg",1))
print(decode("abcdefg",-1))
print ( encode(decode("abrakadabrazzz",1),1) )
Output:
bcdefgh # encode abcdefg , +1
bcdefgh # decode abcdefg , -1
abrakadabrazzz # endoce + decode
The dictionary used looks like:
{'a': 0, 'A': 0, 0: 'a', 'b': 1, 'B': 1, 1: 'b', 'c': 2, 'C': 2, 2: 'c',
'd': 3, 'D': 3, 3: 'd', 'e': 4, 'E': 4, 4: 'e', 'f': 5, 'F': 5, 5: 'f',
'g': 6, 'G': 6, 6: 'g', 'h': 7, 'H': 7, 7: 'h', ...,
'x': 23, 'X': 23, 23: 'x', 'y': 24, 'Y': 24, 24: 'y', 'z': 25, 'Z': 25, 25: 'z'}
essentially it maps any lowercase and uppercase letter to a number and the number back to the lowercase character.
The encoding d[ (d[c]+offset)%26 ]
looks up the "number" that belongs to a character, adds the offset, uses modulo 26 to convert z+1
to a
instead of an error. Then is looks up the correct "new" character by it's number.
You can do the same for your task - you just need the mapping for character
to number
and for number
to character
.
When decoding split your string at '-'
and get the character for the numbervalue you got - when encoding go over all characters of your word and get the correct number from a dict, then '-'.join()
them.
Applied to your task:
from string import ascii_lowercase as low # "abc..xyz"
d = {}
number_for_a = ord("a")
# add the letters/numbers - upper case are 100 + lower case number
for k in low:
d[k] = str(ord(k) - number_for_a)
d[k.upper()] = str(100 + ord(k) - number_for_a)
# add the reverse mapping number to character
for k,v in list(d.items()):
d[v] = k
def encode(word):
# word for both cases - if no `-` in word its iterated character wise, else
# the word is split at '-' and any splits are put through the dictionary
if '-' in word:
return '-'.join(d[c] for c in word.split("-"))
return '-'.join(d[c] for c in word)
def decode(phrase):
return encode(phrase)
print(encode("abcdefg"))
print(decode("1-2-3-4-5-101-100-103-104-105"))
Output:
0-1-2-3-4-5-6
b-c-d-e-f-B-A-D-E-F
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53364567%2fencoding-string-into-numbers-separated-by-dashes-decoding-numbers-separated-by%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think you can simplify this quite a bit if you keep track of the type conversions:
def convert(s, method='encode'):
if method == 'encode':
return '-'.join([str(ord(i)) for i in s])
elif method == 'decode':
return ''.join([str(chr(int(i))) for i in s.split('-')])
s = 'cats on wheels'
encoded = convert(s, method='encode')
decoded = convert(encoded, method='decode')
print(encoded) # prints 99-97-116-115-32-111-110-32-119-104-101-101-108-115
print(decoded) # prints cats on wheels
As you said, one can use ord
to convert a string to an integer, then use chr
to convert an integer back into a string. This lets us flip a string into a sequence of hyphen separated integers, then flip that sequence back into the input string
add a comment |
I think you can simplify this quite a bit if you keep track of the type conversions:
def convert(s, method='encode'):
if method == 'encode':
return '-'.join([str(ord(i)) for i in s])
elif method == 'decode':
return ''.join([str(chr(int(i))) for i in s.split('-')])
s = 'cats on wheels'
encoded = convert(s, method='encode')
decoded = convert(encoded, method='decode')
print(encoded) # prints 99-97-116-115-32-111-110-32-119-104-101-101-108-115
print(decoded) # prints cats on wheels
As you said, one can use ord
to convert a string to an integer, then use chr
to convert an integer back into a string. This lets us flip a string into a sequence of hyphen separated integers, then flip that sequence back into the input string
add a comment |
I think you can simplify this quite a bit if you keep track of the type conversions:
def convert(s, method='encode'):
if method == 'encode':
return '-'.join([str(ord(i)) for i in s])
elif method == 'decode':
return ''.join([str(chr(int(i))) for i in s.split('-')])
s = 'cats on wheels'
encoded = convert(s, method='encode')
decoded = convert(encoded, method='decode')
print(encoded) # prints 99-97-116-115-32-111-110-32-119-104-101-101-108-115
print(decoded) # prints cats on wheels
As you said, one can use ord
to convert a string to an integer, then use chr
to convert an integer back into a string. This lets us flip a string into a sequence of hyphen separated integers, then flip that sequence back into the input string
I think you can simplify this quite a bit if you keep track of the type conversions:
def convert(s, method='encode'):
if method == 'encode':
return '-'.join([str(ord(i)) for i in s])
elif method == 'decode':
return ''.join([str(chr(int(i))) for i in s.split('-')])
s = 'cats on wheels'
encoded = convert(s, method='encode')
decoded = convert(encoded, method='decode')
print(encoded) # prints 99-97-116-115-32-111-110-32-119-104-101-101-108-115
print(decoded) # prints cats on wheels
As you said, one can use ord
to convert a string to an integer, then use chr
to convert an integer back into a string. This lets us flip a string into a sequence of hyphen separated integers, then flip that sequence back into the input string
answered Nov 18 '18 at 19:40
duhaimeduhaime
8,51855580
8,51855580
add a comment |
add a comment |
Using a dictionary makes encryption, decription easier. Example for ceasar chiffre:
d = {}
# build the encode/decode dict
for k in range(26):
cha = chr(ord("a")+k)
d[cha] = k
d[cha.upper()] = k
d[k] = cha
print(d)
def encode(word,offset):
# dont use other things then a-zA-Z or else...
return ''.join(d[ (d[c]+offset)%26 ] for c in word)
def decode(word,offset):
return encode(word,-offset)
print(encode("abcdefg",1))
print(decode("abcdefg",-1))
print ( encode(decode("abrakadabrazzz",1),1) )
Output:
bcdefgh # encode abcdefg , +1
bcdefgh # decode abcdefg , -1
abrakadabrazzz # endoce + decode
The dictionary used looks like:
{'a': 0, 'A': 0, 0: 'a', 'b': 1, 'B': 1, 1: 'b', 'c': 2, 'C': 2, 2: 'c',
'd': 3, 'D': 3, 3: 'd', 'e': 4, 'E': 4, 4: 'e', 'f': 5, 'F': 5, 5: 'f',
'g': 6, 'G': 6, 6: 'g', 'h': 7, 'H': 7, 7: 'h', ...,
'x': 23, 'X': 23, 23: 'x', 'y': 24, 'Y': 24, 24: 'y', 'z': 25, 'Z': 25, 25: 'z'}
essentially it maps any lowercase and uppercase letter to a number and the number back to the lowercase character.
The encoding d[ (d[c]+offset)%26 ]
looks up the "number" that belongs to a character, adds the offset, uses modulo 26 to convert z+1
to a
instead of an error. Then is looks up the correct "new" character by it's number.
You can do the same for your task - you just need the mapping for character
to number
and for number
to character
.
When decoding split your string at '-'
and get the character for the numbervalue you got - when encoding go over all characters of your word and get the correct number from a dict, then '-'.join()
them.
Applied to your task:
from string import ascii_lowercase as low # "abc..xyz"
d = {}
number_for_a = ord("a")
# add the letters/numbers - upper case are 100 + lower case number
for k in low:
d[k] = str(ord(k) - number_for_a)
d[k.upper()] = str(100 + ord(k) - number_for_a)
# add the reverse mapping number to character
for k,v in list(d.items()):
d[v] = k
def encode(word):
# word for both cases - if no `-` in word its iterated character wise, else
# the word is split at '-' and any splits are put through the dictionary
if '-' in word:
return '-'.join(d[c] for c in word.split("-"))
return '-'.join(d[c] for c in word)
def decode(phrase):
return encode(phrase)
print(encode("abcdefg"))
print(decode("1-2-3-4-5-101-100-103-104-105"))
Output:
0-1-2-3-4-5-6
b-c-d-e-f-B-A-D-E-F
add a comment |
Using a dictionary makes encryption, decription easier. Example for ceasar chiffre:
d = {}
# build the encode/decode dict
for k in range(26):
cha = chr(ord("a")+k)
d[cha] = k
d[cha.upper()] = k
d[k] = cha
print(d)
def encode(word,offset):
# dont use other things then a-zA-Z or else...
return ''.join(d[ (d[c]+offset)%26 ] for c in word)
def decode(word,offset):
return encode(word,-offset)
print(encode("abcdefg",1))
print(decode("abcdefg",-1))
print ( encode(decode("abrakadabrazzz",1),1) )
Output:
bcdefgh # encode abcdefg , +1
bcdefgh # decode abcdefg , -1
abrakadabrazzz # endoce + decode
The dictionary used looks like:
{'a': 0, 'A': 0, 0: 'a', 'b': 1, 'B': 1, 1: 'b', 'c': 2, 'C': 2, 2: 'c',
'd': 3, 'D': 3, 3: 'd', 'e': 4, 'E': 4, 4: 'e', 'f': 5, 'F': 5, 5: 'f',
'g': 6, 'G': 6, 6: 'g', 'h': 7, 'H': 7, 7: 'h', ...,
'x': 23, 'X': 23, 23: 'x', 'y': 24, 'Y': 24, 24: 'y', 'z': 25, 'Z': 25, 25: 'z'}
essentially it maps any lowercase and uppercase letter to a number and the number back to the lowercase character.
The encoding d[ (d[c]+offset)%26 ]
looks up the "number" that belongs to a character, adds the offset, uses modulo 26 to convert z+1
to a
instead of an error. Then is looks up the correct "new" character by it's number.
You can do the same for your task - you just need the mapping for character
to number
and for number
to character
.
When decoding split your string at '-'
and get the character for the numbervalue you got - when encoding go over all characters of your word and get the correct number from a dict, then '-'.join()
them.
Applied to your task:
from string import ascii_lowercase as low # "abc..xyz"
d = {}
number_for_a = ord("a")
# add the letters/numbers - upper case are 100 + lower case number
for k in low:
d[k] = str(ord(k) - number_for_a)
d[k.upper()] = str(100 + ord(k) - number_for_a)
# add the reverse mapping number to character
for k,v in list(d.items()):
d[v] = k
def encode(word):
# word for both cases - if no `-` in word its iterated character wise, else
# the word is split at '-' and any splits are put through the dictionary
if '-' in word:
return '-'.join(d[c] for c in word.split("-"))
return '-'.join(d[c] for c in word)
def decode(phrase):
return encode(phrase)
print(encode("abcdefg"))
print(decode("1-2-3-4-5-101-100-103-104-105"))
Output:
0-1-2-3-4-5-6
b-c-d-e-f-B-A-D-E-F
add a comment |
Using a dictionary makes encryption, decription easier. Example for ceasar chiffre:
d = {}
# build the encode/decode dict
for k in range(26):
cha = chr(ord("a")+k)
d[cha] = k
d[cha.upper()] = k
d[k] = cha
print(d)
def encode(word,offset):
# dont use other things then a-zA-Z or else...
return ''.join(d[ (d[c]+offset)%26 ] for c in word)
def decode(word,offset):
return encode(word,-offset)
print(encode("abcdefg",1))
print(decode("abcdefg",-1))
print ( encode(decode("abrakadabrazzz",1),1) )
Output:
bcdefgh # encode abcdefg , +1
bcdefgh # decode abcdefg , -1
abrakadabrazzz # endoce + decode
The dictionary used looks like:
{'a': 0, 'A': 0, 0: 'a', 'b': 1, 'B': 1, 1: 'b', 'c': 2, 'C': 2, 2: 'c',
'd': 3, 'D': 3, 3: 'd', 'e': 4, 'E': 4, 4: 'e', 'f': 5, 'F': 5, 5: 'f',
'g': 6, 'G': 6, 6: 'g', 'h': 7, 'H': 7, 7: 'h', ...,
'x': 23, 'X': 23, 23: 'x', 'y': 24, 'Y': 24, 24: 'y', 'z': 25, 'Z': 25, 25: 'z'}
essentially it maps any lowercase and uppercase letter to a number and the number back to the lowercase character.
The encoding d[ (d[c]+offset)%26 ]
looks up the "number" that belongs to a character, adds the offset, uses modulo 26 to convert z+1
to a
instead of an error. Then is looks up the correct "new" character by it's number.
You can do the same for your task - you just need the mapping for character
to number
and for number
to character
.
When decoding split your string at '-'
and get the character for the numbervalue you got - when encoding go over all characters of your word and get the correct number from a dict, then '-'.join()
them.
Applied to your task:
from string import ascii_lowercase as low # "abc..xyz"
d = {}
number_for_a = ord("a")
# add the letters/numbers - upper case are 100 + lower case number
for k in low:
d[k] = str(ord(k) - number_for_a)
d[k.upper()] = str(100 + ord(k) - number_for_a)
# add the reverse mapping number to character
for k,v in list(d.items()):
d[v] = k
def encode(word):
# word for both cases - if no `-` in word its iterated character wise, else
# the word is split at '-' and any splits are put through the dictionary
if '-' in word:
return '-'.join(d[c] for c in word.split("-"))
return '-'.join(d[c] for c in word)
def decode(phrase):
return encode(phrase)
print(encode("abcdefg"))
print(decode("1-2-3-4-5-101-100-103-104-105"))
Output:
0-1-2-3-4-5-6
b-c-d-e-f-B-A-D-E-F
Using a dictionary makes encryption, decription easier. Example for ceasar chiffre:
d = {}
# build the encode/decode dict
for k in range(26):
cha = chr(ord("a")+k)
d[cha] = k
d[cha.upper()] = k
d[k] = cha
print(d)
def encode(word,offset):
# dont use other things then a-zA-Z or else...
return ''.join(d[ (d[c]+offset)%26 ] for c in word)
def decode(word,offset):
return encode(word,-offset)
print(encode("abcdefg",1))
print(decode("abcdefg",-1))
print ( encode(decode("abrakadabrazzz",1),1) )
Output:
bcdefgh # encode abcdefg , +1
bcdefgh # decode abcdefg , -1
abrakadabrazzz # endoce + decode
The dictionary used looks like:
{'a': 0, 'A': 0, 0: 'a', 'b': 1, 'B': 1, 1: 'b', 'c': 2, 'C': 2, 2: 'c',
'd': 3, 'D': 3, 3: 'd', 'e': 4, 'E': 4, 4: 'e', 'f': 5, 'F': 5, 5: 'f',
'g': 6, 'G': 6, 6: 'g', 'h': 7, 'H': 7, 7: 'h', ...,
'x': 23, 'X': 23, 23: 'x', 'y': 24, 'Y': 24, 24: 'y', 'z': 25, 'Z': 25, 25: 'z'}
essentially it maps any lowercase and uppercase letter to a number and the number back to the lowercase character.
The encoding d[ (d[c]+offset)%26 ]
looks up the "number" that belongs to a character, adds the offset, uses modulo 26 to convert z+1
to a
instead of an error. Then is looks up the correct "new" character by it's number.
You can do the same for your task - you just need the mapping for character
to number
and for number
to character
.
When decoding split your string at '-'
and get the character for the numbervalue you got - when encoding go over all characters of your word and get the correct number from a dict, then '-'.join()
them.
Applied to your task:
from string import ascii_lowercase as low # "abc..xyz"
d = {}
number_for_a = ord("a")
# add the letters/numbers - upper case are 100 + lower case number
for k in low:
d[k] = str(ord(k) - number_for_a)
d[k.upper()] = str(100 + ord(k) - number_for_a)
# add the reverse mapping number to character
for k,v in list(d.items()):
d[v] = k
def encode(word):
# word for both cases - if no `-` in word its iterated character wise, else
# the word is split at '-' and any splits are put through the dictionary
if '-' in word:
return '-'.join(d[c] for c in word.split("-"))
return '-'.join(d[c] for c in word)
def decode(phrase):
return encode(phrase)
print(encode("abcdefg"))
print(decode("1-2-3-4-5-101-100-103-104-105"))
Output:
0-1-2-3-4-5-6
b-c-d-e-f-B-A-D-E-F
edited Nov 18 '18 at 20:11
answered Nov 18 '18 at 19:43
Patrick ArtnerPatrick Artner
23.1k62343
23.1k62343
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53364567%2fencoding-string-into-numbers-separated-by-dashes-decoding-numbers-separated-by%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
why arent you using a dictionary as lookup?
– Patrick Artner
Nov 18 '18 at 19:32
The type error you are getting is likely due to the fact that you're trying to add an integer to a string. While you can do that in some languages (like JavaScript), you can't do that in Python -- in Python we need to convert an integer into a string to add it to a string. So
3 + 's'
throws an error, butstr(3) + 's'
does not.– duhaime
Nov 18 '18 at 19:44
My professor did briefly touch on dictionaries in our last class, and I thought that might be a good way to handle this. I will look for instruction on creating and using dictionaries. Thanks.
– Lisa
Nov 18 '18 at 19:52