Need to explicitly use `cast` when using `pl.col` versus indexing seems inconsistent - python-polars

In the example below, why does scores.filter(scores["zone"] == "North") require adding .cast(str) to work while scores.filter(pl.col("zone") == "North") does not need casting? Interestingly, scores.filter(scores["zone"].is_in(["North", "South"])) works without casting when global string cache is on.
Using polars 0.15.14 (conda)
import polars as pl
pl.toggle_string_cache(True)
scores = pl.DataFrame(
{
"zone": pl.Series([
"North",
"North",
"North",
"South",
"South",
"East",
"East",
"East",
"East",
]).cast(pl.Categorical),
"funding": pl.Series(["yes", "yes", "no", "yes", "no", "no", "no", "yes", "yes"]).cast(pl.Categorical),
"score": [78, 39, 76, 56, 67, 89, 100, 55, 80],
}
)
# works with or without global string cache
scores.filter(pl.col("zone") == "North")
# works without global string cache
scores.filter(pl.col("zone").cast(str).is_in(["North", "South"]))
# works with global string cache
scores.filter(pl.col("zone").is_in(["North", "South"]))
# works with global string cache
scores.filter(scores["zone"].is_in(["North", "South"]))
# requires cast(str)
scores.filter(scores["zone"] == "North")
# works with or without global string cache
scores.filter(scores["zone"].cast(str) == "North")
A related question about the need to cast is shown below. Here, using pl.col requires explicit casting to a float but using [] indexing does not.
zone_count = scores.groupby("zone").agg(pl.count("zone").alias("count"))
# converts to float automatically
zone_count["count"] / 100
# does not convert to float
zone_count.select(pl.col("count")) / 100
# need to explicitly cast to float
zone_count.select(pl.col("count").cast(float)) / 100
Related question here:
Python-Polars: How to filter categorical column with string list

Related

How to add data to an MUI table column-wise instead of row-wise?

Good day! Here is the sandbox react code that I'm using for a project involving MUI tables:
I have been racking my brain over this, but can't seem to get a solution. How can I add to this table column-wise instead of by row?
In line 57-67, the rows are created first and then they are populated row-wise, left-to-right by data.
The data given looks like this:
const data = [
{name: "sample_name",
calories: "19",
fat: "90",
carbs: 70,
protein: 90},
{name: "sample_name",
calories: "19",
fat: "90",
carbs: 70,
protein: 90},
]
What the lines I mentioned do is it takes 1 of the objects in the data and appends them row-wise
I work with a data that looks like this:
const name = ["richard","nixon"]
const calories = [9, 9, 0, 9, 0, 5, 8]
const fat = [10, 9 , 9]
const carbs = [11, 3, 4,5 ]
const protein = [1, 1]
I just want to be able to insert name data into the name column... and so on... this should also hopefully make it easier for me to dynamically insert more data for each column using TextField+button action
Seems to me like this is a data issue, not Material UI. You need to provide row and column data to a table, regardless of what library you use, that's just how tables are build. So if you are getting back data by columns, you need a reducer or a method to convert them into rows. Here is a super quick and dirty example:
const rawData = {
name: ["Ice cream", "Sno cone"],
calories: [32, 45]
};
let columns = Object.keys(rawData);
let rows = rawData.name.map((name, i) => {
return { name, calories: rawData.calories[i] };
});
/*
rows = ["name", "calories"]
columns = [
{ name: "Ice cream", calories: 32 },
{ name: "Sno cone", calories: 45 },
];
*/
Obviously, this is a quick example and not very extensible, but should lead you in a good direction. Perhaps a reducer which could build out row data more elegantly. However, this will allow you to build out the table as intended:
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
{columns.map((i) => (
<TableCell>{i}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell>{row.calories}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>

OrientDB add/edit description attribute of classes with SQL

I am using OrientDB 3.1.1. All the classes have a 'description' attribute whose value is by default null. Is there any way to add description to the class through SQL or by other means.
I have tried ALTER CLASS <className> DESCRIPTION "some text as description". Does not work at all.
It should be a simple matter to update the description but apparently it does not seem to be that way for some reason.
Below is an example of a built in class but it holds good for all classes.
{
customFields: null
defaultClusterId: 10
strictMode: false
description: null
abstract: false
clusterIds: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
superClass: null
name: V
clusterSelection: round-robin
shortName: null
overSize: 0.0
properties: []
superClasses: null
}
After some experimentation; I found that the following syntax works to add or alter a description for a class (though it is not explicitly documented in manual).
ALTER CLASS xClass DESCRIPTION `xClass desc1`
Note the tick (``) marks, not single quotes; double quotes will also not work
{
"customFields": null,
"defaultClusterId": 22,
"strictMode": false,
"description": "xClass desc1",
"abstract": false,
"clusterIds": [22, 23, 24, 25],
"superClass": null,
"name": "xClass",
"clusterSelection": "round-robin",
"shortName": null,
"overSize": 0.0,
"properties": [],
"superClasses": null
}
With the above command the description can be set or altered, as observed in the above example.
NOTE: In case of attribute the syntax is similar, single quote needs to be used instead of tick marks.

Dart How to filter a map by keys

How to handle a map based on the keys?
If in my map the key is equal to my variable then I want to create a list which contains my map
If in my map the key is not equal to my variablecthen I want to create a list which contains 2 map objects with the key which has the nearest lower value and the key which has the nearest higher value
int myVar = 100;
Map values = {
"-900" : 183,
"-800" : 164,
"-700" : 144,
"-600" : 124,
"-500" : 104,
"-400" : 84,
"-300" : 63,
"-200" : 42,
"-100" : 21,
"0" : 0,
"100" : -22,
"200" : -43,
"300" : -64
};
For the exemple with myVar = 100, I want to have this:
int myVar = 100;
Map values = {
"100" : -22,
};
And if myVar = 112 for exemple I need to have the closest keys values. My result must be :
Map values = {
"100" : -22,
"200" : -43,
};
I don't know how to do that.I had perhaps the idea to transform the map into a map list to be able to use the list functions.
List<Map> values = [
{
"arg1" :-900,
"arg2": 183
},
{
"arg1" :-800,
"arg2": 164
},
{
"arg1" :-700,
"arg2": 144
},
// Some other values ...
];
List newValues = values.where((c) => c['arg1'] == 100).toList();
is this the right method? How to transform my basic map if yes ?
EDIT : With the help of #jamesdlin I tried this but I have an error.
import 'dart:collection';
void main() {
int myVar = 100;
Map<int, int> values = {
-900 : 183,
-800 : 164,
-700 : 144,
-600 : 124,
-500 : 104,
-400 : 84,
-300 : 63,
-200 : 42,
-100 : 21,
0 : 0,
100 : -22,
200 : -43,
300 : -64
};
print(values);
Map<int, int> filter(int myVar, SplayTreeMap<int, int> values) {
if (values.containsKey(myVar)) {
return {myVar: values[myVar]};
}
int lowerKey = values.lastKeyBefore(myVar);
int upperKey = values.firstKeyAfter(myVar);
return {
if (lowerKey != null) lowerKey: values[lowerKey],
if (upperKey != null) upperKey: values[upperKey],
};
}
print(filter(myVar, values));
}
I have this on dartpad :
: TypeError: Instance of 'JsLinkedHashMap<int, int>': type 'JsLinkedHashMap<int, int>' is not a subtype of type 'SplayTreeMap<int, int>'Error: TypeError: Instance of 'JsLinkedHashMap<int, int>': type 'JsLinkedHashMap<int, int>' is not a subtype of type 'SplayTreeMap<int, int>'
By default, Map is a LinkedHashMap, where iteration order is key insertion order. For your use, you instead probably will want to use a SplayTreeMap where lookups are O(log n) instead of (ideally) O(1) (WRT the number of elements), but iteration order is in ascending order of keys. This would allow you to use the lastKeyBefore(key) and firstKeyAfter(key) methods to find the previous and next elements if the key isn't directly contained.
I also would recommend that you use int as the key instead of a String. If you use a String, the default ordering will be a lexicographic order ("1" < "10" < "100" < "2"). You could supply you own comparison callback to SplayTreeMap to parse Strings into ints when comparing, but doing so would still require parsing the same Strings multiple times. It'd be much simpler and more efficient to store ints as the keys directly.
Using int keys with a SplayTreeMap, it'd look something like:
import 'package:collection/collection.dart'; // For SplayTreeMap
Map<int, int> filter(int myVar, SplayTreeMap<int, int> values) {
if (values.containsKey(myVar)) {
return {myVar: values[myVar]};
}
int lowerKey = values.lastKeyBefore(myVar);
int upperKey = values.firstKeyAfter(myVar);
return {
if (lowerKey != null) lowerKey: values[lowerKey],
if (upperKey != null) upperKey: values[upperKey],
};
}

Sort array by difference from the given value

I am trying to sort an array of football players - "players". The array consists of players and a single player has the following structure:
var player1 = ["name" : "Joe Smith",
"height": "42.00",
"experience": "yes",
"guardian" : "Jim and Jan Smith"]
The sorting that I would like should be based on the difference in player's height from their average height. So, the average height is 42.4. The player whose height is very close to the average height should be the first one after sorting, and the player whose height is really different from the average should be the last one.
As I understand, it is supposed to follow the following logic:
for player in players {
temp value = averageHeight - player["height"]
}
and then you compare value to values that have been already sorted and insert it in the correct position, however, this is my problem. I have problems writing this algorithm. Looking for any thoughts or pseudocode that would help resolve this issue. Thank you.
I strongly recommend that you convert your data to structs. This would allow you to do these kinds of calculations easily and without having to deal with string conversions all the time.
struct Player {
let name: String
let height: Double
}
var players = [
Player(name: "Foo", height: 42),
Player(name: "Bar", height: 1),
Player(name: "Baz", height: 100)
]
let avgHeight = players.reduce(0.0) { $0 + $1.height } / Double(players.count)
print(avgHeight)
players.sort { player1, player2 in
return abs(player1.height - avgHeight) < abs(player2.height - avgHeight)
}
print(players)
I think you are missing an abs(). Because sorting by averageHeight - player["height"] does not differ from sorting by player["height"] backwards. But sorting by abs(averageHeight - player["height"]) would do what you describe.
Then you can go for sort(by:):
players.sort(by:{abs(averageHeight-$0.height)<abs(averageHeight-$1.height)})
At least that is what I think, but I do not know Swift (ok, I have one from Suzuki)

SoapUI property transfer, using result to look up values

I'm trying to do a property transfer with SoapUI with a groovy script for a Json response. However, I'm not too familiar with groovy so I'm not having any luck.
What I'm trying to do is the following. I want to set the values corresponding to the output for the three digits below, "digit1", "digit2" and "digit3". So I should have three variables with the values "digit1totransfer" = 2, "digit2totransfer" = 1, "digit3totransfer" = 4.
Response
{
"ApiSuccess": true,
"Data": {
"LogOnResult": 1,
"Token": "1",
"LogOnStep1Result": {
"Digit1": 2,
"Digit2": 1,
"Digit3": 4
}
},
"SessionId": ""
}
I then want to use the "digit1totransfer" (so in this case 2) to look up a different values from a known list. The values that for the lookup are [9,8,7,6,5,4]. And then save that looked up value. So I should have a variable called "outputDigit1" with a value of 8. This will be repeated for "digit2totransfer" and "digit3totransfer" with a separate output variable for each.
I then want to transfer these "outputdigit1", "outputdigit2" and "outputdigit3" into a request, the input to the request are called "code1", "code2" and code "code3". See request below.
{
"code1": 8,
"code2": 9,
"code3": 6
}