Python confusion toward class instance - python-3.x

[Class of players that accept a list then proceed to find the player with the highest score.]
class Player:
def __init__(self, name, score):
self.name = name
self.score = score
def best_score(list):
i = 0
while i < len(list):
n = list[i] #list[1] = (Bratt, 250) #list[2] = Lisa 150
s = list[i].score #list 1. score = 250 #list[2].score = 150
ace = list[0] #homer 50 #homer 50
hs = 0
if s > hs: #if s(250>0): #if s(list[2].score) > hs(250): nothing suppsoed to happen
ace = n #ace(homer) = n(list1) aka bratt #ace(bratt) != n because above
hs = s #hs(0) = s(list1) = 250 #hs(250) != list[2]150
#hs is now 250
i += 1
return ace
p1 = Player('Homer', 50)
p2 = Player('Bart', 250)
p3 = Player('Lisa', 150)
ls = [p1, p2, p3]
best = Player.best_score(ls)
msg = '{} has the best score, with {} points!'.format(best.name, best.score)
print(msg) # Bart has the best score, with 250 points!
For some reasons, my code does not return the highest player score and name. Instead, it gives me the latest player score and name instead.
I have tried checking it by going through the loop and it still does not make sense where did I go wrong.

We can focus on this part of the code:
while i < len(list):
hs = 0
if s > hs:
ace = n
hs = s
As it's written, s > hs is the same as s > 0, so the condition will be true for all items of the list that have a score greater than zero.
To keep the greatest value, it should be defined once before entering the loop, like this:
hs = 0
while i < len(list):
if s > hs:
ace = n
hs = s
With this change, the value of hs will be keep during iterations of the while loop, and in the end it will keep the best score as hs.

Related

Target Labeling Using Sliding Window On Stock Data In Python

I'm trying to label BUY, SELL, and HOLD values to the closing stock prices based on the algorithm I found in a paper. I'm not quite able to figure out the error I'm getting. I'd very much appreciate your help. Thank you.
Algorigthm:
[EDITED]
My implementation:
window_size = 11
counter = 0
result = []
window_begin_idx=0; window_end_idx=0; window_middle_idx=0; min_idx=0; max_idx=0;
while counter < len(closing_price):
if counter > window_size:
window_begin_idx = counter - window_size
window_end_idx = window_begin_idx + window_size - 1
window_middle_idx = (window_begin_idx + window_end_idx)//2
for i in range(window_begin_idx, window_end_idx+1):
rng = closing_price[window_begin_idx:window_end_idx+1]
number = closing_price[i]
mins = rng.min()
maxs = rng.max()
if number < mins:
mins=number
min_idx = np.argmin(rng)
if number > maxs:
maxs=number
max_idx = np.argmax(rng)
if max_idx == window_middle_idx:
result.append("SELL")
elif min_idx == window_middle_idx:
result.append("BUY")
else:
result.append("HOLD")
mins = 0.0
maxs = 10000.0
counter+=1
After the edit based on the author's JAVA code, I'm only getting the HOLD label. The author's implementation is here.
You need to initialize mins, maxs, min_idx and max_idx with appropriate values before the main loop.
In your case if max_idx == occurs earlier than any max_idx assignment
Edit after questing change:
Seems in Python you can make similar behavior replacing the whole for-loop with:
rng = closing_price[window_begin_idx:window_end_idx+1]
mins = rng.min()
maxs = rng.max()
min_idx = rng.index(mins)
max_idx = rng.index(maxs)
After reading through the author's implementation and following the suggestions provided by MBo, I have managed to solve this issue. So, now anyone who wants this algorithm in python, below is the code:
window_size = 11
counter = 0
result = []
window_begin_idx=0; window_end_idx=0; window_middle_idx=0; min_idx=0; max_idx=0;
number=0.0; mins=10000.0; maxs=0.0
while counter < len(closing_price):
if counter > window_size:
window_begin_idx = counter - window_size
window_end_idx = window_begin_idx + window_size - 1
window_middle_idx = (window_begin_idx + window_end_idx)//2
for i in range(window_begin_idx, window_end_idx+1):
number = closing_price[i]
if number < mins:
mins=number
min_idx = np.where(closing_price==mins)[0][0]
if number > maxs:
maxs=number
max_idx = np.where(closing_price==maxs)[0][0]
if max_idx == window_middle_idx:
result.append("SELL")
elif min_idx == window_middle_idx:
result.append("BUY")
else:
result.append("HOLD")
mins = 10000.0
maxs = 0.0
counter+=1

Increase speed using only one loop?

Is there a way to rewrite this code using only one loop to increase the speed while the input is very large numbers?
The code is used to count how many integers in a list are greater than all integers to the right of it.
count = 0
for i,x in enumerate(items):
d = True
for y in items[i+1:]:
if x <= y:
d = False
if d:
count = count+1
return count
The current value is larger than all the ones to the right if and only it is larger than the maximum one.
This code implements the above idea by iterating from right to left:
count = 0
max = None
for val in items[::-1]:
if max is None or val > max:
max = val
count += 1
return count
I timed some options to compare them:
The code from the question:
def f1(item_list):
count = 0
for i, x in enumerate(item_list):
d = True
for y in item_list[i+1:]:
if x <= y:
d = False
if d:
count = count+1
return count
The code from this answer from qwertyman:
def f2(item_list):
max_elem = None
count = 0
for val in item_list[::-1]:
if max_elem is None or val > max_elem:
max_elem = val
count += 1
return count
My improved version (just used reversed() instead of [::-1]):
def f3(item_list):
max_elem = None
count = 0
for val in reversed(item_list):
if max_elem is None or max_elem < val:
max_elem = val
count += 1
return count
The comparison code:
if __name__ == '__main__':
func_list = [f1, f2, f3]
print('{:>8s} {:15s} {:>10s} {:>10s} {:>10s}'.format(
'n', 'items', 'f1', 'f2', 'f3'))
for n in (100, 1000, 5000):
items_1 = [random.randint(1, 1000) for _ in range(n)]
items_2 = list(sorted(items_1))
items_3 = list(sorted(items_1, reverse=True))
for label, items in [
('random', items_1),
('sorted', items_2),
('sorted-reverse', items_3),
]:
# assure that all functions return the same result
assert len(set([func(items) for func in func_list])) == 1
t_list = []
for func in func_list:
t_list.append(
timeit.timeit(
'func(items)',
'from __main__ import func, items',
number=100))
print('{:8d} {:15s} {:10.6f} {:10.6f} {:10.6f}'.format(
n, label, *t_list))
The results (using Python 3.6 on Ubuntu 18.04):
n items f1 f2 f3
100 random 0.016022 0.000348 0.000370
100 sorted 0.015840 0.000339 0.000326
100 sorted-reverse 0.014122 0.000572 0.000505
1000 random 1.502731 0.003212 0.003077
1000 sorted 1.496299 0.003332 0.003089
1000 sorted-reverse 1.256896 0.005412 0.005196
5000 random 36.812474 0.015695 0.014762
5000 sorted 36.902378 0.015983 0.015067
5000 sorted-reverse 31.218129 0.019741 0.018419
Clearly, the proposal by qwertyman is orders of magnitude faster than the original code, and it can be sped up a little bit by using reversed() (obviously, for more speed one could use another language instead of Python).

How could I set the staring and ending points randomly in a grid that generates random obstacles?

I built a grid that generates random obstacles for pathfinding algorithm, but with fixed starting and ending points as shown in my snippet below:
import random
import numpy as np
#grid format
# 0 = navigable space
# 1 = occupied space
x = [[random.uniform(0,1) for i in range(50)]for j in range(50)]
grid = np.array([[0 for i in range(len(x[0]))]for j in range(len(x))])
for i in range(len(x)):
for j in range(len(x[0])):
if x[i][j] <= 0.7:
grid[i][j] = 0
else:
grid[i][j] = 1
init = [5,5] #Start location
goal = [45,45] #Our goal
# clear starting and end point of potential obstacles
def clear_grid(grid, x, y):
if x != 0 and y != 0:
grid[x-1:x+2,y-1:y+2]=0
elif x == 0 and y != 0:
grid[x:x+2,y-1:y+2]=0
elif x != 0 and y == 0:
grid[x-1:x+2,y:y+2]=0
elif x ==0 and y == 0:
grid[x:x+2,y:y+2]=0
clear_grid(grid, init[0], init[1])
clear_grid(grid, goal[0], goal[1])
I need to generate also the starting and ending points randomly every time I run the code instead of making them fixed. How could I make it? Any assistance, please?.
Replace,
init = [5,5] #Start location
goal = [45,45] #Our goal
with,
init = np.random.randint(0, high = 49, size = 2)
goal = np.random.randint(0, high = 49, size = 2)
Assuming your grid goes from 0-49 on each axis. Personally I would add grid size variables, i_length & j_length
EDIT #1
i_length = 50
j_length = 50
x = [[random.uniform(0,1) for i in range(i_length)]for j in range(j_length)]
grid = np.array([[0 for i in range(i_length)]for j in range(j_length)])

Not able to create more than one object of the class

I was coding for a scheduling problem where I have to schedule the trainers and the teachers at some venues. Till now I had made the code to find out the nearest three distance from the trainer. Now I want to create multiple objects of the class dynamically for all the trainers present. But I am able to create only one object. In this code I have imported the data from two csv files named mtData.csv and venueData.csvPlease help me to remove the error.
I have tried to make the objects one by one and through the loops. In both the cases I was getting the error.
import math
import csv
from math import radians, sin, cos, acos
class venue:
venueGeoLat = []
venueGeoLon = []
venueName = []
def __init__(self, name, latitude, longitude):
self.name = name
self.latitude = latitude
self.longitude = longitude
with open('venueData.csv') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in csvReader:
venueGeoLat.append(row[1])
venueGeoLon.append(row[2])
venueName.append(row[0])
class masterTrainer:
name = None
location = None
subject = None
latitude = None
longitude = None
distanceFromVenues = []
nearestVenues = []
def __init__(self, name, location, subject, latitude, longitude):
masterTrainer.name = name
masterTrainer.location = location
masterTrainer.subject = subject
masterTrainer.latitude = latitude
masterTrainer.longitude = longitude
x = 1
y = 1
while (x < 2):
while (y < len(venue.venueGeoLat)):
masterTrainer.distanceFromVenues.append(masterTrainer.distanceCalculator(float(masterTrainer.latitude),float(masterTrainer.longitude),float(venue.venueGeoLat[y]),float(venue.venueGeoLon[y])))
y = y + 1
x = x + 1
MAX = 100000
firstmin = MAX
secmin = MAX
thirdmin = MAX
k = 0
l = 0
m = 0
for i in range(0, len(masterTrainer.distanceFromVenues)):
if masterTrainer.distanceFromVenues[i] < firstmin:
thirdmin = secmin
secmin = firstmin
firstmin = masterTrainer.distanceFromVenues[i]
k = i
elif masterTrainer.distanceFromVenues[i] < secmin:
thirdmin = secmin
secmin = masterTrainer.distanceFromVenues[i]
l = i
elif masterTrainer.distanceFromVenues[i] < thirdmin:
thirdmin = masterTrainer.distanceFromVenues[i]
m = i
masterTrainer.nearestVenues.append(venue.venueName[k+1])
masterTrainer.nearestVenues.append(venue.venueName[l+1])
masterTrainer.nearestVenues.append(venue.venueName[m+1])
def distanceCalculator(latitude1,longitude1,latitude2,longitude2):
slat = radians(latitude1)
slon = radians(longitude1)
elat = radians(latitude2)
elon = radians(longitude2)
dist = 6371.01 * acos(sin(slat)*sin(elat) + cos(slat)*cos(elat)*cos(slon - elon))
return dist
name = []
location = []
subject = []
latitude =[]
longitude = []
with open('mtData.csv') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in csvReader:
name.append(row[0])
location.append(row[1])
subject.append(row[4])
latitude.append(row[2])
longitude.append(row[3])
mt1 = masterTrainer(name[0],location[0],subject[0],latitude[0],longitude[0])
print(mt1.nearestVenues)
mt2 = masterTrainer(name[1],location[1],subject[1],latitude[1],longitude[1])
print(mt2.nearestVenues)
print(mt1.nearestVenues)
print(mt2.distanceFromVenues)
I am getting an index error IndexError: list index out of range
Complete Traceback
<ipython-input-115-2ee0ce48bf78> in <module>
103 mt1 = masterTrainer(name[0],location[0],subject[0],latitude[0],longitude[0])
104 print(mt1.nearestVenues)
--> 105 mt2 = masterTrainer(name[1],location[1],subject[1],latitude[1],longitude[1])
106 print(mt2.nearestVenues)
107 print(mt1.nearestVenues)
<ipython-input-115-2ee0ce48bf78> in __init__(self, name, location, subject, latitude, longitude)
74 masterTrainer.nearestVenues.append(venue.venueName[k+1])
75 masterTrainer.nearestVenues.append(venue.venueName[l+1])
---> 76 masterTrainer.nearestVenues.append(venue.venueName[m+1])
77
78
IndexError: list index out of range```

incorrect output from minimax algorithm for Tic Tac Toe

There are no errors in the code execution , but the output of the minimax algorithm in incorrect , please have a look,`
the AI_makemove function is called from the main loop, and the board_state is the copy of the actual board.
The function AI_makemove is supposed to return the best move for the computer against the user , board_state is the current state of the board, depth is the number of positions filled in the board , check_if_won function returns true if the state is a win state for the current player .
def AI_makemove(board_state , isAI , depth):
temp_board = copy.deepcopy(board_state)
depth+=1
print(temp_board , depth , isAI)
if isAI:
bestVal = -9999
a = b = 0
for i in range(0,3):
for j in range(0,3):
if temp_board[i][j] == 0:
temp_board1 = copy.deepcopy(temp_board)
temp_board1[i][j] = 2
if check_if_won(2,temp_board1):
return [1 , i, j]
if depth == 9:
return [bestVal , a ,b]
l = AI_makemove(temp_board1,False,depth)
if int(l[0]) > bestVal:
bestVal = int(l[0])
a = int(l[1])
b = int(l[2])
else:
bestVal = +9999
a = b = 0
for i in range(0, 3):
for j in range(0, 3):
if temp_board[i][j] == 0:
temp_board1 = copy.deepcopy(temp_board)
temp_board1[i][j] = 1
if check_if_won(1,temp_board1):
return [-1 , i, j]
if depth == 9:
return [bestVal , a ,b]
l = AI_makemove(temp_board1,True,depth)
if int(l[0]) < bestVal:
bestVal = int(l[0])
a = int(l[1])
b = int(l[2])
return [bestVal , a ,b]
I tried a couple of times to debug the code , but wasn't able to fix it , so i wrote the code again with a different approach and it worked. Here's the code

Resources