1

I searched and found ways to check the type of an object but that will not help me in this case. I need to find out if a string CAN be changed to an Integer before actually doing it. I am using pyautogui to grab a region of the screen and save it, then pytesseract open the image, read it, and convert it into a string. Ultimately it is an equation that I would like to solve so then I must change the string into an integer (done in my second function below). At times pytesseract does not read the image correctly so instead of saying something like 5 + 4 it ends up with something like 5 - H, so when my code attempts to turn H into an integer it crashes.

My Question: How can I check to see if for example equation[0] can be made an integer before actually running int(equation[0]) on it and causing my script to crash?

My Code: Simplified greatly to only show the needed lines:

from PIL import Image
import PIL.ImageOps
import pytesseract
import pyautogui
import sys
import time

# --- functions ---

def get_text(image):
    return pytesseract.image_to_string(image, config='-psm 6')

def get_int(image):
    return int(get_text(image).replace(',', ''))

# --- main ---

     #Is equation= needed below or can it be removed?
equation = pyautogui.screenshot('equation.png',region=(845, 262, 240, 85))
img = Image.open('equation.png')
equation = get_text(img)
print ('Equation:',equation)

#Numbers are always single digit (ex. 9-7=) Use slicing to pull numbers and symbol
firstnum = int(equation[0])
sign = equation[1]
secondnum = int(equation[2])

#Adition and Subtraction are the only options
if sign == '-':
    answer = firstnum - secondnum
if sign =="+":
    answer = firstnum + secondnum

EDIT: Try and Except seems to be a good way to handle this. Can I somehow turn this into a loop though so it can be checked multiple times. I have found someone used while true as a loop and put try except inside, I am not sure if is will work for me though? Here is how I THINK my Try Except should look? If possible I would like to loop the try until it does not hit an exception.

try:
    firstnum = int(equation[0])
except:
    equation = pyautogui.screenshot('equation.png',region=(845, 262, 240, 85))
    img = Image.open('equation.png')
    equation = get_text(img)
    firstnum = int(equation[0])
8
  • 5
    Do you know how to use try? You should try to parse it, then catch the exception if it fails. (One of) Python's motto(s) is "it's easier to ask for forgiveness than permission". Let it fail, then clean it up if it does. I'd make that an answer, but my breaks almost over. Commented Mar 20, 2017 at 19:37
  • The type of the object isn't a help if it's a string. Commented Mar 20, 2017 at 19:39
  • Possible duplicate of Python: Convert a string to an integer Commented Mar 20, 2017 at 19:41
  • 1
    Use exception handling... Commented Mar 20, 2017 at 19:42
  • 2
    Something doesn't make sense here. Look at equation = pyautogui.screenshot('equation.png',region=(845, 262, 240, 85)) and that is never used, then equation = get_text(img). So it's redefined. Are you sure you're trying to index the right thing? Commented Mar 20, 2017 at 19:53

2 Answers 2

3

First of all, the check is simple if this is a single digit:

if equation[0] in "0123456789":
    firstnum = int(equation[0])

The actual checking function for full-string integer-ness is isdigit.

if equation[0].isdigit():
    firstnum = int(equation[0])

Another possibility is to catch the exception:

try:
    firstnum = int(equation[0])
except ... # you now have enough info to look this up.

Solution to Looping Problem

See here for one example of how to code those loops in general.

In your specific case, you will want to use only the statements needed to get a different result from get_text. Does taking a new screen shot really give you a different result? Does anything change the result? Are you guaranteed that you will eventually get a digit? If not, then you also need a break-out clause, such as giving up after seven failed attempts.

The new code would look something like the code below. Please change your variables to meaningful names. Most of all, using equation everywhere you can really hurts your program's readability.

... 
scan_result = get_text(img)
dgt = scan_result[0]
fail_count = 0
while not dgt.isdigit() and fail_count < 7:
    fail_count += 1
    pyautogui.screenshot('equation.png',region=(845, 262, 240, 85))
    img = Image.open('equation.png')
    scan_result = get_text(img)
    dgt = scan_result[0]

if fail_count >= 7:
    print ("I can't read that number")
else:
    num1 = int(dgt)

Also, note that you might want to extract both digits, and run this in a loop over the two separate digits you find. Can you manage that part on your own now? Something like:

digits = scan_result[0] + scan_result[-1]
for dgt in digits:
    ...
Sign up to request clarification or add additional context in comments.

11 Comments

Wouldn't you need all(isdigit,...)? Doesn't isdigit accept a single char?
@Carcigenicate: No, it operates on the entire string.
Good point ... but the application has only single-digit numbers.
Something doesn't make sense with the initial code. Look at equation = pyautogui.screenshot('equation.png',region=(845, 262, 240, 85)) and that is never used, then equation = get_text(img). So it's redefined.
@roganjosh: Please move the above comment to the main question. You're correct, so OP (and everyone else) should have it in the main section, not hidden under my answer.
|
1

You should try then except.

But if you really want to catch it ahead of time, consider a regex. \d is equivalent to [0-9], so numbers can be matched as [-+]?\d+.

If numbers are always a single digit, just use x in "0123456789"

5 Comments

Could I somehow turn try and accept into a loop? So that it can be checked multiple times? Editing my main question now to throw out there what I mean.
It depends what you want to do on a failure. I assume that pyautogui.screenshot is not a randomized algorithm and so I'd assume that if it fails once, it'll always fail.
I have checked the output of the pyautogui file and I can clearly read the equation myself. It is an issue with pytesseract reading it, so my thought was to just take a new fresh image with pyautogui and let pytesseract read it again.
I would assume that it reads each picture the same way every time. Maybe you can train it or tell it that it should only attempt to read certain characters
That is a really good thought. I had a really hard time finding any info on pytesseract.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.