Assign alphabets in Numbers - python

I am trying to assign alphabets in to numbers. When I print 1 I want to get "a". I tried many codes. Please help me to get out of this issue.
characters = 'abcdefghijklmnopqrstuvwxyz'
d = {}
for x in range(len(characters)):
d[characters[x]] = x+1

Your characters string is most of the way to being a solution all on its own. If you add an extra character to the start of the string (to take up the 0 space), you can just use the number as the index into the string:
>>> characters = ' abcdefghijklmnopqrstuvwxyz'
>>> characters[1]
'a'

You're mixing up the keys and the values in your dictionary. Since you want to look up letters using integer indices, you want to use the index as the key and the letter as the value, not the other way around:
d = {}
for x in range(len(characters)):
d[x + 1] = characters[x]
print(d[1])
This outputs:
a

Related

How to extract words from repeating strings

Here I have a string in a list:
['aaaaaaappppppprrrrrriiiiiilll']
I want to get the word 'april' in the list, but not just one of them, instead how many times the word 'april' actually occurs the string.
The output should be something like:
['aprilaprilapril']
Because the word 'april' occurred three times in that string.
Well the word actually didn't occurred three times, all the characters did. So I want to order these characters to 'april' for how many times did they appeared in the string.
My idea is basically to extract words from some random strings, but not just extracting the word, instead to extract all of the word that appears in the string. Each word should be extracted and the word (characters) should be ordered the way I wanted to.
But here I have some annoying conditions; you can't delete all the elements in the list and then just replace them with the word 'april'(you can't replace the whole string with the word 'april'); you can only extract 'april' from the string, not replacing them. You can't also delete the list with the string. Just think of all the string there being very important data, we just want some data, but these data must be ordered, and we need to delete all other data that doesn't match our "data chain" (the word 'april'). But once you delete the whole string you will lose all the important data. You don't know how to make another one of these "data chains", so we can't just put the word 'april' back in the list.
If anyone know how to solve my weird problem, please help me out, I am a beginner python programmer. Thank you!
One way is to use itertools.groupby which will group the characters individually and unpack and iterate them using zip which will iterate n times given n is the number of characters in the smallest group (i.e. the group having lowest number of characters)
from itertools import groupby
'aaaaaaappppppprrrrrriiiiiilll'
result = ''
for each in zip(*[list(g) for k, g in groupby('aaaaaaappppppprrrrrriiiiiilll')]):
result += ''.join(each)
# result = 'aprilaprilapril'
Another possible solution is to create a custom counter that will count each unique sequence of characters (Please be noted that this method will work only for Python 3.6+, for lower version of Python, order of dictionaries is not guaranteed):
def getCounts(strng):
if not strng:
return [], 0
counts = {}
current = strng[0]
for c in strng:
if c in counts.keys():
if current==c:
counts[c] += 1
else:
current = c
counts[c] = 1
return counts.keys(), min(counts.values())
result = ''
counts=getCounts('aaaaaaappppppprrrrrriiiiiilll')
for i in range(counts[1]):
result += ''.join(counts[0])
# result = 'aprilaprilapril'
How about using regex?
import re
word = 'april'
text = 'aaaaaaappppppprrrrrriiiiiilll'
regex = "".join(f"({c}+)" for c in word)
match = re.match(regex, text)
if match:
# Find the lowest amount of character repeats
lowest_amount = min(len(g) for g in match.groups())
print(word * lowest_amount)
else:
print("no match")
Outputs:
aprilaprilapril
Works like a charm
Here is a more native approach, with plain iteration.
It has a time complexity of O(n).
It uses an outer loop to iterate over the character in the search key, then an inner while loop that consumes all occurrences of that character in the search string while maintaining a counter. Once all consecutive occurrences of the current letter have been consumes, it updates a the minLetterCount to be the minimum of its previous value or this new count. Once we have iterated over all letters in the key, we return this accumulated minimum.
def countCompleteSequenceOccurences(searchString, key):
left = 0
minLetterCount = 0
letterCount = 0
for i, searchChar in enumerate(key):
while left < len(searchString) and searchString[left] == searchChar:
letterCount += 1
left += 1
minLetterCount = letterCount if i == 0 else min(minLetterCount, letterCount)
letterCount = 0
return minLetterCount
Testing:
testCasesToOracles = {
"aaaaaaappppppprrrrrriiiiiilll": 3,
"ppppppprrrrrriiiiiilll": 0,
"aaaaaaappppppprrrrrriiiiii": 0,
"aaaaaaapppppppzzzrrrrrriiiiiilll": 0,
"pppppppaaaaaaarrrrrriiiiiilll": 0,
"zaaaaaaappppppprrrrrriiiiiilll": 3,
"zzzaaaaaaappppppprrrrrriiiiiilll": 3,
"aaaaaaappppppprrrrrriiiiiilllzzz": 3,
"zzzaaaaaaappppppprrrrrriiiiiilllzzz": 3,
}
key = "april"
for case, oracle in testCasesToOracles.items():
result = countCompleteSequenceOccurences(case, key)
assert result == oracle
Usage:
key = "april"
result = countCompleteSequenceOccurences("aaaaaaappppppprrrrrriiiiiilll", key)
print(result * key)
Output:
aprilaprilapril
A word will only occur as many times as the minimum letter recurrence. To account for the possibility of having repeated letters in the word (for example, appril, you need to factor this count out. Here is one way of doing this using collections.Counter:
from collections import Counter
def count_recurrence(kernel, string):
# we need to count both strings
kernel_counter = Counter(kernel)
string_counter = Counter(string)
# now get effective count by dividing the occurence in string by occurrence
# in kernel
effective_counter = {
k: int(string_counter.get(k, 0)/v)
for k, v in kernel_counter.items()
}
# min occurence of kernel is min of effective counter
min_recurring_count = min(effective_counter.values())
return kernel * min_recurring_count

Write a function that takes a string parameter and returns a new string with all the letters of the alphabet that are not in the argument string

Write a function called missing_letters that takes a string parameter and returns a new string with all the letters of the alphabet that are not in the argument string. The letters in the returned string should be in alphabetical order.
It should also use the global variable alphabet. It should use this global variable directly, not through an argument or a local copy. It should loop over the letters in alphabet to determine which are missing from the input parameter.
The function missing_letters should combine the list of missing letters into a string and return that string.
Write a loop over the strings in list test_miss and call missing_letters with each string. Print a line for each string listing the missing letters. For example, for the string "aaa", the output should be the following.
aaa is missing letters bcdefghijklmnopqrstuvwxyz
I tried my best to solve this. The program is working but not giving
the desired output.
test_miss = ["b","zzz"]
def missing_letters(s):
missingAlphabets = ""
global alphabet
for c in s:
i=0
while i < len(alphabet):
if alphabet[i] not in c:
missingAlphabets += alphabet[i]
i += 1
sortedmissingAlphabetslists = sorted(missingAlphabets)
sortedmissingAlphabets = ''.join(sortedmissingAlphabetslists)
return sortedmissingAlphabets
for i in test_miss:
print('{} is missing letters {}'.format(i,missing_letters(i)))
the program is giving appropriate output for any string with a single character, like - "b"
that is: b is missing letters acdefghijklmnopqrstuvwxyz
But for a string with multiple characters, like: "zzz" the output is:
zzz is missing letters aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyy
But I want:
zzz is missing letters abcdefghijklmnopqrstuvwxy
The set type already handles most of the work for you.
import string
def missing_letters(s):
return ''.join(sorted(set(string.lowercase) - set(s)))
If x and y are sets, then x - y is the set of items present in x but not in y. One you have the set of missing characters, you can sort them and re-join the sorted elements into a single string.
>>> set('abc') - set('a')
set(['c', 'b'])
>>> sorted(_)
['b', 'c']
>>> ''.join(_)
'bc'
Keeping with the spirit of what you have already defined. The issue is that you are testing each letter in the missing_letters function more than once. So you just want to check if the character (from the alphabet) is in the string. So take out the extra for loop which loops through the letters in the argument - like such
alphabet = 'abcdefghijklmnopqrstuvwxyz'
test_miss = ["b","zzz"]
def missing_letters(s):
missingAlphabets = ""
global alphabet
i = 0
while i < len(alphabet):
if alphabet[i] not in s:
missingAlphabets += alphabet[i]
i += 1
sortedmissingAlphabetslists = sorted(missingAlphabets)
sortedmissingAlphabets = ''.join(sortedmissingAlphabetslists)
return sortedmissingAlphabets
for i in test_miss:
print('{} is missing letters {}'.format(i,missing_letters(i)))
b is missing letters acdefghijklmnopqrstuvwxyz
zzz is missing letters abcdefghijklmnopqrstuvwxy
def has_duplicates(t):
t= histogram(t)
for i in t:
a=(t[i])
if a > 1:
return True
else:
return False
for i in test_dups:
f = has_duplicates(i)
if f == True:
print(i +' '+ 'has duplicates')
else:
print(i +' '+ 'has no duplicates')

Additional iteration over a list when shifting text

I've encountered a small problem with a simple shift deciphering.
N,K = [int(s) for s in input().split()]
myres = []
alph = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
myalph = [a for a in alph]
for i in range(N):
s = input()
mylist = [d for d in str(s)]
for b in range(len(mylist)):
for c in range(len(myalph)):
if mylist[b] == myalph[c]:
mylist[b] = myalph[c-K]
print(myalph[c-K], c-K, b, c)
myres = myres + mylist
Res = [str(i) for i in myres]
print("".join(Res))
The idea is for every character of my input string to be replaced with a different character from the alphabet that's been shifted by a given key (K).
The problem occurs when c-K < 0 and the replacing key is taken from the back of the list. Then the loop is being iterated twice.
If the key is 3 and I input A instead of getting X, I'm getting U as the first iteration gives X but then X is also iterated and becomes U.
Your mistake is looping over all the letters in alph:
The for loop tests all the letters of the alphabet, in order, and 'A' is matched. You set mylist[b] to 'X' (0 - 3 is -3 and myalph[-3] is 'X'.
The loop then continues to test all the other letters of the alphabet against mylist[b], so eventually it gets to 'X', sees that the letter matches and sets mylist[b] to 'U'.
The loop continues to test the remaining letters of the alphabet against mylist[b], and reaches the end without further matches.
At the very least you need to break out of the loop when you have shifted a letter.
But rather than loop, you could use the str.find() method (directly on the alph string) to find a matching index for the letter; it'll be set to -1 if the letter is not found at all:
for b in range(len(mylist)):
c = alph.find(s[b])
if c > -1: # the letter exists
s[b] = alph[c - K]
Aside from that, there are some other improvements you could make:
You can loop over and index into strings directly, there is no need to turn alph into a list here. When you do need to to turn a string into a list of individual characters, you should use list(stringobject). So mylist = list(s) would suffice.
myres is already a list of strings, there is no need to convert each to a string again.
Rather than put all the letters from s into a list, then adding the whole mylist list to res to myres, you could just directly append each letter you processed to myres; that also removes the need to alter myres.
Python variable names do not need to be limited to single characters. Use more descriptive names so that it is easier to understand what your code does when you return to it later.
Taken together, that'd lead to:
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
parts, key = [int(s) for s in input().split()]
results = []
for part in range(parts):
characters = input()
for character in enumerate(characters):
letter_idx = alphabet.index(character)
if letter_idx > -1:
# this is a letter in the alphabet, shift it with the key
character = alphabet[letter_idx - key]
results.append(character)
print("".join(results))

How to remove characters from the odd numbered string?

If I have a string like this: ABCDE
I want to read two characters at a time (AB then CD) and remove the remaining characters (E) which cannot be read in tuples or in two's. How would I remove those characters?
I have this code below so far:
s = 'ABCDE'
for (first, second) in zip(s[0::2], s[1::2]):
if not first or not second:
if first:
s.replace(first, '')
continue
else:
s.replace(second, '')
continue
print first, second
print s
This code prints (A B C D) which is good but I want to remove that extra E in the for loop which I am trying to do with the if statement. I check if the either the first or second variable of the tuple is an empty string and then remove whichever one isn't an empty string from the original s variable.
This above code doesn't seem to work. Does anyone have a different suggestion or how I can improve this?
If you want to remove the last character in case the string's length is odd:
word = "ABCDE"
if len(word) % 2 == 1:
word = word[:-1]
Now if you want to read the characters two at a time, here is a more instinctive way:
for i in range(len(word) // 2):
print(word[2*i:2*i+2])
The latter will even drop the last character for you.
str = "ABCDE"
for i, k in zip(str[::2], str[1::2]):
print(i + k)
Outputs:
AB
CD

python - ordinal value - list indices must be integers not str

what i want to do is take a string and for each character make the ordinal value 1 more from the value it has.
myinput=input("Message : ")
mylist =list(myinput) #convert to list in order to take each character
for character in mylist:
mylist[character]+=ord(mylist[character])+1
print(character)
The problem is with the "ord(mylist[character])+1"
Thank you!
Probably you are looking for the next:
>>> m = raw_input('Message:')
Message:asdf
>>> ''.join(chr(ord(c) + 1) for c in m)
'bteg'
Notes:
use raw_input when you need to get string input from a user;
ord convert character to integer, chr - vise versa;
... for c in m syntax is a generator expression. It is also used for list comprehension.
Three problems here. First, you're mixing up list indices and list elements. Second, you didn't convert back to a character (I'm assuming you want characters, not numbers). Third, you're adding to the existing value.
One way:
for i range(len(mylist)):
mylist[i] = chr(ord(mylist[i])+1)
Another way:
for i, character in enumerate(mylist):
mylist[i] = chr(ord(character)+1)
Instead of
for character in mylist:
mylist[character]+=ord(mylist[character])+1
(where character is a list index and therefore invalid), you probably want:
mylist = [ord(character) + 1 for character in mylist]
Or a Counter.
You can do like this
def ordsum(astring, tablesize):
sum = 0
for num in range(len(astring)):
sum = sum + ord(astring[num])
return sum
myinput = input() # use raw_input() in Python 2
myinput = map(lambda ch: chr(ord(ch) + 1), myinput)
# or list comp.
myinput = [chr(ord(ch) + 1) for ch in myinput]
You can iterate directly over a string, you do not have to make it a list first. If your end goal is to have a new string, you can do this:
myinput=input("Message : ")
result = []
for character in myinput:
result.append( chr( ord( character ) + 1 )
mynewstring = ' '.join(result)

Categories

Resources