Code Not fulfilling all the Sample Inputs' result on HackerRank - python

Question on HackerRank- You are asked to ensure that the first and last names of people begin with a capital letter in their passports. For example, alison heck should be capitalised correctly as Alison Heck.(What they actually want is to capitalize the first letter of every individual string)
def solve(s):
0<len(s)<1000
abc=[]
for p in s.split():
abc.append(p.capitalize())
x=" ".join(abc)
return x
I am getting correct answers on putting my own custom inputs but HackerRank says otherwise.(4/6 Sample Inputs are unsatisfied)

arr = ['muhammad Atif', 'alison heck','dr dexter Morgan']
def capitalizeName(word):
words = word.split(' ')
for i in range(0,len(words)):
words[i] = words[i].capitalize()
return ' '.join(words)
for word in arr:
print(capitalizeName(word))
Hopefully, This simple function will solve your problem. Further, modify it according to the hackerrank criteria . i-e print or return statements etc

Related

Is there a way in python to count sentences having quotation marks, question mark and full stop?

I have been searching for the solution to this problem. I am writing a custom function to count number of sentences. I tried nltk and textstat for this problem but both are giving me different counts.
An Example of a sentence is something like this.
Annie said, "Are you sure? How is it possible? you are joking, right?"
NLTK is giving me --> count=3.
['Annie said, "Are you sure?', 'How is it possible?', 'you are
joking, right?"']
another example:
Annie said, "It will work like this! you need to go and confront your
friend. Okay!"
NLTK is giving me --> count=3.
Please suggest. The expected count is 1 as it is a single direct sentence.
I have written a simple function that does what you want:
def sentences_counter(text: str):
end_of_sentence = ".?!…"
# complete with whatever end of a sentence punctuation mark I might have forgotten
# you might for instance want to add '\n'.
sentences_count = 0
sentences = []
inside_a_quote = False
start_of_sentence = 0
last_end_of_sentence = -2
for i, char in enumerate(text):
# quote management, to solve your issue
if char == '"':
inside_a_quote = not inside_a_quote
if not inside_a_quote and text[i-1] in end_of_sentence: # 🚩
last_end_of_sentence = i # 🚩
elif inside_a_quote:
continue
# basic management of sentences with the punctuation marks in `end_of_sentence`
if char in end_of_sentence:
last_end_of_sentence = i
elif last_end_of_sentence == i-1:
sentences.append(text[start_of_sentence:i].strip())
sentences_count += 1
start_of_sentence = i
# same as the last block in case there is no end punctuation mark in the text
last_sentence = text[start_of_sentence:]
if last_sentence:
sentences.append(last_sentence.strip())
sentences_count += 1
return sentences_count, sentences
Consider the following:
text = '''Annie said, "Are you sure? How is it possible? you are joking, right?" No, I'm not... I thought you were'''
To generalize your problem a bit, I added 2 more sentences, one with ellipsis and the last one without even any end punctuation mark. Now, if I execute this:
sentences_count, sentences = sentences_counter(text)
print(f'{sentences_count} sentences detected.')
print(f'The detected sentences are: {sentences}')
I obtain this:
3 sentences detected.
The detected sentences are: ['Annie said, "Are you sure? How is it possible? you are joking, right?"', "No, I'm not...", 'I thought you were']
I think it works fine.
Note: Please consider the quote management of my solution works for American style quotes, where the end punctuation mark of the sentence can be inside of the quote. Remove the lines where I have put flag emojis 🚩 to disable this.

Is there a way of getting this string down to 3 words?

There are multiple problems with the code i posted below, since as i also said on my previous post im new to coding i have some trouble finding stuff by myself :(
My goal is to take user input, narrow it down to 3 words by size and then sort them alphabetically. Am i doing this right?
Probably not because it prints it out with commas. For example, with "i like eating cake" as input, the output is:
"'cake',", "'eating'", "'i',", "'like',"
But I want it to be:
cake, eating, like
Any help is much appreciated.
input = input(" ")
prohibited = {'this','although','and','as','because','but','even if','he','and','however','cosmos','an','a','is','what','question :','question','[',']',',','cosmo',' ',' ',' '}
processedinput = [word for word in re.split("\W+",input) if word.lower() not in prohibited]
processed = processedinput
processed.sort(key = len)
processed = re.sub('[\[\]]','',repr(processedinput)) #removes brackets
keywords = processed
keywords = keywords.split()
keywords.sort(key=str.lower)
keywords.sort()
keywords = re.sub('[\[\]]','',repr(keywords))
str(keywords)
print(keywords)
The first issue with your code is input = input(). The problem with this is that input is the name of the function you are calling, but you are overwriting input with the user's string. Consequently, if you tried to run input() again, it would fail.
The second issue is that you are misunderstanding lists. In the code below, tokens is a list, not a string. Each element in the list is a string. So there is no need to strip out brackets and such. You can simply order the list (that part of your code was correct) in reverse order of length, then print the first three words.
Code:
import re
user_input = input(" ")
prohibited = {'this','although','and','as','because','but','even if','he','and','however','cosmos','an','a','is','what','question :','question','[',']',',','cosmo',' ',' ',' '}
tokens = [word for word in re.split("\W+", user_input) if word.lower() not in prohibited]
tokens.sort(key=len, reverse=True)
print(tokens[0], end=', ')
print(tokens[1], end=', ')
print(tokens[2])
Input:
i like eating cake
Output:
eating, like, cake

Replacing duplicated words in python 3

I want to take a piece of text which looks like this:
Engineering will save the world from inefficiency. Inefficiency is a blight on the world and its humanity.
and return:
Engineering will save the world from inefficiency..is a blight on the . and its humanity.
That is, I want to remove duplicated words and replace them with "."
This is how I started my code:
lines= ["Engineering will save the world from inefficiency.",
"Inefficiency is a blight on the world and its humanity."]
def solve(lines):
clean_paragraph = []
for line in lines:
if line not in str(lines):
clean_paragraph.append(line)
print (clean_paragraph)
if word == word in line in clean_paragraph:
word = "."
return clean_paragraph
My logic was to create a list with all of the worst in the strings and add each one to a new list, and then, if the word was already in the list, to replace it with ".". My code returns []. Any suggestions would be greatly appreciated!
PROBLEM:
if word == word in line in clean_paragraph:
I'm not sure what you expect of this, but it will always be False. Here it is gain with some clarifying parentheses:
if word == ((word in line) in clean_paragraph):
This evaluates word in line, which may be either Boolean value. However, that value will not appear in the text of clean_paragraph, so the resulting expression is False.
REPAIR
Write the loops you're trying to encode:
for clean_line in clean_paragraph:
for word in clean_line:
At this point, you'll have to figure out what you want for variable names. You've tried to make a couple of variables stand for two different things at once (line and word; I fixed the first one).
You'll also have to learn to properly manipulate loops and their indices; part of the problem is that you've written more code at once than you can handle -- yet. Back up, write one loop at a time, and print the results, so you know what you're getting into. For instance, start with
for line in lines:
if line not in str(lines):
print("line", line, "is new: append")
clean_paragraph.append(line)
else:
print("line", line, "is already in *lines*")
I think you'll spot another problem here -- one even earlier than the one I found. Fix this, then add only one or two lines at a time, building up your program (and programming knowledge) gradually. When something doesn't work, you know it's almost certainly the new lines.
Here is one way to do this. It replaces all duplicate words with a dot.
lines_test = (["Engineering will save the world from inefficiency.",
"Inefficiency is a blight on the world and its humanity."])
def solve(lines):
clean_paragraph = ""
str_lines = " ".join(lines)
words_lines = str_lines.replace('.', ' .').split()
for word in words_lines:
if word != "." and word.lower() in clean_paragraph.lower():
word = " ."
elif word != ".":
word = " " + word
clean_paragraph += word
return clean_paragraph
print(solve(lines_test))
Output:
Engineering will save the world from inefficiency. . is . blight on . . and its humanity.
It is important to convert words or strings into the lower case or upper case (consistent form) before you make comparisons.
Another way of doing this can be:
lines_test = 'Engineering will save the world from inefficiency. Inefficiency is a blight on the world and its humanity.'
text_array = lines_test.split(" ")
formatted_text = ''
for word in text_array:
if word.lower() not in formatted_text:
formatted_text = formatted_text +' '+word
else:
formatted_text = formatted_text +' '+'.'
print(formatted_text)
Output
Engineering will save the world from inefficiency. . is . blight on . . and its humanity.

BFS issue, trying to find "children", my counter in my method seem to be wrong

So my code is currently looking like this:
def hamta():
ordlista=[]
fil=open("labb9text.txt")
ordlista=[]
for line in fil.readlines():
ordlista.append(line.strip())
return ordlista
def setlista():
ordlista=hamta()
setlista=set()
for a in ordlista:
if a not in setlista:
setlista.add(a)
return setlista
def hittabarn(parent):
mangd=setlista()
children=[]
lparent=list(parent)
mangd.remove(parent)
for word in mangd:
letters=list(word)
count=0
i=0
for a in letters:
if a==lparent[i]:
count+=1
i+=1
else:
i+=1
if count>=2:
children.append(word)
if i==2:
break
return children
The file labb9text.txt is full of words containing three letters, such as fan, man, ulk (swedish words simply). In hamta I just wanna get like a list full of these words, in setlista I dont want any duplicates and I want them to inserted in random order. When it comes to Hittabarn I want it to search through my "setlista" and find "children".
An example is if I use the word "fan" as parameter in the hittabarn-method, then I want it to find words like man, kan, lan (I've switched only the first letter here, but I could just as well have found fsn if that was in my list). Children is with other words the same word but one letter is swapped, doesnt matter where in the word. My hamta() and setlista() is working as far as I can see, but I cant make my hittabarn work, any ideas of where it goes wrong?
maybe difflib could help
import difflib
difflib.SequenceMatcher(None, "fan", "fai").ratio()
0.6666666666666666
difflib.SequenceMatcher(None, "fan", "fin").ratio()
0.6666666666666666

Identify substrings and return responses based on order of substrings in Python

I am a beginner in Python, I am teaching myself off of Google Code University online. One of the exercises in string manipulation is as follows:
# E. not_bad
# Given a string, find the first appearance of the
# substring 'not' and 'bad'. If the 'bad' follows
# the 'not', replace the whole 'not'...'bad' substring
# with 'good'.
# Return the resulting string.
# So 'This dinner is not that bad!' yields:
# This dinner is good!
def not_bad(s):
# +++your code here+++
return
I'm stuck. I know it could be put into a list using ls = s.split(' ') and then sorted with various elements removed, but I think that is probably just creating extra work for myself. The lesson hasn't covered RegEx yet so the solution doesn't involve re. Help?
Here's what I tried, but it doesn't quite give the output correctly in all cases:
def not_bad(s):
if s.find('not') != -1:
notindex = s.find('not')
if s.find('bad') != -1:
badindex = s.find('bad') + 3
if notindex > badindex:
removetext = s[notindex:badindex]
ns = s.replace(removetext, 'good')
else:
ns = s
else:
ns = s
else:
ns = s
return ns
Here is the output, it worked in 1/4 of the test cases:
not_bad
X got: 'This movie is not so bad' expected: 'This movie is good'
X got: 'This dinner is not that bad!' expected: 'This dinner is good!'
OK got: 'This tea is not hot' expected: 'This tea is not hot'
X got: "goodIgoodtgood'goodsgood goodbgoodagooddgood goodygoodegoodtgood
goodngoodogoodtgood" expected: "It's bad yet not"
Test Cases:
print 'not_bad'
test(not_bad('This movie is not so bad'), 'This movie is good')
test(not_bad('This dinner is not that bad!'), 'This dinner is good!')
test(not_bad('This tea is not hot'), 'This tea is not hot')
test(not_bad("It's bad yet not"), "It's bad yet not")
UPDATE: This code solved the problem:
def not_bad(s):
notindex = s.find('not')
if notindex != -1:
if s.find('bad') != -1:
badindex = s.find('bad') + 3
if notindex < badindex:
removetext = s[notindex:badindex]
return s.replace(removetext, 'good')
return s
Thanks everyone for helping me discover the solution (and not just giving me the answer)! I appreciate it!
Well, I think that it is time to make a small review ;-)
There is an error in your code: notindex > badindex should be changed into notindex < badindex. The changed code seems to work fine.
Also I have some remarks about your code:
It is usual practice to compute the value once, assign it to the variable and use that variable in the code below. And this rule seems to be acceptable for this particular case:
For example, the head of your function could be replaced by
notindex = s.find('not')
if notindex == -1:
You can use return inside of your function several times.
As a result tail of your code could be significantly reduced:
if (*all right*):
return s.replace(removetext, 'good')
return s
Finally i want to indicate that you can solve this problem using split. But it does not seem to be better solution.
def not_bad( s ):
q = s.split( "bad" )
w = q[0].split( "not" )
if len(q) > 1 < len(w):
return w[0] + "good" + "bad".join(q[1:])
return s
Break it down like this:
How would you figure out if the word "not" is in a string?
How would you figure out where the word "not" is in a string, if it is?
How would you combine #1 and #2 in a single operation?
Same as #1-3 except for the word "bad"?
Given that you know the words "not" and "bad" are both in a string, how would you determine whether the word "bad" came after the word "not"?
Given that you know "bad" comes after "not", how would you get every part of the string that comes before the word "not"?
And how would you get every part of the string that comes after the word "bad"?
How would you combine the answers to #6 and #7 to replace everything from the start of the word "not" and the end of the word "bad" with "good"?
Since you are trying to learn, I don't want to hand you the answer, but I would start by looking in the python documentation for some of the string functions including replace and index.
Also, if you have a good IDE it can help by showing you what methods are attached to an object and even automatically displaying the help string for those methods. I tend to use Eclipse for large projects and the lighter weight Spyder for small projects
http://docs.python.org/library/stdtypes.html#string-methods
I suspect that they're wanting you to use string.find to locate the various substrings:
>>> mystr = "abcd"
>>> mystr.find("bc")
1
>>> mystr.find("bce")
-1
Since you're trying to teach yourself (kudos, BTW :) I won't post a complete solution, but also note that you can use indexing to get substrings:
>>> mystr[0:mystr.find("bc")]
'a'
Hope that's enough to get you started! If not, just comment here and I can post more. :)
def not_bad(s):
snot = s.find("not")
sbad = s.find("bad")
if snot < sbad:
s = s.replace(s[snot:(sbad+3)], "good")
return s
else:
return s

Categories

Resources