Capitalizing the first letter of each sentence in Python - python

Here is my code:
def fix_capitalization(usrStr):
newString = ''
wordList = []
numLetters = 0
for s in usrStr.split('. '):
if s[0].isupper():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(s)
if s.islower():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(s)
numLetters += 1
if s[0].islower():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(s)
numLetters += 1
newString = '. '.join(wordList)
return newString, numLetters
The string being passed in is:
i want some water. he has some. maybe he can give me some. i think I will ask.
Note that there are 4 spaces before maybe. The result that I want is:
I want some water. He has some. Maybe he can give me some. I think I will ask.
but I get:
I want some water. He has some. maybe he can give me some. I think I will ask.
I know that maybe isn't being capitalized because I split on . and that sentence has more than one space after the period, but I'm not sure how I can fix this or if there's a better way to go about what I'm doing. Any help would be greatly appreciated.

In for loop:
First find the index of non-space character.
Then replace s[0] with s[index].

Solution using regex sub method
def fix_capitalization(mystr):
numLettets = 0
newstr = []
for s in mystr.split('. '):
tmp = re.sub('^(\s*\w+)', lambda x:x.group(1).title(), s)
newstr.append(tmp)
# num of letters
if s.lstrip()[0] != tmp.lstrip()[0]:
numLetters += 1
return '. '.join(newstr).replace(' i ', ' I '), numLetters
fix_capitalization( 'i want some water. he has some. maybe he can give me some. i think I will ask.')
# return ('I want some water. He has some. Maybe he can give me some. I think I will ask.', 4)
Simple fix to original code as below
def fix_capitalization(usrStr):
newString = ''
wordList = []
numLetters = 0
for s in usrStr.split('. '):
# check for leading space
lspace = len(s) - len(s.lstrip())
s = s.lstrip()
if s[0].isupper():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(' '*lspace + s)
if s.islower():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(' '*lspace + s)
numLetters += 1
if s[0].islower():
s = s.capitalize()
s = s.replace(' i ', " I ")
wordList.append(' '*lspace + s)
numLetters += 1
newString = '. '.join(wordList)
return newString, numLetters

Related

Replace a single character in a string

I am trying to make a function that automatically generated a response to a selection of an action in a text adventure game. My problem is that I have to replace every second '_' with ' '. However I have tried everything I have though of and whenever I google the question the only solution I get is to use .replace(). However .replace() replaces every instance of that character. Here is my code, could you please fix this for me and explain how you fixed it.
example_actions = ['[1] Search desk', '[2] Search Cupboard', '[3] Search yard'
def response(avaliable_actions):
for i in avaliable_actions:
print(i, end=' ')
x = avaliable_actions.index(i)
avaliable_actions[x] = avaliable_actions[x][4:]
avaliable_actions = ' '.join(avaliable_actions)
avaliable_actions = avaliable_actions.lower()
avaliable_actions = avaliable_actions.replace(' ', '_')
avaliable_actions = list(avaliable_actions)
count = 0
for i in avaliable_actions:
if count == 2:
count = 0
index = avaliable_actions.index(i)
avaliable_actions[index] = ' '
elif i == '_':
count += 1
avaliable_actions = ' '.join(avaliable_actions)
print('\n\n' + str(avaliable_actions)) #error checking
Here's one approach:
s = 'here_is_an_example_of_a_sentence'
tokens = s.split('_')
result = ' '.join('_'.join(tokens[i:i+2]) for i in range(0,len(tokens),2))
print(result)
The result:
here_is an_example of_a sentence
Did I understand you correct, that you wanna produce something like this?
this_is_a_test -> this is_a test or this_is a_test?
If so, adapt the following for your needs:
s = "this_is_just_a_test"
def replace_every_nth_char(string, char, replace, n):
parts = string.split(char)
result = ""
for i, part in enumerate(parts):
result += part
if i % n == 0:
result += replace
else:
result += char
return ''.join(result)
res = replace_every_nth_char(s, "_", " ", 2)
print(s, "->", res)
# "this_is_just_a_test" -> "this is_just a_test"

Sorting a string and returning it

So I have this code where I want sort a string and return it
def sort_int_string(one_string):
one_string = one_string.replace("\n", ' ')
one_string = one_string.replace("\t", ' ')
one_string = one_string.strip()
if len(one_string) == 0:
return ''
else:
one_string = one_string.split(" ")
one_string = [int(i) for i in one_string]
one_string.sort()
one_string = [str(i) for i in one_string]
return ' '.join(one_string)
But when I try to run it with this.
hello = "\t42 4 -17\n"
print(sort_int_string(hello)
I get the error invalid literal for int() with base 10: ''
Not sure why I'm getting that. Please help.
The issue with your code is that you have empty string present in the array and when a check is made on that it returns an error since it can't be converted to int. So just do a conditional to check that the i value is not an empty string.
def sort_int_string(one_string):
one_string = one_string.replace("\n", ' ')
one_string = one_string.replace("\t", ' ')
one_string = one_string.strip()
if len(one_string) == 0:
return ''
else:
one_string = one_string.split(" ")
one_string = [int(i) for i in one_string if i != ""]
one_string.sort()
one_string = [str(i) for i in one_string]
return ' '.join(one_string)
hello = "\t42 4 -17\n"
print(sort_int_string(hello))
outputs
-17 4 42
The error you are getting is because several of the values for i are '' (empty string) and you are trying to cast them to integers. Like the comments above suggest, use strip and split to remove whitespace. Then sort:
def sort_int_string(one_string):
return sorted(one_string.strip().split())
hello = "\t42 4 -17\n"
output = sort_int_string(hello)
print(output) # returns ['-17', '4', '42']
If you want to recombine the output back into a string you can use ' '.join(output) or something similar.
try this
you don't have to replace \n and \t with " ". strip() will remove leading and trailing spaces.
def sort_int_string(one_string):
string_lst = one_string.strip().split(" ")
string_lst.sort()
return ''.join(string_lst)
hello = "\t42 4 -17\n"
print(sort_int_string(hello))
output:
-17442
I realized some of the list items after
one_string = one_string.split(" ")
were empty quotes so I looped through one_string to eliminate them by storing it in a new list, after the loop, I overwrote the old list with the new one as shown below
def sort_int_string(one_string):
one_string = one_string.replace("\n", ' ')
one_string = one_string.replace("\t", ' ')
one_string = one_string.strip()
if len(one_string) == 0:
return ''
else:
one_string = one_string.split(" ")
new_one_string = [];
for num in one_string:
if num != '':
new_one_string.append(num)
one_string = new_one_string;
one_string = [int(i) for i in one_string]
one_string.sort()
one_string = [str(i) for i in one_string]
return ' '.join(one_string)
The output:
-17 4 42

Different methods to create exceptions to capitalizing a string

Is there another to have exception for capitalizing an entire sentence. I've heard of skipList method, but it didn't work for my code. See below:
string = input('Enter a string: ')
i = 0
tempString = ' '.join(s[0].upper() + s[1:] for s in string.split(' '))
result = ""
for word in tempString.split():
if i == 0:
result = result + word + " "
elif (len(word) <= 2):
result = result + word.lower() + " "
elif (word == "And" or word == "The" or word == "Not"):
result = result + word.lower() + " "
else:
result = result + word + " "
i = i + 1
print ("\n")
print (result)
Sure. Write a complete list of words that should not be title-cased ("and", "the", "or", "not", etc), and title-case everything else.
words = s.split(' ')
result = ' '.join([words[0]] + [w.title() for w in words[1:] if w not in skipwords])
of course this will still miss Mr. Not's last name, which should be capitalized, and some stranger things like "McFinnigan" will be wrong, but language is hard. If you want better than that, you'll probably have to look into NTLK.
You could rewrite this like this
skip_words = {w.capitalize(): w for w in 'a in of or to and for the'.split()}
words = string.title().split()
result = ' '.join(skip_words.get(w, w) for w in words).capitalize()

Python - Remove white space using only loops

I want to remove extra spaces in a string using only for/while loops, and if statements; NO split/replace/join.
like this:
mystring = 'Here is some text I wrote '
while ' ' in mystring:
mystring = mystring.replace(' ', ' ')
print(mystring)
output:
Here is some text I wrote
Here's what I tried. Unfortunately, it doesn't quite work.
def cleanupstring(S):
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
lasti = i
result += i
print(result)
cleanupstring("Hello my name is joe")
output:
Hello my name is joe
My attempt doesn't remove all the extra spaces.
Change your code to this:
for i in S:
if lasti == " " and i == " ":
i = ""
else:
lasti = i
result += i
print(result)
Check that the current character and the next one are spaces, and if not, add them to a clean string. There really is no need for an and in this case, since we are comparing to the same value
def cleanWhiteSpaces(str):
clean = ""
for i in range(len(str)):
if not str[i]==" "==str[i-1]:
clean += str[i]
return clean
Uses the end of result in place of lasti:
def cleanupstring(S):
result = S[0]
for i in S[1:]:
if not (result[-1] == " " and i == " "):
result += i
print(result)
cleanupstring("Hello my name is joe")
Just try this
t = "Hello my name is joe"
" ".join(t.split())
this will output
"Hello my name is joe"

I can't return a value

I'm trying to write a function that will translate the input into so-called "cow Latin." I want to return the values from the if statement but whenever I do I get a syntax error. I can print the value but I want to avoid the function returning None as well.
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
print('{0}moo'.format(cow_word), end=' ')
else:
cow_word = sentence_list[i][1:] + sentence_list[i][:1]
print('{0}oo'.format(cow_word), end=' ')
cow_latin = cow_latinify_sentence("the quick red fox")
print(cow_latin)
In short, how can I get the function to return instead of print?
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
result = ''
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
result += ('{0}moo'.format(cow_word) + ' ')
else:
result += '{0}oo'.format(sentence_list[i][1:] + sentence_list[i][:1]) + ' '
return result.strip()
>>> cow_latinify_sentence('hello there i am a fish')
'ellohoo heretoo imoo ammoo amoo ishfoo'
Why not just replace the two instances of
print('{0}moo'.format(cow_word), end=' ')
with
return '{0}moo'.format(cow_word)+' '
You have to get rid of end=; you don't have to replace the newline that would otherwise follow the output of print, but if you want a space at the end of the returned string you still have to append it yourself.
You need to create a list to accumulate your results.
result = []
your two print statements in your function would need changed to result.append(XXXX). Then when you have processed the entire sentence you can
return (result)
or, to re-form it into a sentence:
return " ".join(result) + '.'
def cow_latinify_sentence(sentence):
vowels = tuple('aeiou1234567890!##$%^&*()-_=+|\\][}{?/.\',><`~"')
sentence = sentence.lower()
sentence_list = sentence.split()
result = ''
for i in range(len(sentence_list)):
cow_word = sentence_list[i][:]
if cow_word.startswith(vowels):
result += '{0}moo'.format(cow_word) + ' '
else:
result += '{0}oo'.format(sentence_list[i][1:] + sentence_list[i][:1]) + ' '
return result.strip()

Categories