Can't pickle <local> object - python

I am having trouble getting my class pickled.[This is an example of my function that creates a spike class with certain attributes]
def load_pt(ptname, data_directory):
"""
input: ptname, a string containing the name of the patient you want to load. example: 'ABC123'
output: object: spike ---- contains: List of 1000 random spikes: spike.select and their subsequent:
values: spike.values, chlabels: spike.chlabels, fs: spike.fs, soz channels: spike.soz
"""
val = mat73.loadmat(data_directory + '/values/values_{}.mat'.format(ptname))
val2 = val['values_all']
select_spikes = loadmat(data_directory + '/randi/randi_{}.mat'.format(ptname))
select_spikes = select_spikes['select_spikes']
ch_labels = loadmat(data_directory + '/chlabels/chlabels_{}.mat'.format(ptname))
ch_labels = ch_labels['ch_labels_all']
fs_all = loadmat(data_directory + '/fs/fs_{}.mat'.format(ptname))
fs_all = fs_all['fs_all']
SOZ_chlabels = pd.read_csv(data_directory + '/pt_data/SOZ_channels.csv')
pt_all = pd.read_csv(data_directory + '/pt_data/ptname_all.csv')
pt_name = ("'{}'".format(ptname))
whichpt = pt_all.index[pt_all['ptname'] == pt_name].tolist()
clean_SOZ_chlabels = prep_clean_soz(SOZ_chlabels)
global spike
class spike:
values = val2
select=select_spikes
chlabels = ch_labels
fs = fs_all
soz = clean_SOZ_chlabels[whichpt[0]]
return spike
I understand that the code requires some global effect. I'm fairly new to coding and would love some pointers.
The error I get is:
AttributeError: Can't pickle local object 'load_pt..spike'
Things I've tried:
add a global spike before initializing my class object in my load_pt function (did not work)
get error: Can't get attribute 'spike' on <module 'ied_functions' from 'directory_name'

You need to instantiate the class Spike first before you can return it.
To do this the class does not need to be global. After defining the class instantiate it by writing spike = Spike(). After that, you can return the instance of spike that you just created with return spike.
Into the pickle function you now need to pass load_pt and not load_pt.spike. Now you are passing the function load_pt which returns an instance of the class Spike. load_pt.spike references a local variable inside of load_pt which was never created.
See the entire code here:
import pickle
def load_pt(ptname, data_directory):
# input: ptname, a string containing the name of the patient you want to load. example: 'ABC123'
# output: object: spike ---- contains: List of 1000 random spikes: spike.select and their subsequent:
# values: spike.values, chlabels: spike.chlabels, fs: spike.fs, soz channels: spike.soz
val = mat73.loadmat(data_directory + '/values/values_{}.mat'.format(ptname))
val2 = val['values_all']
select_spikes = loadmat(data_directory + '/randi/randi_{}.mat'.format(ptname))
select_spikes = select_spikes['select_spikes']
ch_labels = loadmat(data_directory + '/chlabels/chlabels_{}.mat'.format(ptname))
ch_labels = ch_labels['ch_labels_all']
fs_all = loadmat(data_directory + '/fs/fs_{}.mat'.format(ptname))
fs_all = fs_all['fs_all']
SOZ_chlabels = pd.read_csv(data_directory + '/pt_data/SOZ_channels.csv')
pt_all = pd.read_csv(data_directory + '/pt_data/ptname_all.csv')
pt_name = ("'{}'".format(ptname))
whichpt = pt_all.index[pt_all['ptname'] == pt_name].tolist()
clean_SOZ_chlabels = prep_clean_soz(SOZ_chlabels)
class Spike:
values = val2
select = select_spikes
chlabels = ch_labels
fs = fs_all
soz = clean_SOZ_chlabels[whichpt[0]]
spike = Spike()
return spike
pickle.dump(load_pt, open( "spike.pkl", "wb" ))
Hope this helpes! :)
Edit:
Also I would follow #MichaelButschers advice:
It is unusual to define a specialized class in a function. Probably you only need an object of the class holding the data as instance attributes you are currently storing as class attributes. In this case you can define a generic class at global level and create an object in the function.
That might look something like this:
import pickle
def load_pt(ptname, data_directory):
# input: ptname, a string containing the name of the patient you want to load. example: 'ABC123'
# output: object: spike ---- contains: List of 1000 random spikes: spike.select and their subsequent:
# values: spike.values, chlabels: spike.chlabels, fs: spike.fs, soz channels: spike.soz
val2 = val['values_all']
select_spikes = select_spikes['select_spikes']
ch_labels = ch_labels['ch_labels_all']
fs_all = loadmat(data_directory + '/fs/fs_{}.mat'.format(ptname))
fs_all = fs_all['fs_all']
SOZ_chlabels = pd.read_csv(data_directory + '/pt_data/SOZ_channels.csv')
pt_all = pd.read_csv(data_directory + '/pt_data/ptname_all.csv')
pt_name = ("'{}'".format(ptname))
whichpt = pt_all.index[pt_all['ptname'] == pt_name].tolist()
clean_SOZ_chlabels = prep_clean_soz(SOZ_chlabels)
spike = Spike(val2, select_spikes, ch_labels, fs_all, clean_SOZ_chlabels[whichpt[0]])
return spike
class Spike():
def __init__(self, values, select, chlabels, fs, soz):
self.values = values
self.select = select
self.chlabels = chlabels
self.fs = fs
self.soz = soz
spike = load_pt('pt_name', 'data_directory')
pickle.dump(spike, open( "spike.pkl", "wb" ))
print(pickle.load(open( "spike.pkl", "rb" )))

Related

How to read data in a class to solve a tabu search problem

I'm trying to learn search algorithms in order to prepare my master thesis, so I have a TSP problem in which I want to find the best and minimal route to visite all the states , I'm using a .txt file named cities__coordinates.txt that contains the coordinates for every state, so to read the data I've found this source code that has a class to read the data you'll find it here:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import copy
import re
import math
class Data():
'''
the format of solomon dataset
'''
def __init__(self):
self.customerNum = 0 # the number of customers
self.nodeNum = 0 # the sum of customers and depots
self.vehicleNum = 0
self.capacity = 0
self.cor_X = []
self.cor_Y = []
self.demand = []
self.readyTime = []
self.dueTime = []
self.serviceTime = []
self.disMatrix = {}
def read_data(self, path, customerNum, depotNum):
'''
function to read solomom data from .txt files, notice that it must be solomon dataset
INPUT
# data : class Data
# path : Data path
# customerNum : the number of customer
OutPut : none
'''
self.customerNum = customerNum
self.nodeNum = customerNum + depotNum
f = open('cities__coordinates.txt', 'r')
lines = f.readlines()
count = 0
for line in lines:
count = count + 1
if(count == 5):
line = line[:-1].strip()
str = re.split(r" +", line)
self.vehicleNum = float(str[0])
self.capacity = float(str[1])
elif(count >= 10 and count <= 10 + customerNum):
line = line[:-1]
str = re.split(r" +", line)
self.cor_X.append(float(str[2]))
self.cor_Y.append(float(str[3]))
self.demand.append(float(str[4]))
self.readyTime.append(float(str[5]))
self.dueTime.append(float(str[6]))
self.serviceTime.append(float(str[7]))
# compute the distance matrix
self.disMatrix = {}
for i in range(0, self.nodeNum):
dis_temp={}
for j in range(0, self.nodeNum):
dis_temp[j] = int(math.hypot(self.cor_X[i] - self.cor_X[j],self.cor_Y[i] - self.cor_Y[j]))
self.disMatrix[i] = dis_temp
def plot_nodes(self):
'''
Description: function to plot
'''
Graph = nx.DiGraph()
nodes_name = [str(x) for x in list(range(self.nodeNum))]
Graph.add_nodes_from(nodes_name)
cor_xy = np.array([self.cor_X,self.cor_Y]).T.astype(int)
pos_location = {nodes_name[i]:x for i,x in enumerate(cor_xy)}
nodes_color_dict = ['r'] + ['gray'] * (self.nodeNum-1)
nx.draw_networkx(Graph,pos_location,node_size=200,node_color=nodes_color_dict,labels=None)
plt.show(Graph)
def plot_route(self,route,color='k'):
Graph = nx.DiGraph()
nodes_name = [0]
cor_xy=[[self.cor_X[0] , self.cor_Y[0]]]
edge = []
edges = [[0,route[0]]]
for i in route :
nodes_name.append(i)
cor_xy.append([self.cor_X[i] , self.cor_Y[i]])
edge.append(i)
if len(edge) == 2 :
edges.append(copy.deepcopy(edge))
edge.pop(0)
edges.append([route[-1],0])
Graph.add_nodes_from(nodes_name)
Graph.add_edges_from(edges)
pos_location = {nodes_name[i]:x for i,x in enumerate(cor_xy)}
nodes_color_dict = ['r'] + ['gray'] * (len(route))
nx.draw_networkx(Graph,pos_location,node_size=200,node_color=nodes_color_dict,edge_color=color, labels=None)
plt.show(Graph)
so in read_data function I've changed the path to my .txt file , and for the code which will calculate all the distance and took the tabu search and all the staffs, here it is the code:
from itertools import combinations
import os,sys,copy
import numpy as np
import time
from Datareader import Data
import matplotlib.pyplot as plt
class Tabu():
def __init__(self,disMatrix,max_iters=200,maxTabuSize=20):
"""parameters definition"""
self.disMatrix = disMatrix
self.maxTabuSize = maxTabuSize
self.max_iters = max_iters
self.tabu_list=[]
def get_route_distance(self,route):
'''
Description: function to calculate total distance of a route. evaluate function.
parameters: route : list
return : total distance : folat
'''
routes = [0] + route + [0] # add the start and end point
total_distance = 0
for i,n in enumerate(routes):
if i != 0 :
total_distance = total_distance + self.disMatrix[last_pos][n]
last_pos = n
return total_distance
def exchange(self,s1,s2,arr):
"""
function to Swap positions of two elements in an arr
Args: int,int,list
s1 : target 1
s2 : target 2
arr : target array
Ouput: list
current_list : target array
"""
current_list = copy.deepcopy(arr)
index1 , index2 = current_list.index(s1) , current_list.index(s2) # get index
current_list[index1], current_list[index2]= arr[index2] , arr[index1]
return current_list
def generate_initial_solution(self,num=10,mode='greedy'):
"""
function to get the initial solution,there two different way to generate route_init.
Args:
num : int
the number of points
mode : string
"greedy" : advance step by choosing optimal one
"random" : randomly generate a series number
Ouput: list
s_init : initial solution route_init
"""
if mode == 'greedy':
route_init=[0]
for i in range(num):
best_distance = 10000000
for j in range(num+1):
if self.disMatrix[i][j] < best_distance and j not in route_init:
best_distance = self.disMatrix[i][j]
best_candidate = j
route_init.append(best_candidate)
route_init.remove(0)
if mode == 'random':
route_init = np.arange(1,num+1) #init solution from 1 to num
np.random.shuffle(route_init) #shuffle the list randomly
return list(route_init)
def tabu_search(self,s_init):
"""tabu search"""
s_best = s_init
bestCandidate = copy.deepcopy(s_best)
routes , temp_tabu = [] , [] # init
routes.append(s_best)
while(self.max_iters):
self.max_iters -= 1 # Number of iterations
neighbors = copy.deepcopy(s_best)
for s in combinations(neighbors, 2):
sCandidate = self.exchange(s[0],s[1],neighbors) # exchange number to generate candidates
if s not in self.tabu_list and self.get_route_distance(sCandidate) < self.get_route_distance(bestCandidate):
bestCandidate = sCandidate
temp_tabu = s
if self.get_route_distance(bestCandidate) < self.get_route_distance(s_best): # record the best solution
s_best = bestCandidate
if temp_tabu not in self.tabu_list:
self.tabu_list.append(temp_tabu)
if len(self.tabu_list) > self.maxTabuSize :
self.tabu_list.pop(0)
routes.append(bestCandidate)
return s_best, routes
if __name__ == "__main__":
data = Data()
data.read_data(path='cities__coordinates.txt',customerNum=100,depotNum=1) # change the path
""" Tabu :
disMatrix : the distance matrix from 0 to X , 0 represernt starting and stopping point。
for example: disMatrix = [[0,3,4,...
1,0,5,...
3,5,0,...]]
that means the distance from 0 to 0 is 0, from 0 to 1 is 3,... from 1 to 3 is 5....
max_iters : maximum iterations
maxTabuSize : maximum iterations
"""
tsp = Tabu(disMatrix=data.disMatrix,max_iters=10,maxTabuSize=10)
# two different way to generate initial solution
# num : the number of points
s_init = tsp.generate_initial_solution(num=10,mode='greedy') # mode = "greedy" or "random"
print('init route : ' , s_init)
print('init distance : ' , tsp.get_route_distance(s_init))
start = time.time()
best_route , routes = tsp.tabu_search(s_init) # tabu search
end = time.time()
print('best route : ' , best_route)
print('best best_distance : ' , tsp.get_route_distance(best_route))
print('the time cost : ',end - start )
# plot the result changes with iterations
results=[]
for i in routes:
results.append(tsp.get_route_distance(i))
plt.plot(np.arange(len(results)) , results)
plt.show()
# plot the route
data.plot_route(best_route)
when I execute it, it takes a little time and then it shows me this error :
Traceback (most recent call last):
File "C:/Users/malle/OneDrive/Desktop/TS.py", line 100, in <module>
data.read_data(path='cities__coordinates.txt',customerNum=100,depotNum=1) # change the path
File "C:/Users/malle/OneDrive/Desktop\Datareader.py", line 49, in read_data
self.cor_X.append(float(str[2]))
IndexError: list index out of range
anyone can help to resolve this problem please ?

Running Two Objects at Once

I am trying to see if Python can run two objects at once or simultaneously. I have researched multi threading and seems like it can handle this. All the posts I am seeing is to add functions to the target but not an actual instantiation of an object.
file1.py:
from threading import Thread
class Move_Images:
def __init__(self, rps_img_archive_fp, destination_fp, images_count, set_capturebatchno):
self.rps_img_archive_fp = rps_img_archive_fp
self.destination_fp = destination_fp
self.images_count = images_count
self.set_capturebatchno = set_capturebatchno
def get_fp_elem(self):
count = 0
capturebatchno_l = []
img_fn_l = []
final_dest_fp_l = []
input_img_fp_l = []
for path, directories, files in os.walk(self.rps_img_archive_fp):
for file in files:
count += 1
# if count <= self.images_count:
img_fp = os.path.join(path, file)
capturebatchno = img_fp.split("\\")[7]
get_cbn = [cbn for cbn in self.set_capturebatchno if cbn in capturebatchno]
if get_cbn:
capturebatchno_l.append(get_cbn[0])
filename = img_fp.split("\\")[8]
img_fn_l.append(filename)
input_img_fp_l.append(img_fp)
res = []
for i in capturebatchno_l:
if i not in res:
res.append(i)
for cbn, fn in zip(capturebatchno_l, img_fn_l):
dest_fp = os.path.join(str(self.destination_fp) + "\\" + str(cbn) + "\\" + str(fn))
final_dest_fp_l.append(dest_fp)
return res, self.destination_fp, img_fn_l, self.rps_img_archive_fp, input_img_fp_l, final_dest_fp_l
move_images = Move_Images(rps_img_archive_fp=r'c:\\test\test\input',
destination_fp=r'c:\\test\test\output', images_count=100,
set_capturebatchno=['00004002', '00004005'])
res, destination_fp, img_fn_l,rps_img_archive_fp, input_img_fp_l,final_dest_fp_l = \
move_images.get_fp_elem()
move_images_2 = Move_Images(rps_img_archive_fp=rr'c:\\test\test\input',
destination_fp=r'c:\\test\test\output', images_count=100,
set_capturebatchno=['000040010', '000040012'])
if __name__ == '__main__':
Thread(target=move_images).start()
Thread(target=move_images_2).start()
you can create for example a class (Move_Images) that inherhit from Thread itself and create a run function. Look into the accepted answer on this post maybe this is what u want.

How to reuse class from another file

I import technicals.py into bot.py and want to reuse the variable sl and tp from the class instance process_candles.
If a constant number is given to sl and tp in bot.py, the script is able to work. However, the desired result is to get variable sl and tp which is calculated in the class instance process_candles. from technicals.py.
snippet technicals.py as below:
df['PAIR'] = self.pair
decision = NONE
tp = 0
sl = 0
if c[-2]>o[-2]:
if ca[-1]>h[-2]+0.0010:
decision = BUY
tp = ca[-1]+0.010
sl = l[-2]-0.010
elif o[-2]>c[-2]:
if cb[-1]<l[-2]-0.0010:
decision = SELL
tp = cb[-1]-0.010
sl = h[-2]+0.010
else:
decision = NONE
snippet bot.py
def process_pairs(self):
trades_to_make = []
for pair in self.trade_pairs:
if self.timings[pair].ready == True:
self.log_message(f"Ready to trade {pair}")
techs = Technicals(self.settings[pair], self.api, pair, GRANULARITY, log=self.tech_log)
decision = techs.get_trade_decision(self.timings[pair].last_candle)
print ("process decision")
print (decision)
units = decision * self.settings[pair].units
#tp = "154"
#sl = "153"
if units != 0:
trades_to_make.append({'pair': pair, 'units': units,'take_profit':tp, 'stop_loss':sl})
Full script are as below:
technicals.py
import pandas as pd
import numpy as np
from defs import BUY, SELL, NONE
class Technicals():
def __init__(self, settings, api, pair, granularity, log=None):
self.settings = settings
self.log = log
self.api = api
self.pair = pair
self.granularity = granularity
def log_message(self, msg):
if self.log is not None:
self.log.logger.debug(msg)
def fetch_candles(self, row_count, candle_time):
status_code, df = self.api.fetch_candles(self.pair, count=row_count, granularity=self.granularity)
if df is None:
self.log_message(f"Error fetching candles for pair:{self.pair} {candle_time}, df None")
return None
elif df.iloc[-1].time != candle_time:
self.log_message(f"Error fetching candles for pair:{self.pair} {candle_time} vs {df.iloc[-1].time}")
return None
else:
return df
def process_candles(self, df):
open = df.mid_o
o = np.array(open,dtype='float')
#print (o)
high = df.mid_h
h = np.array(high,dtype='float')
#print (h)
low = df.mid_l
l = np.array(low,dtype='float')
#print (l)
close = df.mid_c
c = np.array(close,dtype='float')
print (c)
close_ask = df.ask_c
ca = np.array(close_ask,dtype='float')
print (ca)
close_bid = df.bid_c
cb = np.array(close_bid,dtype='float')
print (cb)
df['PAIR'] = self.pair
decision = NONE
tp = 0
sl = 0
if c[-2]>o[-2]:
if ca[-1]>h[-2]+0.0010:
decision = BUY
tp = ca[-1]+0.010
sl = l[-2]-0.010
elif o[-2]>c[-2]:
if cb[-1]<l[-2]-0.0010:
decision = SELL
tp = cb[-1]-0.010
sl = h[-2]+0.010
else:
decision = NONE
log_cols = ['time','volume','PAIR','bid_c','ask_c','mid_o','mid_h','mid_l','mid_c']
self.log_message(f"Processed_df\n{df[log_cols].tail(3)}")
self.log_message(f"Trade_decision:{decision}")
self.log_message("")
return decision
def get_trade_decision(self, candle_time):
max_rows = self.settings.long_ma + 2
self.log_message("")
self.log_message(f"get_trade_decision() pair:{self.pair} max_rows:{max_rows}")
df = self.fetch_candles(max_rows, candle_time)
print ("xxxx")
print (df)
if df is not None:
return self.process_candles(df)
print("get trade decision")
print(self.process_candles(df))
return NONE
bot.py
import pprint
import time
from settings import Settings
from log_wrapper import LogWrapper
from timing import Timing
from oanda_api import OandaAPI
from technicals import Technicals
from defs import NONE, BUY, SELL
from trade_manager import TradeManager
GRANULARITY = "M1"
SLEEP = 10.0
class TradingBot():
def __init__(self):
self.log = LogWrapper("Bot")
self.tech_log = LogWrapper("Technicals")
self.trade_log = LogWrapper("Trade")
self.trade_pairs = Settings.get_pairs()
self.settings = Settings.load_settings()
self.api = OandaAPI()
self.trade_manager = TradeManager(self.api, self.settings, self.trade_log)
self.timings = { p: Timing(self.api.last_complete_candle(p, GRANULARITY)) for p in self.trade_pairs }
self.log_message(f"Bot started with\n{pprint.pformat(self.settings)}")
self.log_message(f"Bot Timings\n{pprint.pformat(self.timings)}")
print (self.api)
def log_message(self, msg):
self.log.logger.debug(msg)
def update_timings(self):
for pair in self.trade_pairs:
current = self.api.last_complete_candle(pair, GRANULARITY)
self.timings[pair].ready = False
if current > self.timings[pair].last_candle:
self.timings[pair].ready = True
self.timings[pair].last_candle = current
self.log_message(f"{pair} new candle {current}")
def process_pairs(self):
trades_to_make = []
for pair in self.trade_pairs:
if self.timings[pair].ready == True:
self.log_message(f"Ready to trade {pair}")
techs = Technicals(self.settings[pair], self.api, pair, GRANULARITY, log=self.tech_log)
decision = techs.get_trade_decision(self.timings[pair].last_candle)
print ("process decision")
print (decision)
units = decision * self.settings[pair].units
#tp = "154"
#sl = "153"
if units != 0:
trades_to_make.append({'pair': pair, 'units': units,'take_profit':tp, 'stop_loss':sl})
if len(trades_to_make) > 0:
print("bot")
print(trades_to_make)
self.trade_manager.place_trades(trades_to_make)
def run(self):
while True:
self.update_timings()
self.process_pairs()
time.sleep(SLEEP)
if __name__ == "__main__":
b = TradingBot()
b.run()
defs.py
API_KEY = "xxxx"
ACCOUNT_ID = "xyz"
OANDA_URL = 'https://api-fxpractice.oanda.com/v3'
SECURE_HEADER = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}
BUY = 1
SELL = -1
NONE = 0
Instead of just returning the decision, also return the take profit and stop loss values:
return decision, tp, sl
Then you can unpack the tuple in process_pairs:
decision, tp, sl = techs.get_trade_decision(self.timings[pair].last_candle)
You can define your tp and sl as class variables of Technicals.
class Technicals(object):
tp: int = 0
sl: int = 0
and use them within Technicals as:
cls.tp = ... # if you are inside class-method
self.tp = ... # if you are inside instance-method
And in the TradingBot you can then simple import Technicals and use the class-Vars like:
tp = Technicals.tp # you can use the class
tp = techs.tp # or the instance you already have

unsupported operand type(s) for +=: 'zip' and 'zip'

thanks for the answer before and I have changed it what Alperen suggested, but I have another problem, my code :
import sys
import os
import itertools
import os.path
import random
from PIL import Image
from svmutil import *
DIMENSION = 200
sys.path.append("../train/")
ROOT_DIR = os.path.dirname(os.getcwd()) + "/train"
NEGATIVE = "negative"
POSITIVE = "positive"
CLASSES = [NEGATIVE, POSITIVE]
# libsvm constants
LINEAR = 0
RBF = 2
# Other
USE_LINEAR = False
IS_TUNING = False
def main():
try:
train, tune, test = getData(IS_TUNING)
models = getModels(train)
results = None
if IS_TUNING:
print ("!!! TUNING MODE !!!")
results = classify(models, tune)
else:
results = classify(models, test)
print
totalCount = 0
totalCorrect = 0
for clazz in CLASSES:
count, correct = results[clazz]
totalCount += count
totalCorrect += correct
print ("%s %d %d %f") % (clazz, correct, count, (float(correct) / count))
print ("%s %d %d %f") % ("Overall", totalCorrect, totalCount,(float(totalCorrect) / totalCount))
except Exception as e:
print (e)
return 5
def classify(models, dataSet):
results = {}
for trueClazz in CLASSES:
count = 0
correct = 0
for item in dataSet[trueClazz]:
predClazz, prob = predict(models, item)
print ("%s,%s,%f") % (trueClazz, predClazz, prob)
count += 1
if trueClazz == predClazz: correct += 1
results[trueClazz] = (count, correct)
return results
def predict(models, item):
maxProb = 0.0
bestClass = ""
for clazz, model in models.iteritems():
prob = predictSingle(model, item)
if prob > maxProb:
maxProb = prob
bestClass = clazz
return (bestClass, maxProb)
def predictSingle(model, item):
output = svm_predict([0], [item], model, "-q -b 1")
prob = output[2][0][0]
return prob
def getModels(trainingData):
models = {}
param = getParam(USE_LINEAR)
for c in CLASSES:
labels, data = getTrainingData(trainingData, c)
prob = svm_problem(labels, data)
m = svm_train(prob, param)
models[c] = m
return models
def getTrainingData(trainingData, clazz):
labeledData = getLabeledDataVector(trainingData, clazz, 1)
negClasses = [c for c in CLASSES if not c == clazz]
for c in negClasses:
ld = getLabeledDataVector(trainingData, c, -1)
labeledData += ld
random.shuffle(labeledData)
unzipped = [list(t) for t in zip(*labeledData)]
labels, data = unzipped[0], unzipped[1]
return (labels, data)
def getParam(linear = True):
param = svm_parameter("-q")
param.probability = 1
if(linear):
param.kernel_type = LINEAR
param.C = .01
else:
param.kernel_type = RBF
param.C = .01
param.gamma = .00000001
return param
def getLabeledDataVector(dataset, clazz, label):
data = dataset[clazz]
labels = [label] * len(data)
output = zip(labels, data)
return output
def getData(generateTuningData):
trainingData = {}
tuneData = {}
testData = {}
for clazz in CLASSES:
(train, tune, test) = buildTrainTestVectors(buildImageList(ROOT_DIR + clazz + "/"), generateTuningData)
trainingData[clazz] = train
tuneData[clazz] = tune
testData[clazz] = test
return (trainingData, tuneData, testData)
def buildImageList(dirName):
imgs = [Image.open(dirName + fileName).resize((DIMENSION, DIMENSION)) for fileName in os.listdir(dirName)]
imgs = [list(itertools.chain.from_iterable(img.getdata())) for img in imgs]
return imgs
def buildTrainTestVectors(imgs, generateTuningData):
# 70% for training, 30% for test.
testSplit = int(.7 * len(imgs))
baseTraining = imgs[:testSplit]
test = imgs[testSplit:]
training = None
tuning = None
if generateTuningData:
# 50% of training for true training, 50% for tuning.
tuneSplit = int(.5 * len(baseTraining))
training = baseTraining[:tuneSplit]
tuning = baseTraining[tuneSplit:]
else:
training = baseTraining
return (training, tuning, test)
if __name__ == "__main__":
sys.exit(main())
and I got the new massage
Klik this massage to see new error massage
What should I do? I have searched every answer but never make me get the answer. Now I use this code for my final project at university. I hope anyone can help me for this problem. But thank you for another last answer
EDIT:
This lines causes the error:
labeledData += ld
+= operand doesn't work for zips. You can change zips to list.
def getLabeledDataVector(dataset, clazz, label):
...
return list(output)
Also, unzipped list can be empty, you should fix this line too(Thanks to ShadowRanger for comment):
labels, data = unzipped if unzipped else ([], [])
This changes probably will affect your code's logic. You should fix them on your own.
BEFORE EDIT:
In getData(generateTuningData) function, ROOT_DIR + clazz expression causes the error, because ROOT_DIR is None.
sys.path.append doesn't return anything(returns None).
You need to change your code as:
...
import os.path
...
sys.path.append("../train/")
ROOT_DIR = os.path.dirname(os.getcwd()) + "/train/" # parent directory and "/train/"
...
I assumed ROOT_DIR is your current working directory's parent + "/train/". If it is not, you can fix it.
Also, there may be other problems, but this solves unsupported operand type(s).

'Int' object has no attribute

I am trying to create a list objects that holds data about professional golfers. The different data points are golfer name and putting percentages from different distances. I want to sort this list of objects by name once all the data has been entered for every player object. The list of these objects is called PlayerNumber. When I try to sort PlayerNumber by attribute 'name'. I get an error stating that 'int' has no attribute and I am not sure why PlayerNumber is being referred to as an integer and not a list.
Any help would be appreciated. Here is the code:
import operator
import numpy as np
import statistics
import matplotlib.pyplot as plt
from colour import Color
from bs4 import BeautifulSoup
import urllib3
############### ACCESS WEBPAGES ####################
def makeSoup(url):
http = urllib3.PoolManager()
response = http.request('GET', url)
soupdata = BeautifulSoup(response.data)
return soupdata
siteURL = []
for i in range(7):
siteURL.append(i)
siteURL[0] = ''
siteURL[1] = 'http://www.pgatour.com/stats/stat.408.html' #>25
siteURL[2] = 'http://www.pgatour.com/stats/stat.407.html' #20-25
siteURL[3] = 'http://www.pgatour.com/stats/stat.406.html' #15-20
siteURL[4] = 'http://www.pgatour.com/stats/stat.405.html' #10-15
siteURL[5] = 'http://www.pgatour.com/stats/stat.404.html' #5-10
siteURL[6] = 'http://www.pgatour.com/stats/stat.02427.html' #3-5
############### ACCESS TABLE DATA ###################
def row_number(soupdata):
for row in table.findAll('tr'):
tot_row = row
return tot_row
def parse_table(soupdata):
currRank = []
prevRank = []
playerName = []
rounds = []
pctMake = []
attempts = []
puttsMade = []
table = soupdata.find('tbody')
tot_row = 0
for row in table.findAll('tr'):
#for col in row.findAll('td'):
col = row.find_all('td')
#column_1 = col[0]
#currRank.append(column_1)
#column_2 = col[1]
#prevRank.append(column_2)
column_3 = col[2].text
column_3.strip()
playerName.append(column_3)
#column_4 = col[3]
#rounds.append(column_4)
column_5 = col[4].text
pctMake.append(column_5)
#column_6 = col[5]
#attempts.append(column_6)
#column_7 = col[6]
#puttsMade.append(column_7)
tot_row += 1
#return currRank, prevRank, playerName, rounds, pctMake, attempts, puttsMade
return playerName, pctMake, tot_row
"""
>25 ft: distance1
20-25 ft: distance2
15-20 ft: distance3
10-15 ft: distance4
5-10 ft: distance5
3-5 ft: distance6
"""
############### CLASS DEFINITION ###################
class Player:
id_list={}
def __init__(self,name, id, dis1=0.0, dis2=0.0, dis3=0.0, dis4=0.0, dis5=0.0, dis6=0.0):
self.name = name
self.dis1 = dis1
self.dis2 = dis2
self.dis3 = dis3
self.dis4 = dis4
self.dis5 = dis5
self.dis6 = dis6
self.id = id
Player.id_list[self.name] = self # save the id as key and self as he value
def addDis1(self,distance1):
self.dis1 = float(distance1)
def addDis2(self,distance2):
self.dis2 = float(distance2)
def addDis3(self,distance3):
self.dis3 = float(distance3)
def addDis4(self,distance4):
self.dis4 = float(distance4)
def addDis5(self,distance5):
self.dis5 = float(distance5)
def addDis6(self,distance6):
self.dis6 = float(distance6)
def displayPlayer(self):
print("Player: ", self.name, '\n'
">25 Ft %: ", self.dis1, '\n'
"20-25 Ft %: ", self.dis2, '\n'
"15-20 Ft %: ", self.dis3, '\n'
"10-15 Ft %: ", self.dis4, '\n'
"5-10 Ft %: ", self.dis5, '\n'
"3-5 Ft %: ", self.dis6, '\n')
#classmethod
def lookup_player_name_by_id(cls, name):
try:
return cls.id_list[name] # return the instance with the id
except KeyError: # error check for if id does not exist
raise KeyError("No user with id %s" % str(id))
############### DATA POPULATION ###################
PlayerNumber=[]
for i in range(0,195):
PlayerNumber.append(i)
for i in range(1,7):
soupdata = makeSoup(siteURL[i])
playerName, pctMake, tot_row = parse_table(soupdata)
for x in range(0,tot_row):
#PlayerNumber.append(x)
name = playerName[x]
name = name.replace("\xa0", " ")
name = name.replace("\n", "")
if i == 1:
PlayerNumber[x] = Player(name, x)
Player.addDis1(PlayerNumber[x],pctMake[x])
if i == 2:
val = Player.lookup_player_name_by_id(name)
Player.addDis2(PlayerNumber[val.id],pctMake[x])
if i == 3:
val = Player.lookup_player_name_by_id(name)
Player.addDis3(PlayerNumber[val.id],pctMake[x])
if i == 4:
val = Player.lookup_player_name_by_id(name)
Player.addDis4(PlayerNumber[val.id],pctMake[x])
if i == 5:
val = Player.lookup_player_name_by_id(name)
Player.addDis5(PlayerNumber[val.id],pctMake[x])
if i == 6:
val = Player.lookup_player_name_by_id(name)
Player.addDis6(PlayerNumber[val.id],pctMake[x])
PlayerNumber.sort(key = operator.attrgetter("name"))
#PlayerNumber[2].displayPlayer()
I'm using Python 3.4 spyder IDE. I'm relatively new to python as an FYI.
Thanks!
It isn't that PlayerNumber is being referred to as an integer, but rather that PlayerNumber is a list of integers, and every element of that list (and integer) doesn't has an attribute "name", which sort() is trying to access (in order to sort them).
Edit:
To elaborate, the second to last line in your sample:
PlayerNumber.sort(key = operator.attrgetter("name"))
is trying to sort PlayerNumber, using the comparison function: operator.attrgetter("name"), which means it must call that function on each element of PlayerNumber to get its rank in the sorted array. That is why you are trying to grab a .name attribute from the integers in PlayerNumber.

Categories

Resources