reverse order of python - python

I stuck on the following lab exercise:
The first piece we need is a routine that, given a word, will in
someway jumble up the order of all but the first and the last
characters. Rather than just randomly moving the characters around we
will reverse the order of the letters. The following code achieves
this:
def jumble(x):
return x[len(x)::-1]
my_string="Alistair"
print(" Reverse ",jumble(my_string))
Copy the above code to a file and run it. Currently it reverses the
order of all the characters in "my_string". Modify the code so that
the first and last letters of the word are NOT reversed. That is,
instead of producing "riatsilA" it produces "Aiatsilr".
This is my code for the above part:
def jumble(x):
temp0=x[0]
temp_last=x[-1]
x_new=temp0 + x[-2:0:-1] + temp_last
return x_new
my_string="Alistair"
print(" Reverse ",jumble(my_string))
The above routine does not account for leading or trailing white
space, punctuation or other characters that might legitimately be part
of the character string, but that should not be jumbled up. For
example if the string were " Alistair, " the result should be
" riatsilA, ". Modify your routine so that only the FIRST contiguous
series of alphabetical characters (minus the first and last
characters) are reversed. Ensure that the final returned string
includes all other leading and trailing characters.
I am not sure how to do this, as white space and punctuations can happen anywhere, I am thinking about have two lists, one for empty space and punctuations while another one for "contigous series of alphabetical characters", using append method to append elements to each list, but not sure how to preserve index.Can someone help me out? Thanks in advance.

#!/usr/bin/env python
#-*-coding:utf-8-*-
import re
def reverse(s):
p = re.compile(r'\w+')
for m in p.finditer(s):
word = m.group()
if word:
p = s.partition(word)
l = list(p)
index = p.index(word)
l[index] = l[index][::-1]
l2 = list(l[index])
l2[0],l2[-1]=l2[-1],l2[0]
l[index]=''.join(l2)
s = ''.join(l)
return s
s="Alistair Chris,"
print reverse(s)
fixed it.

The following code snipplet might help you for the last task.
There's no special handling for reverting of subsets, if a special char is found somewhere else than at start or end of the string.
# Special chars which should be ignored for reverting
SPECIALCHARS = [' ', '.', ',']
def reverse( string_ ):
# Find occurence of 'special' chars. Stack position and char into a list.
specchar = [( i, ltr ) for i, ltr in enumerate( string_ ) if ltr in SPECIALCHARS]
if specchar:
# Remove all the special characters
newstring = ''.join( c for c in string_ if c not in SPECIALCHARS )
# Reverse the legal characters
newstring = newstring[::-1]
offset = 0
# Re-insert the removed special chars
for pos, char in specchar:
if pos + 1 + offset >= len( newstring ):
# Append at the end
newstring += char
else:
# Insert
newstring = newstring[:pos + offset] + char + newstring[pos + offset:]
offset += 1
return newstring
else: # No special char at all, so just revert
return string_[::-1]
print " '%s' =?= ' riatsilA, '" % ( reverse( " Alistair, " ) )
will lead to the following output: ' riatsilA, ' =?= ' riatsilA, '
Just reverting with ignoring the first and last char is a one liner.
Using this one to invert the 'middle': t[1:-1][::-1]
Then add the first and last char to it.
>>> t = "Alistair"
>>> t[0]+t[1:-1][::-1]+t[-1]
'Aiatsilr'
Edit
Ok, now I think I understood what you want :-)
newstr = ""
fullstr = ""
for char in mystr:
if char in SPECIALCHARS:
if len( newstr ): # Is already something to invert there?
#Ignore 1st and last char and revert the rest
newstr = newstr[0] + newstr[1:-1][::-1] + newstr[-1]
fullstr += newstr + char
else: # Special char found but nothing to revert so far
fullstr += char
newstr = ""
else: # No special char so just append
newstr += char
print "'%s'" % fullstr

Related

Check if character in string has space behind

I am trying to write a function that breaks up camel casing by using a space between words. How do I check if char already has space behind?
def solution(s):
space = ' '
for chr in s:
if chr.isupper() == True:
new_str = s.replace(chr, space + chr)
return new_str
Input:
"camelCaseWord" # a word in camelCasing
Output:
"camel Case Word" # separated by spaces where word starts with capital leter
My solution only gives me "camelCase Word"
Your solution does not work, because you always use the base s as "source":
s = "someWordWithCases"
will replace "W" with " W"and store it in new_str ... then throw that result away and replace "C" with " C" - using the original s again - "W" are back in with no space added before them.
Creating strings by adding to them is wasteful. Strings are immutable so the old one is thrown away after you create a new one.
The solution is to split at capital letters into a list and then join the list elements with spaces:
Yours minimally altered:
def solution(s):
r = []
for chr in s:
# if chr is capital and ( r is empty OR the last one is not a space)
if chr.isupper() and (not r or r[-1] != " "):
# add space then the capital letter
r.append(" "+chr)
else:
# only add letter
r.append(chr)
return ''.join(r)
Or version using slicing:
def solution(s):
k = []
start = 0
for i,c in enumerate(s):
if c.isupper() and start != i:
k.append(s[start:i])
start = i
if c == " ":
k.append(s[start:i])
start = i+1
if i > start:
k.append(s[start:])
return ' '.join(k)
# some test cases are "more" then pure camelCaseSpelling
tests = ["startsLowerThenHasWords", "StartsCapitalThenHasWords",
" starts with spaces no capitals", " Has some Capitals",
"has Capitals ABC and Others that areNotCapitals"]
maxL = max(len(t) for t in tests)
for t in tests:
print(f"{t:<{maxL}} ==> {solution(t)}")
to get
startsLowerThenHasWords ==> starts Lower Then Has Words
StartsCapitalThenHasWords ==> Starts Capital Then Has Words
starts with spaces no capitals ==> starts with spaces no capitals
Has some Capitals ==> Has some Capitals
has Capitals ABC and Others that areNotCapitals ==> has Capitals A B C and Others that are Not Capitals
How about this one? I used enumerate to get the index of iteration.
def solution(s):
space = ' '
space_positions = []
for index, chr in enumerate(s):
print(chr)
if chr != space and chr.isupper() == True:
if s[index - 1] != space:
space_positions.insert(0, index)
for index in space_positions:
s = s[:index] + " " + s[index:]
return s

How to reverse the words of a string considering the punctuation?

Here is what I have so far:
def reversestring(thestring):
words = thestring.split(' ')
rev = ' '.join(reversed(words))
return rev
stringing = input('enter string: ')
print(reversestring(stringing))
I know I'm missing something because I need the punctuation to also follow the logic.
So let's say the user puts in Do or do not, there is no try.. The result should be coming out as .try no is there , not do or Do, but I only get try. no is there not, do or Do. I use a straightforward implementation which reverse all the characters in the string, then do something where it checks all the words and reverses the characters again but only to the ones with ASCII values of letters.
Try this (explanation in comments of code):
s = "Do or do not, there is no try."
o = []
for w in s.split(" "):
puncts = [".", ",", "!"] # change according to needs
for c in puncts:
# if a punctuation mark is in the word, take the punctuation and add it to the rest of the word, in the beginning
if c in w:
w = c + w[:-1] # w[:-1] gets everthing before the last char
o.append(w)
o = reversed(o) # reversing list to reverse sentence
print(" ".join(o)) # printing it as sentence
#output: .try no is there ,not do or Do
Your code does exactly what it should, splitting on space doesn't separator a dot ro comma from a word.
I'd suggest you use re.findall to get all words, and all punctation that interest you
import re
def reversestring(thestring):
words = re.findall(r"\w+|[.,]", thestring)
rev = ' '.join(reversed(words))
return rev
reversestring("Do or do not, there is no try.") # ". try no is there , not do or Do"
You can use regular expressions to parse the sentence into a list of words and a list of separators, then reverse the word list and combine them together to form the desired string. A solution to your problem would look something like this:
import re
def reverse_it(s):
t = "" # result, empty string
words = re.findall(r'(\w+)', s) # just the words
not_s = re.findall(r'(\W+)', s) # everything else
j = len(words)
k = len(not_s)
words.reverse() # reverse the order of word list
if re.match(r'(\w+)', s): # begins with a word
for i in range(k):
t += words[i] + not_s[i]
if j > k: # and ends with a word
t += words[k]
else: # begins with punctuation
for i in range(j):
t += not_s[i] + words[i]
if k > j: # ends with punctuation
t += not_s[j]
return t #result
def check_reverse(p):
q = reverse_it(p)
print("\"%s\", \"%s\"" % (p, q) )
check_reverse('Do or do not, there is no try.')
Output
"Do or do not, there is no try.", "try no is there, not do or Do."
It is not a very elegant solution but sure does work!

Convert the string to a string in which the words are separated by spaces and only the first word starts with an uppercase letter [duplicate]

This question already has answers here:
Split a string at uppercase letters
(22 answers)
Closed 2 years ago.
I am trying to make a script that will accept a string as input in which all of the words are run together, but the first character of each word is uppercase. It should convert the string to a string in which the words are separated by spaces and only the first word starts with an uppercase letter.
For Example (The Input):
"StopWhateverYouAreDoingInterestingIDontCare"
The expected output:
"Stop whatever you are doing interesting I dont care"
Here is the one I wrote so far:
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
start_sentence = string_input[0]
index_of_i = string_input.index("I")
for i in string_input[1:]:
if i == "I" and string_input[index_of_i + 1].isupper():
start_sentence += ' ' + i
elif i.isupper():
start_sentence += ' ' + i.lower()
else:
start_sentence += i
return start_sentence
While this takes care of some parts, I am struggling with differentiating if the letter "I" is single or a whole word. Here is my output:
"Stop whatever you are doing interesting i dont care"
Single "I" needs to be uppercased, while the "I" in the word "Interesting" should be lowercased "interesting".
I will really appreciate all the help!
A regular expression will do in this example.
import re
s = "StopWhateverYouAreDoingInterestingIDontCare"
t = re.sub(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z])', ' ', s)
Explained:
(?<=[a-z])(?=[A-Z]) - a lookbehind for a lowercase letter followed by a lookahead uppercase letter
| - (signifies or)
(?<=[A-Z])(?=[A-Z]) - a lookbehind for a uppercase letter followed by a lookahead uppercase letter
This regex substitutes a space when there is a lowercase letter followed by an uppercase letter, OR, when there is an uppercase letter followed by an uppercase letter.
UPDATE: This doesn't correctly lowercase the words (with the exception of I and the first_word)
UPDATE2: The fix to this is:
import re
s = "StopWhateverYouAreDoingInterestingIDontCare"
first_word, *rest = re.split(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z])', s)
rest = [word.lower() if word != 'I' else word for word in rest]
print(first_word, ' '.join(rest))
Prints:
Stop whatever you are doing interesting I dont care
Update 3: I looked at why your code failed to correctly form the sentence (which I should have done in the first place instead of posting my own solution :-)).
Here is the corrected code with some remarks about the changes.
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
start_sentence = string_input[0]
#index_of_i = string_input.index("I")
for i, char in enumerate(string_input[1:], start=1):
if char == "I" and string_input[i + 1].isupper():
start_sentence += ' ' + char
elif char.isupper():
start_sentence += ' ' + char.lower()
else:
start_sentence += char
return start_sentence
print(organize_string())
!. I commented out the line index_of_i = string_input.index("I") as it doesn't do what you need (it finds the index of the first capital I and not an I that should stand alone (it finds the index of the I in Interesting instead of the IDont further in the string_input string). It is not a correct statement.
for i, char in enumerate(string_input[1:], 1) enumerate states the index of the letters in the string starting at 1 (since string_input[1:] starts at index 1 so they are in sync). i is the index of a letter in string_input.
I changed the i's to char to make it clearer that char is the character. Other than these changes, the code stands as you wrote it.
Now the program gives the correct output.
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
counter = 1
def organize_string():
global counter
start_sentence = string_input[0]
for i in string_input[1:]:
if i == "I" and string_input[counter+1].isupper():
start_sentence += ' ' + i
elif i.isupper():
start_sentence += ' ' + i.lower()
else:
start_sentence += i
counter += 1
print(start_sentence)
organize_string()
I made some changes to your program. I used a counter to check the index position. I get your expected output:
Stop whatever you are doing interesting I dont care
s = 'StopWhateverYouAreDoingInterestingIDontCare'
ss = ' '
res = ''.join(ss + x if x.isupper() else x for x in s).strip(ss).split(ss)
sr = ''
for w in res:
sr = sr + w.lower() + ' '
print(sr[0].upper() + sr[1:])
output
Stop whatever you are doing interesting i dont care
I hope this will work fine :-
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
i=0
while i<len(string_input):
if string_input[i]==string_input[i].upper() and i==0 :
print(' ',end='')
print(string_input[i].upper(),end='')
elif string_input[i]==string_input[i].upper() and string_input[i+1]==string_input[i+1].upper():
print(' ',end='')
print(string_input[i].upper(),end='')
elif string_input[i]==string_input[i].upper() and i!=0:
print(' ',end='')
print(string_input[i].lower(),end='')
if string_input[i]!=string_input[i].upper():
print(string_input[i],end='')
i=i+1
organize_string()
Here is one solution utilising the re package to split the string based on the upper case characters. [Docs]
import re
text = "StopWhateverYouAreDoingInterestingIDontCare"
# Split text by upper character
text_splitted = re.split('([A-Z])', text)
print(text_splitted)
As we see in the output below the separator (The upper case character) and the text before and after is kept. This means that the upper case character is always followed by the rest of the word. The empty first string originates from the first upper case character, which is the first separator.
# Output of print
[
'',
'S', 'top',
'W', 'hatever',
'Y', 'ou',
'A', 're',
'D', 'oing',
'I', 'nteresting',
'I', '',
'D', 'ont',
'C', 'are'
]
As we have seen the first character is always followed by the rest of the word. By combining the two we have the splitted words. This also allows us to easily handle your special case with the I
# Remove first character because it is always empty if first char is always upper
text_splitted = text_splitted[1:]
result = []
for i in range(0, len(text_splitted), 2):
word = text_splitted[i]+text_splitted[i+1]
if (i > 0) and (word != 'I') :
word = word.lower()
result.append(word)
result = ' '.join(result)
split the sentence into individual words. If you find the word "I" in this list, leave it alone. Leave the first word alone. All of the other words, you cast to lower case.
You have to use some string manipulation like this:
output=string_input[0]
for l in string_input[1:]:
if l.islower():
new_s+=l
else:
new_s+=' '+l.lower()
print(output)

Python iterations mischaracterizes string value

For this problem, I am given strings ThatAreLikeThis where there are no spaces between words and the 1st letter of each word is capitalized. My task is to lowercase each capital letter and add spaces between words. The following is my code. What I'm doing there is using a while loop nested inside a for-loop. I've turned the string into a list and check if the capital letter is the 1st letter or not. If so, all I do is make the letter lowercase and if it isn't the first letter, I do the same thing but insert a space before it.
def amendTheSentence(s):
s_list = list(s)
for i in range(len(s_list)):
while(s_list[i].isupper()):
if (i == 0):
s_list[i].lower()
else:
s_list.insert(i-1, " ")
s_list[i].lower()
return ''.join(s_list)
However, for the test case, this is the behavior:
Input: s: "CodesignalIsAwesome"
Output: undefined
Expected Output: "codesignal is awesome"
Console Output: Empty
You can use re.sub for this:
re.sub(r'(?<!\b)([A-Z])', ' \\1', s)
Code:
import re
def amendTheSentence(s):
return re.sub(r'(?<!\b)([A-Z])', ' \\1', s).lower()
On run:
>>> amendTheSentence('GoForPhone')
go for phone
Try this:
def amendTheSentence(s):
start = 0
string = ""
for i in range(1, len(s)):
if s[i].isupper():
string += (s[start:i] + " ")
start = i
string += s[start:]
return string.lower()
print(amendTheSentence("CodesignalIsAwesome"))
print(amendTheSentence("ThatAreLikeThis"))
Output:
codesignal is awesome
that are like this
def amendTheSentence(s):
new_sentence=''
for char in s:
if char.isupper():
new_sentence=new_sentence + ' ' + char.lower()
else:
new_sentence=new_sentence + char
return new_sentence
new_sentence=amendTheSentence("CodesignalIsAwesome")
print (new_sentence)
result is codesignal is awesome

How do I find the first occurrence of a vowel and move it behind the original word (pig latin)?

I need to find the first vowel of a string in python, and I'm a beginner. I'm instructed to move the characters before the first vowel to the end of the word and add '-ay'. For example "big" becomes "ig-bay" and "string" becomes "ing-stray" (piglatin, basically).
This is what I have so far:
def convert(s):
ssplit = s.split()
beginning = ""
for char in ssplit:
if char in ('a','e','i','o','u'):
end = ssplit[char:]
strend = str(end)
else:
beginning = beginning + char
return strend + "-" + beginning + "ay"
I need to find a way to stop the "if" statement from looking for further vowels after finding the first vowel - at least I think it's the problem. Thanks!
Break things down one step at a time.
Your first task is to find the first vowel. Let's do that:
def first_vowel(s):
for index, char in enumerate(s):
if char in 'aeiou':
return index
raise Error('No vowel found')
Then you need to use that first vowel to split your word:
def convert(s):
index = first_vowel(s)
return s[index:] + "-" + s[:index] + 'ay'
Then test it:
print(convert('pig'))
print(convert('string'))
Full code, runnable, is here: https://repl.it/Dijj
The exception handling, for words that have no vowels, is left as an exercise.
Add a break where you want the for loop to end: https://docs.python.org/2/tutorial/controlflow.html
Python has the break and continuestatements for loop control. You can set a boolean that you trigger such that:
if flag:
break
#do code
#set flag
You can use a break statement as soon as you found a vowel.
You also do not need to use any split() functions.
One big mistake you did was using char to get the SubString. You need to use the index of that char to get the SubString instead.
Take a look at this:
def convert(s):
beginning = ""
index = 0;
for char in s:
if char in ('a','e','i','o','u'):
end = str(s[index:])
break
else:
beginning = beginning + char
index = index + 1
return str(end) + "-" + beginning + "ay"
Side note. You can use a regex:
>>> import re
>>> cases=['big','string']
>>> for case in cases:
... print case+'=>', re.sub(r'^([^aeiou]*)(\w*)', '\\2-\\1ay', case)
...
big=> ig-bay
string=> ing-stray

Categories