I'm using this code to draw a random pics from this table
FishImages = {image1 = love.graphics.newImage("bg/fish1.png"),
image2 = love.graphics.newImage("bg/fish2.png"),
image3 = love.graphics.newImage("bg/fish3.png"),
image4 = love.graphics.newImage("bg/fish4.png"),}
with this function love.graphics.draw({FishImages.image1#--I guess the modification is here },pos.x,pos.y)
so how to pick up a random key from a table in Lua ?
math.random(1,4) generates a random integer in the range 1 to 4. So you can use:
FishImages['image' .. tostring(math.random(1,4))]
Related
Hi there, i want to insert a value between 0 and the output of function total polygons twice to the column of 'mer_value'(from the bottom left) of a shapefile so that the print output would look some thing like this.
mer_value
0.0
0.0
1.0
1.0
2.0
2.0
....
right now it only inserts the value from 0.0 all the way to the end repeating only once, like the below example.
mer_value
0.0
1.0
2.0
.....
any help is appreciated
{
import geopandas as gpd
number_of_geocells = 2
#create a funtion to read the total polygons in a given shapefile and divide it by the number of geocells and store the value in a new varialbe called "total_polygons"
def total_polygons(shapefile):
total_polygons = gpd.read_file(shapefile).shape[0] / number_of_geocells
total_geocells_per_zone_rounded = round(total_polygons)
return total_geocells_per_zone_rounded
#create a function to duplicate the shapefile and save it as a new shapefile called "zones"
def duplicate_shapefile(shapefile):
zones = gpd.read_file(shapefile)
zones.to_file("C:/tmp/shapefiletotestautomation/zones.shp")
return zones
#create a function to create a colum called 'mer_value' in the shapefile called "zones"
def create_merge_value(shapefile):
zones = gpd.read_file(shapefile)
zones['mer_value'] = zones.index
zones.to_file("C:/tmp/shapefiletotestautomation/zones.shp")
return zones
#create a loop to insert the same number twice to column "mer_value" in the shapefile called "zones"
def insert_merge_value(shapefile):
zones = gpd.read_file(shapefile)
for i in range(total_polygons(shapefile)):
zones.loc[i, 'mer_value'] = i
zones.loc[i + number_of_geocells, 'mer_value'] = i
zones.to_file("C:/tmp/shapefiletotestautomation/zones.shp")
return zones
print(insert_merge_value("C:/tmp/shapefiletotestautomation/m/GEOCELLS.shp"))
}
I'm struggling on passing the column value to a formula. I tried many different combinations but I only have it working when I hard code the column,
(tbl as table, col as list) =>
let
avg = List.Average(col),
sdev = List.StandardDeviation(col)
in
Table.AddColumn(tbl, "newcolname" , each ([column] - avg)/sdev)
I'd like to replace [column] by a variable. In fact, it's the column I use for the average and the standard deviation.
Please any help.
Thank you
This probably does what you want, called as x= fctn(Source,"ColumnA")
Does the calculations using and upon ColumnA from Source table
(tbl as table, col as text) =>
let
avg = List.Average(Table.Column(tbl,col)),
sdev = List.StandardDeviation(Table.Column(tbl,col))
in Table.AddColumn(tbl, "newcolname" , each (Record.Field(_, col) - avg)/sdev)
Potentially you want this. Does the average and std on the list provided (which can come from any table) and does the subsequent calculations on the named column in the table passed over
called as x = fctn(Source,"ColumnNameInSource",SomeSource[SomeColumn])
(tbl as table, cname as text, col as list) =>
let
avg = List.Average(col),
sdev = List.StandardDeviation(col)
in Table.AddColumn(tbl, "newcolname" , each (Record.Field(_, cname) - avg)/sdev)
In this raw data we have info of baseball players, the schema is:
name:chararray, team:chararray, position:bag{t:(p:chararray)}, bat:map[]
Using the following script we are able to list out players and the different positions they have played. How do we get a count of how many players have played a particular position?
E.G. How many players were in the 'Designated_hitter' position?
A single position can't appear multiple times in position bag for a player.
Pig Script and output for the sample data is listed below.
--pig script
players = load 'baseball' as (name:chararray, team:chararray,position:bag{t:(p:chararray)}, bat:map[]);
pos = foreach players generate name, flatten(position) as position;
groupbyposition = group pos by position;dump groupbyposition;
--dump groupbyposition (output of one position i.e Designated_hitter)
(Designated_hitter,{(Michael Young,Designated_hitter)})
From what I can tell you've already done all of the 'grunt' (Ha!, Pig joke) work. All there it left to do is use COUNT on the output of the GROUP BY. Something like:
groupbyposition = group pos by position ;
pos_count = FOREACH groupbyposition GENERATE group AS position, COUNT(pos) ;
Note: Using UDFs you may be able to get a more efficient solution. If you care about counting a certain few fields then it should be more efficient to filter the postion bag before hand (This is why I said UDF, I forgot you could just use a nested FILTER). For example:
pos = FOREACH players {
-- you can also add the DISTINCT that alexeipab points out here
-- make sure to change postion in the FILTER to dist!
-- dist = DISTINCT position ;
filt = FILTER postion BY p MATCHES 'Designated_hitter|etc.' ;
GENERATE name, FLATTEN(filt) ;
}
If none of the positions you want appear in postion then it will create an empty bag. When empty bags are FLATTENed the row is discarded. This means you'll be FLATTENing bags of N or less elements (where N is the number of fields you want) instead of 7-15 (didn't really look at the data that closely), and the GROUP will be on significantly less data.
Notes: I'm not sure if this will be significantly faster (if at all). Also, using a UDF to preform the nested FILTER may be faster.
You can use nested DISTINCT to get the list of players and than count it.
players = load 'baseball' as (name:chararray, team:chararray,position:bag{t:(p:chararray)}, bat:map[]);
pos = foreach players generate name, flatten(position) as position;
groupbyposition = group pos by position;
pos_count = foreach groupbyposition generate {
players = DISTINCT name;
generate group, COUNT(players) as num, pos;
}
I follow a help How to handle spill memory in pig from alexeipab, it really works fine, but I have another question now, same sample code:
pymt = LOAD 'pymt' USING PigStorage('|') AS ($pymt_schema);
pymt_grp_with_salt = GROUP pymt BY (key,salt)
results_with_salt = FOREACH pymt_grp {
--distinct
mid_set = FILTER pymt BY xxx=='abc';
mid_set_result = DISTINCT mid_set.yyy;
result = COUNT(mid_set_result)
}
pymt_grp = GROUP results_with_salt BY key;
result = FOREACH pymt_grp {
GENERATE SUM(results_with_salt.result); --it is WRONG!!
}
I can't use sum in that group, which it will be very different from result that calculated without salt.
is there any solution? if filter first, it will cost many JOIN job, and slow down the performance.
For this to work, you need to have many to one relationship between mid_set.yyy and salt, so that same value for mid_set.yyy from different rows is mapped into the same value of salt. If it is not, than that value of mid_set.yyy will appear in different bags produced by GROUP pymt BY (key, salt), survive DISTINCT in different salts, thus are included multiple times in the final rollup. That is why you can get wrong results when using salts and COUNT of DISTINCT.
An easy way could be to replace salt with mid_set.yyy itself or to write a UDF/static method which calculates salt by taking hash of mid_set.yyy and does mod N, where N could be 1 to infinity, for best distribution N should be a prime number.
Thanks alexeipab, you give me a great help, what i do as below
pymt = LOAD 'pymt' USING PigStorage('|') AS ($pymt_schema);
pymt = FOREACH pymt GENERATE *, (yyy%$prime_num) as salt;
pymt_grp_with_salt = GROUP pymt BY (key,salt);
It works!!
if yyy is num integer, you can use hash to convert string or others to a integer
I had to write a method that does the following:
There is a DataSet let's say CarDataSet with one table Car and contains Primary key Id and one more column ColorId. And there is a string with Ids seperated with commas for example "5,6,7,8" (random length). The task is to check if all appropriate ColorIds are identical for given Car Ids.
For example:
String ids = "5,6,7,8"
If all the Cars ColorIds are for example 3,3,3,3 where the Car Ids are 5,6,7,8 then return true;
In other words - check if all cars with given Ids are in one color. Now I don't have my code anymore but I made this using 3 foreach loops and 3 linq expressions. Is there any simplier way to do this?
If you want all cars have same color means all of them should have same color as first one:
// first find the cars with given ids
var selectedCars = Cars.Where(x=>ids.Contains(x.ID.ToString());
// select one of them as comparer:
var firstCar = selectedCars.FirstOrDefault();
if (firstCar == null)
return true;
// check all of them has same color as first one:
return selectedCars.All(x=>x.ColorID == firstCar.ColorID);
Edit: Or if you have no problem with throwing exception when there is no car with given ids you can use two query in lambda syntax:
var selectedCars = Cars.Where(x=>ids.Contains(x.ID.ToString()));
return selectedCars.All(x=>x.ColorID == selectedCars.First().ColorID);
You could do this by performing a distinct, and asserting the count is 1.
var colors = Cars.Where(x=>ids.Contains(x.ID.ToString())
.Select(x=>x.ColorID)
.Distinct().Count();
return count == 1;