I'm unsure on how to make this work. I need to encrypt a string given a different alphabet.
def substitute(string, ciphertext):
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
encrypted = []
list(alphabet)
list(ciphertext)
encrypted = ""
for x in string:
if x.isalpa():
encrypted.append(ciphertext[x])
else:
encrypted.append(x)
word = string.join(encrypted)
print(encrypted)
return encrypted
Try this out:
def substitute(string, ciphertext):
alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") # list() returns a list,
ciphertext = list(ciphertext) # it doesn't change (mutate) the variable
encrypted = [] # Not sure why you were storing the empty string here,
# but strings cannot use the append() method.
for x in string:
if x.isalpha(): # Fixed a typo
# Here I think you want to use alphabet.index(x) instead of x.
encrypted.append(ciphertext[alphabet.index(x)])
else:
encrypted.append(x)
return "".join(encrypted) # Turning the list into a string
As the other commenter said, in the future please add examples of what you do and don't what your code to do.
I would suggest looking up the definition of mutability since that seems to be what you are struggling with.
Related
Disclaimer, sorry if I have not explicitly expressed my issue. Terminology is still new to me. Thank you in advance for reading.
alright, I have a function named
def pluralize(word)
The aim is to pluralize all nouns within a file. The output I desire is: {'plural': word_in_plural, 'status' : x}
word_in_plural is the pluralized version of the input argument (word) and x is a string which can have one of the following values; 'empty_string', 'proper_noun', 'already_in_plural', 'success'.
My code so far looks like..
filepath = '/proper_noun.txt'
def pluralize(word):
proper_nouns = [line.strip() for line in open (filepath)] ### reads in file as list when function is called
dictionary = {'plural' : word_in_plural, 'status', : x} ### defined dictionary
if word == '': ### if word is an empty string, return values; 'word_in_plural = '' and x = 'empty_string'
dictionary['plural'] = ''
dictionary['status'] = 'empty_string'
return dictionary
what you can see above is my attempt at writing a condition that returns a value specified if the word is an empty string.
The next goal is to create a condition that if word is already in plural (assuming it ends with 's' 'es' 'ies' .. etc), then the function returns a dictionary with the values: **word_in_plural = word and x = 'already_in_plural'. So the input word remains untouched. eg. (input: apartments, output: apartments)
if word ### is already in plural (ending with plural), function returns a dictionary with values; word_in_plural = word and x = 'already_in_plural'
any ideas on how to read the last characters of the string to implement the rules ? I also very much doubt the logic.
Thank you for your input SOF community.
You can index the word by -1 to get its last character. You can slice a string to get the the last two [-2:] or last three [-3:] characters
last_char = word[-1]
last_three_char = word[-3:]
I am trying a manual implementation of the Soundex Algorithm and this requires converting alpha text characters to numeric text characters. I have defined the following function:
import re
def sub_pattern(text):
sub = [str(i) for i in range(1,4)]
string = text
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
return(string)
This function will encode abc characters to 1 and xyz characters to 2. However, it only works for a single string and I need to pass a list of strings to the function. I've gotten the results I want using:
list(map(sub_pattern, ['aab', 'axy', 'bzz']
But I want to be able to pass the list to the function directly. I've tried this with no success as it ends only returning the first string from the list.
def sub_pattern(text_list):
all_encoded = []
sub = [str(i) for i in range(1,4)]
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for string in text_list:
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
all_encoded.append(string)
A couple things to note:
Because I am implementing the Soundex Algorithm, the order of the text when I encode it matters. I would prefer to update the string character at its orginal index to avoid having to reorganize it afterwards. In other words, you can't do any sorting to the string...I've created the iterator to incrementally update the string and it only grabs the next regex pattern if all the characters have not already been converted.
This function will be a part of two custom classes that I am creating. Both will call the __iter__ method so that I can created the iterable. That's why I use the iter() function to create an iterable because it will create a new instance if the iterator automatically.
I know this may seem like a trivial issue relative to what I'm doing, but I'm stuck.
Thank you in advance.
How about using your own function recursively? You get to keep the original exactly as it is, in case you needed it:
import re
def sub_pattern(text):
if isinstance(text, str):
sub = [str(i) for i in range(1,4)]
string = text
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
return(string)
else:
return([sub_pattern(t) for t in text])
print(list(map(sub_pattern, ['aab', 'axy', 'bzz']))) # old version still works
print(sub_pattern(['aab', 'axy', 'bzz'])) # new version yields the same result
Should a reader don't know what recursively means: calling a function from within itself.
It is allowed because each function call creates its own
scope,
it can be useful when you can solve a problem by performing a simple operation multiple times, or can't predict in advance how many times you need to perform it to reach your solution, e.g. when you need to unpack nested structures
it is defined by choosing a base case (the solution), and call the function in all other cases until you reach your base case.
I assume the issue with your example was, that once you traversed the iterator, you ran into StopIteration for the next string.
I'm not sure this is what you want, but I would create a new iterator for each string, since you have to be able to traverse over all of it for every new item. I tweaked some variable names that may cause confusion, too (string and sub). See comments for changes:
def sub_pattern(text_list):
all_encoded = []
digits = [str(i) for i in range(1,4)]
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
alpha_search = re.compile('[a-zA-Z]')
for item in text_list:
# Create new iterator for each string.
encode_iter = iter(encode)
for i in digits:
if alpha_search.search(item):
pattern = next(encode_iter)
item = pattern.sub(i, item)
else:
all_encoded.append(item)
# You likely want appending to end once no more letters can be found.
break
# Return encoded texts.
return all_encoded
Test:
print(sub_pattern(['aab', 'axy', 'bzz'])) # Output: ['111', '122', '122']
I tried this code to do simple string replacement:
X = "hello world"
X.replace("hello", "goodbye")
Why doesn't X change, from "hello world" to "goodbye world"?
This is because strings are immutable in Python.
Which means that X.replace("hello","goodbye") returns a copy of X with replacements made. Because of that you need replace this line:
X.replace("hello", "goodbye")
with this line:
X = X.replace("hello", "goodbye")
More broadly, this is true for all Python string methods that change a string's content "in-place", e.g. replace,strip,translate,lower/upper,join,...
You must assign their output to something if you want to use it and not throw it away, e.g.
X = X.strip(' \t')
X2 = X.translate(...)
Y = X.lower()
Z = X.upper()
A = X.join(':')
B = X.capitalize()
C = X.casefold()
and so on.
All string functions as lower, upper, strip are returning a string without modifying the original. If you try to modify a string, as you might think well it is an iterable, it will fail.
x = 'hello'
x[0] = 'i' #'str' object does not support item assignment
There is a good reading about the importance of strings being immutable: Why are Python strings immutable? Best practices for using them
Example for String Methods
Given a list of filenames, we want to rename all the files with extension hpp to the extension h. To do this, we would like to generate a new list called newfilenames, consisting of the new filenames.
filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
# Generate newfilenames as a list containing the new filenames
# using as many lines of code as your chosen method requires.
newfilenames = []
for i in filenames:
if i.endswith(".hpp"):
x = i.replace("hpp", "h")
newfilenames.append(x)
else:
newfilenames.append(i)
print(newfilenames)
# Should be ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]
Here is my code:
dictionary = {'A':'3',
'B':'u',
'C':'t',
'D':'5',
'E':'b',
'F':'6',
'G':'7',
'H':'8',
'I':'/',
'J':'9',
'K':'0',
'L':'-',
'M':'o',
'N':'i',
'O':';',
'P':'}',
'Q':'c',
'R':'n',
'S':'4',
'T':'m',
'U':'.',
'V':'y',
'W':'v',
'X':'r',
'Y':',',
'Z':'e',
}
print(dictionary)
inp = input(str("What do you want me to encode?").upper()).upper()
li = list(inp)
print(li)
for letter in inp:
pass
I want to ask how I could use this dictionary to encrypt any message that goes through the input. Like 'Hello my name is Jerry' would turn into: (Without Phrasing) '8b--; o, i3ob /4 9bnn,'.
Could someone please help me with this. Ive seen other questions like this being asked - but they use PyCrypto. I dont want to go through the hassle of installing it. Could someone please help me.
Thanks,
Jerry
You need to pass each character of the user input through the dictionary to get the cypher value out.
# removed the first .upper() here
inp = input(str("What do you want me to encode?")).upper()
li = list(inp)
print(li)
# create a list of letters passed through the dictionary
out = [dictionary[letter] for letter in inp]
# using ''.join makes the new list a single string
print(''.join(out))
You can use the str.translate method. The benefit here is that you only have to create the table once, so you can use the same table even if you have lots of strings to encrypt.
table = str.maketrans(dictionary) # create a translate table
inp = input("What do you want me to encode? ").upper()
res = inp.translate(table)
print(res)
My code that is meant to replace certain letters (a with e, e with a and s with 3 specifically) is not working, but I am not quite sure what the error is as it is not changing the text file i am feeding it.
pattern = "ae|ea|s3"
def encode(pattern, filename):
message = open(filename, 'r+')
output = []
pattern2 = pattern.split('|')
for letter in message:
isfound = false
for keypair in pattern2:
if letter == keypair[0]:
output.append(keypair[1])
isfound = true
if isfound == true:
break;
if isfound == false:
output.append(letter)
message.close()
Been racking my brain out trying to figure this out for a while now..
It is not changing the textfile because you do not replace the textfile with the output you create. Instead this function is creating the output string and dropping it at the end of the function. Either return the output string from the function and store it outside, or replace the file in the function by writing to the file without appending.
As this seems like an exercise I prefer to not add the code to do it, as you will probably learn more from writing the function yourself.
Here is a quick implementation with the desired result, you will need to modify it yourself to read files, etc:
def encode(pattern, string):
rep = {}
for pair in pattern.split("|"):
rep[pair[0]] = pair[1]
out = []
for c in string:
out.append(rep.get(c, c))
return "".join(out)
print encode("ae|ea|s3", "Hello, this is my default string to replace")
#output => "Hallo, thi3 i3 my dafeult 3tring to rapleca"
If you want to modify a file, you need to specifically tell your program to write to the file. Simply appending to your output variable will not change it.