Snowpark with GEOMETRY type fails - snowflake-cloud-data-platform

I try to parse WKT and create GEOMETRY type with Snowpark Python API, but it fails:
session.sql("select to_geometry('POINT(1820.12 890.56)')").show()
TypeError: '>' not supported between instances of 'NoneType' and 'int'
I tested both Version 0.9.0 and 0.8.0, same result
The above SQL works fine in Snowflake's worksheets

It seems Snowpark Python can not handle the output of the geometry objects when showing. This is the failing code in type_utils.py:
if column_type_name == "DECIMAL" or (
(column_type_name == "FIXED" or column_type_name == "NUMBER") and scale != 0
):
if precision != 0 or scale != 0:
if precision > DecimalType._MAX_PRECISION:
return DecimalType(
DecimalType._MAX_PRECISION,
scale + precision - DecimalType._MAX_SCALE,
)
else:
return DecimalType(precision, scale)
else:
return DecimalType(38, 18)
The code fails when it can't determine the precision. So adding a check mitigates the issue:
if column_type_name == "DECIMAL" or (
(column_type_name == "FIXED" or column_type_name == "NUMBER") and scale != 0
):
if precision is None:
return DecimalType(precision, scale)
if precision != 0 or scale != 0:
if precision > DecimalType._MAX_PRECISION:
return DecimalType(
DecimalType._MAX_PRECISION,
scale + precision - DecimalType._MAX_SCALE,
)
else:
return DecimalType(precision, scale)
else:
return DecimalType(38, 18)
Please submit a support ticket to Snowflake, so the code can be fixed.

Related

cellvariable*Diffusion in fipy

I am trying to solve the following coupled pde's in fipy. I tried the following
eq1 = (DiffusionTerm(coeff=1, var=f)-f*DiffusionTerm(coeff=1, var=phi)
+f-f**3 == 0)
eq2 = (2*DiffusionTerm(coeff=f, var=phi)+f*DiffusionTerm(coeff=1, var=phi)
== 0)
eq = eq1 & eq2
eq.solve()
but it does not like "f*DiffusionTerm(coeff=1, var=phi)" and I get the error.
"TermMultiplyError: Must multiply terms by int or float." Is there a way that I can implement a cell variable times a diffusion term?
Neither of the following will work in FiPy,
from fipy import CellVariable, DiffusionTerm, Grid1D
mesh = Grid1D(nx=10)
var = CellVariable(mesh=mesh)
# eqn = var * DiffusionTerm(coeff=1)
eqn = ImplicitSourceTerm(coeff=DiffusionTerm(coeff=1))
eqn.solve(var)
They both simply don't make sense with respect to the discretization in the finite volume method. Regardless, you can use the following identity to rewrite the term of interest
Basically, instead of using
var * DiffusionTerm(coeff=1)
you can use
DiffusionTerm(coeff=var) - var.grad.mag**2
Giving a regular diffusion term and an extra explicit source term.

Titanic Dataset. Logistic Regression Model. Confusion Matrix gives 0 as output

I am running the logistic regression model on the Titanic Dataset with the below code:
#Modeling
#Split into train and test and fit the logistic regression model
titanic_train <- titanic_complete[1:891,]
titanic_test <- titanic_complete[892:1309,]
##############Logistic Regression ###############################
glm_model = glm(Survived~.,data= titanic_train, family = 'binomial')
summary(glm_model)
## Using anova() to analyze the table of devaiance
anova(glm_model, test="Chisq")
final_model = glm(Survived~Sex + Pclass + Age + SibSp + Cabin_f, data = titanic_train, family = 'binomial')
summary(final_model)
varImp(glm_model)
glm.pred <-predict(final_model, titanic_test, type = 'response')
glm.pred <- ifelse(glm.pred > 0.5, "yes", "no")
glm.pred
confusionMatrix(glm.pred, titanic_test$Survived)
As a result I've got this error message:
> confusionMatrix(glm.pred, titanic_test$Survived)
[1] no yes
<0 rows> (or 0-length row.names)
In Ops.factor(predictedScores, threshold) :
‘<’ not meaningful for factors
Cannot understand this error message and what is wrong. The model is working fine on the train data.
I assume it is related to the threshold i apply to the Survived variable (which is a factor variable - 1,0).

invalid sign in external "numeric" value error from Npgsql Binary copy

I get this error on using Npgsql Binary copy (see my implementation at the bottom):
invalid sign in external "numeric" value
The RetailCost column on which it fails has the following PostgreSQL properties:
type: numeric(19,2)
nullable: not null
storage: main
default: 0.00
The PostgreSQL log looks like this:
2019-07-15 13:24:05.131 ACST [17856] ERROR: invalid sign in external "numeric" value
2019-07-15 13:24:05.131 ACST [17856] CONTEXT: COPY products_temp, line 1, column RetailCost
2019-07-15 13:24:05.131 ACST [17856] STATEMENT: copy products_temp (...) from stdin (format binary)
I don't think it should matter, but there are only zero or positive RetailCost values (no negative or null ones)
My implementation looks like this:
using (var importer = conn.BeginBinaryImport($"copy {tempTableName} ({dataColumns}) from stdin (format binary)"))
{
foreach (var product in products)
{
importer.StartRow();
importer.Write(product.ManufacturerNumber, NpgsqlDbType.Text);
if (product.LastCostDateTime == null)
importer.WriteNull();
else
importer.Write((DateTime)product.LastCostDateTime, NpgsqlDbType.Timestamp);
importer.Write(product.LastCost, NpgsqlDbType.Numeric);
importer.Write(product.AverageCost, NpgsqlDbType.Numeric);
importer.Write(product.RetailCost, NpgsqlDbType.Numeric);
if (product.TaxPercent == null)
importer.WriteNull();
else
importer.Write((decimal)product.TaxPercent, NpgsqlDbType.Numeric);
importer.Write(product.Active, NpgsqlDbType.Boolean);
importer.Write(product.NumberInStock, NpgsqlDbType.Bigint);
}
importer.Complete();
}
Any suggestions would be welcome
I caused this problem when using MapBigInt, not realizing the column was accidentally numeric(18). Changing the column to bigint fixed my problem.
The cause of the problem was that the importer.Write statements was not in the same order as the dataColumns

How to get the arclen between two curve points in Maya?

In Maya 2015, I can get the arclen of a curve using this command:
cmds.arclen('bezier1')
But now I want to get the arclen of two points in my curve. Is there anyway to get this?
Using the Maya API, you can use the MFnNurbsCurve::findLengthFromParam (Maya 2016+ only). If you need it between two points, then call this function with each parameters and subtract.
If you don't want to use the api, then the other option is create a duplicate of your original curve and use "detach" it at the needed points and then use the arclen command on that new curve to get your length. So that is another way.
Note that when detaching a curve, it appears to try to keep the curvature as close the original as possible, but this isn't exact so the length may not be the same compared to the original curve. Maybe rebuilding the curve to have more points may increase the accuracy if that is an important factor for you.
Using Maya's API is surely the best way to do it as #scottiedoo said, but here is a function I made when I didn't know API and which gives you the same results.
from maya import cmds
def computeCrvLength(crv, startParam = None, endParam = None):
'''
Compute the length of a curve between the two given UParameters. If the both
UParameters arguments are set to None (default), will compute the length of
the whole curve.
Arguments:
- crv = string; an existing nurbCurve
- startParam = 0 <= float <= 1 or None; default = None; point parameter
value, if not None, will compute the points only between the startPt and
EndPt values.
- endParam = 0 <= float <= 1 or None; default = None; point parameter
value, if not None, will compute the points only between the startPt and
EndPt values.
Returns:
- The length of the curve between the given UParameters
- The length of the curve from its start to the startParam
- The length of the curve from its start to the endParam
'''
###### Exceptions
if cmds.objExists(crv) == False:
cmds.error ('The curve "%s" does\'nt exists.' % crv)
if cmds.filterExpand (crv, sm = 9) == None:
cmds.error ('The object "%s" is not a nurbCurve.' % crv)
if startParam != None:
if (0 <= startParam <= 1) == False:
cmds.error ('The start point parameter value must be between 0 and 1.')
if endParam != None:
if (0 <= endParam <= 1) == False:
cmds.error ('The end point parameter value must be between 0 and 1.')
if (startParam == None and endParam != None) or (startParam != None and endParam == None):
cmds.error ('The start and end points parameters must be both None or ' +
'both have values.')
if startParam != None and endParam != None:
if endParam < startParam:
cmds.error ('The end point parameter value cannot be less or ' +
'equal to start point parameter value.')
###### Function
if startParam == None and endParam == None:
crvLength = cmds.arclen (crv, ch = False)
distCrvToStartParam = 0
distCrvToEndParam = crvLength
else:
tmpArclenDim = cmds.arcLengthDimension (cmds.listRelatives(crv, s = True)[0]
+ '.u[0]')
cmds.setAttr (cmds.listRelatives(tmpArclenDim, p = True)[0] +
'.uParamValue', startParam)
distCrvToStartParam = cmds.getAttr (tmpArclenDim + '.al')
cmds.setAttr (cmds.listRelatives(tmpArclenDim, p = True)[0] +
'.uParamValue', endParam)
distCrvToEndParam = cmds.getAttr (tmpArclenDim + '.al')
cmds.delete (tmpArclenDim)
crvLength = (distCrvToEndParam - distCrvToStartParam)
return crvLength, distCrvToStartParam, distCrvToEndParam

Custom matchers in rspec

I am writing my first custom matcher in rspec. I would like to provide a failure message with a break down on why the comparison has failed. Effectively I would like to output the differences between the expected and the actual object. I effectively just need to do this with 2 arrays on the object. I have done some research and am trying to use =~ as described here. It mentions it has an informative failure message but I am struggling to access the failure message. I would effectively just like to return the combined failure message for two separate arrays to give an informative reason for the matcher returning false.
My attempt is as follows
RSpec::Matchers.define :have_same_state_as_measure_table do |expected_measure_table , max_delta = 1e-06|
match do |actual_measure_table|
actual_measure_table.equivalence(expected_measure_table, max_delta)
end
description do
"checks if measure has same state as expected measure table within a given number of precision"
end
# Optional method description
description do
"checks if measure has same state as expected measure table, within a given level of precision"
end
# Optional failure messages
failure_message do |actual_measure_table|
mismatch_string = ""
mismatch_string += (actual_measure_table.columns =~ expected_measure_table.columns || "")
mismatch_string += (actual_measure_table.names =~ expected_measure_table.names || "")
"Measure tables missmatch as follows %s" % (mismatch_string.to_s)
end
failure_message_when_negated do |actual_measure_table|
"expected friend not to be in zipcode"
end
end
My final matcher was as follows :
class CompareMeasureTables
attr_reader :expected_measure_table, :max_delta, :actual_measure_table
def initialize(expected_measure_table, max_delta=1e-06)
#expected_measure_table = expected_measure_table
#max_delta = max_delta
end
def description
"Checks if measure has same state as expected measure table, within a given level of precision"
end
def matches?(actual_measure_table)
#actual_measure_table = actual_measure_table
actual_measure_table.equivalence(expected_measure_table, max_delta, false)
end
def failure_message
#mismatch_description = ""
if actual_measure_table.columns.sort != expected_measure_table.columns.sort
#mismatch_description += "\nColumns mismatch \nExpected =" + expected_measure_table.columns.inspect
#mismatch_description += "\nActual =" + actual_measure_table.columns.inspect
end
if (#mismatch_description == "")
#mismatch_description += "\nData mismatch \nExpected =" + (expected_measure_table.records - actual_measure_table.records).inspect
#mismatch_description += "\nActual =" + (actual_measure_table.records - expected_measure_table.records).inspect
#mismatch_description += "\nTolerance set at #{#max_delta}"
end
"Measure tables mismatch as follows %s" % (#mismatch_description)
end
end

Resources