Statement has no effect(Python) - python-3.x

program to get a string from a given string where all occurrences of its first char have been changed to '$', except the first char itself.
Sample String : 'restart'
Expected Result : 'resta$t'
here's my code
def change(string):
string_len = len(string)
t = string[0]
for each in range(1, string_len):
if each is t:
each == '$'
else:
continue
return string
print(change("restart"))
output
restart
i'using Pycharm. Line no 6 (each == '$')says this statement has no effect. i don't want to use replace method. just want to know what is the problem.

Your code commented:
def change(string):
string_len = len(string)
t = string[0]
for each in range(1, string_len):
if each is t: # To compara strings you should use the == operator not the 'is' operator.
each == '$' # This will not have any effect because is a temporal variable visible just inside the 'for' loop and you are not using it.
else:
continue
return string
print(change("restart"))
A solution could be:
def change(s):
result = ''
for character in s:
result += '$' if character == s[0] else character
return result
print(change('restart'))
Python strings are immutable objects, so you can't do 'aaa'[1] = 'b' to get aba.

each is set to an integer and you are comparing it to a string.

Related

Python3: Midnumeral Strings to Rightnumeral Strings

My attempt:
m = str(input())
# m = list(m)
w = ""
r = ""
num = [int(i) for i in m.split() if i.isdigit()]
for c in range(0,len(m)-1):
if m[len(m)-1]:
for num in w:
if num.isnumeric():
w.remove(num)
num.join(r)
elif m[c].isalpha():
r.join(m[c])
elif m[c].isnumeric() and (len(w)==0 or w[c]=='('):
w.join(m[c])
elif len(num)!=0:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
elif m[c]==')':
for number in m:
if number.isnumeric():
w+=number
elif number=='(':
m.remove('(')
m.remove(')')
break
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w=""): # In this statement it gives an invalid syntax error
w = m[c]
else:
break
print(r)
I would like to know why get a invalid syntax at line 34 (elif statement).
Also, would like to know if there is any better way to solve this question.
Thanks
QUESTION:
Midnumeral Strings to Rightnumeral Strings
Midnumeral string is a string which contains one number in between letters. For example, a1b2c is a midnumeral string. A midnumeral strings may contain letters a to z, numbers 1 to 9 and both left and the right parentheses.
Rightnumeral string is a string which can be formed from midnumeral string:
(i) All the characters except left and right parenthesis in the midnumeral string is present in rightnumeral string.
(ii) A number ‘n’ which is between letters ‘a’ anb ‘b’ in the midnumeral string will appear in the right hand of side of the letters ‘a’ and ‘b’ in rightnumeral string in a particular fashion.
(iii)During the process of conversion of a midnumeral string to a rightnumeral string, a waiting stream is used.
Given a midnumeral string ‘m’ it can be converted to a rightnumeral string ‘r’ as follows:
i. Process character by character of midnumeral string ‘m’.
ii. When a letter is seen add it to rightnumeral string ‘r’.
iii. When a number ‘n’ is seen and waiting stream is empty or the recently added character to waiting stream is left parenthesis then add ‘n’ to waiting stream
iv. If a number ‘n’ seen and there are some numbers in the waiting stream then, If the recently added numeral in waiting stream is less than ‘n’ then add ‘n’ to waiting stream, Otherwise process waiting stream from most recent to least recent:-Remove number from waiting stream and add it to ‘r’
Repeat part (i), until the recent value available in waiting stream is less than ‘n’ or the recent character the waiting stream is left parenthesis or the waiting stream becomes empty
v. Add ‘n’ to the waiting stream
vi. If a left parenthesis is seen then add it to waiting stream
vii. When right parenthesis is seen then remove all numbers from most recent to least recent from waiting stream and add it to r till left parenthesis is seen. Discard left and right parenthesis
viii. When the end of the midnumeral ‘m’ string is reached remove all numerals from most recent to least recent from waiting stream and add it to right numeral string ‘r’
For example,
a1b2c will be abc21
a2b1c will be ab2c1
(a1b)2c will be ab1c2
a1b4(c5d2e)7f will be abcd5e2f741
Note: All the characters in the midnumeral will be distinct and only valid input is given
Input Format
First line contains the midnumeral string, m
Output Format
First line should contain the rightnumeral string, r
.1 The Syntax error
It is simple a missing '=' sign, so change it to this
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w==""):
w = m[c]
else:
break
.2 Code improvements & Best practices
I suggest you for this to post the answer on Code Review as is meant for this. There are quite few errors and not best practices follow.
For instance, this error block:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
The except is catching too many types of error, better like:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except ValueError:
continue
Have a look at Should I always specify an exception type in except statements? for more information about this. Also there is too much 'logic' in that try block. but for simplicity that is ok.
EDIT
Consideration
Note that I used different combination of sets ( accepted_numbers, accepted_chars, left_parenthesis, right_parenthesis) instead of list of other thing, this is because set are super fast when used for Looks up, more info --> Time complexity of python set operations?. And also is very clear what you are trying to use them for.
The Variable r, is way better decision to use it during the Algorithm as a List and Then turn it as a String, that's because is just easier to manipulate.
I don't even used 1 try except block, this is because, is was clear what to do, I mean we knew it ahead, so you can just handle it with a if else block, apart of what I stated Above regarding the Try blocks, another important aspect is that the slow down the code if finds and exception (in this code it won't even matter) look here try-except vs If in Python
The Algorithm problem that you posted uses and demands a Stack as a Collection, you can see it implemented in the process_waiting_stream() function
in a LIFO (last in, first out) fashion.
process_waiting_stream()
Answer Testing one case
m = '(a1b)2c' # test string Added on the top as requested in the exercise
import string # If you don't want to import string, just hard code the letters
m = m
r = []
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
global WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream():
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
print(r)
Answer 2
Testing All cases
import string # If you don't want to import string, just hard code the letters
def rightnumeral_string(m):
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
nonlocal WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
# ------ Iterate Through each Character (number included) in the string
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream(): # Check if there are currently nums in stream
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
# Last Step is to Remove left_parenthesis
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
return r
print(rightnumeral_string('a1b2c'))
print(rightnumeral_string('a2b1c'))
print(rightnumeral_string('(a1b)2c'))
print(rightnumeral_string('a1b4(c5d2e)7f'))
# Checking if the Answer Are correct
assert rightnumeral_string('a1b2c') == 'abc21'
assert rightnumeral_string('a2b1c') == 'ab2c1'
assert rightnumeral_string('(a1b)2c') == 'ab1c2'
assert rightnumeral_string('a1b4(c5d2e)7f') == 'abcd5e2f741'
Documentation
string
Iterating each character in a string using Python
What is the use of “assert” in Python?

How can I change upper case to lower and vice versa?

I am playing around with a small script, just for fun. I'm trying to reverse the items in a string and witch the upper case to lower and lower to upper. The reverse part works, but the case part doesn't. What am I doing wrong here?
def reverse(s):
if len(s) == 0:
return s
else:
if s.lower():
s.upper()
else:
s.lower()
return reverse(s[1:]) + s[0]
mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt)
Here is my current output.
sdrawkcab ekil skool txet siht woh rednow I
str.lower does not return a boolean of whether it's lowercase or not. It returns a string in lowercase. It also doesn't change a string in place.
Since that is the case you need to check the character you are currently interested in.
In this case s[0]. Additionally, strings aren't mutable so you can't change them in place. You'll need a temp variable.
def reverse(s):
if len(s) == 0:
return s
else:
# The character of interest
char = s[0]
# If it's equal to the lowercase version of it
if char == char.lower():
# Change it to upper
char = char.upper()
else:
# and vice versa
char = char.lower()
return reverse(s[1:]) + char
mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt)
s.lower() and s.upper() do not modify s but instead return another string with all letters converted to lowercase or uppercase, respectively. They don't return booleans, either (which is done by s.islower() and s.isupper()).
If you want to rewrite s, you must construct a new string from the return values.
def reverse(s):
if len(s) == 0:
return s
else:
s0 = s[0]
if s0.islower():
s0 = s0.upper()
elif s0.isupper():
s0 = s0.lower()
return reverse(s[1:]) + s0
mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt)
Here I checked for both islower and isupper, because both return False in the absence of cased characters (e.g. "0".islower() and "0".isupper() are both false).
str.lower() and str.upper() return a copy of the string converted to lower and upper case. To check whether a string is lower or uppercase, use str.islower() and str.isupper()
Python also has str.swapcase() to do exactly what you want.
Reversing a string can be done simply by using the slice notation, no need for recursion or loops. Your code could be simplified to something like:
def swapcasereverse(s):
return s[::-1].swapcase()
If you want to write your own code for swapcase as an exercise, here's a pythonic way:
def swapcasereverse(s):
newlist = [c.upper() if c.islower() else c.lower() for c in reversed(s)]
return "".join(newlist)
This function uses a list comprehension to
iterate over s in reverse order, with each character going in c
if c is lowercase, adds c.upper() to the list
otherwise, adds c.lower() to the list
Joins the list with "" to make a string, returns the joined string
def reverse(s):
if len(s) == 0:
return s
else:
if s.lower():
s.upper()
else:
s.lower()
return reverse(s[1:]) + s[0]
mytext = reverse("I wonder how this text looks like Backwards").swapcase()
print(mytext)

Concatenating string outputs of a for loop in Python 3

I have a code which, after a nested for loop, provides me with a unique string in each iteration. I want to find a way to concatenate those outputs so that my final line is a single string of those unique strings. Ignoring how ugly and inefficient this code is, what steps can I take to achieve the desired result?
VOWELS = ('a','e','i','o','u','A','E','I','O','U')
ad = "Desirable unfurnished flat in quiet residential area"
# remove all vowels, unless the word starts with a vowel
def is_vowel(c):
return c in VOWELS
def mod3(ad):
testAd =ad.split()
for word in testAd:
modAd = ""
i = 0
for char in word:
if i == 0:
modAd += char
elif not is_vowel(char):
modAd += char
i+=1
print(modAd)
mod3(ad)
my output for this code:
Otherwise, when I modify my code to look like this:
But my output is:
I don't believe a .join() would work here as it's not a list type. And I can't figure out where to put a string concat + anywhere without my for loop going bonkers. Any advice?
You can create a string result where you can concatenate your each iteration result and print that. You need to add spaces after each addition of words. So, append + " " to your result variable as well.
def mod3(ad):
result = ""
testAd =ad.split()
for word in testAd:
modAd = ""
i = 0
for char in word:
if i == 0:
modAd += char
elif not is_vowel(char):
modAd += char
i+=1
result += modAd + " "
print(result)
Second option: This is my take on it:
def mod4(ad):
result = ""
testAd =ad.split()
for word in testAd:
for i, char in enumerate(word):
if i == 0:
result += char
if i > 0 and char not in VOWELS:
result += char
result += " "
print(result)

Recursively remove all the numbers in the string and return reversed version of that string without numbers

I need to remove all the numbers from the string recursively and then return the reversed string.
def remove_numbers_and_reverse(string):
if string == "":
return string
elif string[-1].isdigit():
string.replace(string[-1], "")
return string[-1] + remove_numbers_and_reverse(string[:-1])
For example if the input is "bunny1234" then the output should be "ynnub". But i get "4321ynnub".
"bunny1234" -> "ynnub"
"3434string" -> "gnirts"
For Removing number try below approach:
1. using join and isdigit
ini_string = "Test123ing127you"
print("initial string : ", ini_string)
res = ''.join([i for i in ini_string if not i.isdigit()])
print("final string : ", res)
2. Using translate and digits
from string import digits
ini_string = "Test123ing127you"
remove_digits = str.maketrans('', '', digits)
res = ini_string.translate(remove_digits)
# printing result
print("final string : ", res)
3. Using filter and lambda
ini_string = "amol23bais"
res = "".join(filter(lambda x: not x.isdigit(), ini_string))
# printing result
print("final string : ", str(res))
The problem with your solution is the elifpart: You are not doing anything with your replaced string, replace is not working in-place. So instead you might try this:
def remove_numbers_and_reverse(string):
if string == "":
return string
elif string[-1].isdigit():
return remove_numbers_and_reverse(string[:-1])
else:
return string[-1] + remove_numbers_and_reverse(string[:-1])
print(remove_numbers_and_reverse("bunny1234"))
print(remove_numbers_and_reverse("3434string"))
Here I just ignore the last character if it is a digit.
For shorter and smarter solutions see #Amolb's answer.
Other people have answered it but might as well throw in my example too.
def remove_numbers_and_reverse(my_string):
if not my_string:
return my_string
else:
for letter in my_string:
if letter.isdigit():
continue
output = letter + output
return output
The output:
[user#machine test-dir]$ python3
Python 3.6.9 (default, Aug 15 2019, 16:59:35)
>>> import test
>>> test.remove_numbers_and_reverse("bunny1234")
'ynnub'
>>> test.remove_numbers_and_reverse("3434string")
'gnirts'
>>> test.remove_numbers_and_reverse("3434string123123morestring")
'gnirtseromgnirts'
>>> test.remove_numbers_and_reverse("")
''
>>>

How can I find a string in sequence (with Booleans)?

I receive a String. For example in here I have :
Mystring= ‘alohrefllluqoo’
I can see all the letter of 'Hello' word, in the correct sequence, in Mystring string
is it possible to use Booleans?
in that string the final output would be 'YES', cause when I remove extra letter I can see the 'Hello' word (in correct sequence) in string.
and if the sequence is not correct and the word can not be found, the output will be 'NO'
This is one approach.
Ex:
Mystring= 'alohrefllluqoo'
to_find = "hello"
def check_string(Mystring, to_find):
c = 0
for i in Mystring:
if i == to_find[c]:
c += 1
if c == len(to_find):
return "YES"
return "NO"
print(check_string(Mystring, to_find))
You can use something like this:
mystring = 'alohreflllouq'
wordtofind = "hello"
i=0
word=''
for char in mystring:
if char == wordtofind[i]:
word = word + char
i+= 1
if word == wordtofind:
break
result = "YES" if word == wordtofind else "NO"
print(result)
making a function, and passing your string, and the thing you search for:
def IsItHere(some_string, sub_string)
try:
some_string.index(sub_string)
return 'YES'
except:
return 'NO'

Resources