Python method to create a dateutil.relativedelta.relativedelta object from a dict - python-dateutil

I'm using the following method to create the object stated in the title:
from dateutil import relativedelta
MA_dict = {'years': 0,
'months': 0,
'weeks': 0,
'days': 1,
'hours': 0,
'minutes': 0,
'seconds': 0}
def dict2relativedelta(dict):
'''
creates relativedelta variable that can be used to calculate dates
'''
dt = relativedelta.relativedelta(years=dict['years'], months=dict['months'], weeks=dict['weeks'], days=dict['days'],
hours=dict['hours'], minutes=dict['minutes'], seconds=dict['seconds'])
return dt
However, I would like to simplify this so that I can just pass
MA_dict = {'days': 1}
and the function will return the same. How can I do that?

You don't need a special function for this as Python has argument unpacking with the ** operator. You can accomplish what you want with:
MA_dict = {"days": 1}
rd = relativedelta.relativedelta(**MA_dict)

Related

OpenSCAD: How to avoid extra grouping in CSG tree

I want to write a module that can optionally combine its children as either a union or a difference.
module u_or_d(option="d") {
if (option == "d") {
difference() children();
} else {
union() children();
}
}
module thing(option) {
u_or_d(option) {
cube(10, center=true);
cylinder(h=20, d=5, center=true);
}
}
translate([-15, 0, 0]) thing("d");
translate([ 15, 0, 0]) thing("u");
I was surprised that this doesn't work. Both instances of thing appear to create a union of the cube and the cylinder.
The CSG Tree Dump shows the problem. Here's the relevant excerpt:
difference() {
group() {
cube(size = [10, 10, 10], center = true);
cylinder($fn = 0, $fa = 12, $fs = 2, h = 20, r1 = 2.5, r2 = 2.5, center = true);
}
}
The children are wrapped in a group, so the difference() effectively has only one child, which happens to be an implicit union of the wrapped children.
Is there a way to invoke children() that avoids this unwanted grouping? If not, is there another way for a module to allow the invoker to select how the module combines its children?
I found a solution:
module u_or_d(option="d") {
if (option == "d" && $children > 1) {
difference() {
children([0]);
children([1:$children-1]);
}
} else {
union() children();
}
}
You still get a group wrapped around each invocation of children, but at least we can make two groups.

Bokeh RangeSlider callback issue, source.change.emit() gives error "Cannot read property 'emit' of undefined"

I recently started on a new project that requires me to plot lat and long data on a map. I've managed to plot everything out so far, but I've gotten stuck at creating the callback function for the Range Slider I'm using to control which data to plot.
My current code uses this response here by Amstrad2Python as its base. Running the code that Amstrad2Python provided gave me no errors. However, when I try to run the code, it gives me the error "Cannot read property 'emit' of undefined" when I check the console output in the html plot.
Here is sample code that is similar to the actual code I am using, which creates the exact same error:
import bokeh.events as bev
import bokeh.layouts as bla
import bokeh.models as bmo
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
sample_data = pd.DataFrame(
data=np.array(
[
[1, 12, 21, 15000],
[2, 25, 90, 15500],
[3, 37, 47, 15500],
[4, 41, 56, 15000],
[5, 50, 21, 14500]
]
),
columns=['Seconds', 'lat', 'long', 'alt']
)
#create 2 sources, 1 for editting, 1 for referencing
source = bmo.ColumnDataSource(sample_data) #const data
filtered_source = bmo.ColumnDataSource(sample_data) #alterable data
#create callback function
callback = bmo.CustomJS(args=dict(source=source, filtered_source = filtered_source),
code="""
var data = source.data;
var start = cb_obj.value[0];
var end = cb_obj.value[1];
function generateNewDataObject(oldDataObject){
var newDataObject = {}
for (var key of Object.keys(oldDataObject)){
newDataObject[key] = [];
}
return newDataObject
}
function addRowToAccumulator(accumulator, dataObject, index) {
for (var key of Object.keys(dataObject)){
accumulator[key][index] = dataObject[key][index];
}
return accumulator;
}
var new_data = generateNewDataObject(data);
for (var i = 0; i < source.data['Seconds'].length; i++){
if (source.data['Seconds'][i] > start) {
if (source.data['Seconds'][i] <= end) {
new_data = addRowToAccumulator(new_data, source.data, i);
}
}
}
console.log(new_data)
filtered_source = new_data;
filtered_source.change.emit();
""")
#create slider and add on_change event
testSlider = bmo.RangeSlider(width = 525, bar_color = 'red',
start = 0, end = sample_data['Seconds'].max(),
value=(0,1), step = 1 )
testSlider.js_on_change('value', callback)
#create figure and plot points
p = figure(toolbar_location = 'below',
x_axis_label = 'Longitude', y_axis_label = 'Latitude')
p.circle(x = 'long', y = 'lat', source=filtered_source)
#create layout and show
layout = bla.column(p, testSlider)
show(layout)
For reference, this is the resulting error I get when I try to change the slider:
https://i.stack.imgur.com/OTBEm.png
Does anyone know what the issue is with my current code? Any feedback regarding to my code is also appreciated. Thank you in advance.
You need to assign the new_data to the .data field of filtered_source.
When changing the line filtered_source = new_data; to filtered_source.data = new_data;, your example works for me.

Creating a lookup table in CHISEL

I am trying to create a lookup table in Chisel of width 72 bits and 1024 entries. These 1024 entries are stored separately in a file, which I read into my code. The code I have written so far is:
import Chisel._
import scala.io.Source._
module mdlNm {
// function to read entries from file 'omega_i.dat'
def fileRead() = {
val fileIn = fromFile("omega_i.dat").getLines.toList
val num = fileIn.map(i => BigInt(i, 16)) // converting the hexadecimal entries from string to BigInt
val uInt = num.map(i => UInt(i, width = 72)) // converting BigInt entries to UInt of width 72
ROM (uInt) // Chisel construct for creating an LUT for fixed entries
}
// The above LUT is later read as follows:
val in = Bits("h123") // Any 10-bit input to the LUT
val lutOut = fileRead().read(in) // Value read from the LUT
}
The above code throws up many errors of the form:
cppBackend//sinCos.cpp:2407:23: error: ‘T1785’ was not declared in this scope
{ T425.put(1018, 0, T1785[0]); T425.put(1018, 1, T1785[1]);}
^
cppBackend//sinCos.cpp:2408:23: error: ‘T1786’ was not declared in this scope
{ T425.put(1019, 0, T1786[0]); T425.put(1019, 1, T1786[1]);}
^
cppBackend//sinCos.cpp:2409:23: error: ‘T1787’ was not declared in this scope
{ T425.put(1020, 0, T1787[0]); T425.put(1020, 1, T1787[1]);}
^
cppBackend//sinCos.cpp:2410:23: error: ‘T1788’ was not declared in this scope
{ T425.put(1021, 0, T1788[0]); T425.put(1021, 1, T1788[1]);}
^
cppBackend//sinCos.cpp:2411:23: error: ‘T1789’ was not declared in this scope
{ T425.put(1022, 0, T1789[0]); T425.put(1022, 1, T1789[1]);}
^
cppBackend//sinCos.cpp:2412:23: error: ‘T1790’ was not declared in this scope
{ T425.put(1023, 0, T1790[0]); T425.put(1023, 1, T1790[1]);}
However, when I change the width of uInt to any number <= 64, no such issues arise and the code works properly.
Is there an alternative way to create an LUT of the size I specified above, in Chisel? Or am I doing something wrong in the above code?
Please help.
In chisel3,, the current version, this would be constructed a little bit differently. VecInit is used instead of ROM
I would recommend the creation of an intermediate value lut to hold the rom created by buildLookupTable
because each call to buildLookupTable would read the file again and create another rom.
import chisel3._
import chisel3.util._
import firrtl.FileUtils
class SomeModule extends MultiIOModule {
def buildLookupTable(): Vec[UInt] = {
VecInit(FileUtils.getLines("file1.dat").map { s => BigInt(s, 16).U })
}
val lut = buildLookupTable()
// The above LUT is later read as follows:
val in = 0x123.U // Any 10-bit input to the LUT
val lutOut = lut(in) // Value read from the LUT
// rest of module
...
}
I don't know what the problem with lengths you had but I have tested the above with UInts with widths of 500 and it works fine.

How to find specific value in MongoDB-C driver

When my structure looks like this:
X: {
Y: "blabla"
}
So I use the function "bson_iter_find_descendant(&iter, "X.Y", &desc)" to recover my data. But how to retrieve the values of "X.Y", "X.Z"... when my structure looks like this:
X: [
{
Y: "blihblih"
},
{
Z: "bloublou"
}
]
Note that I use the latest version of MongoDB-C Driver ...
Thank you in advance!
//MONGOC_VERSION_S "0.92.3" ./configure --with-libbson=bundled
const bson_t *doc;
bson_iter_t iter;
bson_iter_t iter2;
uint32_t length;
mongoc_client_get_collection
mongoc_collection_find
mongoc_cursor_next
and then
bson_iter_init(&iter,doc);
bson_iter_find_descendant(&iter,"X.0.Y",&iter2); // for first
bson_iter_find_descendant(&iter,"X.1.Z",&iter2); // for second array element
printf("%d\n",bson_iter_type(&iter2));
for type 2
printf("%s\n",bson_iter_utf8(&iter2,&length));

DateTimeOffset adding TimeSpan returns invalid UTC offset for its TimeZoneInfo

I am in the process of building a temporal expression library that must be properly globalized and therefore work in all available Time Zones.
Now I seem to be stuck as I'm not sure how to retrieve adjusted dates from DateTimeOffset objects in the correct Daylight Savings Time (DST) when the transition boundary is crossed using any variety of .Add to move days, hours, etc.
Interestingly, I figured out a work around for the local system's Time Zone but haven't found any way to apply the same strategy to any arbitrary Time Zone.
I was able to find a snippet (didn't keep source, sorry!) which tries to reverse lookup the Time Zone Info by offset but as there are multiple potential results, each of which likely have different DST rules that will not work. (There may be some optimizations available but the base premis is flawed I think)
public TimeZoneInfo GetTimeZoneInfo(DateTimeOffset Value)
{
// Search available sytem time zones for a matching one
foreach (var tzi in TimeZoneInfo.GetSystemTimeZones())
{
// Compare value offset with time zone offset
if (tzi.GetUtcOffset(Value).Equals(Value.Offset))
{
return tzi;
}
}
}
This stuff can be a bit tedious to prove out so I've extracted the core issue into a couple methods and unit tests which will hopefully demonstrate the issue I'm facing.
public DateTimeOffset GetNextDay_Wrong(DateTimeOffset FromDateTimeOffset)
{
// Cannot create a new DateTimeOffset using simply the supplied value's UtcOffset
// because in PST, for example, it could be -7 or -8 depending on DST
return new DateTimeOffset(FromDateTimeOffset.Date.AddDays(1), FromDateTimeOffset.Offset);
}
[TestMethod]
public void GetNextDay_WrongTest()
{
var tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_Wrong(workingDate_tz);
var actual_failingDate_tz = GetNextDay_Wrong(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
public DateTimeOffset GetNextDay_LooksRight(DateTimeOffset FromDateTimeOffset)
{
// Because we cannot create a new DateTimeOffset we simply adjust the one provided!
var temp = FromDateTimeOffset;
// Move back to midnight of the current day
temp = temp.Subtract(new TimeSpan(temp.Hour, temp.Minute, temp.Second));
// Now move to the next day
temp = temp.AddDays(1);
// Let the DateTimeOffset class do it's magic
temp = temp.ToLocalTime();
// Check if the time zone has changed
if (FromDateTimeOffset.Offset != temp.Offset)
{
// Calculate the change amount (could be 30 mins or even stranger)
var delta = FromDateTimeOffset.Offset - temp.Offset;
// Adjust the temp value by the delta
temp = temp.Add(delta);
}
return temp.ToLocalTime();
}
[TestMethod]
public void GetNextDay_LooksRightTest()
{
// Everything is looking good and the test passes now, so we're home free yeah?
// { To work this needs to match your system's configured Local Time Zone, I'm in PST }
var tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_LooksRight(workingDate_tz);
var actual_failingDate_tz = GetNextDay_LooksRight(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
[TestMethod]
public void GetNextDay_LooksRight_FAILTest()
{
// Here is where the frustrating part is... aparantly the "magic" that DateTimeOffset provides only works for your systems Local Time Zone...
// { To properly fail this cannot match your system's configured Local Time Zone, I'm in PST so I use EST }
var tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_LooksRight(workingDate_tz);
var actual_failingDate_tz = GetNextDay_LooksRight(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
The underlying issue with this case is that there is not enough information to perform the appropriate Time Zone conversions. Simple offset is not specific enough to infer the Time Zone because for a given offset at a specific moment there can be multiple potential Time Zones. Because the DateTimeOffset object does not capture and maintain the information about the Time Zone it was created with it must be the responsibility of something external to that class to maintain this relationship.
The thing that threw me off the scent was the call ToLocalTime() which I later realized was in fact introducing an implied TimeZoneInfo into the calculation, that of the configured local time for the machine and I believe that internally the DateTimeOffset must be converting to UTC by simply removing the configured offset and then creating a new DateTimeOffset class using the constructor taking DateTime [in UTC] and TimeZoneInfo [from local system] to produce the correct dst aware resulting date.
Given this limitation I no longer see any value in the DateTimeOffset class over the equally accurate and more valuable combination of DateTime and TimeZoneInfo.