pythonmultithreadingcookiestimer

a timer within a timer


hello and thank you in advance, i'm currently coding The Cookie Cutter game from 100 Days of Code by Angela Yu, the goal is to get as many clicks as possible within the span of 5 mins , while checking every 5 secs for the money (i called it "score") i've accumulated so i can purchase the highest available upgrade.

this is Angela's solution on Github: i found it to be long and unnecessarily complicated.

my code is a bit messy as it's still a work in progress.

what i've been meaning to do with my code is to iterate through a directory that contains the #id and price of upgrade, and as soon as it recognizes a match for a possible purchase it clicks on it.

import threading
import time
from collections import defaultdict

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from threading import Thread
from time import sleep
from datetime import datetime, timedelta

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("detach", True)

driver = webdriver.Chrome(options=chrome_options)
driver.get("https://orteil.dashnet.org/experiments/cookie/")
driver.maximize_window()

#######################ELEMENTS & CONVERTING TO LISTS\DICT#######################
cookie = driver.find_element(By.CSS_SELECTOR, '#cookie')
score = driver.find_element(By.CSS_SELECTOR, '#money')
scoreNum = int(score.text)
all_prices = driver.find_elements(By.CSS_SELECTOR, '#store b')
all_ids = driver.find_elements(By.CSS_SELECTOR, '#store div')
new_all_prices = []
new_all_ids = []
for new_id in all_ids:
    new_all_ids.append(new_id.get_attribute("id"))
for price in all_prices:
    a, b, c = price.text.partition('-')
    new_price = c.replace(" ", "")
    if c == "":
        pass
    else:
        new_all_prices.append(c.replace(" ", ""))

tuples = [(key, value)
          for i, (key, value) in enumerate(zip(new_all_prices, new_all_ids))]

myDict = dict(tuples)

#######################FUNCTIONS#######################


def five_seconds_check():
    for key, value in myDict.items():
        if scoreNum >= key:
            my_clickable_purchase = driver.find_element(By.CSS_SELECTOR, f'{myDict[key]}')
            my_clickable_purchase.click()


timeout = time.time() + 5
five_min = time.time() + 60 * 5  # 5 minutes

while True:
    cookie.click()
    if time.time() > timeout:
        five_seconds_check()
    elif time.time() > five_min:
        break

#########################CLOSING BROWSER#########################
time.sleep(5)
driver.close()

the part i'm struggling with is how to write a timer within a timer - meaning, how do i get the overall while loop to run for 5 mins, and simultaneously check the money\purchase upgrade every 5 secs.


Solution

  • in case anyone is struggling with the same challenge or just wants to have a look - this is the final result after i've gotten some input and made more alterations to the overall code, as there were several things wrong with it except for the while loop.

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_experimental_option("detach", True)
    
    driver = webdriver.Chrome(options=chrome_options)
    driver.get("https://orteil.dashnet.org/experiments/cookie/")
    driver.maximize_window()
    
    #######################ELEMENTS & CONVERTING TO LISTS\DICT#######################
    cookie = driver.find_element(By.CSS_SELECTOR, '#cookie')
    all_prices = driver.find_elements(By.CSS_SELECTOR, '#store b')
    all_ids = driver.find_elements(By.CSS_SELECTOR, '#store div')
    new_all_prices = []
    new_all_ids = []
    for new_id in all_ids:
        new_all_ids.append(new_id.get_attribute("id"))
    for price in all_prices:
        a, b, c = price.text.partition('-')
        new_price = c.replace(" ", "")
        if c == "":
            pass
        else:
            new_all_prices.append(int(c.replace(" ", "").replace(",", "")))
    
    tuples = [(key, value)
              for i, (key, value) in enumerate(zip(new_all_prices, new_all_ids))]
    
    
    #######################FUNCTIONS#######################
    
    def five_seconds_check():
        for key, value in myDict.items():
            score = driver.find_element(By.CSS_SELECTOR, '#money')
            scoreNum = int(score.text.replace(",", ""))
            if scoreNum >= key:
                my_clickable_purchase = driver.find_element(By.CSS_SELECTOR, f'#{value}')
                my_clickable_purchase.click()
                break
    
    
    myDict = dict(tuples.__reversed__())
    
    start_time = time.time()
    timeout = start_time + 5
    five_min = start_time + (60 * 5)  # 5 minutes
    
    while time.time() < five_min:
        cookie.click()
        if time.time() >= timeout:
            five_seconds_check()
            timeout = time.time() + 5
    
    #########################CLOSING BROWSER#########################
    time.sleep(5)
    driver.close()