Convert string to all lower case without built-in functions - python

#variable defination#
lower="abcdefghijklmnopqrstuvwxyz"
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
valid=True
x=0
g=0
string=input("enter a string:")
#data validation#
for char in string:
if char in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
valid=True
else:
valid=False
#finding the character#
if valid:
for char in string:
g+=1
for ele in upper:
if char!=ele:
x+=1
print(lower[x]+string[g::])
**I can't get it to work, it keeps iterating through the entire string without the condition ever being met. **

Since you are allowed to use lowercase and uppercase character inputs, you can create a dictionary mapping between them and use str.join with a list comprehension:
from string import ascii_lowercase, ascii_uppercase
d = dict(zip(ascii_uppercase, ascii_lowercase))
string = input("enter a string:")
res = ''.join([d.get(i, i) for i in string])
It's not clear whether this satisfies your "no in-built function" requirement.

I tried to minimize changes from your original code (But remember, it's obvious that other solutions are much better.)
#variable defination#
lower="abcdefghijklmnopqrstuvwxyz"
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string=input("enter a string:")
#data validation#
valid = True
for char in string:
if char not in lower + upper:
valid=False
#finding the character#
if valid:
result = ""
for char in string:
if char in lower:
result += char
else:
# uppercase character
for i in range(len(upper)):
if char == upper[i]:
result += lower[i]
break
print(result)

You can create mapping(dictionary) between uppercase and lowercase alphabets such that upper_to_lower[uppercase] should give you lowercase. You may refer below implementation as reference though.
import string
def to_lower_case(word):
# construct auxilliary dictionary to avoid ord and chr built-in methods
upper_to_lower = {}
for index in range(len(string.ascii_uppercase)): # this is 26 we can use it as constant though
upper_to_lower[string.ascii_uppercase[index]] = string.ascii_lowercase[index]
result = ''
for alphabet in word:
if alphabet in string.ascii_uppercase:
result += upper_to_lower[alphabet]
else:
result += alphabet
return result
# sample input
In [5]: to_lower_case('ANJSNJN48982984aadkaka')
Out[5]: 'anjsnjn48982984aadkaka'

You can also write an index method to get the index of an uppercase character in the upper string:
lower = "abcdefghijklmnopqrstuvwxyz"
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def index(char):
i = 0
for c in upper:
if char == c: return i
i += 1
Then you can convert your string to lowercase like this:
#data validation#
# ...
#finding the character#
s = ''
if valid:
for char in string:
if char in lower: s += char
else: s += lower[index(char)]
print(s)

Related

Need to assign different values to letters and non-letters in a sentence

Need to assign a value 1-26 to letters of the alphabet (i.e., a = 1, b = 2, etc.) and -1 to anything else in a sentence and then add up the values.
Currently have:
from string import ascii_lowercase
s = "Isn't it amazing?"
s = s.lower() #upper case version should have the same value as lower
letters = {letter: str(i) for i, letter in enumerate(ascii_lowercase, start=1)}
answer = [letters[char] for char in s if char in letters elif char not in letters -1]
for i in range(0, len(answer)):
answer[i] = int(answer[i])
sum(answer)
Desired return for sentence s is 158. Is there a way to use else in list comprehension?
Your else is in the wrong position. Also, ord is the usual way to translate a character to a number (subtract the value for 'a', adding one, to get 1-based numbers).
from string import ascii_lowercase
s = "Isn't it amazing?"
s = s.lower() #upper case version should have the same value as lower
vals = [ord(ch)-ord('a')+1 if ch in ascii_lowercase else -1 for ch in s ]
answer = sum(vals)
print(answer)
Dictionary provides a specific function for your use case: dict.get, from the documentation:
Return the value for key if key is in the dictionary, else default. If
default is not given, it defaults to None, so that this method never
raises a KeyError.
Code
from string import ascii_lowercase
s = "Isn't it amazing?"
s = s.lower() # upper case version should have the same value as lower
letters = {letter: i for i, letter in enumerate(ascii_lowercase, start=1)}
answer = [letters.get(char, -1) for char in s]
print(sum(answer))
Output
158
Also, notice that if plan to use the integer value of the enumerate you don't need to transform it into a string. If you insist in using a ternary operator, you could do it like this:
answer = [letters[char] if char in letters else -1 for char in s]
you can 1st convert the string into bytes and use the ascii byte value like below
s = "Isn't it amazing?"
s = s.lower()
sum([(b-96) if b>=97 and b<=122 else -1 for b in bytes(s, "ascii") ])
Considering char code of starting letter "a" as constant subtraction number:
sub_num = ord('a') - 1
answer = [ord(c) - sub_num if c.isalpha() else -1 for c in s]
print(sum(answer)) # 158

How to generate random characters within an existing string?

I'm making a text converter, and I'd like to select random characters in a string that already exists.
When I research it, all that comes up is someone that wants to generate random letters in the alphabet or someone that wants to generate a random string. That's not what I'm looking for.
new_string = ""
index = 0
for letter in input_text:
if letter not in "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM":
new_string = new_string + (letter)
continue
index += 1
if index % 2 == 0:
new_string = new_string + (letter.upper())
else:
new_string = new_string + (letter.lower())
My existing text converter capitalizes every other letter, but I'd like to have it randomly capitalize the letters. Is this possible?
You may want to look at the random.choice and random.choices functions in the random library (built-in), which allows you to randomly select an item from a list:
>>> import random
>>> a = random.choice("ABCDabcd")
'C'
>>> my_text = "".join(random.choices("ABCDabcd", k=10))
'baDdbAdDDb'
In order to randomly capitalize, you can choice from a list of the lower- and upper-case version of a letter:
import random
new_string = ""
for letter in input_text:
if letter not in "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM":
new_string = new_string + (letter)
else:
new_string += random.choice([letter.upper(), letter.lower()])
(Note that random.choices returns a list, not a str, so we need to join() the elements together.)
Finally, you may also want to use the isalpha function:
>>> "A".isalpha()
True
>>> "a".isalpha()
True
>>> "7".isalpha()
False
(Relevant question)
But upper() and lower() functions have no effect on non-alpha characters. So you can completely remove this check from your code:
new_string = ""
for letter in input_text:
new_string += random.choice([letter.upper(), letter.lower()])

How to create a circular Alphabet in Python so that the letter after z is a and the letter before a is z

Is there a Function in Python to easily create a circular Alphabet, so that the letter after z is a and the letter before a is z?
I tried something with chr() and .join(Alphabet), but that didn't worked because i got the error message an integer is required (got type str).
for character in word:
if chr(Alphabet[Alphabet.find(character)) >= "z":
new_Alphabet = Alphabet.join(Alphabet)
elif chr(Alphabet[Alphabet.find(character)) <= "a":
new_Alphabet = Alphabet.join(Alphabet[:-1])
Use itertools.cycle ans string.ascii_lowercase:
from itertools import cycle
import string
circular_alphabet = cycle(string.ascii_lowercase)
That is an infinite iterator with the lowercase letters:
>>> "".join(next(circular_alphabet ) for _ in range(50))
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx'
I think you have to use circular queue. for more information please check this link.
Alternative (old fashion?) solution:
def cycle_letter(ch,up=True):
upper = 'A' <= ch <= 'Z'
ch = ch.lower()
letters = 'abcdefghijklmnopqrstuvwxyz'
pos = letters.find(ch)
if pos < 0: return ch
length = len(letters)
pos += 1 if up else length-1
ans = letters[pos%length]
if upper: ans = ans.upper()
return ans
################################################################################
def cycle_string(s,up=True):
return ''.join(cycle_letter(ch,up) for ch in s)
################################################################################
if __name__ == '__main__': #Test
s = cycle_string('Hello, World!')
print(s)
s = cycle_string(s,False)
print(s)
In case it helps someone, this snippet shifts a word by the desired number of spaces. (e.g. shift_word('abcdef', 12) = 'opqrst' )
def shift_word(word: str, spaces: int) -> str:
first_ordinal = 97
last_ordinal = 122
alphabet_size = 26
return ''.join(chr((ord(letter) - last_ordinal - spaces - 1) % alphabet_size + first_ordinal) for letter in word)
It simply iterates over the word letter-by-letter, applies some modulo math to calculate the right "bucket" where the letter should fall, and makes sure the result is in the boundaries of ordinals 97-122 (letters a-z)

Check if the letters of one string are in another string

Okey so basically I have to check if one string has the same letters of another string. Both strings are obtained via input().
I don't want to double check if a letter is in the other string, so if I already checked that letter I want to skip to the next letter.
The code I have for now is this:
str1, str2 = list(input()), list(input())
if len(str1) > len(str2):
str = str1
else:
str = str2
for x in str:
c = 0
if x in str2:
c += 1
if c != 0:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
I don't know if I should work with the lists instead of using a counter.. please a detailled explanation of the solution or some good quality guidance would be very appreciated! <3
Converting strings to sets of individual symbols remove duplicate symbols, so we can simply compare them:
if set(str1) == set(str2):
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
Note:
As the order of elements in sets is not important, we may even compare them, e. g.
if set(str1) <= set(str2): # <= means "is subset" in this context
print("All symbols in str1 are in str2, too.")
or
if set(str1) < set(str2): # < means "is a proper subset" in this context
print("All symbols in str1 are in str2, too, "
"but str2 has at least 1 symbol not contained in str1.")
Some issues with the code are that, str2 is always used for comparison even if str2 is longer than str1
for x in str:
c = 0
if x in str2:
Next, c is set to 0 for every character in str, Instead you can have a counter to count the number of chars not in the other string
This should do the job
str1, str2 = list(input()), list(input())
if len(str1) > len(str2):
str = str1
compared_string = str2
else:
str = str2
compared_string = str1
not_in_other_string = 0
for x in str:
if x not in compared_string:
not_in_other_string += 1
if not_in_other_string == 0:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
It sounds like you want to find if all of the characters in one string are in some larger string.
You could use unique = ''.join(set(substring)) to get a list of chars in the substring and then make a list comprehension to get all the chars in the larger string.
Here is my example:
unique = ''.join(set(substring))
not_in = [char for char in unique if char not in superstring]
Now you can check not_in to see if it is null, otherwise there was a char in the substring that was not in the superstring.
For example:
superstring = "hello"
substring = "xllo"
unique = ''.join(set(substring))
not_in = [char for char in unique if char not in superstring]
print not_in
>>>['x']
print not_in == []
>>>False
Typically, the preferred way to do things in python is using list comprehensions or use some built in function that already checks strings for you, rather than the C style where you go through a loop and check letter for letter explicitly. This is the idiomatic way of pythonic programming.
Breaking apart the list comprehension we have a loop like this:
for char in unique:
if char not in superstring:
char #char meets conditions so it is the value used in [char ...
Here would be the modification I would make
str1, str2 = input(), input()
unique = ''.join(set(str1))
not_in = [char for char in unique if char not in str2]
if not_in == []:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
str1, str2 = input().split()
if len(str1) > len(str2):
string_to_check= str1
string_from_which_to_check = str2
else:
string_to_check = str2
string_from_which_to_check = str1
not_in_other_string = set(string_to_check) - set(string_from_which_to_check)
if len(not_in_other_string )==0:
print("character are present in string")
else:
print("{} not present in string".format(str(not_in_other_string )))

Create a function that contains only the first occurrence of a letter from the original phrase

The function needs to behave as follow:
The first letter occurrence can be upper or lower case (newPhrase).
Non-alpha characters - are left unchanged.
So far I thought of :
def keepFirstLetter(phrase):
'''Returns a new string that contains only the first occurrence of a
letter from the original phrase.
letterSeenSoFar = ''
newPhrase = ''
if (letterSeenSoFar == '' or letterSeenSoFar[-1] != letterSeenSoFar):
letterSeenSoFar += c
for letter in letterSeenSoFar:
if letter.isalpha:
newPhrase += char
else:
newPhrase += letter
return newPhrase
You seem to be on the right track. If you want to improve you efficiency, you can store the seen letters as a set. Searching a set is O(1).
def unique_first(s):
letters = set()
out = ''
for x in s:
if not x.isalpha():
out += x
continue
if not x.lower() in letters:
out += x
letters.add(x.lower())
return out
The most straightforward, sure-to-have-learned solution is probably:
def keepFirstLetter(phrase):
output = ''
for letter in phrase:
if (letter.lower() not in output.lower()) or (not letter.isalpha()):
output += letter
return output
print(keepFirstLetter('Amy says, "Me?"')) # Amy s, "e?"
(the parens around the two if clauses are optional)
James's solution still gets my vote though.
My name was in the question so let me take a try.
I learned set.add() from James for the first time. (Thank you, James.) James' code is shorter and runs faster (3.48us vs. 3.76us on my PC).
def keepFirstLetter(phrase):
phrase = list(phrase)
'''Returns a new string that contains only the first occurrence of a
letter from the original phrase.'''
letterSeenSoFar = []
newPhrase = ''
for char in phrase:
# if char is not an alphabet, add char to the newPhrase as is
if not char.isalpha():
newPhrase += char
# if char is an alphabet and not seen so far, add char to the newPhrase and append it to letterSeenSoFar
elif char.lower() not in letterSeenSoFar:
letterSeenSoFar.append(char.lower())
newPhrase += char
return newPhrase
print(keepFirstLetter('Amy says, " Me?"'))
This outputs:
Amy s, " e?"

Categories