11

I have a a user-inputted polynomial and I only want to use it if it only has characters in the string 1234567890^-+x.

How can I check if it does or not without using external packages? I only want to use built-in Python 2.5 functions.

I am writing a program that runs on any Mac without needing external packages.

0

6 Answers 6

18

Here are some odd ;-) ways to do it:

good = set('1234567890^-+x')

if set(input_string) <= good:
    # it's good
else:
    # it's bad

or

if input_string.strip('1234567890^-+x'):
    # it's bad!
else:
    # it's good
Sign up to request clarification or add additional context in comments.

6 Comments

I love the set subset approach :-) Care to take a timeit potshot at it?
@MartijnPieters, not a chance - there are sooooo many ways to do this I don't want to spend half an hour organizing them all ;-)
@user2357112, just because I can never remember what .issuperset() does, exactly, without looking it up :-( But I understand <= at once, and as Martijn says, they're the same thing in the end. .issuperset() is likely slower due to the method lookup expense.
@MartijnPieters, sure, but with the method spellings I can never remember which one is <= and which >= without looking it up. So I avoid them. <= and >= are obvious to me.
@MartijnPieters: issuperset would... wait, apparently it doesn't short-circuit. I thought it would do the test without building a set from the input_string, but when I tried {0}.issuperset(xrange(1000000000)) a few seconds ago, it started eating memory in a way that seems to indicate it turns the input into a set. I guess there's no performance advantage.
|
10

Use a regular expression:

import re

if re.match('^[-0-9^+x]*$', text):
    # Valid input

The re module comes with Python 2.5, and is your fastest option.

Demo:

>>> re.match('^[-0-9^+x]*$', '1x2^4-2')
<_sre.SRE_Match object at 0x10f0b6780>

Comments

4

What about just convert both the string into set and checking input_set is subset of good_set as below:

>>> good_set = set('1234567890^-+x')
>>> input_set1 = set('xajfb123')
>>> input_set2 = set('122-32+x')
>>> input_set1.issubset(good_set)
False
>>> input_set2.issubset(good_set)
True
>>>

Comments

4
  1. You can convert the valid chars to a set, as sets offer faster lookup
  2. Then you can use all function like this

    valid_chars = set("1234567890^-+x")  # Converting to a set
    if all(char in valid_chars for char in input_string):
        # Do stuff if input is valid
    
  3. We can convert the input string also a set and check if all characters in the inputstring is in the valid list.

    valid_chars = set("1234567890^-+x")  # Converting to a set
    if set(input_string).issubset(valid_chars):
        # Do stuff if input is valid
    

6 Comments

Sets have an issuperset method for this.
@user2357112 Please check my answer now, I have used issubset
That's not the syntax for turning a string into a set; you want set("1234567890^-+x"). (Why did I see the other thing first?)
@user2357112 That's called set comprehension.
No, it's not. It's a set literal with 1 element.
|
1

Yet another way to do it, now using string.translate():

>>> import string
>>> all_chars = string.maketrans('', '')
>>> has_only = lambda s, valid_chars: not s.translate(all_chars, valid_chars)
>>> has_only("abc", "1234567890^-+x.")
False
>>> has_only("x^2", "1234567890^-+x.")
True

It is not the most readable way. It should be one of the fastest if you need it.

2 Comments

You can pass as None as the first argument to translate() instead.
Does anyone even have a Python 2.5 anymore to check? LOL ;-) It works in all current Pythons :-)
0
whitelist = '1234567890^-+x'

str = 'x^2+2x+1'
min([ch in whitelist for ch in str])
True


str='x**2 + 1' 
min([ch in whitelist for ch in str])
False

2 Comments

min() is hardly the best function for this task.
Agree that all would be the best choice. Hangover from other languages.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.