so I have the encrypt dictionary already set up:
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "
word = input("Enter the message: ")
d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}
and lets say I want to encrypt word, I would use replace()here, but if I use that one, it just replaces everything with A and B.
My code currently looks like that:
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "
d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}
word = input("Enter a word: ")
for key in d.keys():
word = word.upper().replace(key, d[key])
print(word)
and in the Terminal it prints out "BAAB".
Not sure why its only using the A and B and nothing more.
You can do it with .join():
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQ9RSTUVWXYZAB "
d = {a: e for a, e in zip(alphabet, encrypt)}
''.join(d[i] for i in 'word'.upper())
Output:
'XQSF'
You're replacing the letter one by one so the letter a is changed to c but in the next loop, c will be changed to e etc, you only have b and a because it's the 2 last letters in your code and the gap in your code is 2.
You have to use another variable and iterate through the initial variable and add the value letter in another variable from the key in the first variable
Not sure if it's really clear so here's an example :
word2 = ""
for i in word:
word2 += d[i]
First you replace every A with C, so you don't have As anymore (only B to Z). Then you replace every B with D, so you don't have Bs anymore, either (only C to Z). Etc. Near the end, you only have Ys and Zs left, and you replace them with A and B, respectively. That's why your output only has As and Bs.
You should make all replacements "in parallel" instead of sequentially like you do, and a proper way to do that is to use str.translate:
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "
trans = str.maketrans(alphabet, encrypt)
word = 'Chaos'
print(word.upper().translate(trans))
Output:
EJCQU
Something like this should solve it for you:
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "
d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}
print(''.join([d[i.upper()] for i in input("Enter a word: ")]))
Adding to #Nin17's answer and assuming the dictionary d is given, you can use map instead of a list comprehension to obtain the string:
res = "".join(map(d.get, "word".upper()))
As NicoCaldo points out, you may also simply add 2 to the ASCII numerical representation of each character, wrapping around and making an exception for the space character .
from_letter = ord("A")
to_letter = ord("Z")
range = to_letter - from_letter
offset = ord("B") - from_letter
res = "".join(map(lambda c: c if c == " " else chr(from_letter + ((ord(c)-from_letter+offset) % range)), "some words".upper()))
Related
I am a beginner and this is what I came up with so far. However, it does not output the correct number of words that end with "a" or "b." Any tips on how to correct this code?
names = input("Enter list of names: ")
name = names.split(" ")
num = len(name)
ab = ""
print("Number of words:", num)
for i in range(num):
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
a_b = ab.split(' ')
print("Number of words that end with a or b: ",len(a_b))
In Python boolean (True and False) are the same as the integers 1 and 0. This means you can use sum() to count True booleans. str.endswith() returns a boolean. This means you can just do this:
words = ["stab", "drama", "hello", "magma", "test"]
a_b = sum(word.endswith(('a', 'b')) for word in words)
# 3
z_c = sum(word.endswith(('z', 'c')) for word in words)
# 0
Any tips on how to correct this code?
Others have answered alternative, working solutions, but I want to try to point out the specific things wrong in your code snippet and tips to correct.
First here's a copy of your snippet with some simple debugging prints along with their output (running in python 3.10).
names = "Barry Lima Bab"
name = names.split(" ")
print(f"{name=}") # name=['Barry', 'Lima', 'Bab']
num = len(name)
print(f"{num=}") # num=3
ab = ""
print("Number of words:", num)
for i in range(num):
print(name[i]) # Barry -> Lima -> Bab
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
print(f"{ab=}") # ab=''
a_b = ab.split(' ')
print(f"{a_b=}") # a_b=['']
Breaking things down step by step like this is a great starting point for better understanding what's going on.
if name[i] == ' ': Notice the value of name[i] so this check never resolves to True meaning the code inside never runs
if the inner code did run, you'd hit a NameError: name 'a' is not defined. Did you mean: 'ab'? because a is undefined. Probably meant 'a' here. same for b
In my example, name[i-1] would be 'Bab' -> 'Barry' -> 'Lima' which is probably not what you're expecting. This is because you're getting the -1th, 0th, 1st items in name. to get the last letter from the name, you want name[i][-1] here
if you then get into either of the furthest inside conditions, you'd encounter AttributeError: 'str' object has no attribute 'append' which happens because append is for list not str. You couldchange ab to be a list to use this in which case you'd want ab.append(name[i]) or you can use string concatenation like ab += " " + name[i] or using str.concat
1 last note of interest, you may have noticed your code as-is really likes to return and say that there's 1 item. This is because the above issues always (if the program doesn't break) leaves ab == '' and ''.split(' ') => [''] and thus len(ab.split(" ")) => 1
1 tip that I think would help in code comprehension is that the name variable here is not a single name string like it implies. It's actually a list[str]. I'd probably denote the variables something more like names_str: str vs names: list[str] or raw_names vs names. Then just use something like for name in names: and not worry about indexes. You can also use name.endswith('a') instead of name[-1] == 'a' for better readability.
Eventually you can combine these into a list comprehension for maximal succinctness -> len([name for name in names if name.endswith('a') or name.endswith('b')]).
words = ["ab", "bab", "pa", "pap"]
result = 0
for word in words:
if word[-1] in "ab":
result += 1
print(result)
As a list comprehension:
words = ["word1a", "word2b", "word3", "word4", "word5a"] # ['word1a', 'word2b', 'word5a']
filtered_words = [word for word in words if word[-1] in "ab"]
filtered_words = [word for word in words if word.endswith(("a", "b"))] # better, if you have multiple endings you want to search for with different lengths
len(filtered_words) # 3
name[i-1] is the previous name in the list, not the last character of the current name in the loop.
There's no need to append the matching names to a string. If you just need the count of matches, increment a counter variable.
You need to put a and b in quotes to make them strings, not variables.
names = input("Enter list of names: ")
name = names.split(" ")
matches = 0
print("Number of words:", len(name))
for cur_name in name:
if cur_name.endswith('a') or cur_name.endswith('b'):
matches += 1
print("Number of words that end with a or b: ", matches)
Use the endswith string method to detect if the last letter is "a" or "b"
names = ["bob","boba","larry","curly","moe"]
count = 0
for name in names:
if name.endswith("a") or name.endswith("b"):
count += 1
print(f"{count=}") # count=2
I'm a Python beginner and would like to know how to split a user input at pair and at space and add it to a list.
E.g:
user = input('A1 KW')
user.split(" " ) # split on space
Then I'd like to print the input on index 0 what should be A1 and also print the alphabet and number/alphabet of each index.
E.g:
input[0] = A1
alphabet = A
number = 1
input[1] = KW
alphabet1 = K
alphabet2 = W
Then add it to a list.
list = ['A1, KW']
I hope you guys know what I mean.
Basic String manipulation.
There are lots of tutorials out there on that, go look them up.
From your question, it looks like you would want to use the isalpha() builtin.
Here's a function that should do the string manipulation like you said.
def pair(user):
user=user.split(" ")
for x in range(len(user)):
print ("\nPair part "+str(x)+":")
for char in user[x]:
if char.isalpha():
print ("Alphabet: "+char)
else:
print ("Number: "+char)
then you can call it with:
print("example pair was 'A1 KW'")
pair("A1 KW")
pair(input("\nEnter your pair: "))
output:
example pair was 'A1 KW'
Pair part 0:
Alphabet: A
Number: 1
Pair part 1:
Alphabet: K
Alphabet: W
Enter your pair: AB 3F
Pair part 0:
Alphabet: A
Alphabet: B
Pair part 1:
Number: 3
Alphabet: F
I have been playing with Python and came across a task from MIT, which is to create coded message (Julius Cesar code where for example you change ABCD letters in message to CDEF). This is what I came up with:
Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))
listPhrase = list(Phrase)
listLenght = len(listPhrase)
ascii = []
for ch in listPhrase:
ascii.append(ord(ch))
print (ascii)
asciiCoded = []
for i in ascii:
asciiCoded.append(i+shiftValue)
print (asciiCoded)
phraseCoded = []
for i in asciiCoded:
phraseCoded.append(chr(i))
print (phraseCoded)
stringCoded = ''.join(phraseCoded)
print (stringCoded)
The code works but I have to implement not shifting the ascii value of spaces and special signs in message.
So my idea is to select values in list in range of range(65,90) and range(97,122) and change them while I do not change any others. But how do I do that?
If you want to use that gigantic code :) to do something as simple as that, then you keep a check like so:
asciiCoded = []
for i in ascii:
if 65 <= i <= 90 or 97 <= i <= 122: # only letters get changed
asciiCoded.append(i+shiftValue)
else:
asciiCoded.append(i)
But you know what, python can do the whole of that in a single line, using list comprehension. Watch this:
Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))
# encoding to cypher, in single line
stringCoded = ''.join(chr(ord(c)+shiftValue) if c.isalpha() else c for c in Phrase)
print(stringCoded)
A little explanation: the list comprehension boils down to this for loop, which is easier to comprehend. Caught something? :)
temp_list = []
for c in Phrase:
if c.isalpha():
# shift if the c is alphabet
temp_list.append(chr(ord(c)+shiftValue))
else:
# no shift if c is no alphabet
temp_list.append(c)
# join the list to form a string
stringCoded = ''.join(temp_list)
Much easier it is to use the maketrans method from the string module:
>>import string
>>
>>caesar = string.maketrans('ABCD', 'CDEF')
>>
>>s = 'CAD BA'
>>
>>print s
>>print s.translate(caesar)
CAD BA
ECF DC
EDIT: This was for Python 2.7
With 3.5 just do
caesar = str.maketrans('ABCD', 'CDEF')
And an easy function to return a mapping.
>>> def encrypt(shift):
... alphabet = string.ascii_uppercase
... move = (len(alphabet) + shift) % len(alphabet)
... map_to = alphabet[move:] + alphabet[:move]
... return str.maketrans(alphabet, map_to)
>>> "ABC".translate(encrypt(4))
'EFG'
This function uses modulo addition to construct the encrypted caesar string.
asciiCoded = []
final_ascii = ""
for i in ascii:
final_ascii = i+shiftValue #add shiftValue to ascii value of character
if final_ascii in range(65,91) or final_ascii in range(97,123): #Condition to skip the special characters
asciiCoded.append(final_ascii)
else:
asciiCoded.append(i)
print (asciiCoded)
How do I print a specific character from a string in Python? I am still learning and now trying to make a hangman like program. The idea is that the user enters one character, and if it is in the word, the word will be printed with all the undiscovered letters as "-".
I am not asking for a way to make my idea/code of the whole project better, just a way to, as i said, print that one specific character of the string.
print(yourstring[characterposition])
Example
print("foobar"[3])
prints the letter b
EDIT:
mystring = "hello world"
lookingfor = "l"
for c in range(0, len(mystring)):
if mystring[c] == lookingfor:
print(str(c) + " " + mystring[c]);
Outputs:
2 l
3 l
9 l
And more along the lines of hangman:
mystring = "hello world"
lookingfor = "l"
for c in range(0, len(mystring)):
if mystring[c] == lookingfor:
print(mystring[c], end="")
elif mystring[c] == " ":
print(" ", end="")
else:
print("-", end="")
produces
--ll- ---l-
all you need to do is add brackets with the char number to the end of the name of the string you want to print, i.e.
text="hello"
print(text[0])
print(text[2])
print(text[1])
returns:
h
l
e
Well if you know the character you want to search you can use this approach.
i = character looking for
input1 = string
if i in input1:
print(i)
you can change the print statement according to your logic.
name = "premier league"
for x in name:
print(x)
Result shown below:-
To print specific characters of the given string. For example to print 'l' from the given string
name = "premier league"
for x in name:
if x == "l":
print("element found: "+x)
word = raw_input('Enter a word: ')
for i in word:
if i in ['a','e','i','u','A','E','I','O','o','U']:
word1 = i
break
else:
print i,
print ""
i = 0
while word[i]!=word1:
This is where I am having a problem. I need to save each letter before the vowel(or g as I have attempted). This is the beginnings of a pig latin translator. In this stage, I am trying to flip the prefix and the rest of the word.
g = word[i]
i = i+1
prefix = g + word1
print prefix
Example:
input - person
output - rsonpe
input - hello
output - llohe
input - pppat
output - tpppa
input - hhhhhelllllloool
output - llllllooolhhhhhe
I am flipping the letters before the first vowel, and the rest of the word.
you can use regular expression if you are familiar with it or you can just edit your code like this in a very simple and crude way.
word = raw_input('Enter a word: ')
word1 = 0
for i in range(0,len(word)) :
if word[i] in ['a','e','i','u','A','E','I','O','o','U']:
word1=i
break
print word[word1+1:]+word[:word1]+word[word1]
Looks like a job for regular expressions:
import re
Vowel = re.compile('[aeiouAEIOU]')
def flipper ( inStr ) :
myIndex = Vowel.search( inStr ).start() + 1
return inStr[myIndex:] + inStr[:myIndex]
flipper( 'hello' )
output:
'llohe'
Alternatively, if you really want to do it with a while loop, you just need to define a global variable outside of the while loop that you can save to.