I was trying this code:
str = input("Enter the string:")
num = input("By how much you want to increment:")
x = int(str) + num
print(char(num))
but this throws a traceback, What will be the correct code and what if the person enters (z + 1) i.e. how will the code be fixed around only the 26 alphabets.
Thank you
You can use ord to get ascii of them and chr to get back the value using ascii value
def inc_letter(char, inc):
start_char = ord('a') if char.islower() else ord('A')
start = ord(char) - start_char
offset = ((start + inc) % 26) + start_char
result = chr(offset)
return result
str_ = input("Enter the string:")
num = int(input("By how much you want to increment:"))
inc_letter(str_, num)
Result:
Enter the string:Z
By how much you want to increment:12
'L'
Related
I have to create a program that gets a string, and an integer n; it will increment each character of the string by n characters; for example, if the string is "abc" and n=1, the output would be "bcd", if n=2, it'd be "cde".
So far I have written this code
string = list( input( "Insert a string, it will be codified: " ) )
n = int( input( "Insert an integer, each string's character will be increased by that number: " ) )
for characterIndex in range( len( string ) ):
string[characterIndex] = chr( ord( string[characterIndex] ) + n )
print( ''.join( string ) )
Nonetheless, if I input "xyz" and n=1, I get "yz{", which makes sense since ascii's next character to "z" is "{". You can imagine that for a higher n, it gets worse; I have been trying to solve this problem for any n using modulo, tried to take advantage from the fact that there are 26 letters, but I'm still unable to find a mathematical increment that detects when the string has been incremented further than "z", so it "gets back" to "a".
Any recommendations? Thanks in advance.
It's kind of cheating, but here's the approach I would take:
def string_bump(s):
letter_list = "abcdefghijklmnopqrstuvwxyza" #note the extra 'a' at the end
old_positions = []; new_positions = []
for character in s:
old_positions.append(letter_list.find(character))
for pos in old_positions:
new_positions.append(pos+1)
new_string = ""
for pos in new_positions:
new_string += letter_list[pos]
return new_string
for s in ["abc", "bcd", "xyz"]:
print("before:", s, "after:", string_bump(s))
prints:
before: abc after: bcd
before: bcd after: cde
before: xyz after: yza
Basically, I scan the string to convert the characters to positions in the alphabet string; add 1 to each position; and rebuild the string from those positions. The "cheat" is adding an extra 'a' so a position-25 (counting from 0) 'z' translates to that extra position-26 'a'.
If that offends you, you could leave off the extra 'a' and instead just take another pass at the list of positions and when you see "26" (which would be past the end of the letter_list without the 'a'), knock it down to zero.
This is just a proof-of-concept for your example; to support an arbitrary shift, you'd extend the letter_list out for the full alphabet, and use modulo on the input (e.g. n = n%26) to ensure the input stayed in range.
Also, I would actually use list expressions in place of the for loops, but you may not have encountered those yet, so I used the more explicit for loops instead above.
Let's break it down so that individual steps with named variables make it clear what you're dealing with:
asciiValue = ord(string[characterIndex])
alphabetIndex = asciiValue - ord('a')
alphabetIndex = (alphabetIndex + n) % 26
asciiValue = alphabetIndex + ord('a')
string[characterIndex] = chr(asciiValue)
Note that the above assumes that your input string is composed only of lowercase ASCII letters. For uppercase characters, you'd need to subtract (and re-add) ord('A') instead.
Integrating it into your existing code:
def shift_letter(letter, n):
asciiValue = ord(letter)
alphabetIndex = asciiValue - ord('a')
alphabetIndex = (alphabetIndex + n) % 26
asciiValue = alphabetIndex + ord('a')
return chr(asciiValue)
string = list( input( "Insert a string, it will be codified: " ) )
n = int( input( "Insert an integer, each string's character will be increased by that number: " ) )
for characterIndex in range( len( string ) ):
string[characterIndex] = shift_letter(string[characterIndex], n)
print( ''.join( string ) )
I thought since we needed to encrypt only the alphabets I created a list of alphabets and looped them as below. This way when you input alphabets only alphabets shifted by the given number comes out even if the shift is large.
print("welcome to encryptor!!")
print("Do you want to encrypt or decrypt")
s = int(input("Press 1 for encrypt and 2 for decrypt: "))
alpha = list("abcdefghijklmnopqrstuvwxyz")
print(alpha)
def encrypt():
string = list(input("Enter your string without space to encrypt: "))
print(string)
string1 = []
n = int(input("Enter the value key for caesar crypt: "))
for characterIndex in range(len(string)):
for i in range(len(alpha)):
if string[characterIndex] == alpha[i]:
if((i + n)+1) >= 26:
string1.append(alpha[(i+n) % 26])
else:
string1.append(alpha[i+n])
else:
continue
print(''.join(string1))
This code does produce the desired ouput..
Here is the modified answer from the comments:
c = chr((ord(a) - 97) % 25 + 97)
The output I should get if I type in "eat" should be "hdw" if I shift it by 3. However, the end result is only "w". I'm pretty sure I have everything I need, but maybe it's the formatting?
def shifter():
phrase = input("Please enter a message: ")
key = eval(input("Please enter the number of places to be shifted: "))
list = phrase.split()
for word in list:
for ch in word:
conversion = (chr)((ord(ch) - ord("a") + key) % 26 + ord("a"))
newPhrase = " "
newPhrase = newPhrase + conversion
print(newPhrase)
shifter()
The issue is that you are setting conversion inside your for loop, instead of appending to it, so only the last character in the word is appended to the newPhrase at the end.
You should be appending to conversion, rather than setting it.
Also, you should initialize newPhrase outside the loop and then append to it inside.
Example -
def shifter():
phrase = input("Please enter a message: ")
key = eval(input("Please enter the number of places to be shifted: "))
list = phrase.split()
newPhrase = ""
for word in list:
conversion = ''
for ch in word:
conversion += (chr)((ord(ch) - ord("a") + key) % 26 + ord("a"))
newPhrase = newPhrase + conversion + " "
print(newPhrase)
shifter()
I think it's with your indenting!
Right now, before you do anything with the variable conversion, you've already looped through every ch in word, so you're stuck at the last ch.
Try doing conversion += ... Instead of conversion = ...
(You might need to initialize conversion before that but idts.)
Given the word "coral", I need it to give me reversals of each letter pair. For example:
ocral
croal
coarl
corla
What I've got:
string = raw_input("Enter a word:")
char_values = len(string) #length of string
char_values = int(char_values) #converts to number
print "DELETIONS:"
for word_value in range(char_values):
print string[:word_value] + string[word_value+1:] #deletion pattern
print "TRANSPOSITIONS:"
for x in range(char_values):
print string[:x:-1]+string[x+2:] #shift pattern
I'm throwing out guesses in my last line. My result here was laroral laral lal l.
This should do it for you:
#!/usr/bin/env python
wrd = raw_input('Enter a word: ')
for i in range(len(wrd) - 1):
print wrd[0:i] + wrd[i+1] + wrd[i] + wrd[i+2:]
Output:
paul#local:~/Documents/src/sandbox$ ./rev.py
Enter a word: coral
ocral
croal
coarl
corla
paul#local:~/Documents/src/sandbox$
Swapping the characters
string = "apple"
char_values = len(string) #length of string
char_values = int(char_values) #converts to number
index = 0
for word_value in range(char_values):
firstcharacter = string[word_value]
others = string[:word_value] + string[word_value+1:]
if index+1 < char_values:
nextCharacter = string[index+1]
print others[:index] + nextCharacter + firstcharacter+ others[index+1:]
index = index +1
Output:
ocral
croal
coarl
corla
I am new to programming and I need some help for an free online tutorial to learn Python. I am building my own method to convert a an input string to all lower cases. I cannot use the string.lower() method. In the code I have so far I cannot figure out how to separate the input string into characters that can be inputed into my character converter lowerChar(char).
string=input #input string
def lowerChar(char): #function for converting characters into lowercase
if ord(char) >= ord('A') and ord(char)<=ord('Z'):
return chr(ord(char) + 32)
else:
return char
def lowerString(string): #function for feeding characters of string into lowerChar
result = ""
for i in string:
result = result + lowerChar(string[i])
return result
You are really close:
def lowerString(string):
result = ""
for i in string:
# i is a character in the string
result = result + lowerChar(i)
# This shouldn't be under the for loop
return result
Strings are iterable just like lists!
Also, make sure to be careful about your indentation levels, and the number of spaces you use should be consistent.
You are returning only the first letter, you have to return in a outer scope, try this, also it is better to use += instead of result = result + lowerChar(i)
def lowerString(string): #function for feeding characters of string into lowerChar
result = ""
for i in string:
result += lowerChar(i)
return result
print lowerString("HELLO") #hello
A tip: You don't need to use ord(). Python can directly do the following comparision:
if char >= 'A' and char<='Z':
My solution:
string = input("Input one liner: ")
def lowerChar(char):
if char >= 65 and char <= 90:
char = chr(char + 32)
return char
else:
char = chr(char)
return char
def lowerString(string):
result = ""
for i in range(0, len(string)):
result = result + lowerChar(ord(string[i]))
return result
print(lowerString(string))
Try something like this:
def lowerChar(c):
if 'A' <= c <= 'Z':
return chr(ord(c) - ord('A') + ord('a'))
else:
return c
def lowerString(string):
result = ""
x=0
for i in string:
while x < len(string):
result = result + lowerChar(string[x])
x+=1
return result
I'm writing code so you can shift text two places along the alphabet: 'ab cd' should become 'cd ef'. I'm using Python 2 and this is what I got so far:
def shifttext(shift):
input=raw_input('Input text here: ')
data = list(input)
for i in data:
data[i] = chr((ord(i) + shift) % 26)
output = ''.join(data)
return output
shifttext(3)
I get the following error:
File "level1.py", line 9, in <module>
shifttext(3)
File "level1.py", line 5, in shifttext
data[i] = chr((ord(i) + shift) % 26)
TypError: list indices must be integers, not str
So I have to change the letter to numbers somehow? But I thought I already did that?
You are looping over the list of characters, and i is thus a character. You then try to store that back into data using the i character as an index. That won't work.
Use enumerate() to get indexes and the values:
def shifttext(shift):
input=raw_input('Input text here: ')
data = list(input)
for i, char in enumerate(data):
data[i] = chr((ord(char) + shift) % 26)
output = ''.join(data)
return output
You can simplify this with a generator expression:
def shifttext(shift):
input=raw_input('Input text here: ')
return ''.join(chr((ord(char) + shift) % 26) for char in input)
But now you'll note that your % 26 won't work; the ASCII codepoints start after 26:
>>> ord('a')
97
You'll need to use the ord('a') value to be able to use a modulus instead; subtracting puts your values in the range 0-25, and you add it again afterwards:
a = ord('a')
return ''.join(chr((ord(char) - a + shift) % 26) + a) for char in input)
but that will only work for lower-case letters; which might be fine, but you can force that by lowercasing the input:
a = ord('a')
return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in input.lower())
If we then move asking for the input out of the function to focus it on doing one job well, this becomes:
def shifttext(text, shift):
a = ord('a')
return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in text.lower())
print shifttext(raw_input('Input text here: '), 3)
and using this on the interactive prompt I see:
>>> print shifttext(raw_input('Input text here: '), 3)
Input text here: Cesarsalad!
fhvduvdodgr
Of course, now punctuation is taken along. Last revision, now only shifting letters:
def shifttext(text, shift):
a = ord('a')
return ''.join(
chr((ord(char) - a + shift) % 26 + a) if 'a' <= char <= 'z' else char
for char in text.lower())
and we get:
>>> print shifttext(raw_input('Input text here: '), 3)
Input text here: Ceasarsalad!
fhdvduvdodg!
Looks you're doing cesar-cipher encryption, so you can try something like this:
strs = 'abcdefghijklmnopqrstuvwxyz' #use a string like this, instead of ord()
def shifttext(shift):
inp = raw_input('Input text here: ')
data = []
for i in inp: #iterate over the text not some list
if i.strip() and i in strs: # if the char is not a space ""
data.append(strs[(strs.index(i) + shift) % 26])
else:
data.append(i) #if space the simply append it to data
output = ''.join(data)
return output
output:
In [2]: shifttext(3)
Input text here: how are you?
Out[2]: 'krz duh brx?'
In [3]: shifttext(3)
Input text here: Fine.
Out[3]: 'Flqh.'
strs[(strs.index(i) + shift) % 26]: line above means find the index of the character i in strs and then add the shift value to it.Now, on the final value(index+shift) apply %26 to the get the shifted index. This shifted index when passed to strs[new_index] yields the desired shifted character.
Martijn's answer is great. Here is another way to achieve the same thing:
import string
def shifttext(text, shift):
shift %= 26 # optional, allows for |shift| > 26
alphabet = string.lowercase # 'abcdefghijklmnopqrstuvwxyz' (note: for Python 3, use string.ascii_lowercase instead)
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
return string.translate(text, string.maketrans(alphabet, shifted_alphabet))
print shifttext(raw_input('Input text here: '), 3)
It's easier to write a straight function shifttext(text, shift). If you want a prompt, use Python's interactive mode python -i shift.py
> shifttext('hello', 2)
'jgnnq'
Tried with Basic python.
may useful for someone.
# Caesar cipher
import sys
text = input("Enter your message: ")
cipher = ''
try:
number = int(input("Enter Number to shift the value : "))
except ValueError:
print("Entered number should be integer. please re0enter the value")
try:
number = int(input("Enter Number to shift the value : "))
except:
print("Error occurred. please try again.")
sys.exit(2)
for char in text:
if not char.isalpha():
flag = char
elif char.isupper():
code = ord(char) + number
if 64 < code <= 90:
flag = chr(code)
elif code > 90:
flag = chr((code - 90) + 64)
elif char.islower():
code = ord(char) + number
if 96 < code <= 122:
flag = chr(code)
elif code > 122:
flag = chr((code - 122) + 96)
else:
print("not supported value by ASCII")
cipher += flag
print(cipher)