If I wanted mystring = (any number between 0-9) is there any way to assign a value like this to a string?
If I had something similar to this :
mystring = "7676-[0-9]-*"
I would want this in theory to be equal to 7676-5-0 and also 7676-9-100 etc.
The reason I want this is because later in my script I will be writing a conditional statement such as:
if mystring == yourstring:
print('something cool')
else:
print('not cool')
where yourstring is equal to a number such as 7676-3-898 where it would equal mystring or 7777-7-8 where it would not equal mystring
You are looking for regex.
As an example, here is something that should be working for you:
import re
# 7676 + one digit between 0 and 9 + at least one digit between 0 and 9 (can be more)
pattern = "7676-[0-9]-[0-9]+"
and later in your code:
if re.match(pattern, "7676-9-100"):
print("something cool")
else:
print("not cool")
Alternative to regex version, you can achieve this in Pythonic way using split() function in Python:
mystring = "7676-5-*"
if '0' <= mystring.split('-')[1] <= '9':
print('something cool')
else:
print('not cool')
Related
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
I have a string as an input for the code I'm writing and let an example of the string be:
"12 inches makes 1 foot"
My goal is to have my code run through this string and just pull out the integers and add them. So the output for the string above would be 13. I am using try and except in here as well since another sample input string could be something like "pi is 3.14".
msg= "12 inches makes 1 foot"
thesum = 0
s= msg.split()
for a in s:
try:
if a == int(a):
a= int(a)
thesum += a
print (thesum)
except ValueError as e:
print("Value Error: no int present")
I did what is above and I am not getting it to add the value of a (if it is an int) to "thesum". How can I get this to work? Also, I do want to have it in the try, except format so that I can call the ValueError
There is no need to check equality with a string. In fact, just try '4' == 4 in an interpreter. The answer is False because strings and integers are never equivalent. Just put thesum += int(a) into the loop instead of your if statement. If you don't want try-except, use if a.isdigit(): instead of try: and take out except: altogether:
for a in s:
if a.isdigit():
thesum += int(a)
print(thesum)
A good way would be the combination of several built-ins:
string = "12 inches makes 1 foot"
total = sum(map(int, filter(str.isdigit, string.split())))
filter() finds only the characters that are digits. We then convert each to an integer with map() and find the total with sum().
a is str, and int(a) is int(if possible), so a == int(a) will never equal.
just add the value of int(a), if the convert fails, it will raise ValueError.
The following codes should work.
msg= "12 inches makes 1 foot"
thesum = 0
s= msg.split()
for a in s:
try:
thesum += int(a)
except ValueError as e:
print a
print thesum
I like "re" and comprehension to make it easier to read:
import re
print(sum(int(a) for a in re.findall(r'\d+', '12 inches make 1 foot')))
Then you can extend the regular expression for floats, etc.
Most of the earlier approaches discount the second input which is "pi is 3.14". Although question has been asked with stated assertion of parsing integer. It requires treatment of numbers as float to successfully process second input.
import unittest
import re
def isDigit(s):
return re.match(r'[\d.]+', s)
def stringParse(input):
input = [i.strip() for i in input.split()]
input = filter(lambda x: isDigit(x), input)
input = map(lambda x: float(x), input)
return sum(input)
class TestIntegerMethods(unittest.TestCase):
def test_inches(self):
self.assertEqual(stringParse("12 inches makes 1 foot"), 13.0)
def test_pi(self):
self.assertTrue(stringParse('pi is 3.14'), 3.14)
if __name__ == '__main__':
unittest.main()
Another take on the problem
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 7 years ago.
Improve this question
I am writing an algorithm that takes a user input and sees if it contains all of the characters in the alphabet. For some reason, one of my loops is true every iteration and is causing my algorithm not to work. Can anyone help me out?
sentence = raw_input()
sentence = sentence.lower()
sentence = sentence.replace(' ', '')
alphabet = 'abcdefghijklmnopqrstuvwxyz'
if len(sentence) < len(alphabet):
print 'not pangram'
else:
for i in range(len(alphabet)):
for z in range(len(sentence)):
if alphabet[i] != sentence[z]:
continue
else:
alphabet.replace(alphabet[i], '1')
if len(alphabet) > 0:
print 'not pangram'
else:
print 'pangram'
print alphabet
I think you can achieve the same result with set():
if set(alphabet) == set(sentence):
print('pangram')
else:
print('not pangram')
Also you don't need to write alphabet, since it's defined in the string module:
import string
if set(string.ascii_lowercase) == set(sentence):
print('pangram')
...
You may use all function after applying the lower,replace functions.
>>> s = "abcdefghijklmnopqrstuvwxyz hfashf"
>>> alphabet = 'abcdefghijklmnopqrstuvwxyz'
>>> all(i in s for i in alphabet)
True
>>> s = "abcdefghijklmnopqrstwxyz hfashf"
>>> all(i in s for i in alphabet)
False
>>>
You may achieve this through regex also but it's an overkill.
re.match(r'(?=.*?a)(?=.*?b)(?=.*?c)', s)
In the above regex, write upto z.. For case insentive match, add (?i) at the start.
Just to explain what you did wrong.
The str.replace() function does not replace strings inplace, it returns a new string with the characters/substrings replaced. In your code, when you are doing - alphabet.replace(alphabet[i], '1') , it just replaces the characters and returns back the new string, it does not replace it within the alphabet string, since strings are immutable.
You should assign the returned string back to alphabet, also, if you replace the string with 1 its len would never go to 0. Just before checking for if len(alphabet) == 0: , you should replace all 1 with empty string - '' .
else:
alphabet = alphabet.replace(alphabet[i], '1')
alphabet = alphabet.replace('1','')
Though the others answers are much better and faster ways to achieve your solution.
First of all, the length of alphabet in your code does not change, because of:
alphabet.replace(alphabet[i], '1')
You are just replacing one character with another.
Secondly, your code is a little bit complicated, the simpler solution can be:
if len(sentence) < len(alphabet):
print 'not pangram'
else:
for letter in sentence:
alphabet = alphabet.replace(letter, '')
if len(alphabet) > 0:
print 'not pangram'
else:
print 'pangram'
print alphabet
This code, preserves your idea of replacing the characters, but doing it with an empty string which causes len(alphabet) to decrement on every iteration.
You're not doing anything to change the length of alphabet, so len(alphabet) > 0 will always be true.
The question I'm answering requires you to validate a Car Reg Plate. It must look for a sequence of two letters, then three numbers, then three letters, otherwise return a message like "not a valid postcode"
I need to know how to check if a string contains a certain letter, or number, by comparing it with a list.
So far, I've got this:
# Task 2
import random
import re
def regNumber():
# Generate a Car Reg Number
letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
numbers = ["1","2","3","4","5","6","7","8","9","0"]
letter1 = random.choice(letters)
letter2 = random.choice(letters)
number1 = random.choice(numbers)
number2 = random.choice(numbers)
letter3 = random.choice(letters)
letter4 = random.choice(letters)
letter5 = random.choice(letters)
licensePlate = (letter1 + letter2 + number1 + number2 + letter3 + letter4 + letter5)
return licensePlate, letters, numbers
carReg, letters, numbers = regNumber()
print(carReg)
if letters not in carReg: print("Success")
However, I get this error:
TypeError: 'in <string>' requires string as left operand, not list
Any help appreciated.
You need to be checking for characters in your string with this method, it will not simply iterate over your list for you.
Try using something like this instead, to check every character in your list of strings:
if any(letter in carReg for letter in letters):
This will cut out on the first True, which is I think what you're looking for.
Note: If using any like this is unfamiliar territory for you, you can also always just iterate over every string within your list of strings to check for those given characters.
Update: If you're attempting to match a given format of letters and numbers, it would make much more sense (IMHO) for you to familiarize yourself with Python's regex methods to pattern match to a valid license plate than attempt to use loops to validate one. I won't write the regex for your particular case, but to give you an idea, the following would allow you to match 3 letters followed by 1-4 digits (valid license plate where I live)
match_plate = re.compile(r"^[A-Z]{3}\d{1,4}$",re.I)
If you really must use a list to check, you will have to use a series of conditional statements to split the license plate into parts over which you can validate with iterations.
The error is telling you the exact issue in this case,
letters is a list being returend from regNumber but in requires a string on the leftside
like 'ASD111' in carReg
change
if letters not in carReg: print("Success")
to
for l in letters:
if l not in carReg:
print("Success")
in your code you are having a list of strings and, that is why I have changed your if condition to a for loop so that each element of the list is checked for occurance in carReg string.
alternatively, i think you should be using a flag to solve your probem. Like so:
flag = 0
for l in letters:
if l in carReg:
flag = 1
break
if flag == 0:
print("Success")
Another way in which you could generate a certain number of letters rather than having to use so many variables would be to use just two variables that would allow the generation of, for the first one, 2 letters and for the second 3 letters.
An example of how I would implement this would be:
def randomLetters1(y):
return ''.join(random.choice(string.ascii_uppercase) for x in range(y))
firstLetters = (randomLetters1(2))
secondLetters = (randomLetters1(3))
I know this because I have had to do this exact same task.
You could do it without regular expressions:
Define the pattern you want using str methods in a list
pattern = [str.isalpha, str.isalpha,
str.isdigit, str.isdigit, str.isdigit,
str.isalpha, str.isalpha, str.isalpha]
Use that pattern to check a string.
def is_foo(pattern, s):
'''Return True if s matches pattern
s is a string
pattern is a list of functions that return a boolean
len(s) == len(pattern)
each function in pattern is applied to the corresponding character in s
'''
# assert len(s) == len(pattern)
return all(f(c) for f, c in zip(pattern, s))
Usage
if is_foo(pattern, 'aa111aaa'):
print 'yes!!!'
if not is_foo(pattern, '11aa111'):
print ':('
I wrote the following program to determine whether a string s a palindrome using recursion. My problem is that I am not sure how to add a print statement that tells me whether the string is a palindrome or not. I realize that there are other codes which do the same thing, but I am trying to understand if my reasoning is correct.
import re
s= raw_input( " Enter a string to check if it is a palindrome ")
newstring = re.sub('\W', '', s)
newstring =newstring.lower()
def Palind(newstring):
if newstring[0] != newstring[-1]:
#print 'The given string is not a palindrome'
return False
else:
s_remain = newstring[1:-1]
if s_remain == '':
return True
elif len(s_remain) == 1 :
return True
else:
return Palind(s_remain)
if Palind(newstring):
print 'Yes'
else:
print 'No'
First, correctly indent your code, and properly lowercase the input:
import re
s= raw_input( " Enter a string to check if it is a palindrome ")
newstring = re.sub('\W', '', s)
newstring = newstring.lower()
def Palind(newstring):
if newstring[1] != newstring[-1]:
#print 'The given string is not a palindrome'
return False
else:
s_remain = newstring[1:-1]
return Palind(s_remain)
Then actually call your function and deal with the result:
if Palind(newstring):
print ('Yes')
else:
print ('No')
That's how you print the result of your function..
You will have problems when you enter a palindrome though, because you never actually return true. You'll need to fix that by checking if you've gotten to the end of the string without returning false.
Your logic is roughly right, but you are missing some things.
The first character in a string is string[0] not string[1], so you are comparing the wrong characters.
You need to call Palind() as well as defining it.
If you correct those problems, you are taking one letter off each side of the string each time, it gets shorter and shorter - the next interesting thing that happens is you either get down to a single character or you run out of characters. You should be looking for that state.