Define a function named encrypt which takes as input a string (which is the name of a text file in the current directory). The function should then print the encrypted content of this file.
Here text encryption is done by replacing every occurence of a vowel with its next in the list 'aeiou'. So 'a' is replaced by 'e', 'e' is replaced by 'i', so on and 'u' is replaced by 'a'. Also each consonant is replaced with its next in the list 'bcdfghjklmnpqrstvwxyz' so 'b' is replaced by 'c', 'c' by 'd' so on and lastly 'z' is replaced by 'b'. The same replacement logic holds for upper case letters. Note that non-alphabetic characters should appear in their original form without modification.
def encrypt (eo):
vowel = 'aeiou'
con = 'bcdfghjklmnpqrstvwxyz'
for eo in vowel (t[i+1]):
res=
return res
This piece of code could be useful. Pay attention to the vowel and con content. I appended one letter in each variable vowel and com to avoid the modulo operation. Assume the eo is the input string.
def encrypt (eo):
vowel = 'aeioua'
con = 'bcdfghjklmnpqrstvwxyzb'
encrytTable = vowel + con
res = ""
for letter in eo:
res += encrytTable[encrytTable.find(letter)+1]
return res
If eo is the input filename, you need some file read operation like:
>>> fh = open(eo)
>>> fh.read()
>>> fh.>>> fh.close()
And a more effient way to do it, is pre-compute a encryptTable array and use the table to replace the origianl input in a linear manner. In following code, I assume your input only include lower-case letters. Abd if the shift distance is not 1, you need to modify the code. Pre-compute:
>>> vowel = 'aeioua'
>>> con = 'bcdfghjklmnpqrstvwxyzb'
>>> encryptTable = []
>>> for i in xrange(97,123):
temp = chr(i)
if temp in vowel:
encryptTable.append(vowel[vowel.find(temp)+1])
else:
encryptTable.append(con[con.find(temp)+1])
>>> encryptTable
['e', 'c', 'd', 'f', 'i', 'g', 'h', 'j', 'o', 'k', 'l', 'm', 'n', 'p', 'u', 'q', 'r', 's', 't', 'v', 'a', 'w', 'x', 'y', 'z', 'b']
And then replace the content:
>>> plain = "helloworld"
>>> encrypted = "".join([encryptTable[ord(i)-ord('a')] for i in plain])
>>> encrypted
'jimmuxusmf'
def encrypt(s):
vowels = 'aeiou'
vowelReps = dict(zip(vowels, vowels[1:]+vowels[0]))
cons = 'bcdfghjklmnpqrstvwxyz'
consReps = dict(zip(cons, cons[1:]+cons[0]))
answer = []
for char in s:
if char.lower() in vowelReps:
answer.append(vowelReps[char.lower()]
else:
answer.append(consReps[char.lower()]
if char.isupper():
answer[-1] = answer[-1].upper()
return ''.join(answer)
You have multiple problems here:
for eo in ... would replace the eo argument; except
t isn't defined, so will give a NameError;
res= is a SyntaxError; and
Even if all of the above was fixed, return res will happen on the first character, as it is indented too far.
Instead, you could do the following:
def encrypt(eo):
vowels = "aeiou"
for index, vowel in enumerate(vowels): # iterate through the five vowels
new_v = vowels[(index + 1) % len(vowels)] # determine replacement
eo = eo.replace(vowel, new_v) # do replacement
You can then do the same thing for the consonants, then return eo (which should be indented to the same level as vowels = ...!).
Note:
the use of % to keep the index into vowels within the appropriate range; and
the use of enumerate to get both the character vowel from the string vowels and its index within that string.
Alternatively, and more efficiently:
build a dictionary mapping character in to character out;
build a list of replacement characters using the input eo and the dict; and
str.join the output characters together and return it.
Related
I am doing this code wars kata https://www.codewars.com/kata/57eb8fcdf670e99d9b000272/train/python
you have to return the highest scoring word within a string. letters are scored based on position in the alphabet
a =1, z= 26
I've created a list :
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
I want to iterate through the words, which will be in the string (x) passed as a parameter, and if the letter being checked is in the alphabet list, which it of course will be, then to a sperate variable: score, increment score by the number at which the current letter being checked is indexed within the alphabet list.
Is it possible to use list indexes in this way?
Here's my code soo far:
def high(x):
alphabet = []
scores = [] # ignore
score = 0
for letter in range(97,123):
alphabet.append(chr(letter))
word_list = x.split()
for word in word_list:
for letter in word:
if letter in alphabet:
score += # find way to use alphabet list index number as integer here
Thanks.
From what I can see the list of letters isn't needed at all :
import string
def high(x):
score = 0
for word in x.split():
for letter in word:
if letter in string.ascii_lowercase:
score += ord(letter)-96
return score
or even simpler :
import string
def high(x):
# Sum expression on multiple lines for clarity
return sum( ord(letter)-96
for word in x.split()
for letter in word
if letter in string.ascii_lowercase)
Use list comprehensions and dictionary score to keep track of each letter and its score. Notice that the input string is lowercased - I assume that upper- and lowercase letters are scored the same.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
score = dict(zip(list(alphabet), [i + 1 for i in range(len(alphabet))]))
x = 'aB, c'
score = sum([score[c] for c in list(x.lower()) if c in score])
print(score)
# 6
#AlanJP, would you like to try this program:
# simple word scoring program
import string
characters = string.ascii_lowercase
ranking = {c: i for i, c in enumerate(characters, 1)}
#print(ranking)
word_list = 'abba is great'.split()
for word in word_list:
score = 0 # reset the score for each incoming word
for char in word:
score += ranking[char]
print(word, score)
Output:
abba 6
is 28
great 51
>>>
Yes. alphabet.index(letter) + 1 will give you what you want.
index() you're going also want to +1 to account for index [0]
# vowels list
vowels = ['a', 'e', 'i', 'o', 'i', 'u']
# index of 'e' in vowels
index = vowels.index('e')
print('The index of e:', index)
I'm trying to create a Python function that receives a letter (a string with only one alphabetic character) and returns the 0-based numerical position of that letter in the alphabet. It should not be case-sensitive, and I can't use import.
So entering "a" should return
0
Entering "A" should also return
0
Entering "O" should return
14
And so on.
I had noticed this question but the top answer uses import and the second answer doesn't make any sense to me / doesn't work. I tried to apply the second answer like this:
letter = input("enter a letter")
def alphabet_position(letter):
return ord(letter) - 97
print((alphabet_position)(letter))
but I got a TypeError:
TypeError: ord() expected a character, but string of length 2 found
Just like the asker in the question that I linked, I'm also trying to send the characters "x" amount of steps back in the alphabet, but in order to do that I need to create this helper function first.
I'm thinking there must be a way to store the letters in two separate lists, one lower-case and one upper-case, and then see if the string that the user entered matches one of the items in that list? Then once we find the match, we return it's (0-based) numerical position?
letter = input("enter a letter")
def alphabet_position(letter):
position = 0
#letter_position = index value that matches input
lower_case_list ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z']
upper_case_list ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y','Z']
#if letter is in lower_case_list, return it's 0-based numerical position.
#else, if letter is in upper_case_list, return it's 0-based numerical position.
#else, print("Enter a valid letter")
return letter_position
Please help if you have any suggestions. Thank you.
It's probably simpler to just convert from uppercase or lowercase to specifically lowercase with the .lower() method, and use the built in list of letters (string.ascii_lowercase). You can find the index of a list's element by using the .index() method.
import string
letter = input('enter a letter: ')
def alphabet_position(letter):
letter = letter.lower()
return list(string.ascii_lowercase).index(letter)
print(alphabet_position(letter))
When you called alphabet_position, it is expecting an argument so you need to do func_name(arg) format.
Another way you could do this is to use dictionary comprehension to create a dict of letter-position pairs, like so:
from string import lowercase as l
alphabet_lookup = {letter:pos for letter,pos in zip(l, range(len(l)))}
and then
f = lambda letter: alphabet_lookup[letter.lower()]
is the desired function.
I suggest using a dictionary. It might be a large amount of code to do something relatively simple, but I find it easier to make sense of it this way (and if you are new to python it will help you learn). If you google python dictionaries you can learn lots more about them, but here is the basic concept:
Code for python version 3.X:
def alphabet_position(letter):
alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1}
pos = alphabet_pos[letter]
return pos
letter = input('Enter a letter: ')
print(alphabet_position(letter))
Code for python version 2.7:
def alphabet_position(letter):
alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1}
pos = alphabet_pos[letter]
return pos
letter = raw_input('Enter a letter: ')
print alphabet_position(letter)
If you run that, it will print 1 because it searches through the alpahbet_pos dictionary and finds the value that corresponds to the entry entitled 'B'. Notice that you can have multiple entries with the same value, so you can do uppercase and lowercase in the same dictionary. I only did letters A and B for the sake of time, so you can fill out the rest yourself ;)
I once had to enter every element on the periodic table and their corresponding atomic mass, and that took forever (felt much longer than it actually was).
I have put the letters a-z in a list. How would I find the value of an item in the list depending on what the user typed?
For example if they type the letter a it would return c, f would return h and x would return z.
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
newletters = []
offset = 2
userInput = input('type a string')
newvalue = chr(ord(userInput)+offset)
split = list(newvalue)
print split
the above works for a character but not for a string..help?!
You can try this:
>>> offset = 2
>>> aString = raw_input("digit a letter: ")
>>> aString
'a'
>>> chr(ord(aString)+offset)
'c'
documentation:
https://docs.python.org/2/library/functions.html#chr
https://docs.python.org/2/library/functions.html#ord
If you want to iterate over an entire string, a simple way is using a for loop. I assume the input string is always lowercase.
EDIT2: I improved the solution to handle the case when a letter is 'y' or 'z' and without "rotation" should begin a not alphabetic character, eg:
# with only offset addiction this return a non-alphabetic character
>>> chr(ord('z')+2)
'|'
# the 'z' rotation return the letter 'b'
>>> letter = "z"
>>> ord_letter = ord(letter)+offset
>>> ord_letter_rotated = ((ord_letter - 97) % 26) + 97
>>> chr(ord_letter_rotated)
'b'
The code solution:
offset = 2
aString = raw_input("digit the string to convert: ")
#aString = "abz"
newString = ""
for letter in aString:
ord_letter = ord(letter)+offset
ord_letter_rotated = ((ord_letter - 97) % 26) + 97
newString += chr(ord_letter_rotated)
print newString
The output of this code for the entire lowercase alphabet:
cdefghijklmnopqrstuvwxyzab
Note: you can obtain the lowercase alphabet for free also this way:
>>> import string
>>> string.lowercase
'abcdefghijklmnopqrstuvwxyz'
See the wikipedia page to learn something about ROT13:
https://en.wikipedia.org/wiki/ROT13
What should happen for z? Should it become b?
You can use Python's maketrans and translate functions to do this as follows:
import string
def rotate(text, by):
s_from = string.ascii_lowercase
s_to = string.ascii_lowercase[by:] + string.ascii_lowercase[:by]
cypher_table = string.maketrans(s_from, s_to)
return text.translate(cypher_table)
user_input = raw_input('type a string: ').lower()
print rotate(user_input, 2)
This works on the whole string as follows:
type a string: abcxyz
cdezab
How does it work?
If you print s_from and s_to they look as follows:
abcdefghijklmnopqrstuvwxyz
cdefghijklmnopqrstuvwxyzab
maketrans creates a mapping table to map characters in s_from to s_to. translate then applies this mapping to your string.
The program identifies if one of the elements in the string word is a consonant by looping though the word string, and then for each iteration though the word string, iterating though the consonants list and comparing if the current element in word string equals to the current element of consonant list.
If yes, the current element of the word string is a consonant and the consonant gets printed (not the index of the consonant, but the actual consonant, for e.g. "d".)
The problem is, I get this instead:
1
1
What am I doing wrong? Shouldn't the nested loops work so that the below loop iterates every element for each element in the above loop? That is, each index above makes the below loop iterate though each index?
That's the program:
word = "Hello"
consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
for character in range(len(word)):
for char in range(len(consonants)):
if consonants[char] == word[character]:
consonant = word[character]
print consonant
You are misreading the output. The character is the letter L lowercase, not the number 1.
In other words, your code is working as designed. The captital letter H is not in your consonants list, but the two lowercase letters l in Hello are.
Note that it'd be much more efficient to use a set for consonants here; you'd not have to loop over that whole list and just use in to test for membership. That works with lists too, but is much more efficient with a set. If you lowercase the word value you'd also be able to match the H.
Last but not least, you can loop over the word string directly rather than use range(len(word)) then use the generated index:
word = "Hello"
consonants = set('bcdfghjklmnpqrstvwxz')
for character in word.lower():
if character in consonants:
print character
Demo:
>>> word = "Hello"
>>> consonants = set('bcdfghjklmnpqrstvwxz')
>>> for character in word.lower():
... if character in consonants:
... print character
...
h
l
l
I'm trying to see if a word or sentence has each letter of the alphabet and I can't get it to print all the letters that isn't in the sentence/word.
alpha = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'
,'u','v','w','x','y','z']
x = raw_input('')
counter = 0
counter2 = 0
for i in range(len(x))
counter += 1
for o in range(26):
counter2 += 1
if alpha[counter2] not in x[counter]:
and I'm stuck there...
alphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'
,'u','v','w','x','y','z'}
input_chars = set(raw_input())
print alphabet - input_chars
All we do is set difference between the set of alphabet characters and the set of characters in our input. Note that the difference operation can take as a second operand any iterable, so we don't even really have to turn our input into a set if we don't want to, although this will speed up the difference a small amount. Furthermore, there is a built-in string which gives us the ascii letters so we could do it like this:
import string
print set(string.ascii_lowercase) - raw_input()
using set difference:
import string
x=raw_input()
not_found=set(string.ascii_lowercase) - set("".join(x.split()))
print (list(not_found))
output:
>>>
the quick brown fox
['a', 'd', 'g', 'j', 'm', 'l', 'p', 's', 'v', 'y', 'z']
Since you're already iterating over both strings, there is no need to use counter and counter2.
You were almost there. Python makes list operations simple, so there's no need to iterate over the lists element-by-element using indices:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
sentence = raw_input('Enter a sentence: ').lower() # Because 'a' != 'A'
letters = []
for letter in sentence:
if letter in alphabet and letter not in letters:
letters.append(letter)
print(letters)
Much easier:
import string
x = raw_input()
print [c for c in string.ascii_lowercase if c not in x]