Is there a concise way to program these two conditions? - python

exactSearch is a boolean variable. True means looking for an exact match with ==, False means looking for a like match with 'in'.
The resulting operations of appending to a DataFrame or continuing are the same regardless of the value of exactSearch, just that the operator will change depending on exactSearch.
The following code does indeed work, but I'm curious if there's a better way to program these conditions concisely.
if exactSearch:
if payerName == payer: # Look for exact match
result.loc[len(result)] = [provider,payer] + status.split(" ") # If located, add to results
else:
continue
else:
if payerName in payer: # Look for like match
result.loc[len(result)] = [provider,payer] + status.split(" ") # If located, add to results
else:
continue

How aboout:
match = (payerName == payer) if exactSearch else (payerName in payer)
if match:
result.loc[len(result)] = [provider,payer] + status.split(" ") # If located, add to results
else:
continue

Would this work?
if (payerName == payer) or (payerName in payer):
result.loc[len(result)] = [provider,payer] + status.split(" ")
else:
continue

Related

How to change a global variable from within a for if...?

My program tries to guess if an input number or letter is in a specific string. For that I have this simplified piece of code:
obtained = False
for i in range(6+len(chosen_set)):
try_let = input("Input something")
for index, letnum in enumerate(chosen_set):
if letnum == try_let:
obtained = True
else:
obtained = False
if obtained:
# do something
else:
# do something else
Say I input the letter "R" and the string I'm testing is XXXRXRX. When the inner for loop goes through its 4th iteration, the variable obtained will be True, and the same will happen for the 6th iteration, but not for the last one, which means the final value of obtained will be False. How should I change my code so that obtained will be True as long as it finds a coincidence regardless of when it finds it? Note that I can't use break in the for loop as soon as it finds a coincidence because the string could have more than one coincidence.
Maybe that?
for i in range(6+len(chosen_set)):
try_let = input("Input something")
obtained = False
for index, letnum in enumerate(chosen_set):
if letnum == try_let:
obtained = True
if obtained:
# do something
else:
# do something else
If you can't use a break, then change the logic of using an explicit True/False boolean as the primary decision factor and make use of a count as well.
For example:
count=0
if letnum == try_let:
count+=1
if count > 0:
obtained = True
else:
obtained = False

How to return something if Python re.findall() finds something without using else statement?

I want to use if and elif conditions to check if re.findall() was able to find characters in an input without using else. Is it possible?
Here's what I've tried:
import re
a = input('')
txt = '[a-zA-Z0!#]'
search = re.findall(txt, a)
if len(search) == 0:
print('nothing')
elif len(search) == 1: # assuming that the user input contains many numbers of characters, it's
print('ok') # impossible to guess how many characters len(search) will be equal to..
If the user input exceeds 1 character, the elif statement gets ignored. What should I do?
This is hugely contrived and not recommended because if/else is going to be more readable/understandable. But to answer the question as asked:
import re
d = {True: 'ok', False: 'nothing'}
ui = input('Type something: ')
t = re.findall('[a-zA-Z0!#]', ui)
print(d[bool(t)])
Just use bool:
bool(search)
example:
bool(re.findall('[a-zA-Z0!#]', 'abc'))
True
bool(re.findall('[a-zA-Z0!#]', ''))
False

doesn't test all code when fixing my string index out range

Okay so the following code is supposed to test whether or not r and b are alternating. So a test of "rbrbrb" would be accepted but "rbbrbbr" would not be accepted.
However my issue is that only tests the first two under def manufactoria()
def manufactoria():
test(alternating_colors, "")
test(alternating_colors, "r")
test(alternating_colors, "rb")
test(alternating_colors, "rbrbrbr")
test(alternating_colors, "b")
test(alternating_colors, "brbr")
test(alternating_colors, "brbrbrbr")
def alternating_colors(string):
length = len(string)
check = 0
if len(string) == 0 or len(string)==1:
return True
while check <= len(string)-1:
if string[check]+string[check+1] == "rr" or string[check]+string[check+1] == "bb":
return False
check +=1
def test(fn, string):
if fn(string):
result = "accepted"
else:
result = "not accepted"
print('The string "' + string + '" is ' + result)
manufactoria()
Here is the corrected version:
def alternating_colors(s):
length=len(s)
if length<2:
return True
for i in range(length-1):
curr_slice = s[i:i+2]
if curr_slice in ["rr", "bb"]:
return False
return True
This is basically using most of what Prune answered.
An even better solution is using regular expressions. This will find any repetition of either r or b:
import re
def alternating_colors(s):
if re.search(r"r{2,}|b{2,}", s):
return False
return True
It doesn't check all of your code because the "index out of range" exception kills your program.
Your index is out of range because you tried to access position 2 of a string of length 2: "rb" has indices 0 and 1, but you tried to check string[1] + string[1+1]. You need to stop your checking loop one index earlier, as one commenter already mentioned.
You can make this program shorter and easier to maintain if you learn to use these Python language features:
< (less than operator)
for statement (replaces your while and
increment loop)
string slicing (instead of concatenating individual
characters)
in operator (instead of checking individual locations)

Python, checking if string consists only of 1's and 0's

I'm trying to write a function that checks if given string is binary or not. I'm using a while loop to browse characters in string one by one. If all of them are 0's or 1's it's going to return True, if anything is not - break the loop and return False.
I've just written this tiny part of code, but it doesn't run. Why?
def fnIsBin(string):
count = 0
while count < len(string):
character = string[count]
if character == '0' or character == '1':
print (count, character[count], "OK")
count = count+1
continue
else:
print (count, character[count], "ERROR")
return False
break
EDIT:
I also tried using 'set' to elude iterating with loop, but i don't quite get how does "set(string)" work. I got error that i cant consider it as a list. So how can I compare elements to 0 & 1?
def fnIsBin(string):
charactersList = set(string)
if len(charactersList) > 2:
return False
else:
if (charactersList[0] == '0' or charactersList[0] == '1') and (charactersList[1] == '0' or charactersList[1] == '1'): #there i made error, how to deal with it?
return True
else:
return False
Your function fails because you never actually return True. That means if the string is actually binary, you'd return None which Python would consider as False in any boolean check.
Simply add return True at the end of the function.
As #Barmar mentioned in the comment, you also print the value of character[count] instead of string[count] which would cause IndexError.
An easier way to check if the string is binary would be:
test_string = '010101'
all_binary = all(c in '01' for c in test_string)
There are many ways to do this:
Set:
fnInBin(s):
return set(s).issubset({'0', '1'}) and bool(s)
Regular expression:
fnInBin(s):
return bool(re.fullmatch('[01]+', s))
Integer conversion:
fnIsBin(s):
try:
int(s, 2)
return True
except ValueError:
return False
The last one will strip whitespace from the input, though.
fnIsBin('\n 1 ') == True
You can use the int object and give it a base. It will fail if the object passed doesn't consist of a binary representation. Recall that a binary string is base 2.
def fnIsBin(string):
try:
binary_repr = int(string, 2)
except ValueError as err
print("error: {0}".format(err))
return False
return True
You're printing OK for each character that's 0 or 1, even though there may be a later character that isn't. You need to wait until the end of the loop to know that it's really OK.
def fnIsBin(string):
for character in string:
if character != '0' and character != '1':
print (character, "ERROR")
return False
print "OK"
return True
There's no need for break after return False -- returning from the function automatically breaks out of the loop.
Here's one of the ways you could rewrite your function and maintain a similar structure (looping through each character):
def fnIsBin(string):
for character in string:
if not character in '01':
return False
return True
You could also do it using regular expressions:
import re
def fnIsBin(string):
return re.match(r'^[10]+$', '01') is not None
My two cents (A short way):
test_string = '010101'
result = set(test_string) <= {'0','1'}
print(result)
Using set(test_string) converts the string into list of characters,
{0,1,0,1,0,1}
Using <= operator checks whether the set on the left-side is a proper subset of the set on the right-hand side
Ultimately checking whether there are only 0 and 1 are in the string or not in an in-direct and mathematical way.
Adding a XOR solution to the mix:
bin_string = '010101'
for j in range(0, len(bin_string)):
if int(bin_string[j]) != 0 ^ int(bin_string[j]) != 1:
break

Replace a substring in a string with python

I am trying to replace every instance of a substring in a string using python. The following is the code that I have done and it is giving me some weird result.
def main():
s='IN GOING GO'
x='IN'
y='aa'
print(rep_str(s,x,y))
def rep_str(s,x,y):
result=""
if x in s:
for i in range(len(s)):
if s[i:i+len(x)] == x:
result=result+y
else:
result=result+s[i+1:i+len(x)]
return result
main()
I am not allowed to use the replace method. In fact, my function is supposed to do what replace function does in python. The following is the output that I am getting.
aa GOIaaG GO
I would appreciate if someone could give me some input about how to change the logic to get the right out put i.e.
aa GOaaG GO.
As I mentioned in comments, the mistake is that you are not skipping len(x) characters after match. Also in keyword is quite high-level routine (it does not less than search part of search & replace), so here is fixed version without in:
def rep_str(string, search, replacement):
result = ''
i = 0
while i < len(string):
if string[i : i + len(search)] == search:
result += replacement
i += len(search)
else:
result += string[i]
i += 1
return result
If you just want to have the result try with:
import re
re.sub(r'IN','aa','IN GOING GO')
but if you need some logic then you should compare for blocks of same length as the pattern, not char by char
#Zag asnwer is better, because can compare longer patterns and has return when it does not match nothing but if you want to get your code running you need to skip for when you have a match like this :
def rep_str(s,x,y):
result=""
skip = False
if x in s:
for i in range(len(s)):
if skip:
skip = False
continue
if s[i:i+2] == x:
result+=y
skip = True
else:
result+=s[i:i+1]
return result
else:
return s
but your code won't work when you will call the function with rep_str("A example test","test", "function") for example.
If you are allow to use the index() function, you can try this:
def main():
s='IN GOING GO'
x='IN'
y='aa'
print(rep_str(s,x,y))
def rep_str(s,x,y):
while x in s:
s = s[:s.index(x)] + y + s[s.index(x) + len(x):]
return s
main()

Categories

Resources