Receiving an IndexError when the range in the list should not be out of bounds - index-error

I'm new to programming and I can't figure out why I'm getting this error. This is a snippet of code for my battleship script. What I'm trying to do is have a function select spots that are empty to place ships. I've imported random and I have mostly reused this code from my function on setting up the player's ships, which does work. Every once in a while I do not get this error and the game loop progresses as normal. I apologize if I have not given enough information and will update with more and provide full code if you wish to see it. Thank you for looking.
row_headers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
column_headers = [' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
rows = columns = 10
grid_enemy = []
for row in range(row):
grid_enemy.append([])
for column in range(columns):
grid_enemy[row].append('.')
def setup_ship_enemy(ship_enemy):
random_coordinate = []
random_coordinate.append(random.randint(1,10))
random_coordinate.append(random.randint(1,10))
random_direction = random.randint(1,4) #direction is: UP DOWN LEFT RIGHT
valid_spot_e = 0
for unit_e in range(ship_enemy.size):
if random_direction == 1:
spot_e = -unit_e + -1 + random_coordinate[0]
if spot_e < 0:
return False
elif grid_enemy[spot_e][-1 + random_coordinate[1]] != '.':
return False
else:
valid_spot_e += 1
if valid_spot_e == ship.size:
for unit_e in range(ship_enemy.size):
ship_enemy.position.append([random_coordinate[0] + -unit_e, random_coordinate[1]])
if random_direction == 2:
spot_e = unit_e + -1 + random_coordinate[0]
if spot_e >= 10:
return False
elif grid_enemy[spot_e][-1 + random_coordinate[1]] != '.':
return False
else:
valid_spot_e += 1
if valid_spot_e == ship_enemy.size:
for unit_e in range(ship_enemy.size):
ship_enemy.position.append([random_coordinate[0] + unit_e, random_coordinate[1]])
if random_direction == 3:
spot_e = -unit_e + -1 + random_coordinate[1]
if spot_e < 0:
return False
elif grid_enemy[-1 + random_coordinate[0]][spot_e] != '.':
return False
else:
valid_spot_e += 1
if valid_spot_e == ship_enemy.size:
for unit_e in range(ship_enemy.size):
ship_enemy.position.append([random_coordinate[0], random_coordinate[1] -unit_e])
if random_direction == 4:
spot_e = unit_e + -1 + random_coordinate[1]
if spot_e >= 10:
return False
elif grid_enemy[-1 + random_coordinate[0]][spot_e] != '.':
return False
else:
valid_spot_e += 1
if valid_spot_e == ship_enemy.size:
for unit_e in range(ship_enemy.size):
ship_enemy.position.append([random_coordinate[0], random_coordinate[1] + unit_e])

Related

How can I increase the efficiency of my loop that replaces values?

def assignGroup(row):
if row['democ_bad']== 1:
return 4
elif row['democ_bad'] == 2:
return 3
elif row['democ_bad'] == 3:
return 2
elif row['democ_bad'] == 4:
return 1
else:
return np.nan
wvs['demo_better']=wvs.apply(assignGroup,axis=1)
Try this.
mapping = {1: 4, 2: 3, 3: 2, 4: 1}
wvs['demo_better'] = wvs['democ_bad'].map(mapping)
It should return nans when there is no mapping.

Pi Pico Micropython Loop seems to get stuck

I am using a Pico as part of my dissertation along with an Arduino Due for a low cost fully autonomous UAV.
Anyway to the point, the code was working before I added the GPS part but now even if I take it out the ultrasonics won't work correctly. only shows the left sensor and doesn't continue on to the GPS.
I was also trying to use the multithreader with no joy :(
Any help or suggestions would be great.
Its a bit messy I know not quite got round to polishing it.
from machine import Pin
import utime, _thread, machine
import os
from rp2 import PIO, StateMachine, asm_pio
#print sys info
print(os.uname())
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0) # onboard LED OFF for 0.5 sec
utime.sleep(0.5)
led_onboard.value(1)
uart = machine.UART(0, baudrate=9600)
ser = machine.UART(1, baudrate=9600)
print(uart)
print(ser)
baton = _thread.allocate_lock()
rcvChar = b""
trigger = Pin(3, Pin.OUT) #left
echo = Pin(2, Pin.IN)
trigger2 = Pin(6, Pin.OUT) #right
echo2 = Pin(7, Pin.IN)
trigger4 = Pin(9, Pin.OUT) #backward
echo4 = Pin(8, Pin.IN)
def decode(coord):
#Converts DDDMM.MMMMM > DD deg MM.MMMMM min
x = coord.split(".")
head = x[0]
tail = x[1]
deg = head[0:-2]
min = head[-2:]
return deg + " deg " + min + "." + tail + " min"
def ultraleft():
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep_us(5)
trigger.low()
while echo.value() == 0:
signaloff = utime.ticks_us()
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
Ldistance = (timepassed * 0.0343) / 2
utime.sleep(0.1)
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep_us(5)
trigger.low()
while echo.value() == 0:
signaloff = utime.ticks_us()
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
Ldistance2 = (timepassed * 0.0343) / 2
newLdist = (Ldistance + Ldistance2) / 2
if newLdist > 120:
newLdist = 120
elif newLdist <= 100:
print("Distance Left less than 100")
return True
print("The distance Left from object is ",newLdist,"cm")
def ultraright():
trigger2.low()
utime.sleep_us(2)
trigger2.high()
utime.sleep_us(5)
trigger2.low()
while echo2.value() == 0:
signaloff2 = utime.ticks_us()
while echo2.value() == 1:
signalon2 = utime.ticks_us()
timepassed2 = signalon2 - signaloff2
Rdistance = (timepassed2 * 0.0343) / 2
utime.sleep(0.1)
trigger2.low()
utime.sleep_us(2)
trigger2.high()
utime.sleep_us(5)
trigger2.low()
while echo2.value() == 0:
signaloff2 = utime.ticks_us()
while echo2.value() == 1:
signalon2 = utime.ticks_us()
timepassed2 = signalon2 - signaloff2
Rdistance2 = (timepassed2 * 0.0343) / 2
newRdist = (Rdistance + Rdistance2) / 2
if newRdist > 120:
newRdist = 120
elif newRdist <= 100:
print("Distance Right less than 100")
return True
print("The distance Right from object is ",newRdist,"cm")
def ultradwn():
trigger4.low()
utime.sleep_us(2)
trigger4.high()
utime.sleep_us(5)
trigger4.low()
while echo4.value() == 0:
signaloff4 = utime.ticks_us()
while echo4.value() == 1:
signalon4 = utime.ticks_us()
timepassed4 = signalon4 - signaloff4
Ddistance = (timepassed4 * 0.0343) / 2
utime.sleep(0.1)
trigger4.low()
utime.sleep_us(2)
trigger4.high()
utime.sleep_us(5)
trigger4.low()
while echo4.value() == 0:
signaloff4 = utime.ticks_us()
while echo4.value() == 1:
signalon4 = utime.ticks_us()
timepassed4 = signalon4 - signaloff4
Ddistance2 = (timepassed4 * 0.0343) / 2
newDdist = (Ddistance + Ddistance2) / 2
if newDdist > 120:
newDdist = 120
elif newDdist >20 :
print("Distance Down is greater than 20")
x = 1
#uart.write("D20")
#uart.write("\n")
#print("Sent TO Height")
return True
elif newDdist <12 :
print("Distance Down is less than 12")
x = 2
#uart.write("D12")
#uart.write("\n")
#print("Sent Landed")
return True
print("The distance Down from object is ",newDdist,"cm")
def gps():
while True:
#baton.acquire()
rcvChar = ser.readline()
gps_data =rcvChar.decode("ASCII")
data = gps_data
if (data[0:6] == "$GPRMC"):
sdata = data.split(",")
if (sdata[2] == 'V'):
print("no satellite data available")
print ("---Parsing GPRMC---")
time = sdata[1][0:2] + ":" + sdata[1][2:4] + ":" + sdata[1][4:6]
lat = decode(sdata[3]) #latitude
dirLat = sdata[4] #latitude direction N/S
lon = decode(sdata[5]) #longitute
dirLon = sdata[6] #longitude direction E/W
speed = sdata[7] #Speed in knots
trCourse = sdata[8] #True course
date = sdata[9][0:2] + "/" + sdata[9][2:4] + "/" + sdata[9][4:6]#date
print ("time : %s, latitude : %s(%s), longitude : %s(%s), speed : %s, True Course : %s, Date : %s" % (time,lat,dirLat,lon,dirLon,speed,trCourse,date))
#baton.acquire()
#_thread.start_new_thread(gps(), ())
while True:
x = 0
#baton.acquire()
ultraleft()
utime.sleep(0.1)
ultraright()
utime.sleep(0.1)
ultradwn()
utime.sleep(0.1)
if ultraleft():
uart.write("LO")
uart.write("\n")
print("Sent Left")
utime.sleep(1)
if ultraright():
uart.write("RO")
uart.write("\n")
print("Sent Right")
uart.sendbreak()
utime.sleep(1)
if ultradwn():
if x == 1:
uart.write("D20")
uart.write("\n")
print("Sent TO Height")
utime.sleep(1)
if x == 2:
uart.write("D12")
uart.write("\n")
print("Sent Landed")
utime.sleep(1)
utime.sleep(1)
gps()
#baton.release()

Group people which have different locations

I need help. My function to group people does not really work. The problem is quite simple:
I have a dataframe with following columns:
latitude
longitude
floor
These columns are random locations of people.
The dataframe has a length of multiple of 9 (in this example the length is 36. I reality it is much longer).
I want to group people by the following idea:
First I create a new column with the name "group".
People who live close together (according to coordinates) are assigned to a specific group number (1, 2 3,...). Each group contains 3 people.
Now the tricky part: People with identical coordinates can not be in the same group!
This is how I did it:
Here is the data:
array_data=([[ 50.56419 , 8.67667 , 2. , 160. ],
[ 50.5643136, 8.6772816, 3. , 89. ],
[ 50.5646274, 8.6763909, 0. , 259. ],
[ 50.5661047, 8.6765931, 1. , 100. ],
[ 50.5663442, 8.6575205, 1. , 117. ],
[ 50.56686 , 8.67598 , 1. , 95. ],
[ 50.56747 , 8.67604 , 2. , 199. ],
[ 50.56762 , 8.6702799, 0. , 148. ],
[ 50.5693473, 8.6640855, -1. , 50. ],
[ 50.5693473, 8.6640855, 0. , 111. ],
[ 50.5705819, 8.6597279, 2. , 183. ],
[ 50.57067 , 8.65694 , 2. , 257. ],
[ 50.57075 , 8.65748 , 1. , 211. ],
[ 50.57075 , 8.65748 , 1. , 292. ],
[ 50.5722461, 8.6598248, 2. , 142. ],
[ 50.57254 , 8.65895 , 1. , 116. ],
[ 50.57259 , 8.6592 , 2. , 228. ],
[ 50.5731636, 8.667609 , 1. , 181. ],
[ 50.5737814, 8.6720067, 0. , 173. ],
[ 50.5740356, 8.6718179, 1. , 5. ],
[ 50.5746321, 8.6831284, 3. , 202. ],
[ 50.5747453, 8.6765588, 4. , 119. ],
[ 50.5748992, 8.6611471, 2. , 260. ],
[ 50.5748992, 8.6611471, 3. , 102. ],
[ 50.575 , 8.65985 , 2. , 267. ],
[ 50.5751 , 8.66027 , 2. , 7. ],
[ 50.5751 , 8.66027 , 2. , 56. ],
[ 50.57536 , 8.67741 , 1. , 194. ],
[ 50.57536 , 8.67741 , 1. , 282. ],
[ 50.5755255, 8.6884584, 0. , 276. ],
[ 50.5755273, 8.674282 , 3. , 167. ],
[ 50.57553 , 8.6826 , 2. , 273. ],
[ 50.5755973, 8.6847492, 0. , 168. ],
[ 50.5756757, 8.6846139, 4. , 255. ],
[ 50.57572 , 8.65965 , 0. , 66. ],
[ 50.57591 , 8.68175 , 1. , 187. ]])
Convert array to dataframe and rename the columns:
df = pd.DataFrame(data=array_data) # convert back to dataframe
df.rename(columns={0: 'latitude', 1: 'longitude', 2:'floor', 3:'id'}, inplace=True) # rename columns
Now we have the dataframe. With the following functions I was trying to group the people:
First we need to find a way, to get the distances to the people:
def calculate_distance(lat1, lon1, lat2, lon2):
"""
Calculate the shortest distance between two points given by the latitude and
longitude.
"""
earth_radius = 6373 # Approximate / in km.
lat1 = radians(lat1)
lon1 = radians(lon1)
lat2 = radians(lat2)
lon2 = radians(lon2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return earth_radius * c # in km.
And here is the main function. I try to group people if they have NOT the same location:
def sort_people(all_persons, max_distance_parameter):
'''
People in the same group have different location!
'''
assert len(all_persons) % 9 == 0
all_persons.set_index("id", drop=False, inplace=True)
all_persons["host"] = np.nan
all_persons["group"] = np.nan
scattering_factor= 0.0001 # to seperate same floor numbers
max_distance = max_distance_parameter
group_number = 0
group = []
for _, candidate in all_persons.iterrows():
if len(group) == 3:
for person in group:
all_persons.at[person["id"], "group"] = group_number
group_number += 1
group = []
if len(group) == 0:
group.append(candidate)
else:
for person in group:
distance = calculate_distance(
candidate["latitude"],
candidate["longitude"],
person["latitude"],
person["longitude"],
)
distance = distance
if candidate['floor'] == -1: # consider the floor when calculating the distance
distance = distance + scattering_factor + 0.001
elif candidate['floor'] == 0:
distance = distance + scattering_factor + 0.002
elif candidate['floor'] == 1:
distance = distance + scattering_factor + 0.003
elif candidate['floor'] == 2:
distance = distance + scattering_factor + 0.004
elif candidate['floor'] == 3:
distance = distance + scattering_factor + 0.005
elif candidate['floor'] == 4:
distance = distance + scattering_factor + 0.006
elif candidate['floor'] == 5:
distance = distance + scattering_factor + 0.007
elif candidate['floor'] == 6:
distance = distance + scattering_factor + 0.008
elif candidate['floor'] == 7:
distance = distance + scattering_factor + 0.009
elif candidate['floor'] == 8:
distance = distance + scattering_factor + 0.010
elif candidate['floor'] == 9:
distance = distance + scattering_factor + 0.011
elif candidate['floor'] == 10:
distance = distance + scattering_factor + 0.012
elif candidate['floor'] == 11:
distance = distance + scattering_factor + 0.013
elif candidate['floor'] == 12:
distance = distance + scattering_factor + 0.014
elif candidate['floor'] == 13:
distance = distance + scattering_factor + 0.015
elif candidate['floor'] == 14:
distance = distance + scattering_factor + 0.016
else:
distance = distance + scattering_factor + 0.017
if 0 < distance <= max_distance:
group.append(candidate)
break
Long story short: this doesn't really work. At the end, I get a dataframe and I find people in the same locations which are assigned to the same group. How would you do it?
Using your solution, add logic to see if the person with same coordinates is already in the group. When you check if the group has no people, add. But if there is a person in the group, for each person in the group calculate the distance between that person and the candidate. If it is 0, then break(exit and don't add the person to that group). Then go to next group and do the same.
Btw. I'm not familiar with this programming language so I might've written bad syntax, so please use the above pseudocode to be a guide. Cheers!
if len(group) == 0:
group.append(candidate)
else:
for person in group:
distance = calculate_distance(
candidate["latitude"],
candidate["longitude"],
person["latitude"],
person["longitude"],
)
distance = distance
**if distance == 0 : break;**
if candidate['floor'] == -1: # consider the floor when calculating the distance
distance = distance + scattering_factor + 0.001
elif candidate['floor'] == 0:
distance = distance + scattering_factor + 0.002
elif candidate['floor'] == 1:
distance = distance + scattering_factor + 0.003
elif candidate['floor'] == 2:
distance = distance + scattering_factor + 0.004
elif candidate['floor'] == 3:
distance = distance + scattering_factor + 0.005
elif candidate['floor'] == 4:
distance = distance + scattering_factor + 0.006
elif candidate['floor'] == 5:
distance = distance + scattering_factor + 0.007
elif candidate['floor'] == 6:
distance = distance + scattering_factor + 0.008
elif candidate['floor'] == 7:
distance = distance + scattering_factor + 0.009
elif candidate['floor'] == 8:
distance = distance + scattering_factor + 0.010
elif candidate['floor'] == 9:
distance = distance + scattering_factor + 0.011
elif candidate['floor'] == 10:
distance = distance + scattering_factor + 0.012
elif candidate['floor'] == 11:
distance = distance + scattering_factor + 0.013
elif candidate['floor'] == 12:
distance = distance + scattering_factor + 0.014
elif candidate['floor'] == 13:
distance = distance + scattering_factor + 0.015
elif candidate['floor'] == 14:
distance = distance + scattering_factor + 0.016
else:
distance = distance + scattering_factor + 0.017
if 0 < distance <= max_distance:
group.append(candidate)
break

How can I implement dynamic wait in it?

class getPageObj:
#staticmethod
def getIDByLabel(driver, form_type, label_name):
#driver = webdriver.Chrome(executable_path="D:\\chromedriver.exe")
if label_name.find("[") == -1:
xpath_exp = "//label[text()='"+label_name+"'][1]"
else:
label_sub_str = label_name[:label_name.find("[")]
label_indx_str = label_name[label_name.find("["):label_name.find("]") + 1]
xpath_exp = "//label[text()='" + label_sub_str + "']"+label_indx_str
if len(driver.find_elements_by_xpath(xpath_exp)) > 0:
if form_type == "Form":
id=getPageObj()
attr_id = id.getAttrValueByXPath(driver, xpath_exp, "for")
return attr_id
else:
id=getPageObj()
attr_id = id.getAttrValueByXPath(driver, xpath_exp, "for")
return attr_id

google-bigquery UDF for jaro_winkle_distance

I am the following UDF code that calculate jaro_winkle_distance
It seems to work when test it with json test data but when I try to call it in the google-bigquery UI, it keeps consistently gives me a score of zero.
even with self join e.g.
input:
[
{a: "Liu",b:"Lau"},
{a: "John",b:"Jone"}]
Output:
[
{
"scr": 80
},
{
"scr": 87
}
]
SQL:
CREATE TEMP FUNCTION
jwd(a STRING,
b STRING)
RETURNS INT64
LANGUAGE js AS """
// Assumes 'doInterestingStuff' is defined in one of the library files.
//return doInterestingStuff(a, b);
return jaro_winkler_distance(a,b);
""" OPTIONS ( library="gs://kayama808/javascript/jaro_winkler_google_UDF.js" );
SELECT
x.name name1,
jwd(x.name,
x.name) scr
FROM
babynames.usa_1910_2013_copy x
WHERE
x.gender = 'F' and x.number >= 1000 and x.state = 'CA'
ORDER BY
scr DESC;
http://storage.googleapis.com/bigquery-udf-test-tool/testtool.html
https://storage.cloud.google.com/kayama808/javascript/jaro_winkler_google_UDF.js?_ga=1.184402278.1320598031.1475534357
Try below. It works as expected with result as
name1 name2 scr
Liu Liu 100
John Jone 87
Liu Lau 80
Hopefully, you will be able to put it back to your external lib file :o)
CREATE TEMP FUNCTION jwd(a STRING, b STRING)
RETURNS INT64
LANGUAGE js AS """
/* JS implementation of the strcmp95 C function written by
Bill Winkler, George McLaughlin, Matt Jaro and Maureen Lynch,
released in 1994 (http://web.archive.org/web/20100227020019/http://www.census.gov/geo/msb/stand/strcmp.c).
a and b should be strings. Always performs case-insensitive comparisons
and always adjusts for long strings. */
var jaro_winkler_adjustments = {
'A': 'E',
'A': 'I',
'A': 'O',
'A': 'U',
'B': 'V',
'E': 'I',
'E': 'O',
'E': 'U',
'I': 'O',
'I': 'U',
'O': 'U',
'I': 'Y',
'E': 'Y',
'C': 'G',
'E': 'F',
'W': 'U',
'W': 'V',
'X': 'K',
'S': 'Z',
'X': 'S',
'Q': 'C',
'U': 'V',
'M': 'N',
'L': 'I',
'Q': 'O',
'P': 'R',
'I': 'J',
'2': 'Z',
'5': 'S',
'8': 'B',
'1': 'I',
'1': 'L',
'0': 'O',
'0': 'Q',
'C': 'K',
'G': 'J',
'E': ' ',
'Y': ' ',
'S': ' '
};
if (!a || !b) { return 0.0; }
a = a.trim().toUpperCase();
b = b.trim().toUpperCase();
var a_len = a.length;
var b_len = b.length;
var a_flag = []; var b_flag = [];
var search_range = Math.floor(Math.max(a_len, b_len) / 2) - 1;
var minv = Math.min(a_len, b_len);
// Looking only within the search range, count and flag the matched pairs.
var Num_com = 0;
var yl1 = b_len - 1;
for (var i = 0; i < a_len; i++) {
var lowlim = (i >= search_range) ? i - search_range : 0;
var hilim = ((i + search_range) <= yl1) ? (i + search_range) : yl1;
for (var j = lowlim; j <= hilim; j++) {
if (b_flag[j] !== 1 && a[j] === b[i]) {
a_flag[j] = 1;
b_flag[i] = 1;
Num_com++;
break;
}
}
}
// Return if no characters in common
if (Num_com === 0) { return 0.0; }
// Count the number of transpositions
var k = 0; var N_trans = 0;
for (var i = 0; i < a_len; i++) {
if (a_flag[i] === 1) {
var j;
for (j = k; j < b_len; j++) {
if (b_flag[j] === 1) {
k = j + 1;
break;
}
}
if (a[i] !== b[j]) { N_trans++; }
}
}
N_trans = Math.floor(N_trans / 2);
// Adjust for similarities in nonmatched characters
var N_simi = 0; var adjwt = jaro_winkler_adjustments;
if (minv > Num_com) {
for (var i = 0; i < a_len; i++) {
if (!a_flag[i]) {
for (var j = 0; j < b_len; j++) {
if (!b_flag[j]) {
if (adjwt[a[i]] === b[j]) {
N_simi += 3;
b_flag[j] = 2;
break;
}
}
}
}
}
}
var Num_sim = (N_simi / 10.0) + Num_com;
// Main weight computation
var weight = Num_sim / a_len + Num_sim / b_len + (Num_com - N_trans) / Num_com;
weight = weight / 3;
// Continue to boost the weight if the strings are similar
if (weight > 0.7) {
// Adjust for having up to the first 4 characters in common
var j = (minv >= 4) ? 4 : minv;
var i;
for (i = 0; (i < j) && a[i] === b[i]; i++) { }
if (i) { weight += i * 0.1 * (1.0 - weight) };
// Adjust for long strings.
// After agreeing beginning chars, at least two more must agree
// and the agreeing characters must be more than half of the
// remaining characters.
if (minv > 4 && Num_com > i + 1 && 2 * Num_com >= minv + i) {
weight += (1 - weight) * ((Num_com - i - 1) / (a_len * b_len - i*2 + 2));
}
}
return Math.round(weight*100);
""";
SELECT
name1, name2,
jwd(name1, name2) scr
FROM -- babynames.usa_1910_2013_copy x
(
select "Liu" as name1, "Lau" as name2 union all
select "Liu" as name1, "Liu" as name2 union all
select "John" as name1, "Jone" as name2
) x
ORDER BY scr DESC
In addition: I've just double checked your jaro_winkler_google_UDF2.js file and clearly see that issue is in this file.
Fix this file using code in my answer
Or, just remove below lines in it
var a = r.a;
var b = r.b;
and uncomment
//jaro_winkler.distance = function(a, b) {
//return Math.round(weight*100)
and comment all with emit in it
jaro_winkler_distance=function(r, emit) {
emit(weight);
You should be ok then!