I failed to write a program that prints the longest substring of a string in which the letters occur in alphabetical order for my very first Python test.
The comment read
"Your program does meet what the question asks but also contradicts with rule number 4 and hence your answer will not be accepted"
So here was my attempt of the code :
def obtain_longest_substring(string):
current_substring = longest_substring = string[0]
for letter in string[1:]:
if letter >= current_substring[-1]:
current_substring += letter
if len(current_substring) > len(longest_substring):
longest_substring = current_substring
else:
current_substring = letter
return longest_substring
def main():
s = input("Enter a string: ")
print("Longest substring in alphabetical order is: " + obtain_longest_substring(s))
if __name__ == "__main__":
main()
But the solution that was expected had some rules that I had to follow. Rule Number 4 said:
For problems such as these, do not include input statements or define variables which are already mentioned. Our automated testing will provide values for you.
I am new to Python. Can anyone tell me what I am doing wrong?
The rule clearly states not to include input statements or define variables (which you also did).
You could try re-writing it as :
current_substring = longest_substring = s[0]
for letter in s[1:]:
if letter >= current_substring[-1]:
current_substring += letter
if len(current_substring) > len(longest_substring):
longest_substring = current_substring
else:
current_substring = letter
print("Longest substring in alphabetical order is: " + str(longest_substring))
The rule says "do not include input statements"; you included an input statement (in main).
Related
I've created a function that takes a user-inputted guess, compared it to a hidden word taken randomly from a word doc, and returns a string that indicates if any letters match or are in the word at all. Here is the function:
def wordResults(guess, testGuess):
#guess = user inputted guess
#testGuess = secret word
results = ""
for i in range(5):
#Check if letters at given position match
#in each word, append capital letter if so
if guess[i] == testGuess[i]:
results += guess[i].upper()
#Check if letter at given position is in
#the secret word at all, append lowercase
#letter if so
elif testGuess.find(guess[i]) != -1:
results += guess[i]
#Append underscore if neither condition is met
else:
results += "_"
return results
My issue lies with the elif-statement. I would like it to print a lowercase only if that letter appears in the word, but not if the letter is already in the correct spot. Here is the program running to show what I'm referring to:
(Note: the hidden word is also user-inputted until I get the program working as intended)
For Guess #2, I would like it so that the first 'h' does not show up, since it is indicating the 5th letter in 'conch' that is already confirmed with a capital 'H'. Hope that makes sense.
It's a lot easier to work with a list and then make it a string at the end:
guess = guess.lower()
testGuess = testGuess.lower()
result = []
for i, letter in enumerate(guess):
if letter in testGuess:
if letter == testGuess[i]:
result.append(letter)
else:
result.append(letter.upper())
else:
result.append('_')
for i, letter in enumerate(result):
if letter.upper() in result and result[i] != letter:
result[i] = '_'
return ''.join(result)
For guess two, then the second loop checks if each letter is already in the loop and placed correctly and if it's not in the correct spot, makes it back into an _.
I'm doing the pig latin question that I'm sure everyone here is familiar with it. The only thing I can't seem to get is matching the case of the input and output. For example, when the user enters Latin, my code produces atinLay. I want it to produce Atinlay.
import string
punct = string.punctuation
punct += ' '
vowel = 'aeiouyAEIOUY'
consonant = 'bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ'
final_word = input("Please enter a single word. ")
first_letter = final_word[:1]
index = 0
if any((p in punct) for p in final_word):
print("You did not enter a single word!")
else:
while index < len(final_word) and (not final_word[index] in vowel):
index = index+1
if any((f in vowel) for f in first_letter):
print(final_word + 'yay')
elif index < len(final_word):
print(final_word[index:]+final_word[:index]+'ay')
What you need is str.title(). Once you have done your piglatin conversion, you can use title() built-in function to produce the desired output, like so:
>>> "atinLay".title()
'Atinlay'
To check if a string is lower case, you can use str.islower(). Take a peek at the docs.
simply use the built in string functions.
s = "Hello".lower()
s == "hello"
s = "hello".upper()
s == "HELLO"
s = "elloHay".title()
s == "Ellohay"
I am writing a hangman game in python as part of a college project, and I am trying to use string.replace(old, new) to substitute the blanks (_) with letters. Instead of using actual string characters though, I am trying to use variables for 'old' and 'new'. Here's what I've got so far for this bit:
if validGuess == 'true':
if guess in word:
for letter in word:
if letter == guess:
word.replace(letter, guess)
else:
missNum = (missNum + 1)
else:
tryNum = (tryNum - 1)
However, it isn't working. I don't get any errors, it simply will not replace the blanks.
What am I doing wrong here? Is there a better way to achieve what I am doing?
-EDIT-
I tried to implement #Peter Westlake's solution (which seemed to me the most elegant) but I have run into an issue. I have a section of code which converts a randomly selected word into underscores:
#converting word to underscores
wordLength = len(word)
wordLength = (wordLength - 1)
print(wordLength) #testing
for i in range(0,wordLength):
wordGuess = (wordGuess + '_')
print(wordGuess)
And this seems to work fine. Here is the code for letter substitution:
if validGuess == 'true':
wordGuess = ''.join([letter if guess == letter else wordGuess[pos]
for pos, letter in enumerate(word)])
if guess not in word:
tryNum = (tryNum - 1)
print(wordGuess)
However, here is the output:
Guess a letter: a
test
Traceback (most recent call last):
File "G:\Python\Hangman\hangman.py", line 60, in <module>
for pos, letter in enumerate(word)])
File "G:\Python\Hangman\hangman.py", line 60, in <listcomp>
for pos, letter in enumerate(word)])
IndexError: string index out of range
String index out of range? What does that mean?
str.replace() returns the new string, store the new value:
word = word.replace(letter, guess)
Python strings are immutable and cannot be altered in-place.
However, you are replacing letter with the exact same value; letter == guess is only True if both are the same character.
I'd keep a separate set of correctly guessed letters instead, and rebuild the displayed underscores and correct guesses each time:
correct_guesses = set()
incorrect_guesses = set()
if guess in correct_guesses & incorrect_guesses:
print('You already guessed that letter')
elif guess in word:
# correct guess!
correct_guesses.add(guess)
display_word = ''.join(char if char in correct_guesses else '_' for char in word)
else:
# incorrect guess!
incorrect_guesses.add(guess)
print('Oops, incorrect guess!')
missNum += 1
I think I understand what you're getting at here.
I would probably rebuild the word-so-far on the spot instead of having a persistent string for it, keeping the tested letters separately. When the user tries a new character, make two checks:
See if the guess character has been guessed already: if guess in tried. If so, proceed however you like (penalize or ignore), but don't add the character to the tried-characters list.
If not, see if the character is in the target word: elif guess in word. If not, assess some penalty and add the guess to the tried-characters list.
For any other result: else. Add the guess to the tried-characters list.
To display the user's progress, make a blank string. Go through the target word character-at-a-time: for char in word, like you have been. But instead of trying to modify an extant string, just add the character to the end of the blank string if it's in the tried-characters string, or an underscore if not: show += char if char in tried else "_". Once that for loop is exhausted, display what you've got!
Alternatively, use .join with a slightly different iterator: show = "".join(char if char in tried else '_' for char in word). It'll iterate through word, keeping each letter if it's in your tried-characters string, or substituting an underscore if not, putting whatever is in "" between them (or nothing, if you leave it as ""). It looks like you already know that, though.
At the hazard of completely rewriting your code, this is what it might look like:
## init
word = "mauritius" # the word you're looking for. I chose this one.
tried = str() # initialize a list of tested characters
tryNum = 3 # however many wrong guesses the user gets
...
## in your run loop...
if tryNum: # evaluates 0 as Fasle, if you didn't already know
guess = UserInput() # some means to get the guess from the user; a single-character string.
if guess in tried:
print "Tried that letter already!"
elif guess not in word: # the letter hasn't been tested yet, but isn't in the word, either.
print "Wrong! %d guesses left!" % tryNum
tryNum -= 1
tried += guess
else: # the guess is new (not tried) and it's valid (in the word)
tried += guess
show = str() # this is the string you will display. make a blank one each time.
for char in word:
show += char if char in tried else "_" # if the character has been tried, add it to the output. Otherwise, an underscore.
print show # display the word so far
if show == word:
print "You win!" # Congratulations! You hung a man.
else: # Out of tries; the convict lives another day.
print "Game Over!" # I am not sure how committed to this vocabulary-based execution you really are...
You can swap if tryNum: with while tryNum: and it should work all by itself, after initialization. If you do, there are fun things you can do with continues and breaks, but that goes a bit beyond the scope of your question.
You can swap show = str() and the for char in word: block out with the .join singleton in this next example, too. Change ''.join(..) to ' '.join(..) to add a space between characters/underscores!
This compressed version is probably a bit less Pythonic:
# post-init...
if tryNum:
guess = UserInput()
if guess in tried: pass
elif guess not in word:
print "Wrong! %d guesses left!" % tryNum
tryNum -= 1
tried += guess
else: tried += guess
show = ''.join(char if char in tried else '_' for char in word)
if show == word: print "You win!"
else: print "Game Over!"
This does not answer your first question of "What am I doing wrong?" but I think it might be a better way of going about what you intend? It might be a bit easier to maintain and expand for you, too.
Note: Go ahead and replace UserInput() with something like str(raw_input("Guess a letter!"))[0] if you want to try this thing out on its own.
Replacing a letter with an identical guess isn't going to do anything! I think you want to find the position in the word where the guessed letter appears, and replace the _ in that position with the letter. For that you will need to find every position where the letter occurs, e.g. using the index() method.
For instance, to replace the first occurrence of the guess:
# Illustration of the principle, not the complete answer.
word = 'faq'
display = '___'
# Put in a loop, one iteration for each guess input.
guess = 'a'
display = ''.join([letter if guess == letter else display[pos]
for pos, letter in enumerate(word)])
print display
Which will print _a_.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So the question reads:
Write a program that accepts as input a sentence in which all of the words are run together but the first character of each word is uppercase. Convert the sentence to a string in which the words are separated by spaces and only the first word starts with an uppercase letter. For example the string "StopAndSmellTheRoses." would be converted to " Stop and smell the roses."
I am so confused this my code so far.
def main():
#User enters a sentence
my_string=input('enter a sentence: ')
print(my_string.capitalize())
main()
You can loop through the string and add a character each time to a result:
my_string = "StopAndSmellTheRoses"
i = 0
result = ""
for c in my_string:
if c.isupper() and i > 0:
result += " "
result += c.lower()
else:
result += c
i += 1
print result
We'll use c for each character as we walk through the string and we'll use i to keep track of the position in the string.
There are two possibilities: it's either an uppercase character (excluding the first one) or it's not.
In the first case we'll add a space and that character as lowercase to the result. This ensures a space is inserted before each uppercase character further in the sentence.
In the second case it's a lowercase character or the uppercase character at the beginning of the sentence. We don't have to do anything with these and we'll add it right away.
Lastly we add one to i whenever we're done with a character (i += 1) as this means we correctly know where we are in the sentence.
Welcome to SO!
One way to do this is to loop through your string, checking the chars one by one:
#You've learned how to iterate through something, right?
i = 0 #a counter
for c in my_string: #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
i += 1
Edit added a double-check to see if it's the first letter of the sentence or not. Updated demo.
As an alternative to using a counter, you can also use the built-in function enumerate, which returns a tuple of index and values.
for i,c in enumerate(my_string): #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+c.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
Demo
>>> my_string = 'ImCool'
>>> new_string = ''
>>> i = 0 #a counter
>>> for c in my_string: #get the characters of my_string, one by one.
if c.isupper(): #check if it's in upper case
if i == 0: #if it's the first letter
new_string += c #let it be like the original
else:
new_string += ' '+.lower() #it's not the first letter,
#so add space, and lower the letter.
else:
new_string += c #else, only add the letter to the new string
i += 1
>>> new_string
'Im cool'
Hope this helps!
You'll need a bit of regex.
import re
split = re.findall(r'[A-Z][a-z\.]+', 'HelloThisIsMyString.')
You'll also need to join those together (inserting spaces)
' '.join(...)
and handle case conversions
' '.join(word.lower() for word in split)
(and as you already did, capitalize the first word)
' '.join(word.lower() for word in split).capitalize()
It appears that you are a little confused and this is to be expected if you are new to Python. I'm assuming you take input from the user as opposed to input for a function. Either way I would create a simple function that you could insert the users input into. The function below will accomplish what the problem asks.
def sentenceSplitter(sentence):
result = ""
for i, x in enumerate(sentence): #i is character index, x is the element
if i == 0:
result = result + x
elif x.isupper() == False: #if element is not uppercase, add it to the result
result = result + x
else: # Otherwise, add a space and lowercase the next letter
result = result + " " +x.lower()
return(result)
To reiterate, if you are looking to print out the sentence you would write this after the function:
def main():
#User enters a sentence
my_string=input('enter a sentence: ')
print(sentenceSplitter(my_string))
main()
If you are still confused feel free to ask any further questions.
I have a person calling a function with three inputs:
puzzle - so a random word, for example. 'john'
view - their view of the puzzle (they guess letters and they become revealed scoring points, etc) so lets say they only see j^h^ (^ represents hidden characters).
letter_guessed - they guess a letter, so if someone guessed 'o', the view would come back as 'joh^'
But my code just doesn't seem work and I can't seem to understand why, and please if you could do it using my bit of code below, I understand there are many ways to solve it but I'm interested in what I had to do if I wanted to solve this question using a for statement with nested if statements.
What it doesnt do: it simply displays the view again, the line of incorrect code is result = result + letter because i dont know how to make python scan for the hidden variable and replace the ^ with set found alphabetic letter.
def update_view(puzzle,view,letter_guessed):
result = ""
for index in range(0,len(puzzle)):
if puzzle[index] == letter_guessed:
result = result + letter_guessed
else:
result = view
return result
If the letter is currently "^" and the letter was guessed correctly, you want to add the guessed letter to result. Else, you want to add whatever was on the view earlier
def guess(word, view, letter) :
result = ""
for i in range(0,len(word)) :
if view[i] == "^" and word[i] == letter:
result += word[i]
else :
result += view[i]
return result
Demo
The above if-else condition can be further shortened using Python's true if condition else false construct
def guess(word, view, letter) :
result = ""
for i in range(0,len(word)) :
result += word[i] if view[i] == "^" and word[i] == letter else view[i]
return result