I am having trouble getting "hours" int value from hive box and get the sum of all hours total and display it in a card as a String hours. what I have is:
var data = fastBox.values.where((element) => element.hours !=
0).toList();
if (fastBox.isNotEmpty){
int hoursInt = data.reduce((value, element) => {
value.hours + element.hours
});
hours = "${hoursInt.toString()}";
} else{
hours = "0 " + Languages.of(context)!.hours;
}`
i am getting error:
Class 'List<dynamic>' has no instance getter 'hours'.
Receiver: Instance(length:1) of '_GrowableList'
Tried calling: hours
my hive is:
#HiveType(typeId: 4)
class FastHive{
#HiveField(0)
final int days;
#HiveField(1)
final List<DateTime> dates;
#HiveField(2)
final int hours;
#HiveField(3)
DateTime startTime;
#HiveField(4)
DateTime endTime;
FastHive(this.days, this.dates, this.hours, this.startTime,
this.endTime);
}
just learning here. pls, help! Thank you!
Related
Working in Google Scripts, I'm trying to create a function that will look at the names of all tabs in a Google Sheet, and delete all sheets that meet these conditions: 1) tab name include a date (sheet names that do have a date are prefaced with some other text - the mm/dd/yyyy formatted date is in the string) and 2) the date in that sheet name is older than today's date minus 2 days).
There are two sheet names that include dates: "Leadership Review mm/dd/yyyy" and "Leadership Review w/notes mm/dd/yyyy". I have a script that auto-runs DAILY to create these sheets, so the goal is to automate a one-time clean-up for old sheets and set up a daily trigger to auto-run that function.
So far, I've created an array to capture the names of each sheet name ("tabNameArray") and have a regexp for use in matching for mm/dd/yyyy text that shows up in a sheet name.
My thought on how this would work - not sure how to accomplish 2 and 3:
create that array
parse the array - match each sheetname in the array against the regexp mm/dd/yyyy to identify sheetnames with a date.
A loop through that array... IF that sheetname has a date (create a new array or subarray with just those? doesn't seem necessary, but a thought), AND that date is > 2 days from today(), delete those sheets.
function deleteOldReportSheets() {
var sheetNameArray = new Array();
var sheetWithDatesArray = new Array(); //not sure this is necessary
var dateRegex = new RegExp("[0-3]?[0-9]\/[0-3]?[0-9]\/(?:[0-9]{2})?[0-9]{2}"); //for mm/dd/yyyy match, tested successfully on regex101.com
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i=0 ; i<sheets.length ; i++) sheetNameArray.push( [ sheets[i].getName() ] ) // populates the sheetNameArray with names of each sheet
(do this: for sheets that have a date that is older than 2 days from today, delete...)
I'd appreciate support to code this - even better if there's a more efficient way than what I started thinking through.
Thanks for your assistance.
Description
The following example will compare the named sheets containing the date to today and indicate which sheets should be deleted. I leave the deletion operation to the OP.
Script
function test() {
try {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let sheets = spread.getSheets();
let dateRegex = new RegExp("[0-3]?[0-9]\/[0-3]?[0-9]\/(?:[0-9]{2})?[0-9]{2}"); //for mm/dd/yyyy match, tested successfully on regex101.com
let today = new Date();
console.log("today = "+Utilities.formatDate(today,"GMT","MM/dd/yyyy"));
today = new Date(today.getFullYear(),today.getMonth(),today.getDate()-2);
for( let i=0; i<sheets.length; i++ ) {
let sheet = sheets[i];
let name = sheet.getName();
console.log("Sheet name = "+name);
let match = name.match(dateRegex);
if( match ) {
match = new Date(match[0]);
if( match.valueOf() <= today.valueOf() ) {
console.log("delete");
}
else {
console.log("keep");
}
}
}
}
catch(err) {
console.log(err);
}
}
Console.log
11:45:16 AM Notice Execution started
11:45:17 AM Info today = 05/01/2022
11:45:17 AM Info Sheet name = Sheet1
11:45:17 AM Info Sheet name = Sheet 04/29/2022
11:45:17 AM Info delete
11:45:17 AM Info Sheet name = Sheet 04/30/2022
11:45:17 AM Info keep
11:45:17 AM Info Sheet name = Sheet 05/01/2022
11:45:17 AM Info keep
11:45:16 AM Notice Execution completed
Reference
Date()
String.match()
I think it can be something like this:
function myFunction() {
const reg = new RegExp(/\d{2}\/\d{2}\/\d{4}/);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const if_two_days_ago = date =>
new Date(date).valueOf() < new Date().valueOf() - 3600000 * 48;
ss.getSheets()
.filter(s => reg.test(s.getName()))
.filter(s => if_two_days_ago(s.getName().match(reg)))
.forEach(s => { console.log('bye-bye -->', s.getName()); ss.deleteSheet(s) });
}
Delete Sheets with dates older than two days
function delSheets() {
const ss = SpreadsheetApp.getActive();
const dt = new Date();
const dtv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate() - 2).valueOf();//date threshold value
ss.getSheets().forEach(sh => {
let m = sh.getName().match(/\d{1,2}\/\d{1,2}\/\d{4}/g);//includes a date
if(m && new Date(m[0]).valueOf() < dtv) {
ss.deleteSheet(sh);
}
});
}
I am trying to write a test for a before trigger that takes fields from a custom object and concatenates them into a custom Key__c field.
The trigger works in the Sandbox and now I am trying to get it into production. However, whenever I try and do a System.assert/assertEquals after I create a purchase and perform DML, the value of Key__c always returns null. I am aware I can create a flow/process to do this, but I am trying to solve this with code for my own edification. How can I get the fields to concatenate and return properly in the test? (the commented out asserts are what I have tried so far, and have failed when run)
trigger Composite_Key on Purchases__c (before insert, before update) {
if(Trigger.isBefore)
{
for(Purchases__c purchase : trigger.new)
{
String eventName = String.isBlank(purchase.Event_name__c)?'':purchase.Event_name__c+'-';
String section = String.isBlank(purchase.section__c)?'':purchase.section__c+'-';
String row = String.isBlank(purchase.row__c)?'':purchase.row__c+'-';
String seat = String.isBlank(String.valueOf(purchase.seat__c))?'':String.valueOf(purchase.seat__c)+'-';
String numseats = String.isBlank(String.valueOf(purchase.number_of_seats__c))?'':String.valueOf(purchase.number_of_seats__c)+'-';
String adddatetime = String.isBlank(String.valueOf(purchase.add_datetime__c))?'':String.valueOf(purchase.add_datetime__c);
purchase.Key__c = eventName + section + row + seat + numseats + adddatetime;
}
}
}
#isTest
public class CompositeKeyTest {
public static testMethod void testPurchase() {
//create a purchase to fire the trigger
Purchases__c purchase = new Purchases__c(Event_name__c = 'test', section__c='test',row__c='test', seat__c=1.0,number_of_seats__c='test',add_datetime__c='test');
Insert purchase;
//System.assert(purchases__c.Key__c.getDescribe().getName() == 'testesttest1testtest');
//System.assertEquals('testtesttest1.0testtest',purchase.Key__c);
}
static testMethod void testbulkPurchase(){
List<Purchases__c> purchaseList = new List<Purchases__c>();
for(integer i=0 ; i < 10; i++)
{
Purchases__c purchaserec = new Purchases__c(Event_name__c = 'test', section__c='test',row__c='test', seat__c= i+1.0 ,number_of_seats__c='test',add_datetime__c='test');
purchaseList.add(purchaserec);
}
insert purchaseList;
//System.assertEquals('testtesttest5testtest',purchaseList[4].Key__c,'Key is not Valid');
}
}
You need to requery the records after inserting them to get the updated data from the triggers/database
I'm new here and this is my second question, but as the first, I have a problem already tried to solve in different ways, but have not found a solution, so I'm resorting to you, here we go.
My code:
string sql = "SELECT NEW Filial(fil.NumSequencial, fil.Numero, fil.Nome, fil.Cnpj, fil.Empresa, fil.LstUsuario)" +
" FROM Filial fil" +
" join fetch fil.LstUsuario usrFil";
IQuery query = session.CreateQuery(sql);
lstFilial = (List<Filial>)query.List<Filial>();
I've tried with and without the line "join fetch", but the error is always the same:
{"illegal syntax near collection: id [SELECT NEW Filial(fil.NumSequencial, fil.Numero, fil.Nome, fil.Cnpj, fil.Empresa, fil.LstUsuario) FROM Leitor_NFe_XML_Entidade.Filial fil\tjoin fetch fil.LstUsuario usrFil]"}
The constructor:
public Filial(long numSequencial, int numero, string nome, string cnpj, Empresa empresa, IList<Usuario> lstUsuario)
{
this.numSequencial = numSequencial;
this.numero = numero;
this.nome = nome;
this.cnpj = cnpj;
this.empresa = empresa;
this.lstUsuario = lstUsuario;
}
Am thankful since already
This thread was useful in finding out the next run-time for a scheduled task.
How do I find out the next run time for a Scheduled Task?
But, is there also a way to simply get the next scheduled task due to run?
If I can get the date and name of the next task due to run, I can plug that date into a jQuery countdown timer, which will display a countdown to the next scheduled task, something like:
TaskABC due to run in:
12 03 20
hrs min sec
. This is for an admin interface in case you're wondering how geeky can people get:-)
EDIT
I had the same thought as Bill. But was curious if there was another way.
I poked around and apparently the internal Scheduler class maintains a list of upcoming tasks. The list is private, but you can use the same reflection technique to access it. Interestingly the list also includes system tasks like the mail spooler, session/application trackers, watchers, etecetera. So you must iterate through it until you find a "scheduled task" ie CronTabEntry
Below is a very lightly tested function that seems to do the trick in CF9. (Note, includes the CreateTimeStruct function from http://www.cflib.org).
Rules:
Returns a structure containing the name and time remaining until the next task. If no tasks were found, result.task is an empty string.
Excludes paused tasks
Usage:
result = new TaskUtil().getNextTask();
WriteDump(result);
CFC
component {
public struct function getNextTask() {
// get list of upcoming tasks from factory (UNDOCUMENTED)
local.scheduler = createObject("java", "coldfusion.server.ServiceFactory").getSchedulerService();
local.taskField = local.scheduler.getClass().getDeclaredField("_tasks");
local.taskField.setAccessible( true );
local.taskList = local.taskField.get(local.scheduler);
// taskList contains system jobs too, so we must iterate
// through the tasks to find the next "scheduled task"
local.nextTask = "";
local.tasks = local.taskList.iterator();
while ( local.tasks.hasNext() ) {
local.currTask = local.tasks.next();
local.className = local.currTask.getRunnable().getClass().name;
// exit as soon as we find a scheduled task that is NOT paused
if (local.className eq "coldfusion.scheduling.CronTabEntry"
&& !local.currTask.getRunnable().paused) {
local.nextTask = local.currTask;
break;
}
}
// if we found a task, calculate how many days, hours, etcetera
// until its next run time
local.details = { task="", remaining={} };
if ( isObject(local.nextTask) ) {
local.secondsToGo = (local.nextTask.getWhen() - now().getTime()) / 1000;
local.details.task = local.nextTask.getRunnable().task;
local.details.remaining = createTimeStruct(local.secondsToGo);
local.details.nextDate = dateAdd("s", local.nextTask.getWhen() / 1000
, "January 1 1970 00:00:00" );
}
return local.details;
}
/**
* Abbreviated version of CreateTimeStruct by Dave Pomerance
* See http://www.cflib.org/index.cfm?event=page.udfbyid&udfid=421
*
* #param timespan The timespan to convert.
* #return Returns a structure.
* #author Dave Pomerance
* #version 1, January 7, 2002
*/
public struct function CreateTimeStruct(required numeric timespan) {
var timestruct = StructNew();
var mask = "s";
// only 4 allowed values for mask - if not one of those, return blank struct
if (ListFind("d,h,m,s", mask)) {
// compute seconds
if (mask eq "s") {
timestruct.s = (timespan mod 60) + (timespan - Int(timespan));
timespan = int(timespan/60);
mask = "m";
} else timestruct.s = 0;
// compute minutes
if (mask eq "m") {
timestruct.m = timespan mod 60;
timespan = int(timespan/60);
mask = "h";
} else timestruct.m = 0;
// compute hours, days
if (mask eq "h") {
timestruct.h = timespan mod 24;
timestruct.d = int(timespan/24);
} else {
timestruct.h = 0;
timestruct.d = timespan;
}
}
return timestruct;
}
}
My first thought is to iterate Leigh's getNextRunTime(string taskName) function over the collection of tasks. You can get an array of structs containing the details of all scheduled tasks using taskArray = createobject("java","coldfusion.server.ServiceFactory").getCronService().listAll();
The key in the struct containing the task name is "task". So you can extract all the task names as an array for example, run Leigh's function on each element and determine which one will run next.
How do you show mean values in custom graphs, rather than total values?
Previously I've had success generating cluster summary graphs by creating custom .php files, as described here:
http://sourceforge.net/apps/trac/ganglia/wiki/Custom_graphs
However, up to this point, I've wanted to show total actions per second for a given metric. But now, I have some timing data where I want to show the mean (average) metric value for all cluster nodes. How is this done? With my current implementation, the generated graphs show the total time value for all nodes, which is not helpful.
Here is the .php:
<?php
/* Pass in by reference! */
function graph_jmx_times_report ( &$rrdtool_graph ) {
global $context,
$hostname,
$graph_var,
$range,
$rrd_dir,
$size,
$strip_domainname;
if ($strip_domainname) {
$hostname = strip_domainname($hostname);
}
$jmx = $graph_var;
$title = $jmx.' Processing Time';
if ($context != 'host') {
$rrdtool_graph['title'] = $title;
} else {
$rrdtool_graph['title'] = "$hostname $title last $range";
}
$rrdtool_graph['lower-limit'] = '0';
$rrdtool_graph['vertical-label'] = 'milliseconds';
$rrdtool_graph['extras'] = '--rigid --base 1024';
$rrdtool_graph['height'] += ($size == 'medium') ? 89 : 0;
$series = "DEF:'tot_time'='${rrd_dir}/jmx_tomcat_proc_time_ms.rrd':'sum':AVERAGE"
."DEF:'fc_time'='${rrd_dir}/jmx_tomcat_freqcap_lookup_time_75.rrd':'sum':AVERAGE "
."DEF:'ro_time'='${rrd_dir}/jmx_tomcat_readonly_lookup_time_75.rrd':'sum':AVERAGE "
."DEF:'rt_time'='${rrd_dir}/jmx_tomcat_realtime_lookup_time_75.rrd':'sum':AVERAGE "
."AREA:'tot_time'#CFF1FC:'' "
."LINE2:'fc_time'#F19A2A:'Freq Cap 75' "
."LINE2:'ro_time'#66CC33:'Read-only 75' "
."LINE2:'rt_time'#CC99CC:'Realtime 75' "
."LINE2:'tot_time'#20ABD9:'Processing Time' "
;
$rrdtool_graph['series'] = $series;
return $rrdtool_graph;
}
?>
The summary RRDs Ganglia uses have a num data source in addition to the sum data source. The num value indicates the number of hosts the sum was calculated from and is available only in summary RRDs.
You can use the RRDtool CDEF instruction to calculate the average over all hosts by dividing sum by num.
Here's an example:
if ($context != 'host') { // cluster or grid summary graph context
$series =
"'DEF:fc_time_sum=${rrd_dir}/jmx_tomcat_freqcap_lookup_time_75.rrd:sum:AVERAGE' "
."'DEF:fc_time_num=${rrd_dir}/jmx_tomcat_freqcap_lookup_time_75.rrd:num:AVERAGE' "
."'CDEF:avg_fc_time=fc_time_sum,fc_time_num,/' "
."'LINE2:avg_fc_time#0000FF:Average Freq Cap 75' ";
} else { // single host graph context
//here you can't use the num data source
}
This averaging is also shown in the sample_report.php file included with ganglia-web.