Python Forum
Looping issue, stops working
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Looping issue, stops working
#1
The code will loop itself for around 5 minutes. That no functions will be running in the while loops and it loops 700+ it breaks and loops really fast and lags. It tries to run stuff but does not, might cause the lag I don't know. How do I fix this so it can loop and not break? I think it has to do with the pixelMatchesColor call. Less I have longer it runs?

Mose of the functions I'm making into modules but making it all in one place to get help. I'm new to python as well, trying my best.
from time import sleep
from random import uniform, randint
from pyautogui import pixelMatchesColor, keyDown, keyUp, moveRel, position, click, press

fail_safe = 0
shut_down = 0
on_off = 0
click_one = 1
click_two = 1
move_one = 1

def look(): #trys to see if a pixel im looking at is one of the 4 colors, moves my mouse x amount on what one it sees.
    first_cord, second_cord = position()  
    find_look_left_1 = pixelMatchesColor(first_cord, second_cord, (95, 95, 0), tolerance=20) 
    find_look_left_2 = pixelMatchesColor(first_cord, second_cord, (148, 148, 0), tolerance=30)
    find_look_right_1 = pixelMatchesColor(first_cord, second_cord, (0, 89, 0), tolerance=30)
    find_look_right_2 = pixelMatchesColor(first_cord, second_cord, (0, 45, 0), tolerance=30)
    find_look_hard_left_1 = pixelMatchesColor(first_cord, second_cord, (46, 0, 93), tolerance=20) 
    find_look_hard_left_2 = pixelMatchesColor(first_cord, second_cord, (36, 0, 72), tolerance=20)
    find_look_hard_right_1 = pixelMatchesColor(first_cord, second_cord, (178, 89, 0), tolerance=20)
    find_look_hard_right_2 = pixelMatchesColor(first_cord, second_cord, (197, 98, 0), tolerance=20)

    if find_look_left_1 or find_look_left_2:
        moveRel(-50,0, duration=0.17)
    elif find_look_right_1 or find_look_right_2:
        moveRel(40,0, duration=0.17)
    elif find_look_hard_left_1 or find_look_hard_left_2:
        moveRel(-110,0, duration=0.17)
    elif find_look_hard_right_1 or find_look_hard_right_2:
        moveRel(110,0, duration=0.17)
    else:
        return

def attack(): #trys to see if a pixel im looking attack has moves my mouse a lot or little of my mouse while clicking.
    global click_one
    global click_two
    look_chance = 60#%
    first_cord, second_cord = position()  
    attack_1 = pixelMatchesColor(first_cord, second_cord, (186, 112, 186), tolerance=20)
    attack_2 = pixelMatchesColor(first_cord, second_cord, (135, 81, 135), tolerance=30)

    if attack_1 or attack_2:
        chance = randint(1, 100)
        if chance <= look_chance:
            #print('Hit Chance ='+ str(chance))
            if click_two == 1: #look main
                click()
                moveRel(3,2, duration=0.1)
                click_two = 2
            else:
                if click_two == 2: #look back
                    click()
                    moveRel(-3,-2, duration=0.1)
                    click_two = 1
        elif click_one == 1: #big look main
            click()
            moveRel(-40,3, duration=0.17)
            click_one = 2
        else:
            if click_one == 2: #big look back
                click()
                moveRel(40,-3, duration=0.17)
                click_one = 1
    else:
        return

def move(): #trys to see if a pixel im looking at then has moves from side to side.
    global move_one
    move_chance = 50#%
    first_cord, second_cord = position()  
    find_move_1 = pixelMatchesColor(first_cord, second_cord, (169, 56, 93), tolerance=20)
    find_move_2 = pixelMatchesColor(first_cord, second_cord, (90, 18, 90), tolerance=30)
    find_move_3 = pixelMatchesColor(first_cord, second_cord, (203, 76, 127), tolerance=20)

    if find_move_1 or find_move_2 or find_move_3:
        chance = randint(1, 100)
        time_to_wait = uniform(0.12, 0.16)
        if chance <= move_chance:
            #print('Move Chance ='+ str(chance))
            if move_one == 1: #main move
                keyDown('a')
                press('backspace')
                sleep(time_to_wait)
                keyUp('a')
                move_one = 2
            elif move_one == 2:#move back
                keyDown('d')
                press('backspace')
                sleep(time_to_wait)
                keyUp('d')
                move_one = 1
    else:
        return

while fail_safe == 0:
    shut_down += 1
    print(shut_down)
    if shut_down > 669:
        fail_safe = 1
    first_cord, second_cord = position()
    #trys to see if a pixel im looking at is bad and stops it.
    bad_pixel = pixelMatchesColor(first_cord, second_cord, (0, 0, 0), tolerance=20)
    if bad_pixel:
        fail_safe = 1
        print('SS!')
    #trys to see if a pixel im looking at then toggles on and off.
    toggler = pixelMatchesColor(first_cord, second_cord, (37, 0, 18), tolerance=10)
    if toggler:
        if on_off == 0:
            on_off = 1
            print('Script toggled OFF!')
            sleep(2)
        elif on_off == 1:
            on_off = 0
            print('Script toggled back ON!')
            sleep(2)
    if on_off == 0:
        look()
        attack()
        move()
    
Reply
#2
Try profiling it (probably with less than 700 times, so it doesn't take too long): python -m cProfile -s tottime your_file_name.py
Reply
#3
(Apr-05-2018, 06:03 PM)nilamo Wrote: Try profiling it (probably with less than 700 times, so it doesn't take too long): python -m cProfile -s tottime your_file_name.py

101921 function calls (101457 primitive calls) in 300.688 seconds

or 5.01 Min

https://pastebin.com/uWUKEURD all the calls

The pixelMatchesColor is causing the issue. I took it out and it lasted 100x longer???

But I need it in for my script :(
Reply
#4
It looks like your guess was right, most of the slowdown is in constantly taking a screenshot. Specifically, the pixel() method is taking the most time, which is called by pixelMatchesColor(). Since it looks like you often use the same pixel, and compare it against several colors, I'd suggest starting with writing a custom pixelMatchesColor(), that you pass a pixel's color to, instead of x/y coordinates. That way you're only taking a single screenshot each time and comparing it against a handful of things, instead of taking a handful of screenshots.

Something along the lines of:
def pixelMatchesColor(color, matches, threshold=0):
    # should always be 3 or 4 (rbg, possibly with an alpha channel)
    for index in range(len(color)):
        if color[index]-threshold > matches[index]:
            # too high
            return False
        if color[index]+threshold < matches[index]:
            # too low
            return False
    return True

def look():
    first_cord, second_cord = position()  
    pixel_color = pyautogui.pixel(first_cord, second_cord)
    find_look_left_1 = pixelMatchesColor(pixel_color, (95, 95, 0), tolerance=20) 
    find_look_left_2 = pixelMatchesColor(pixel_color, (148, 148, 0), tolerance=30)
    find_look_right_1 = pixelMatchesColor(pixel_color, (0, 89, 0), tolerance=30)
    find_look_right_2 = pixelMatchesColor(pixel_color, (0, 45, 0), tolerance=30)
    find_look_hard_left_1 = pixelMatchesColor(pixel_color, (46, 0, 93), tolerance=20) 
    find_look_hard_left_2 = pixelMatchesColor(pixel_color, (36, 0, 72), tolerance=20)
    find_look_hard_right_1 = pixelMatchesColor(pixel_color, (178, 89, 0), tolerance=20)
    find_look_hard_right_2 = pixelMatchesColor(pixel_color, (197, 98, 0), tolerance=20)

    # then your code progresses as before
Reply
#5
(Apr-05-2018, 07:07 PM)nilamo Wrote: It looks like your guess was right, most of the slowdown is in constantly taking a screenshot. Specifically, the pixel() method is taking the most time, which is called by pixelMatchesColor(). Since it looks like you often use the same pixel, and compare it against several colors, I'd suggest starting with writing a custom pixelMatchesColor(), that you pass a pixel's color to, instead of x/y coordinates. That way you're only taking a single screenshot each time and comparing it against a handful of things, instead of taking a handful of screenshots.

Something along the lines of:
def pixelMatchesColor(color, matches, threshold=0):
    # should always be 3 or 4 (rbg, possibly with an alpha channel)
    for index in range(len(color)):
        if color[index]-threshold > matches[index]:
            # too high
            return False
        if color[index]+threshold < matches[index]:
            # too low
            return False
    return True

def look():
    first_cord, second_cord = position()  
    pixel_color = pyautogui.pixel(first_cord, second_cord)
    find_look_left_1 = pixelMatchesColor(pixel_color, (95, 95, 0), tolerance=20) 
    find_look_left_2 = pixelMatchesColor(pixel_color, (148, 148, 0), tolerance=30)
    find_look_right_1 = pixelMatchesColor(pixel_color, (0, 89, 0), tolerance=30)
    find_look_right_2 = pixelMatchesColor(pixel_color, (0, 45, 0), tolerance=30)
    find_look_hard_left_1 = pixelMatchesColor(pixel_color, (46, 0, 93), tolerance=20) 
    find_look_hard_left_2 = pixelMatchesColor(pixel_color, (36, 0, 72), tolerance=20)
    find_look_hard_right_1 = pixelMatchesColor(pixel_color, (178, 89, 0), tolerance=20)
    find_look_hard_right_2 = pixelMatchesColor(pixel_color, (197, 98, 0), tolerance=20)

    # then your code progresses as before

You are a god! Can you reply or PM me how you went about fixing this and finding out the issue so I can learn from it?
Reply
#6
You found it yourself, it's in your edit. You knew that that's the function that was taking time. Also, very near the top of the profile text you shared, was the pixel() call, with a cumulative time almost equal to the time spent in pixelMatchesColor(), meaning that pixelMatchesColor wasn't really slow, it was just waiting for pixel() the entire time.

So I looked up the docs for pyautogui, and it says that pixelMatchesColor is the same thing as pixel(), except that it then checks if the color fits within the passed color parameters. So instead of calling pixel() a lot, I juggled things around to call it just once, and check it's output several times.

I don't think there's any special secret for any of that. Maybe it just takes time programming to be able to have halfway right guesses on where you should start looking :p
Reply
#7
(Apr-05-2018, 08:01 PM)nilamo Wrote: You found it yourself, it's in your edit. You knew that that's the function that was taking time. Also, very near the top of the profile text you shared, was the pixel() call, with a cumulative time almost equal to the time spent in pixelMatchesColor(), meaning that pixelMatchesColor wasn't really slow, it was just waiting for pixel() the entire time.

So I looked up the docs for pyautogui, and it says that pixelMatchesColor is the same thing as pixel(), except that it then checks if the color fits within the passed color parameters. So instead of calling pixel() a lot, I juggled things around to call it just once, and check it's output several times.

I don't think there's any special secret for any of that. Maybe it just takes time programming to be able to have halfway right guesses on where you should start looking :p

Thanks, again I appreciate it. :D
Reply
#8
Quote:
def pixelMatchesColor(color, matches, threshold=0):
    pass

def look():
    pixel_color = pyautogui.pixel(first_cord, second_cord)
    find_look_left_1 = pixelMatchesColor(pixel_color, (95, 95, 0), tolerance=20) 

My mistake, I called it threshold, but you called it tolerance everywhere. You'll need to rename it in your function, since it's a keyword argument, or your tolerances will never be used.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pip stops waiting for python walker 6 970 Nov-28-2023, 06:55 PM
Last Post: walker
  [SOLVED] [Linux] Script in cron stops after first run in loop Winfried 2 894 Nov-16-2022, 07:58 PM
Last Post: Winfried
  Last caracter of a string truncated issue when working from the end of the string Teknohead23 3 1,560 Oct-03-2021, 01:08 PM
Last Post: snippsat
  Know when the pyttsx3 engine stops talking UsualCoder 3 3,142 Aug-29-2021, 11:08 PM
Last Post: snippsat
  IDLE stops responding upon saving tompi1 2 1,890 Oct-01-2020, 05:44 PM
Last Post: Larz60+
  Infinite Looping Issue nsadams87xx 1 1,352 Jun-15-2020, 12:13 AM
Last Post: SheeppOSU
  Python timer script stops before should ozstar 3 2,174 May-04-2020, 12:55 AM
Last Post: ozstar
  Python stops without errors shahgourav 4 2,706 Feb-04-2020, 11:44 PM
Last Post: micseydel
  looping and indentation issue ameydiwanji 3 2,396 Jul-01-2019, 10:53 AM
Last Post: perfringo
  First for loop stops after first iteration Divanova94 10 8,728 May-01-2019, 04:27 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020