Python code for alphabet after given number [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
Input:
D
3
Output:
G
Explanation:
3rd element from D is G in alphabets
And how do you code if the input is x and 4 and I should get the output as b.
Help!!!

You could consider utilizing the modulo operator (%), string.ascii_lowercase, str.islower(), str.isalpha(), str.upper(), and ord():
from string import ascii_lowercase
def shift_letter(c: str, n: int) -> str:
if len(c) != 1:
raise ValueError('c must be a single letter.')
if not c.isalpha():
raise ValueError('c must be a letter.')
current_index = ord(c.lower()) - ord('a')
new_index = (current_index + n) % 26
new_c = ascii_lowercase[new_index]
return new_c if c.islower() else new_c.upper()
def main() -> None:
print(f"shift_letter('D', 3) = {shift_letter('D', 3)}")
print(f"shift_letter('x', 4) = {shift_letter('x', 4)}")
if __name__ == '__main__':
main()
Output:
shift_letter('D', 3) = G
shift_letter('x', 4) = b

You already have ascii_lowercase and ascii_uppercase in string module to use. Using the indexes from these strings and % operator you can shift the character:
from string import ascii_lowercase, ascii_uppercase
def shift_char(char: str, n):
if char.isupper():
idx = ascii_uppercase.index(char)
return ascii_uppercase[(idx + n) % len(ascii_uppercase)]
else:
idx = ascii_lowercase.index(char)
return ascii_lowercase[(idx + n) % len(ascii_lowercase)]
print(shift_char("D", 3))
print(shift_char("x", 4))
output:
G
b

ord and chr string methods are really useful for this problem.
ord gives you the Unicode code for a character:
>>> ord('a')
97
>>> ord('b')
98
>>> ord('A')
65
>>> ord('B')
66
Given the code, chr, will give you the Unicode character
>>> chr(65)
'A'
So to get the 3rd character from 'D', you could do
>>> code = ord('D') + 3
>>> char = chr(code)
>>> print(char)
G
or, as a one-liner
>>> print(chr(ord('D')+3))
G

Related

sequential counting using letters instead of numbers [duplicate]

This question already has answers here:
How to count sequentially using letters instead of numbers?
(3 answers)
Closed 2 months ago.
I need a method that 'increments' the string a to z and than aa to az and then ba to bz and so on, like the columns in an excel sheet. I will feed the method the previous string and it should increment to the next letter.
PSEUDO CODE
def get_next_letter(last_letter):
return last_letter += 1
So I could use it like so:
>>> get_next_letter('a')
'b'
>>> get_next_letter('b')
'c'
>>> get_next_letter('c')
'd'
...
>>> get_next_letter('z')
'aa'
>>> get_next_letter('aa')
'ab'
>>> get_next_letter('ab')
'ac'
...
>>> get_next_letter('az')
'ba'
>>> get_next_letter('ba')
'bb'
...
>>> get_next_letter('zz')
'aaa'
I believe there are better ways to handle this, but you can implement the algorithm for adding two numbers on paper...
def get_next_letter(string):
x = list(map(ord, string)) # convert to list of numbers
x[-1] += 1 # increment last element
result = ''
carry = 0;
for c in reversed(x):
result = chr((c + carry )) + result # i'm not accounting for when 'z' overflows here
carry = c > ord('z')
if carry: # add the new letter at the beggining in case there is still carry
result = 'a' + result
return result.replace('{', 'a') # replace overflowed 'z' with 'a'
all proposed are just way too complicated
I came up with below, using a recursive call,
this is it!
def getNextLetter(previous_letter):
"""
'increments' the provide string to the next letter recursively
raises TypeError if previous_letter is not a string
returns "a" if provided previous_letter was emtpy string
"""
if not isinstance(previous_letter, str):
raise TypeError("the previous letter should be a letter, doh")
if previous_letter == '':
return "a"
for letter_location in range(len(previous_letter) - 1, -1, -1):
if previous_letter[letter_location] == "z":
return getNextLetter(previous_letter[:-1])+"a"
else:
characters = "abcdefghijklmnopqrstuvwxyz"
return (previous_letter[:-1])\
+characters[characters.find(previous_letter[letter_location])+1]
# EOF
Why not use openpyxl's get_column_letter and column_index_from_string
from openpyxl.utils import get_column_letter, column_index_from_string
# or `from openpyxl.utils.cell import get_column_letter, column_index_from_string`
def get_next_letter(s: str) -> str:
return get_column_letter(
column_index_from_string(s) + 1
).lower()
and then
>>> get_next_letter('aab')
'aac'
>>> get_next_letter('zz')
'aaa'
?
Keeping in mind that this solution only works in [A, ZZZ[.
I fact what you want to achieve is increment a number expressed in base26 (using the 26 alphabet letters as symbols).
We all know decimal base that we use daily.
We know hexadecimal that is in fact base16 with symbols including digits and a, b, c, d, e, f.
Example : 0xff equals 15.
An approach is to convert into base10, increment the result decimal number, then convert it back to base26.
Let me explain.
I define 2 functions.
A first function to convert a string (base26) into a base10 (decimal) number.
str_tobase10("abcd") # 19010
The inverse function to convert a base10 number (decimal) to a string (base26).
base10_tostr(19010) # abcd
get_next_letter() just has to convert the string to a number, increment by one and converts back to a string.
Advantages :
pure Python, no extra lib/dependency required.
works with very long strings
Example :
get_next_letter("abcdefghijz") # abcdefghika
def str_tobase10(value: str) -> int:
n = 0
for letter in value:
n *= 26
n += ord(letter)-ord("a")+1
return n
def base10_tostr(value: int) -> str:
s = ""
n = value
while n > 26:
r = n % 26
s = chr(ord("a")-1+r) + s
n = n // 26
return chr(ord("a")-1+n) + s
def get_next_letter(value: str):
n = str_tobase10(value)
return base10_tostr(n+1)

Creating a Rolling Cipher using a function [duplicate]

This question already has an answer here:
How to write a Ceaser Cipher Python
(1 answer)
Closed 2 years ago.
I'm trying to write a function that is supposed to take a string like "abcd" and move the letter up or down by a certain number.
rolling_cipher("abcd", 1) ➞ "bcde"
Here is my code so far:
import string
def rolling_cipher(String, num):
letters = string.ascii_lowercase
print(letters)
String = String.index(string)
rolling_cipher("abcd", 2)
This is a possible solution:
from string import ascii_lowercase
def rolling_cipher(s, n):
idx = ascii_lowercase.index(s)
new_idx = (idx + n) % len(ascii_lowercase)
l = new_idx + len(s) - len(ascii_lowercase)
a1 = ascii_lowercase[new_idx: new_idx + len(s)]
a2 = '' if l <= 0 else ascii_lowercase[: l]
return a1 + a2
Examples:
>>> rolling_cipher('abcd', 3)
'defg'
>>> rolling_cipher('rst', 6)
'xyz'
>>> rolling_cipher('rst', 8)
'zab'
>>> rolling_cipher('rst', 33)
'yza'
You might alternatively want to use deque:
from collections import deque
from string import ascii_lowercase
def rolling_cipher(s, n):
d = deque(ascii_lowercase)
d.rotate(-ascii_lowercase.index(s) - n)
return ''.join(list(d)[:len(s)])
Just for fun, here's a one-liner that will do the trick:
import string
l = string.ascii_lowercase
s = 'eggs'
''.join(l[(l.rindex(i) + n) % 26] for i in s)
Output:
n = 1
>>> 'fhht'
n = 5
>>> 'jllx'
n = 100 # Same as -4
>>> 'acco'
n = -26
>>> 'eggs'
And, if you want to wrap it in a function:
def rolling(s, n) -> str:
"""Caesar cipher.
Args:
s (str): String to be encrypted.
n (int): Shift value.
Returns:
Encrypted string.
"""
return ''.join(l[(l.rindex(i) + n) % 26] for i in s)
Output:
rolling('eggs', -5)
>>> 'zbbn'
Try something like this
def foo(str:string, idx:int):
print(string.ascii_lowercase[idx: len(str) + idx])

a becomes z, b becomes y. abcd becomes zyxw ...etc in python

def string_transf():
input('Enter a word or string')
#letters = 'abcdefghijklmnopqrstvwxyz'
#for i in letters:
#i+=
if c >= 'a' and c <='z':
i = 'z' - c + 'a'
print(i)
I tried to come up with an algorithm, but I'm lost.
Since you didn't say you want to handle uppercase letters, here is a single line answer:
>>> ''.join(chr(122 - ord(c) + 97) for c in 'abcd')
'zyxw'
Where 122 is ord('z') and 97 is ord('a'). ord function converts the character to its Unicode code point and chr function does the opposite.
You can skip non lowercase characters if you will:
>>> ''.join(chr(122 - ord(c) + 97) for c in 'abcdEFG' if 'a' <= c <= 'z')
'zyxw'
If you want to handle uppercase following the same model:
>>> def inv(c):
... if 'a' <= c <= 'z':
... return chr(122 - ord(c) + 97)
... if 'A' <= c <= 'Z':
... return chr(90 - ord(c) + 65)
... return c
...
>>> ''.join(inv(c) for c in 'Hello world!')
'Svool dliow!'
You can use the following approach.
Create a dictionary my_map, which describes the character's translation:
import string
ascii_alph = string.ascii_lowercase
my_map = dict(zip(ascii_alph, ascii_alph[::-1]))
str_input = 'abcd'
str_output = ''.join(my_map[c] for c in str_input) # assume every c in my_map
print(str_output) # zyxw
Also you can implement that with the translate method:
# my_map = string.maketrans(ascii_alph, ascii_alph[::-1]) # Python 2
my_map = str.maketrans(ascii_alph, ascii_alph[::-1]) # Python 3
str_input = 'abcd'
str_output = str_input.translate(my_map)
print(str_output) # zyxw
For the general case (ASCII uppercase and other chars) you can always expand 'my_map' dictionary.
Note that the described approach is quite flexible since it allows you to make translation not only for the case of inversion of the alphabet.

Python get range using start, end characters compatible with Excel [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How can I make this work with alpha_range(A, ZZ)?
right now it only work until Z
Code:
def alpha_range(start, stop):
""" Returns chars between start char and stop char(A,D -> A,B,C,D).
:param start: start char
:param stop: stop char
:return: list of chars
"""
return [chr(x) for x in range(ord(start), ord(stop)+1)]
You can easily make a bidirectional mapping between A-ZZ and numbers. This actually is pretty similar to a numeric system with different characters to represent the digits.
BASE = ord('Z') - ord('A') + 1
def to_number(str_input):
res = 0
for letter in str_input:
res = res * BASE + ord(letter) - ord('A') + 1
return res
def to_str(int_input):
res = ''
while int_input > 0:
int_input -= 1
res = res + chr(int_input % BASE + ord('A'))
int_input //= BASE
return res[::-1]
Now you can replace ord and chr with this functions.

Convert numbers into corresponding letter using Python

I was wondering if it is possible to convert numbers into their corresponding alphabetical value. So
1 -> a
2 -> b
I was planning to make a program which lists all the alphabetical combinations possible for a length specified by a user.
See I know how to build the rest of the program except this!
Any help would be wonderful.
Big Letter:
chr(ord('#')+number)
1 -> A
2 -> B
...
Small Letter:
chr(ord('`')+number)
1 -> a
2 -> b
...
import string
for x, y in zip(range(1, 27), string.ascii_lowercase):
print(x, y)
or
import string
for x, y in enumerate(string.ascii_lowercase, 1):
print(x, y)
or
for x, y in ((x + 1, chr(ord('a') + x)) for x in range(26)):
print(x, y)
All of the solutions above output lowercase letters from English alphabet along with their position:
1 a
...
26 z
You'd create a dictionary to access letters (values) by their position (keys) easily. For example:
import string
d = dict(enumerate(string.ascii_lowercase, 1))
print(d[3]) # c
You can use chr() to turn numbers into characters, but you need to use a higher starting point as there are several other characters in the ASCII table first.
Use ord('a') - 1 as a starting point:
start = ord('a') - 1
a = chr(start + 1)
Demo:
>>> start = ord('a') - 1
>>> a = chr(start + 1)
>>> a
'a'
Another alternative is to use the string.ascii_lowercase constant as a sequence, but you need to start indexing from zero:
import string
a = string.ascii_lowercase[0]
What about a dictionary?
>>> import string
>>> num2alpha = dict(zip(range(1, 27), string.ascii_lowercase))
>>> num2alpha[2]
b
>>> num2alpha[25]
y
But don't go over 26:
>>> num2alpha[27]
KeyError: 27
But if you are looking for all alphabetical combinations of a given length:
>>> import string
>>> from itertools import combinations_with_replacement as cwr
>>> alphabet = string.ascii_lowercase
>>> length = 2
>>> ["".join(comb) for comb in cwr(alphabet, length)]
['aa', 'ab', ..., 'zz']
Try a dict and some recursion:
def Getletterfromindex(self, num):
#produces a string from numbers so
#1->a
#2->b
#26->z
#27->aa
#28->ab
#52->az
#53->ba
#54->bb
num2alphadict = dict(zip(range(1, 27), string.ascii_lowercase))
outval = ""
numloops = (num-1) //26
if numloops > 0:
outval = outval + self.Getletterfromindex(numloops)
remainder = num % 26
if remainder > 0:
outval = outval + num2alphadict[remainder]
else:
outval = outval + "z"
return outval
Here is a quick solution:
# assumes Python 2.7
OFFSET = ord("a") - 1
def letter(num):
return chr(num + OFFSET)
def letters_sum_to(total):
for i in xrange(1, min(total, 27)):
for rem in letters_sum_to(total - i):
yield [letter(i)] + rem
if total <= 26:
yield [letter(total)]
def main():
for letters in letters_sum_to(8):
print("".join(letters))
if __name__=="__main__":
main()
which produces
aaaaaaaa
aaaaaab
aaaaaba
aaaaac
aaaabaa
aaaabb
aaaaca
aaaad
aaabaaa
# etc
Note that the number of solutions totalling to N is 2**(N-1).
for i in range(0, 100):
mul = 1
n = i
if n >= 26:
n = n-26
mul = 2
print chr(65+n)*mul

Categories

Resources