How to increment letters in Python? - python

Write a program that takes a character as input (a string of length 1), which you should assume is an upper-case character; the output should be the next character in the alphabet. If the input is 'Z', your output should be 'A'. (You will need to use an if statement.)
So far I've tried several codes like this:
chr = input()
if chr == '65':
x = chr(ord(chr) + 1)
print(chr(65) + 1)
It says it prints with no output, just unsure how to get to the the right output. Im very new to programming.

This should work:
my_chr = ord(input())
if my_chr == 90:
print('A')
else:
print(chr(my_chr+1))
It takes the input letter (A-Z) and gets its ord() value. It then checks to see if the value is equal to Z (ord('Z') == 90) and prints A otherwise, it increments it by 1 then turns it back to a string and prints it.

You can use the following idea:
A = 65
Z = 90
If you subtract ord('A') from the input, you reduce the range to [0, 25]
So, you need to define the output inside the range [0, 25]. To avoid getting out this range, you should use '%'.
char_input = input()
return chr((ord(char_input) - ord('A') + 1) % 26 + ord('A'))
it means that, giving the input, you will subtract the value of ord('A') to "fix" the range and, after that, add + 1. You will take % 26 to avoid getting out the range. After all of that, add ord('A') again.

Hope this is what you are looking for
_chr = input('Enter character(A-Z): ')
if _chr == 'Z':
print('A')
else:
print(chr(ord(_chr) + 1))

alpha=input()
if alpha =='Z': print('A')
else:print(chr(ord(alpha)+1))
"You will need to use an if statement"

The below method is using ascii_letters.
import string
// returns a string of all the alphabets
// abcdefghijklmnopqrstuvwxyz"
result = string.ascii_letters
// get the index of the input alphabet and return the next alphabet in the results string.
// using the modulus to make sure when 'Z' is given as the input it returns to the first alphabet.
result[(result.index(alphabet.lower()) + 1) % 26].upper()

Related

even and uneven letter, TypeError: not all arguments converted during string formatting

def ul(a):
if a %2 == 0:
print(a.upper())
else:
print(a.lower())
ul(input())
I get following error:
TypeError: not all arguments converted during string formatting
I want to write every even letter in uppercase and every uneven letter in lowercase
What I'm doing wrong?
What you are now doing with this function is check whether the input (a string) is divisible by 2. This is not really what you wanted to do and it raises an error because strings are not modulo divisible.
You should better loop through the indices of the input string to fill a second string with upper and lower case letters:
def ul(s):
outstring = ''
for i in range(len(s)): ## For each index of the string
if i%2==0:
outstring += s[i].upper() ## Even indices become upper case
else:
outstring += s[i].lower() ## Odd indices become lower case
print(outstring)
ul(input("Enter a string: "))
You are trying to get mode of string as I understand. You should use len(a).
def ul(a):
if len(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
ul(input())
Try this
def ul(a):
a = a.lower()
if ord(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
if you want user to enter only Alphabets, then try this
def ul(a):
if ord(a) >= 110 and ord(a) < 123:
a = a.lower()
if ord(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
else:
print("Please enter Alphabets only")
Input will give you a string. You want to use the modulo operator %, which is exactly how you usually find the evenness of a number. So, you are on the right track!
What actually happens is that Python interprets your % as the format operator (probably has a fancy name).
number = 2
print("Number %d is this" % number)
>>> Number 2 is this
Strings in Python are immutable, so you can't just change the string that easily.
Try this Replacing every 2nd character in a string , where you construct a new string by adding all the individual characters together.
def ul(word):
new = []
for i in range(len(word)):
if i%2 == 0:
new += word[i].upper()
else:
new += word[i].lower()
print("".join(new))
This will go through the string character by character, transform the individual character based on if it is even or not, and then construct a list "new", that holds all the individual characters. In the end, just join it, so create a new string out of the list.
There are more pythonic ways to do this using list comprehension, but for now this is easier to read and understand.

Give a string as a input and print the next alphabet. Input: xyzabc Output: yzabcd

user_input = (input("Enter: ")).lower()
for item in user_input:
output = chr(ord(item)+1)
print(output, end="")
#I have tried this but while I run the program the after z it is printing {. But I need to print a after z. How can it be done?
Use modulo arithmetic. In place of
chr(ord(item)+1)
you can use:
chr(ord("a") + (ord(item) - ord("a") + 1) % 26)
(For efficiency, you could store the ord("a") in a variable rather than evaluate it every time.)

Python vigenere cipher going further than needed?

I am attempting to create the vigenere cipher in python and there seems to be a problem. Here is my encryption code:
def encryption():
plaintext=input("Please enter the message you wish to encode.")
#This allows the user to enter the message they wish to encrypt.
keyword=input("Please enter your keyword, preferably shorter than the plaintext.")
#This allows the user to enter a keyword.
encoded=""
#This creates a string for the user to input the encrypted message to.
while len(keyword)<len(plaintext):
#This begins a while loop based on the fact that the length of the keyword is shorter than the length of the plaintext.
keyword+=keyword
#This repeats the keyword.
if len(keyword)>len(plaintext):
#This sees if the string length of the keyword is now longer than the string length of the plaintext.
newkey=keyword[:len(plaintext)]
#This cuts the string length of the keyword
for c in range(len(plaintext)):
char=ord(plaintext[c])
temp=ord(keyword[c])
newchar=char+temp
if newchar>ord("Z"):
newchar-=26
newnewchar=chr(newchar)
encoded+=newnewchar
print(encoded)
I cannot seem to find the problem with it, however when I enter the plaintext "hello" and the keyword "hi" it come up with the following symbols: ¶´º»½. I think the addition in the for loop may be going too far.
You need to understand the ord() function, chr() is the inverse of ord()
for i in range(300):
print(str(i) + ' ' + chr(i))
If you don't use Unicode characters, you can use an alphabet string
alphabet = 'abcdefghijklmnopqrstuvwxyz'
for p,k in zip(plaintext,keyword): # you can directly iterate strings
char = alphabet.index(p)
temp = alphabet.index(k)
newchar = char + temp
if newchar > 25:
newchar -= 25
newchar = alphabet[newchar]
I won't just solve the bug for you as there are many other things to improve here !
Put space around operators: a=b should be a = b, same with +, -, etc.
I find it better to use function params than input. You can always have a second function to get input and encrypt the input:
def encryption(plaintext, keyword):
pass # (do nothing)
I'll let you write the auxiliary function.
I, and most, usually put comments on the line above the corresponding code. Also, no need to write This every time, and imperative is generally preferred.
Now let's have a look at your while loop. The condition is len(keyword) < len(plaintext), inside you check len(keyword) > len(plaintext). When can that happen ? Only during the last iteration. So move the code out of the loop.
Also, what you do inside the if doesn't need an if:
any_string[:len(any_string) + n] == any_string (n being a positive int).
Plus you never use newkey!
So we can simplify the loop to:
# Begin a while loop based on the fact that the length of the keyword is
# shorter than the length of the plaintext.
while len(keyword) < len(plaintext):
# Repeat the keyword.
keyword += keyword
# Cut the string length of the keyword
keyword = keyword[:len(plaintext)]
Which is equivalent to:
# Do the operation once
txt_len = len(plaintext)
# Get a string just a bit longer than plaintext
# Otherwise we would have issues when plaintext is not a multiple
# of keyword
keyword *= txt_len // len(keyword) + 1
# Chop of the extra part
keyword = keyword[:txt_len]
Note that both will fail when len(keyword) == 0.
Now to the for loop:
You could use zip, as polku showed you, but I'll assume it's too complicated for now and keep the range.
You could also use the alphabet, but plain arithmetic can do the trick:
alphabet.index(x) == ord(x) - ord('a'), so in your code:
char = ord(plaintext[c]) - ord('a')
temp = ord(keyword[c]) - ord('a')
newchar = char + temp
# Or simply:
newchar = ord(plaintext[c]) + ord(keyword[c]) - 194 # 2 * ord('a')
If we ignore capital letters, we can safely substitute
if newchar > 25:
newchar -= 25
# With
newchar %= 25
Finally:
alphabet[i] == ord(i + ord('a')).
Here's all this put together:
def encryption(plaintext, keyword):
# Do the operation once
txt_len = len(plaintext)
# Get a string just a bit longer than plaintext
# Otherwise we would have issues when plaintext is not a multiple
# of keyword
keyword *= txt_len // len(keyword) + 1 # // is floor division
# Chop of the extra characters (if there are any)
keyword = keyword[:txt_len]
# Create a string to store the encrypted message
encoded = ""
# Now you should change this to work with capital letters
for c in range(txt_len):
# 194 = 2 * ord('a')
newchar = ord(plaintext[c]) + ord(keyword[c]) - 194
newchar %= 25
encoded += chr(newchar + 97) # 97 = ord('a')
return encoded
def encrypt_input():
# This function should use input to get plaintext and keyword
# Then use encryption with those strings and print the result
pass
Indeed the addition goes too far, because ord uses ASCII (where A is 65), while de Vigenère had A in the first position. You could subtract ord('A'). The code also assumes all characters are capital letters. Here's a variation that uses a few of Python's library functions to perform the task.
import string, itertools
def encrypt(text, key='N'): # default to rot13 (:
'''Performs a Vigenere cipher of given plaintext and key'''
result=[]
key=key.upper()
for plain,shift in itertools.izip(text,itertools.cycle(key)):
shiftindex=string.ascii_uppercase.index(shift)
shiftto=(string.ascii_uppercase[shiftindex:] +
string.ascii_uppercase[:shiftindex])
trans=string.maketrans(string.ascii_letters,
shiftto.lower()+shiftto)
result.append(plain.translate(trans))
return ''.join(result)
A more complete variant might only consume key for letters, but this will be fine if your strings only contain letters. The reason I stuck to the ASCII letters is because locale specific alphabets might not have the intended ordering nor a matching set of upper and lower case (for instance, german ß). It's also entirely possible to translate the key into a list of translation tables only once.

How to make Caesar decoder circular in Python (2.7)?

After much frustration, I have made my first Caesar Decoder :)
But the problem now is to make the program circular...
For example if we want to shift doge by 1, no problem, it's ephf...
But what about xyz, and the shift was 4???
So programming pros help a first time novice aka newb out :P
Thanks...
import string
def main():
inString = raw_input("Please enter the word to be "
"translated: ")
key = int(raw_input("What is the key value? "))
toConv = [ord(i) for i in inString] #now want to shift it by key
toConv = [x+key for x in toConv]
#^can use map(lambda x:x+key, toConv)
result = ''.join(chr(i) for i in toConv)
print "This is the final result due to the shift", result
Here is Python code that I wrote to be easy to understand. Also, I think the classic Caesar cipher didn't define what to do with punctuation; I think the classic secret messages were unpunctuated and only contained letters. I wrote this to only handle the classic Roman alphabet and pass any other characters unchanged.
As a bonus, you can use this code with a shift of 13 to decode ROT13-encoded jokes.
def caesar_ch(ch, shift):
"""
Caesar cipher for one character. Only shifts 'a' through 'z'
and 'A' through 'Z'; leaves other chars unchanged.
"""
n = ord(ch)
if ord('a') <= n <= ord('z'):
n = n - ord('a')
n = (n + shift) % 26
n = n + ord('a')
return chr(n)
elif ord('A') <= n <= ord('Z'):
n = n - ord('A')
n = (n + shift) % 26
n = n + ord('A')
return chr(n)
else:
return ch
def caesar(s, shift):
"""
Caesar cipher for a string. Only shifts 'a' through 'z'
and 'A' through 'Z'; leaves other chars unchanged.
"""
return ''.join(caesar_ch(ch, shift) for ch in s)
if __name__ == "__main__":
assert caesar("doge", 1) == "ephf"
assert caesar("xyz", 4) == "bcd"
assert caesar("Veni, vidi, vici.", 13) == "Irav, ivqv, ivpv."
The part at the end is a "self-test" for the code. If you run this as a stand-alone program, it will test itself, and "assert" if a test fails.
If you have any questions about this code, just ask and I'll explain.
Just add the key to all the actual character codes, then if the added value is greater than z, modulo with character code of z and add it with the character code of a.
inString, key = "xyz", 4
toConv = [(ord(i) + key) for i in inString] #now want to shift it by key
toConv = [(x % ord("z")) + ord("a") if x > ord("z") else x for x in toConv]
result = ''.join(chr(i) for i in toConv)
print result # cde
I'd recommend using string.translate().
So, we can do the following:
key = 1
table = string.maketrans(string.ascii_lowercase + string.ascii_uppercase, string.ascii_lowercase[key:] + string.ascii_lowercase[:key] + string.ascii_uppercase[key:] + string.ascii_uppercase[:key])
And then we can use it as follows:
'doge'.translate(table) # Outputs 'ephf'
'Doge'.translate(table) # Outputs 'Ephf'
'xyz'.translate(table) # Outputs 'yza'
In particular, this doesn't change characters that are not ascii lowercase or uppercase characters, like numbers or spaces.
'3 2 1 a'.translate(table) # Outputs '3 2 1 b'
in general, to make something "wrap" you use the modulo function (% in Python) with the number you want to wrap, and the range you want it to wrap in. For example, if I wanted to print the numbers 1 through 10 a bajillion times, I would do:
i = 0
while 1:
print(i%10+1)
# I want to see 1-10, and i=10 will give me 0 (10%10==0), so i%10+1!
i += 1
In this case it's a little more difficult because you're using ord, which doesn't have a nice happy "range" of values. If you had done something like string.ascii_lowercase you could do...
import string
codex = string.ascii_lowercase
inString = "abcdxyz"
key = 3
outString = [codex[(codex.index(char)+key)%len(codex)] for char in inString]
However since you're using ord, we're kind of going from ord('A') == 65 to ord('z')==122, so a range of 0 -> 57 (e.g. range(58), with a constant of 65. In other words:
codex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"
# every char for chr(65) -> chr(122)
codex = ''.join([chr(i+65) for i in range(58)]) # this is the same thing!
we can do this instead, but it WILL include the characters [\]^_`
inString, key = 'abcxyzABCXYZ', 4
toConv = [(ord(i)+key-65)%58 for i in inString]
result = ''.join(chr(i+65) for i in toConv)
print(result)
# "efgBCDEFG\\]^"
I know this is kind of an old topic, but I just happened to be working on it today. I found the answers in this thread useful, but they all seemed to use a decision to loop. I figured a way to accomplish the same goal just using the modulus(remainder) operator (%). This allows the number to stay within the range of a table and loop around. It also allows for easy decoding.
# advCeaser.py
# This program uses a ceaser cypher to encode and decode messages
import string
def main():
# Create a table to reference all upper, lower case, numbers and common punctuation.
table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890,.!?-#'
print 'This program accepts a message and a key to encode the message.'
print 'If the encoded message is entered with the negative value of the key'
print 'The message will be decoded!'
# Create accumulator to collect coded message
code =''
# Get input from user: Message and encode key
message = raw_input('Enter the message you would like to have encoded:')
key = input('Enter the encode or decode key: ')
# Loop through each character in the message
for ch in message:
# Find the index of the char in the table add the key value
# Then use the remainder function to stay within range of the table.
index = ((table.find(ch)+key)%len(table))
# Add a new character to the code using the index
code = code + table[index]
# Print out the final code
print code
main()
The encode and decode output look like this.
encode:
This program accepts a message and a key to encode the message.
If the encoded message is entered with the negative value of the key
The message will be decoded!
Enter the message you would like to have encoded:The zephyr blows from the east to the west!
Enter the encode or decode key: 10
croj0ozr92jlvy73jp2ywj4rojok34j4yj4roj7o34G
decode:
This program accepts a message and a key to encode the message.
If the encoded message is entered with the negative value of the key
The message will be decoded!
Enter the message you would like to have encoded:croj0ozr92jlvy73jp2ywj4rojok34j4yj4roj7o34G
Enter the encode or decode key: -10
The zephyr blows from the east to the west!
Sorry if my formatting looks catywompus I literally found stackoverflow yesterday! Yes, I literally mean literally :)

noob python question, extract letter from list

not sure why this isn't working.
error I'm getting: ord() expected a character, but string of length 0 found
code:
phrase = 'test'
number = 0
text = 0
random1 = ''
while (number <= len(phrase)):
letter = phrase[number:number+1]
text = ord(letter) - ord('a')
....
number = number + 1
if a print letter, i get the t for the first iteration
thanks,
You are failing on your last iteration. Because you let number take the value len(phrase), you are trying to slice your string beyond the end.
For example:
>>> "abc"[3:4]
''
String indices range from 0 to len(s)-1.
BTW: Python gives you much nicer ways to iterate over strings:
phrase = 'test'
for letter in phrase:
text = ord(letter) - ord('a')
....
You are iterating past the end of phrase, try this:
phrase = 'test'
number = 0
text = 0
random1 = ''
while (number < len(phrase)):
letter = phrase[number:number+1]
text = ord(letter) - ord('a')
Note the:
while (number < len(phrase)):
You do indeed have to show more code. What is i? Are you incrementing it each loop?
Typically, if you ARE incrementing i to act just like a for loop, you want to loop such that number < len(phrase), not <=.
Also, you can replace
letter = phrase[number:number+1]
with
letter = phrase[number]
Use for..in instead to process each letter in your string:
Code:
phrase = 'test'
for letter in phrase:
print letter
Output:
t
e
s
t
This would be the more "pythonic" way of doing character iteration. This way you're guaranteed to hit every letter without having to consider hitting the end, as what's happening in your code.
You want a char and not a string, right? Try to replace your
letter = phrase[number:number+1]
with
letter = phrase[number]

Categories