I'm currently writing a program that is attempting to synchronize a visitor, car, pump, and gas station thread at a zoo where guests arrive, wait for an available car, take a tour, then exit, the cars must refuel every 5 rides, and the gas station must refuel every time 3 cars are refilled. My tests are with 35 visitors, 6 cars, 5 gas pumps, and a time interval of 2. The program reads a text file with the number of guests, cars, pumps, and a time interval between visitors boarding vehicles, then uses the data to fill a class. I create methods for each thread, then create the threads themselves in main. My problem is that my program gets stuck at 6 vehicles, which is the number specified by the text file, after running my first thread method, visitor_thread, and I cannot tell if any other threads are even running concurrently. I am a total novice at multithreading and python alike, and I'm not sure what the problem is. I have worked on the project for twelve hours straight and have been stuck at this point for the past four hours. In theory, visitor_thread, car_thread, and gas_station_thread should all run concurrently from main, and visitor_thread should have vehicles to work with again after some visitors finish their ride, but I just get stuck with six full cars in an infinite loop within visitor_thread. What is causing this infinite loop and how can I make sure all of my threads are actually running?
My code:
from threading import Thread
from threading import Lock
from threading import Event
event = Event()
lock = Lock()
done = Event()
is_done = 0
class Arguments:
def __init__(self, m_visitors, n_cars, k_pumps, t_time, thread_num, _done):
self.m_visitors = m_visitors
self.n_cars = n_cars
self.k_pumps = k_pumps
self.t_time = t_time
self.thread_num = thread_num
self.done = _done
class Car:
def __init__(self, control, rides, time, in_service, int_cus, in_queue):
self.control = control
self.rides = rides
self.time = time
self.in_service = in_service
self.int_cus = int_cus
self.in_queue = in_queue
class Pump:
def __init__(self, control, in_use, car_num, time):
self.control = control
self.in_use = in_use
self.car_num = car_num
self.time = time
class PumpQueue:
def __init__(self, pQueue, MAXsize, front, back, size):
self.q = Lock()
self.pQueue = pQueue
self.MAXsize = MAXsize
self.front = front
self.back = back
self.size = size
def visitor_thread(_visitor):
global is_done
visitor = _visitor
v = visitor.m_visitors
c = visitor.n_cars
p = visitor.k_pumps
t = visitor.t_time
id = visitor.thread_num
i = 0
j = 0
while i < v:
for j in range(0, c):
lock.acquire()
if cars[j].in_service is False and cars[j].rides < 5:
print('\nVisitor %d is currently in car %d' % (i+1, j+1))
cars[j].in_service = True
i += 1
print('\n%d customers waiting for a ride.' % (v - i))
lock.release()
break
lock.release()
lock.acquire()
is_done += 1
lock.release()
def car_thread(_car):
global is_done
carThread = _car
cars_done = 0
v = carThread.m_visitors
c = carThread.n_cars
p = carThread.k_pumps
t = carThread.t_time
id = carThread.thread_num
i = 0
while cars_done == 0:
cars_in_service = 0
while i < c:
lock.acquire()
if cars[i].in_service is True and cars[i].rides < 5:
# Car still being used, add more time
cars[i].time += 1
if cars[i].time == t:
cars[i].in_service = False
cars[i].rides += 1
cars[i].time = 0
if cars[i].rides == 5 and cars[i].in_queue is False:
push(i)
cars[i].in_queue = True
if cars[i].in_service is False:
cars_in_service += 1
i += 1
lock.release()
if cars_in_service == c and is_done >= 1:
cars_done = 1
lock.acquire()
is_done += 1
lock.release()
def gas_station_thread(_gas_station):
global is_done
gas_station = _gas_station
truck = False
cars_filled = 0
v = gas_station.m_visitors
c = gas_station.n_cars
p = gas_station.k_pumps
t = gas_station.t_time
id = gas_station.thread_num
gas_done = 0
pumps_in_service = 0
j = 0
while gas_done == 0:
while j < p:
lock.acquire()
if pumps[j].in_use is True:
pumps[j].time += 1
if pumps[j].time == 3:
lock.acquire()
cars[j].in_service = 0
cars[j].rides = 0
cars[j].time = 0
cars[j].in_queue = False
lock.release()
pumps[j].time = 0
pumps[j].in_use = False
cars_filled += 1
pumps_in_service -= 1
if truck is True and pumps[j].in_use is False:
truck = False
print('Fuel Truck is currently filling up the gas station.')
elif pumps[j].in_use is True and pump_line.size > 0:
pumps_in_service += 1
pumps[j].in_use = True
pumps[j].car_num.pop()
print('Car %d, pump %d' % (pumps[j].car_num + 1, i + 1))
pumps[j].time = 0
j += 1
lock.release()
if cars_filled > 3:
print('The Fuel Truck is on its way')
truck = True
cars_filled = 0
if pumps_in_service == 0 and is_done == 2:
gas_done = True
lock.acquire()
is_done += 1
lock.release()
def pop():
lock.acquire()
fr = pump_line.front
f = pump_line.pQueue[fr]
print("\n%d cars are waiting for pumps" % int(pump_line.size - 1))
if fr < (pump_line.MAXsize - 1):
pump_line.front += 1
else:
pump_line.front = 0
lock.release()
return f
def push(_c):
c =_c
lock.acquire()
b = pump_line.back
pump_line.pQueue[b] = c
print("\n%d cars are waiting for pumps" % int(pump_line.size + 1))
if b < (pump_line.MAXsize - 1):
pump_line.back += 1
else:
pump_line.back = 0
lock.release()
def isEmpty():
lock.acquire()
if (pump_line.front == pump_line.back):
boolean = True
else:
boolean = False
lock.release()
return boolean
if __name__ == "__main__":
arguments = Arguments(0, 0, 0, 0, 0, False)
main = Arguments(0, 0, 0, 0, 0, False)
thread = []
round_number = 0
io_control = 0
input_file = []
number_of_threads = 3
print("Enter the name of the text file to use as input:")
while io_control == 0:
try:
filename = input()
input_file = open(filename)
io_control = 1
except IOError:
print("Specified file does not exist, enter a different text file:")
# parse file into lines, separating by endlines
file_lines = []
num_lines = 0
for line in input_file:
line = line.replace(",", " ")
line = line.split()
num_lines += 1
if line:
line = [int(i) for i in line]
file_lines.append(line)
while main.done is False and round_number < num_lines:
main.m_visitors = int(file_lines[round_number][0])
main.n_cars = int(file_lines[round_number][1])
main.k_pumps = int(file_lines[round_number][2])
main.t_time = int(file_lines[round_number][3])
print("\nRound Number: %d" % (round_number + 1))
if main.n_cars == 0:
print('No data to read in this round, press enter to continue:')
input()
print("Number of Visitors: %d" % main.m_visitors)
print("Number of Cars: %d" % main.n_cars)
print("Number of Pumps: %d" % main.k_pumps)
print("Units of Time: %d" % main.t_time)
M = main.m_visitors
N = main.n_cars
K = main.k_pumps
T = main.t_time
thread_info = []
cars = []
pumps = []
for i in range(0, 3):
temp = Arguments(M, N, K, T, i, False)
thread_info.append(temp)
for i in range(0, N):
temp = Car(0, 0, 0, False, 0, False)
cars.append(temp)
for i in range(0, K):
temp = Pump(0, False, 0, 0)
pumps.append(temp)
pump_line = PumpQueue(0, 0, 0, 0, N)
visitorThread = Thread(target=visitor_thread, args=(thread_info[0],))
thread.append(visitorThread)
carsThread = Thread(target=car_thread, args=(thread_info[1],))
thread.append(carsThread)
gasThread = Thread(target=gas_station_thread, args=(thread_info[2],))
thread.append(gasThread)
visitorThread.start()
carsThread.start()
gasThread.start()
visitorThread.join()
carsThread.join()
gasThread.join()
round_number += 1
My output:
Round Number: 1 Number of Visitors: 35 Number of Cars: 6 Number of
Pumps: 5 Units of Time: 2
Visitor 1 is currently in car 1
34 customers waiting for a ride.
Visitor 2 is currently in car 2
33 customers waiting for a ride.
Visitor 3 is currently in car 3
32 customers waiting for a ride.
Visitor 4 is currently in car 4
31 customers waiting for a ride.
Visitor 5 is currently in car 5
30 customers waiting for a ride.
Visitor 6 is currently in car 6
29 customers waiting for a ride.
I think there's an index problem here:
if cars[j].in_service is False and cars[i].rides < 5:
should be
if cars[j].in_service is False and cars[j].rides < 5:
Index for cars is j not i
Related
I'm trying solve N Puzzle with Depth First Search using python 3.
With 3 x 3 puzzle it run good and fast but with 4 x 4 puzzle, it runs too slow and can't find solution with error: "MemoryError".
I also use "h(n) = depth + number of wrong tiles" to evaluate priority of each node.
I'm a newbie to python so hope you can help me with this
Here is my code:
import sys
import getopt
import random
import time
class State:
def __init__(self, parent, board, move, depth):
self.parent = parent
self.previousMove = move
self.board = board
self.map = ''.join(str(e) for e in board)
self.depth = depth
self.cost = self.calculateCost()
def calculateCost(self):
pos = 1
count = 0
for tile in self.board:
if tile == pos:
count += 1
pos += 1
return self.depth + 8 - count
class Puzzle:
def __init__(self, k, customBoard = None):
self.k = k
self.n = k*k - 1
self.sizeOfBoard = k*k
self.timeOfSolving = 0
self.timeOfGenerateSuccessors = 0
self.maxDeepSearch = 0
self.inititalState = State(None, self.createInitialBoard(customBoard), 'Start', 0)
self.goalBoard = self.createGoalBoard()
self.finalState = None
self.stateStorage = set() # Store states that have visited
self.path = [] # Store states that lead to goalstate
self.stack = []
def isSolvable(self, board):
# count invertion in puzzle's board
invCount = 0
for i in range(0, self.sizeOfBoard - 1):
if board[i] == 0:
continue
for j in range(i+1, self.sizeOfBoard):
if board[j] == 0:
continue
if board[i] > board[j]:
invCount += 1
# print(invCount)
if (invCount % 2 == 0):
return True
return False
def createInitialBoard(self, customBoard):
print("Creating initial state")
if customBoard is None:
board = []
lstAddSuccess = []
while 1:
board.clear()
lstAddSuccess.clear()
for count in range(0, self.k*self.k):
newTile = random.randint(0, self.n)
while newTile in lstAddSuccess:
newTile = random.randint(0, self.n)
lstAddSuccess += [newTile]
board += [newTile]
if self.isSolvable(board):
break
else:
board = [int(e) for e in customBoard]
if not self.isSolvable(board):
print("Cant find solution with this puzzle! Exiting...")
exit(-1)
return board
def createGoalBoard(self):
board = []
for count in range(1, self.n + 1):
board += [count]
board += [0]
return board
def printBoard(self, board):
for row in range(0, self.sizeOfBoard, self.k):
# for col in range(row, row + self.k):
print(board[row:row + self.k])
def generateSuccessors(self, currentState):
indexOfZero = currentState.board.index(0)
rowIndexOfZero = indexOfZero % self.k
colIndexOfZero = indexOfZero // self.k
lstSuccessors = []
# Slide to zero to up
if colIndexOfZero != 0:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero - self.k]
newState[indexOfZero - self.k] = 0
lstSuccessors.append(
State(currentState, newState, 'up', currentState.depth + 1))
# Slide zero to down
if colIndexOfZero != self.k - 1:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero + self.k]
newState[indexOfZero + self.k] = 0
lstSuccessors.append(
State(currentState, newState, 'down', currentState.depth + 1))
# slide zero to left
if rowIndexOfZero != 0:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero - 1]
newState[indexOfZero - 1] = 0
lstSuccessors.append(
State(currentState, newState, 'left', currentState.depth + 1))
# Slide zero to right
if rowIndexOfZero != self.k - 1:
newState = currentState.board.copy()
newState[indexOfZero] = newState[indexOfZero + 1]
newState[indexOfZero + 1] = 0
lstSuccessors.append(
State(currentState, newState, 'right', currentState.depth + 1))
lstSuccessorsCost = [ele.cost for ele in lstSuccessors]
lstSuccessorsInOrderOfCost = []
for i in range(0, len(lstSuccessorsCost)):
lstSuccessorsInOrderOfCost.append(lstSuccessors[lstSuccessorsCost.index(min(lstSuccessorsCost))])
lstSuccessorsCost[lstSuccessorsCost.index(min(lstSuccessorsCost))] = 100
return lstSuccessorsInOrderOfCost
def solvePuzzle(self, currentState):
self.stack.append(currentState)
self.stateStorage.add(currentState.map)
while len(self.stack) > 0:
currentState = self.stack.pop()
if currentState.board == self.goalBoard:
# find path
# self.printBoard(currentState.board)
self.finalState = currentState
print("Solving " + str(self.n) + " puzzle done!")
return
start_time_gen = time.time()
lstSuccessor = self.generateSuccessors(currentState)
end_time_gen = time.time()
timeOfGen = end_time_gen - start_time_gen
self.timeOfGenerateSuccessors += timeOfGen
for successor in lstSuccessor[::-1]:
if successor.map not in self.stateStorage:
self.stack.append(successor)
self.stateStorage.add(successor.map)
if successor.depth > self.maxDeepSearch:
self.maxDeepSearch += 1
print("Cant solve puzzle! Exiting...")
exit(-1)
def solve(self):
start_time = time.time()
self.solvePuzzle(self.inititalState)
end_time = time.time()
self.timeOfSolving = end_time - start_time
print("Running time: " + str(self.timeOfSolving))
print("Max Search Dept: " + str(self.maxDeepSearch))
print("Final State Dept: " + str(self.finalState.depth))
def printInitialBoard(self):
self.printBoard(self.inititalState.board)
def printPath(self):
if self.finalState is None:
print("No solution found!")
return
path = []
state = self.finalState
while (state is not None):
if state.previousMove is not None:
path.append(state.previousMove)
state = state.parent
print("path: "),
print(path[::-1])
def main(argv):
# if (len(argv) != 1 or int(argv[0]) not in range(1, 10000)):
# print("Input must be k of integer, which is k*k matrix of puzzle")
# exit()
# eight_puzzle = Puzzle(int(argv[0]))
k = int(input("Enter size of k * k puzzle, k = "))
while k not in range(2, 100):
print("k must be in range 2 - 100")
k = int(input("Enter size of k * k puzzle, k = "))
print("""
Choose:
1. Randome puzzle
2. Custome puzzle
""")
file = input()
if int(file) == 1:
puzzle = Puzzle(k)
elif int(file) == 2:
board = input("Enter puzzle: ")
puzzle = Puzzle(k ,list(board.split(" ")))
puzzle.printInitialBoard()
puzzle.solve()
puzzle.printPath()
if __name__ == "__main__":
main(sys.argv[1:])
A similar question was asked earlier but it didn't provide the correct answer.
I am trying to code to test threading in Python in which a ticker ticks every second. I am trying to keep the ticker function named 'clicking' running in a thread whose output is continously being incremented by one every second.
import time
import threading
import queue
q = queue.Queue()
apple = 0
orange = 0
rate = 1
clix = 0
def clicking(clix, rate):
while True:
time.sleep(1)
clix += rate
q.put(clix)
threading.Thread(target=clicking, args=(clix, rate)).start()
curr = q.get()
print(curr)
print('\nClicker Starting...')
endgame = False
while not endgame:
print(f'Clix: {curr}')
print('1. Apple : 10 clix | 2. Orange : 8 clix | 3. Exit')
ch = int(input('\nPurchase ID: '))
if ch == 1 and curr >= 10:
print(f'You have {curr} clix.')
print('Got an Apple!')
apple += 1
rate += 1.1
curr -= 10
elif ch == 2 and curr >= 8:
print('Got an Orange!')
orange += 1
rate += 1.2
curr -= 8
elif ch == 3:
endgame = True
stopflag = True
else:
print('Need more Clix')
But my otuput is always 1 instead of incrementing every second by defined rate. What am I missing? I even tried return clix in place of q.put(clix) but didn't work.
the problem is that you are not updating the curr variable inside the while loop. But do notice that when you write "curr = q.get()" inside the while loop it will get the next value in the queue and not the last value (as I suppose you intend). I guess a more straightforward approach is to keep track on the seconds increment inside your while loop using time.time()
import time
apple = 0
orange = 0
rate = 1
clix = 0
curr = 0
last_ts = time.time()
print('\nClicker Starting...')
endgame = False
while not endgame:
ts = time.time()
curr += (ts - last_ts) * rate
last_ts = ts
print(f'Clix: {curr:.0f}')
print('1. Apple : 10 clix | 2. Orange : 8 clix | 3. Exit')
ch = int(input('\nPurchase ID: '))
if ch == 1 and curr >= 10:
print(f'You have {curr:.0f} clix.')
print('Got an Apple!')
apple += 1
rate *= 1.1 # I guess you meant x1.1
curr -= 10
elif ch == 2 and curr >= 8:
print('Got an Orange!')
orange += 1
rate *= 1.2 # I guess you meant x1.2
curr -= 8
elif ch == 3:
endgame = True
stopflag = True
else:
print('Need more Clix')
this way you can exit properly also, notice that on your example even when the loop breaks the thread continues.
but in case you want to maintain a background thread, I suggest creating a class and storing class variables for the current counter and run condition.
I have a Q-Learning program trying to predict my stock simulated stock market where the price of the stock goes 1-2-3-1-2-3...
I have been trying to debug this for a few days and just can't get it. I even completely started from scratch and the problem persists. If you have extra time, I just need an extra set of eyes on this.
The getStock() function is what simulates the stock price.
The reducePricesToBinary() function takes the stocks and makes it into an put of [Whether the stock went up or down last, how many times it went down/up in a row, how many times the stock went up/down in a row]
The readAI() function just reads what should happen given the inputs
The checkGuess() function checks the previous guess and changes the policyGradient based on whether or not it was right.
Thank you so much!
import requests
import sys
import time
# Constants
learningRate = 0.5
stocksToBuy = 250
discountFactor = 0.5
# Variables declared:
# getStock()
currentStockPrice = 0
pastStockPrice = 0
# reducePricesToBinary()
binaryVersionOfPrices = ""
# Ai()
AI = dict()
# convertBinaryToInputs()
inputsForAI = [0,0,0]
# Ai
guess = 0
oldGuess = 0
reward = 0
pastInputsForAI = ['0',0,0]
firstTurnOver = False
# Buying and Selling stocks
money = 1000000
shares = 0
#
countToSaveEveryFifteen = 0
# Saving anything to a file.
def save(name, data):
with open(name, 'w') as f:
f.write(str(data))
def saveEverything():
save("AI", AI)
save("binaryStockPrices", binaryVersionOfPrices)
save("money", money)
save("shares", shares)
# Runs after an error.
def onExit():
saveEverything()
sys.exit()
# Prints and saves an error log if a function crashes.
def crashProgram(errorMessage):
print(errorMessage)
with open("crashLogs", 'w') as f:
f.write("{}\n\n".format(errorMessage))
onExit()
# Runs a function with try catches to catch an error.
def doFunction(function):
try:
function()
except Exception, e:
crashProgram("Fatal error running {}().\n{}".format(function.__name__, e))
# Gets the current stock value.
#def getStock():
# global currentStockPrice
# res = requests.get("https://markets.businessinsider.com/stocks/aapl-stock")
# stockCostString = ""
# for x in range (9):
# stockCostString += res.text[res.text.find('"price": "')+10 + x]
# currentStockPrice = float(stockCostString)
# print(currentStockPrice)
def getStock():
global currentStockPrice
currentStockPrice = 1 if currentStockPrice == 3 else (2 if currentStockPrice == 1 else 3)
# Turns the prices into 0's and 1's.
def reducePricesToBinary():
global pastStockPrice
global binaryVersionOfPrices
binaryString = "1" if currentStockPrice > pastStockPrice else "0" if currentStockPrice < pastStockPrice else ""
binaryVersionOfPrices += binaryString
pastStockPrice = currentStockPrice
# Converts the binaryStockPrices to inputs for the AI.
def convertBinaryToInputs():
global inputsForAI
inputsForAI[0] = binaryVersionOfPrices[len(binaryVersionOfPrices)-1]
counterOfFirstNumber = 1
counterOfSecondNumber = 1
while(binaryVersionOfPrices[len(binaryVersionOfPrices) - counterOfFirstNumber] == inputsForAI[0]):
counterOfFirstNumber+=1
counterOfFirstNumber-=1
while(binaryVersionOfPrices[len(binaryVersionOfPrices) - counterOfFirstNumber - counterOfSecondNumber]!=inputsForAI[0]):
counterOfSecondNumber += 1
counterOfSecondNumber-=1
inputsForAI[0] = binaryVersionOfPrices[len(binaryVersionOfPrices)-1]
inputsForAI[1] = counterOfFirstNumber
inputsForAI[2] = counterOfSecondNumber
# AI functions
def readAI():
global guess
try:
AIGuess = AI[inputsForAI[0], inputsForAI[1], inputsForAI[2]]
except:
AI[inputsForAI[0], inputsForAI[1], inputsForAI[2]] = 0.5
AIGuess = 0.5
guess = AIGuess
print("GUESS: {}".format(guess))
print("INPUTS: {}".format(inputsForAI))
return guess
def checkGuess():
global firstTurnOver
if(firstTurnOver):
global oldGuess
global reward
global pastInputsForAI
oldGuess = 0 if oldGuess == -1 else 1
print("Old guess: " + str(oldGuess) + " Input: " + str(int(round(float(inputsForAI[0])))))
reward = 1 if oldGuess == int(round(float(inputsForAI[0]))) else -1
AI[pastInputsForAI[0], pastInputsForAI[1], pastInputsForAI[2]] = (1-learningRate) * AI[pastInputsForAI[0], pastInputsForAI[1], pastInputsForAI[2]] + learningRate * (reward + discountFactor * 1)
oldGuess = int(round(float(guess)))
pastInputsForAI = inputsForAI
firstTurnOver = True
def buySellStocks():
global money
global shares
oldStocks = shares
if(guess > 0):
while(money > currentStockPrice and (shares - oldStocks) < stocksToBuy * guess):
money -= currentStockPrice
shares += 1
else:
while(shares > 0 and (oldStocks - shares) > stocksToBuy * guess):
money += currentStockPrice
shares -= 1
# Loads the binaryVersionOfPrices from a file.
def loadBinaryPrices():
global binaryVersionOfPrices
with open("binaryStockPrices", 'r') as f:
binaryVersionOfPrices = f.read()
def loadMoney():
global money
with open("money", 'r') as f:
money = int(f.read())
def loadShares():
global shares
with open("shares", 'r') as f:
shares = int(f.read())
# Loads the AI from a file.
def loadAI():
global AI
with open("AI", 'r') as f:
AI = eval(f.read())
#Prints relative information
def printStuff():
print("Stock price: {}\nCurrent balance: {}\nCurrent shares: {}\nTotal value: {}\nGuess: {}\n".format(currentStockPrice, money, shares, money + shares * currentStockPrice, guess))
# Loads all variables from files.
def onProgramStart():
doFunction(loadAI)
doFunction(loadBinaryPrices)
doFunction(loadMoney)
doFunction(loadShares)
# Saves every 15 checks
def saveEveryFifteen():
global countToSaveEveryFifteen
countToSaveEveryFifteen += 1
if(countToSaveEveryFifteen == 15):
saveEverything()
countToSaveEveryFifteen = 0
# Runs all functions.
def doAllFunctions():
doFunction(reducePricesToBinary)
doFunction(convertBinaryToInputs)
doFunction(readAI)
doFunction(checkGuess)
doFunction(buySellStocks)
doFunction(saveEveryFifteen)
doFunction(printStuff)
doFunction(getStock)
# Loads variables from files.
onProgramStart()
# Repeats the process.
while(1):
doAllFunctions()
time.sleep(0.5)
As I mentioned in my comment, here is a version of the program after some basic refactoring:
import sys
import time
# constants
learning_rate: float = 0.5
stocks_to_buy: float = 250
discount_factor: float = 0.5
# variables declared:
# get_stock()
current_stock_price: int = 0
past_stock_price: int = 0
# reduce_prices_to_binary()
binary_version_of_prices: str = ''
# ai()
a_i: dict = {}
# convert_binary_to_inputs()
inputs_for_a_i = [0, 0, 0]
# ai
guess = 0
old_guess = 0
reward = 0
past_inputs_for_a_i = ['0', 0, 0]
first_turn_over: bool = False
# buying and selling stocks
money: int = 1000000
shares: int = 0
#
count_to_save_every_fifteen: int = 0
# saving anything to a file.
def save(name, data):
with open(name, 'w') as f:
f.write(str(data))
def save_everything():
save("a_i", a_i)
save("binary_stock_prices", binary_version_of_prices)
save("money", money)
save("shares", shares)
# runs after an error.
def on_exit():
save_everything()
sys.exit()
# gets the current stock value.
# def get_stock():
# global current_stock_price
# res = requests.get("https://markets.businessinsider.com/stocks/aapl-stock")
# stock_cost_string = ""
# for x in range (9):
# stock_cost_string += res.text[res.text.find('"price": "')+10 + x]
# current_stock_price = float(stock_cost_string)
# print(current_stock_price)
def get_stock():
global current_stock_price
if current_stock_price == 3:
current_stock_price = 1
elif current_stock_price == 1:
current_stock_price = 2
else:
current_stock_price = 3
# turns the prices into 0's and 1's.
def reduce_prices_to_binary():
global past_stock_price
global binary_version_of_prices
if current_stock_price > past_stock_price:
binary_string = "1"
elif current_stock_price < past_stock_price:
binary_string = "0"
else:
binary_string = ""
binary_version_of_prices += binary_string
past_stock_price = current_stock_price
# converts the binary_stock_prices to inputs for the a_i.
def convert_binary_to_inputs():
global inputs_for_a_i
inputs_for_a_i[0] = binary_version_of_prices[len(binary_version_of_prices) - 1]
counter_of_first_number = 1
counter_of_second_number = 1
while binary_version_of_prices[len(binary_version_of_prices) - counter_of_first_number] == inputs_for_a_i[0]:
counter_of_first_number += 1
counter_of_first_number -= 1
while (binary_version_of_prices[
len(binary_version_of_prices) - counter_of_first_number - counter_of_second_number] !=
inputs_for_a_i[0]):
counter_of_second_number += 1
counter_of_second_number -= 1
inputs_for_a_i[0] = binary_version_of_prices[len(binary_version_of_prices) - 1]
inputs_for_a_i[1] = counter_of_first_number
inputs_for_a_i[2] = counter_of_second_number
# a_i functions
def read_ai():
global guess
try:
a_i_guess = a_i[inputs_for_a_i[0], inputs_for_a_i[1], inputs_for_a_i[2]]
except:
a_i[inputs_for_a_i[0], inputs_for_a_i[1], inputs_for_a_i[2]] = 0.5
a_i_guess = 0.5
guess = a_i_guess
print(f'guess: {guess}')
print(f'inputs: {inputs_for_a_i}')
return guess
def check_guess():
global first_turn_over
if first_turn_over:
global old_guess
global reward
global past_inputs_for_a_i
old_guess = 0 if old_guess == -1 else 1
print(f'old guess: {old_guess}, input: {round(float(inputs_for_a_i[0]))}')
if old_guess == round(float(inputs_for_a_i[0])):
reward = 1
else:
reward = -1
a_i[past_inputs_for_a_i[0], past_inputs_for_a_i[1], past_inputs_for_a_i[2]] = (1 - learning_rate) * a_i[
past_inputs_for_a_i[0], past_inputs_for_a_i[1], past_inputs_for_a_i[2]] + learning_rate * (
reward + discount_factor * 1)
old_guess = int(round(float(guess)))
past_inputs_for_a_i = inputs_for_a_i
first_turn_over = True
def buy_sell_stocks():
global money
global shares
old_stocks = shares
if guess > 0:
while money > current_stock_price and (shares - old_stocks) < stocks_to_buy * guess:
money -= current_stock_price
shares += 1
else:
while shares > 0 and (old_stocks - shares) > stocks_to_buy * guess:
money += current_stock_price
shares -= 1
# loads the binary_version_of_prices from a file.
def load_binary_prices():
global binary_version_of_prices
with open("../resources/ai_stock_files/binary_stock_prices", 'r') as f:
binary_version_of_prices = f.read()
def load_money():
global money
with open("../resources/ai_stock_files/money") as f:
money = int(f.read())
def load_shares():
global shares
with open("../resources/ai_stock_files/shares") as f:
shares = int(f.read())
# loads the _a_i from a file.
def load_a_i():
global a_i
with open("../resources/ai_stock_files/a_i") as f:
a_i = eval(f.read())
# prints relative information
def print_stuff():
print(f"stock price: {current_stock_price}\n"
f"current balance: {money}\n"
f"current shares: {shares}\n"
f"total value: {money + shares * current_stock_price}\n"
f"guess: {guess}\n")
# loads all variables from files.
def on_program_start():
load_a_i()
load_binary_prices()
load_money()
load_shares()
# saves every 15 checks
def save_every_fifteen():
global count_to_save_every_fifteen
count_to_save_every_fifteen += 1
if count_to_save_every_fifteen == 15:
save_everything()
count_to_save_every_fifteen = 0
# runs all functions.
def do_all_functions():
reduce_prices_to_binary()
convert_binary_to_inputs()
read_ai()
check_guess()
buy_sell_stocks()
save_every_fifteen()
print_stuff()
get_stock()
# loads variables from files.
on_program_start()
# repeats the process.
while True:
do_all_functions()
time.sleep(0.5)
When correcting the policies in the policy gradient, I was using inputs from a cycle ago and over compensating by calling the functions in an order where it already used inputs from a cycle ago, effectively making the gradient off by two inputs. Since I was cycling the input in 3's it made it look like an "off-by-one" error when in reality I was off by two, making it hard to detect.
I am writing a scheduling algorithm for testing purposes and following the "Introduction to Algorithm book", but this is as far as I can get. As of now the job is dying in the weed "Endless loop somewhere". Generally, the algorithm should have a profit and we sort all other arrays according to profit "But I am just ignoring that for now" and my inputs are already sorted. So, the deadline and jobs passed are already sorted. Need somehelp as its still not working.
#!/usr/bin/python3.6
class Scheduling:
def schedule(self, n, deadline, jobs):
self.fdeadline = deadline
self.J = []
self.J.append(jobs[0])
self.i = 1
while self.i <= n:
self.K = self.J.copy()
self.K.append(jobs[self.i])
self.i = self.i + 1
if self.feasible(self.K, self.fdeadline) == True :
self.J = self.K
return self.J
def feasible(self, K, fdl):
self.tmp = K
self.isFeasible = True
self.i = 0
self.j = 1
self.k = 0
while self.i < len(self.tmp):
while self.j < len(self.tmp):
self.index1 = self.i
self.index2 = self.j
if (fdl[self.index1] > fdl[self.index2]):
self.tmp[i], self.tmp[j] = self.tmp[j], self.tmp[i]
while self.k < len(self.tmp):
self.job = self.tmp[self.k]
if (fdl[self.job] < k + 1):
isFeasible = False
break
return isFeasible
def main():
sins = Scheduling()
n = 4
deadline = [1,1,2,2]
jobs = [4, 2, 1, 3]
sjobs = sins.schedule(n, deadline, jobs)
print (sjobs)
if __name__ == "__main__":
main()
Here is a fully functioning code to the scheduling, it might need some small refinements, but its working fine.
#!/usr/bin/python3.6
from operator import itemgetter
class Scheduling:
def __init__(self, jobs):
self.jobs = jobs
def schedule(self, n, deadline):
self.sdl = deadline
self.J = []
self.J.append(self.jobs[1])
self.x = 2
while self.x < n:
self.K = self.J.copy()
self.K.append(self.jobs[self.x])
self.x = self.x + 1
self.feasibility = self.feasible(self.K, self.sdl)
if self.feasibility == True:
self.J = self.K.copy()
return self.J
def feasible(self, K, fdl):
self.tmp = K
self.isFeasible = True
self.i = 0
self.j = 1
self.k = 0
while self.i < len(self.tmp):
while self.j < len(self.tmp):
self.index1 = self.jobs.index(self.tmp[self.i])
self.index2 = self.jobs.index(self.tmp[self.j])
self.j = self.j + 1
if (fdl[self.index1] > fdl[self.index2]):
self.tmp[self.i], self.tmp[self.j] = self.tmp[self.j], self.tmp[self.i]
self.i = self.i + 1
while self.k < len(self.tmp):
self.job = self.tmp[self.k]
self.jobindex = self.jobs.index(self.job)
self.dlineval = fdl[self.jobindex]
self.ftest = self.k + 1
self.k = self.k + 1
if (self.dlineval < self.ftest):
self.isFeasible = False
break
return self.isFeasible
def main():
n = 7
jobs = [0, 1, 2, 3, 4, 5, 6]
deadline = [0, 2, 4, 3, 3, 2, 1]
profit = [0 , 46, 52, 30, 36 ,56, 40]
midresult = [list(x) for x in zip(deadline, profit ,jobs)]
midresult.sort(key=lambda k: (k[0], -k[1]))
deadline, profit, jobs = map(list, zip(*midresult))
sins = Scheduling(jobs)
sjobs = sins.schedule(n, deadline)
print("\n Jobs", sjobs)
finalprofit = []
finaldl = []
for c in range(len(sjobs)):
item = sjobs[c]
jobsindex = jobs.index(item)
finalprofit.append(profit[jobsindex])
finaldl.append(deadline[jobsindex])
print("\n profit", finalprofit)
print("\n Deadline", finaldl)
if __name__ == "__main__":
main()
First of all understand self in python. Read link
Secondly understand the job sequencing problem. Read link
Then, look at the below code
class Scheduling:
def schedule(self, n, deadline, jobs):
# max number of jobs you can schedule is the max deadline available.
filledJobs = ['dummy']*max(deadline);
i = 0
# start assigning the jobs in a greeedy way
while i < n:
job = jobs[i]
j = deadline[i]
# assign the job from the last deadline
while j > 0:
if(filledJobs[j-1] == 'dummy'):
filledJobs[j-1] = job
break
j = j - 1
i = i + 1
return filledJobs
def main():
sins = Scheduling()
n = 4
deadline = [1,1,2,2]
# assuming jobs are sorted w.r.t profits
# I represented the jobs with string to be clear
jobs = ['a', 'b', 'c', 'd']
sjobs = sins.schedule(n, deadline, jobs)
print (sjobs)
if __name__ == "__main__":
main()
I would like to create function that will count up & count down and I would like to access the counted value every let's say 500ms from another function.
How can I return this value 'a' every 500ms so I can read it externaly every e.g. 500ms ?
PS. I am using Python 2.7
This is my code so far with yield usage but it does not give what I want:
import time
class PLCApplication(object):
def generate_data(self):
a = 0
countup = True
while a >= 0:
time.sleep(0.5)
if countup == True:
a += 2
else:
a -= 2
if a < 0:
countup = True
a += 2
if a == 12:
countup = False
a -= 2
yield a
while True:
plc = PLCApplication()
b = plc.generate_data()
for z in b:
time.sleep(0.5)
print 'z...', z
EDIT:
This is the functionality I wanted to achieve. Thanks:
import time
from drawnow import *
import matplotlib.pyplot as plt
x = []
y = []
plt.ion()
class PLCApplication(object):
def generate_data(self):
a = 0
countup = True
while a >= 0:
time.sleep(0.5)
if countup: # no need to do test if it equals True
a += 2
else:
a -= 2
if a < 0:
countup = True
a += 2
if a == 12:
countup = False
a -= 2
yield a
def makefig(self):
plt.ylim(-10,30)
plt.plot(x, 'ro-', label='testgraph')
plt.grid(True)
if __name__ == '__main__':
plc = PLCApplication()
cnt = 0
for t in plc.generate_data():
i = t
x.append(int(i))
cnt=cnt+1
if cnt > 20:
x.pop(0)
print x, cnt
drawnow(plc.makefig)
UPDATE: updated answer according to C14L's comment, original answer below.
import time
class PLCApplication(object):
def generate_data(self):
a = 0
countup = True
while a >= 0:
time.sleep(0.5)
if countup: # no need to do test if it equals True
a += 2
else:
a -= 2
if a < 0:
countup = True
a += 2
if a == 12:
countup = False
a -= 2
yield a
def do_stuff(b):
print b
if __name__ == '__main__':
plc = PLCApplication()
for t in plc.generate_data():
do_stuff(t)
Original answer:
You need to print a at an approriate place inside the while loop:
[...]
while a >= 0:
print a
time.sleep(0.5)
[...]
This example from the Python Coroutine page seems to do that in a non-blocking way, using new asyncio.
import asyncio
import datetime
#asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
loop = asyncio.get_event_loop()
# Blocking call which returns when the display_date() coroutine is done
loop.run_until_complete(display_date(loop))
loop.close()