How to setup cron job to run every 5 days? - arrays

I want to setup cronjob which will start on for example today and it will run every 5 days.
This is what I have now, is this will work correctly ? If I install this job at 5 o`clock and then every 5 days on 6 AM.
0 6 */5 * * mailx -r root#mail.com -s "Message title" -c "cc#mail.com" primary#mail.com < body.txt

0 0 */5 * * midnight every 5 days.
See this, similar question just asked for every 3 days.
Cron job every three days

Bear with me, this is my first time posting an answer... let me know if anything I put is unclear.
I don't think you have what you need with:
0 0 */5 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!
Unfortunately, the */5 is setting the interval based on day of the month. See: explanation here. At the end of the month there is recurring issue guaranteed.
1st at 2019-01-01 00:00:00
then at 2019-01-06 00:00:00 << 5 days, etc. OK
then at 2019-01-11 00:00:00
...
then at 2019-01-26 00:00:00
then at 2019-01-31 00:00:00
then at 2019-02-01 00:00:00 << 1 day WRONG
then at 2019-02-06 00:00:00
...
then at 2019-02-26 00:00:00
then at 2019-03-01 00:00:00 << 3 days WRONG
According to this article, you need to add some modulo math to the command being executed to get a TRUE "every N days". For example:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 5 == 0 )) && runmyjob.sh
In this example, the job will be checked daily at 12:00 AM, but will only execute when the number of days since 01-01-1970 modulo 5 is 0.
If you want it to be every 5 days from a specific date, use the following format:
0 0 * * * bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 5 == 0 )) && runmyjob.sh

The last snippet of Brad will not work because it ignores the actual date.
date +%s -d "2019-01-01"
will always return the same amount of seconds which will end up in either always true or always false depending on which date you choose.
you would have to do an extra calculation like this to run it every 5 days at 00:00 from 2019-01-01 00:00:00 on:
0 0 * * * bash -c '(( ( $(date +\%s) - $(date +\%s -d "2019-01-01 00:00:00") ) / 86400 \% 5 == 0 )) && runmyjob.sh'

Related

Working with an upper-triangular array in SAS (challenge +2 Points)

I'm looking to improve my code efficiency by turning my code into arrays and loops. The data i'm working with starts off like this:
ID Mapping Asset Fixed Performing Payment 2017 Payment2018 Payment2019 Payment2020
1 Loan1 1 1 1 90 30 30 30
2 Loan1 1 1 0 80 20 40 20
3 Loan1 1 0 1 60 40 10 10
4 Loan1 1 0 0 120 60 30 30
5 Loan2 ... ... ... ... ... ... ...
So For each ID (essentially the data sorted by Mapping, Asset, Fixed and then Performing) I'm looking to build a profile for the Payment Scheme.
The Payment Vector for the first ID looks like this:
PaymentVector1 PaymentVector2 PaymentVector3 PaymentVector4
1 0.33 0.33 0.33
It is represented by the formula
PaymentVector(I)=Payment(I)/Payment(1)
The above is fine to create in an array, example code can be given if you wish.
Next, under the assumption that every payment made is replaced i.e. when 30 is paid in 2018, it must be replaced, and so on.
I'm looking to make a profile that shows the outflows (and for illustration, but not required in code, in brackets inflows) for the movement of the payments as such - For ID=1:
Payment2017 Payment2018 Payment2019 Payment2020
17 (+90) -30 -30 -30
18 N/A (+30) -10 -10
19 N/A N/A (+40) -13.3
20 N/A N/A N/A (+53.3)
so if you're looking forwards, the rows can be thought of what year it is and the columns representing what years are coming up.
Hence, in year 2019, looking at what is to be paid in 2017 and 2018 is N/A because those payments are in the past / cannot be paid now.
As for in year 2018, looking at what has to be paid in 2019, you have to pay one-third of the money you have now, so -10.
I've been working to turn this dataset row by row into the array but there surely has to be a quicker way using an array:
The Code I've used so far looks like:
Data Want;
Set Have;
Array Vintage(2017:2020) Vintage2017-Vintage2020;
Array PaymentSchedule(2017:2020) PaymentSchedule2017-PaymentSchedule2020;
Array PaymentVector(2017:2020) PaymentVector2017-PaymentVector2020;
Array PaymentVolume(2017:2020) PaymentVolume2017-PaymentVolume2020;
do i=1 to 4;
PaymentVector(i)=PaymentSchedule(i)/PaymentSchedule(1);
end;
I'll add code tomorrow... but the code doesn't work regardless.
data have;
input
ID Mapping $ Asset Fixed Performing Payment2017 Payment2018 Payment2019 Payment2020; datalines;
1 Loan1 1 1 1 90 30 30 30
2 Loan1 1 1 0 80 20 40 20
3 Loan1 1 0 1 60 40 10 10
4 Loan1 1 0 0 120 60 30 30
data want(keep=id payment: fraction:);
set have;
array p payment:;
array fraction(4); * track constant fraction determined at start of profile;
array out(4); * track outlay for ith iteration;
* compute constant (over iterations) fraction for row;
do i = dim(p) to 1 by -1;
fraction(i) = p(i) / p(1);
end;
* reset to missing to allow for sum statement, which is <variable> + <expression>;
call missing(of out(*));
out(1) = p(1);
do iter = 1 to 4;
p(iter) = out(iter);
do i = iter+1 to dim(p);
p(i) = -fraction(i) * p(iter);
out(i) + (-p(i)); * <--- compute next iteration outlay with ye olde sum statement ;
end;
output;
p(iter) = .;
end;
format fract: best4. payment: 7.2;
run;
You've indexed your arrays with 2017:2020 but then try and use them using the 1 to 4 index. That won't work, you need to be consistent.
Array PaymentSchedule(2017:2020) PaymentSchedule2017-PaymentSchedule2020;
Array PaymentVector(2017:2020) PaymentVector2017-PaymentVector2020;
do i=2017 to 2020;
PaymentVector(i)=PaymentSchedule(i)/PaymentSchedule(2017);
end;

Recode each element in an array list variable using for loop in R

I am new to R and i've been stuck on this. I have a data set below wherein I created a new array list variable called 'amountOfTxn_array' that contains three numeric values in sequential order. These are amounts of transactions taken from Jan to Mar. My objective is to create new variables from this array list that iterate each data elements in the 'amountOfTxn_array'.
> head(myData_05_Array)
Index accountID amountOfTxn_array
1:00 8887 c(36.44, 75.00,185.24)
2:00 13462 c(639.45,656.10,237.00)
3:00 47249 c(0, 24, 2012)
4:00 49528 c(1189.20,2326.26,1695.89)
5:00 57201 c(24.67, 0.00, 0.00)
6:00 57206 c(0.00, 661.98,2957.68)
str(myData_05_Array)
Classes ‘data.table’ and 'data.frame': 3176 obs. of 4 variables:
$ accountID : int 8887 13462 47249 49528 57201 57206 58522 79073 80465 81032 ...
$ amountOfTxn_200501: num 36.4 639.5 0 1189.2 24.7 ...
$ amountOfTxn_200502: num 75 656 24 2326 0 ...
$ amountOfTxn_200503: num 185 237 2012 1696 0 ...
$ amountOfTxn_array :List of 3176
Also, an example code for creating a new variable is provided below wherein I would like to tag 1 if a value in the array is greater than 100 and 0 else. When I ran the example code, I am getting "Error: (list) object cannot be coerced to type ‘double’ error. May I ask for a solution for this. I would highly appreciate any response.
Thanks!
> for(i in 1:3)
+ {
+ if(myData_05_Array$amountOfTxn_array[i] > 100){
+ myData_05_Array$testArray[i] <- 1
+ }
+ else{
+ myData_05_Array$testArray[i] <- 0
+ }
+ }
Error: (list) object cannot be coerced to type 'double'
What I am expecting as the output is as follows:
amountOfTxn_testArray
c(0, 0, 1)
c(1, 1, 1)
c(0, 0, 0)
c(1, 1, 1)
c(0, 0, 0)
c(0, 1, 1)
"Doing calculations for 24 columns is quite cumbersome"
a HA! welcome to the dplyr world:
library(dplyr)
#generate dummy data
dummyDf <-read.table(text='Index accountID Jan Feb March
1:00 8887 36.44 75.00 185.24
2:00 13462 639.45 656.10 237.00
3:00 47249 0 24 2012
4:00 49528 1189.20 2326.26 1695.89
5:00 57201 24.67 0.00 0.00
6:00 57206 0.00 661.98 2957.68', header=TRUE, stringsAsFactors=FALSE)
mutate column by column index
#the dot (.) argument refers to the focal column
df %>% mutate_at(3:5, funs(as.numeric(.>100)))
mutate columns by predefined names
changeVars =c("Jan","Feb","March")
df %>% mutate_at(.cols=changeVars, funs(as.numeric(.>100)))
mutate columns if some condition is met
df %>%mutate_if(is.double, funs(as.numeric(.>100)))
output:
Index accountID Jan Feb March
1 1:00 8887 0 0 1
2 2:00 13462 1 1 1
3 3:00 47249 0 0 1
4 4:00 49528 1 1 1
5 5:00 57201 0 0 0
6 6:00 57206 0 1 1

total days in Arrears calculation

guys i have problem with one old SP which calculates total days late when the costumer is late with the payments of an instalment
it goes like this:
#total days paid# #1st inst days due# #2nd inst days due# #total days#
---------------------------------------------------------------------------
---------------------------------------------------------------------------
0 1 0 1
0 2 0 2
0 3 0 3
0 4 0 4
0 30 0 30
0 31 1 31
0 32 2 32
32 0 3 35
so the procedure calculates (total days paid) + max of the days due
0+32 =32
32+3 =35
etc
and makes mistakes whenever the costumer is latemore then 30 days
its should always increment by 1 and not overlap the calculations
can anyone think of a quick way to fix this without over writhing the whole thing
so you have an existing formula for calculating #total days#, if you can locate the final place where that is returned, it could be a formula or a field name, let's call that (...) because we don't know what it is here, you can change it to
(...) + CASE WHEN (...) >= 30 THEN 1 ELSE 0 END AS '#total days#'

SSRS. How to group in a group?

I have SSRS report like below with Boolean parameter to show 12h view or 24h view. To fit report into single screen the 24h report need to group by every 2hr.
07:00 08:00 09:00 10:00 11:00 12:00 13:00 14:00 ...
Line 1 25 30 24 26 25 25 30 30 ...
08:00 10:00 12:00 14:00 ...
Line 1 55 50 50 60 ...
The query for the dataset is:
SELECT LineID
,Hour
,HourValue
,Target
FROM vwData
ORDER BY LineID, CASE WHEN [Hour] > 6 THEN - 1 ELSE [Hour] END
How can I achieve this?
This declares your bit variable (which should be true when they want the 24 hour view - false when 12 hour)
DECLARE #24Hour bit = 0
SELECT CASE WHEN #24Hour = 0
THEN Hour
ELSE Hour + (Hour % 2)
END AS [HourGroup]
,SUM(Target) AS [TargetTotal]
FROM vwData
GROUP BY CASE WHEN #24Hour = 0
THEN Hour
ELSE Hour + (Hour % 2)
END
If they want the 24 hour view, we make hour = hour + hour % 2. (7 = 8, 8=8, 9=10, etc., etc.). If you had a more complex query, I would suggest reading up on cross apply, but this is so simple I think this will suffice. The grouping by makes sure to aggregate the REAL 7 and REAL 8 hour records (which will both be returned as "8", if using the 24 hour view). If you don't group your results, you will get two 8 oclock records - one with the REAL 7 hour total and one with the REAL 8 hour total.
EDIT:
Since you didn't include the schema of your DB, I'm guessing that 'Target' is the value being summated, but it could just as easily be 'HourValue'. Furthermore, I have no idea why you would need LineID, so I omitted it from my answer. But you can easily modify that if it's inaccurate. In the future, you should provide some sample data and your database schema so that others aren't forced to make assumptions or guess.
You could add a calculated field with a value given by something like this: `Fields!Hour.Value + Fields!Hour.Value Mod 2' and then group on that field, using a parameter to choose the Group By field in the report (Your new field or the actual hour value).

How set RRD to store for 2 years?

I'm monitoring more than 300 servers, for that I'm using Ganglia.
Which use RRD as database to collect and store data related the resources of each server.
I would like to have a history about 2 years or more, so reading this article, I think that my RRA configuration should be :
RRAs "RRA:AVERAGE:0.5:1:17520"
17520 = (365 days [year] x 2) * 24 [hour]
This is Ganglia default configuration, which is running today:
#
# Round-Robin Archives
# You can specify custom Round-Robin archives here (defaults are listed below)
#
# RRAs "RRA:AVERAGE:0.5:1:244" "RRA:AVERAGE:0.5:24:244" "RRA:AVERAGE:0.5:168:244" "RRA:AVERAGE:0.5:672:244" \
# "RRA:AVERAGE:0.5:5760:374"
#
Is that right my way of thinking or I'm missing something here ?
After studying this subject for a while, I came up with an answer that may help someone in the future. I read these two articles many times, which I recommend.
Read this one first, Creating an initial RRD then read this one. How to create an RRDTool database:
I will try to explain it simply. Format RRA:CF:xff:steps:rows:
RRA: Round Robin Archive
CF: Consolidation Factor
XFF: Xfile Factor
steps
rows
The biggest issue for me was to discover the right value for steps and rows.
After reading, I came up with this explanation:
1 day - 5-minute resolution
1 week - 15-minute resolution
1 month - 1-hour resolution
1 year - 6-hour resolution
RRA:AVERAGE:0.5:1:288 \
RRA:AVERAGE:0.5:3:672 \
RRA:AVERAGE:0.5:12:744 \
RRA:AVERAGE:0.5:72:1480
Keep in mind that our step is 300 seconds, so the idea is very simple:
If I want to resolve one day which has 86400 seconds, as shown in the first example, how many rows do I need? The answer is 288 rows. Why?
`86400 seconds [1 day] / 300 seconds [5 minutes`] = 288 rows
Another example, if I want to resolve:
1 week [ = 604800 seconds ] in 15 minutes [ = 900 seconds ] = 604800/900 = 672 rows
And so it goes on for the other values. This way you are going to find out how many rows you need.
Finding out how many steps you need is very simple, you just have to take the multiplier of your steps.
Let me explain: Our steps are 300 seconds, right?
So if we want to resolve 5 minutes [ = 300 seconds ], we just need to multiply by 1, right?
So, 15 minutes means by 300 seconds x 3, 1 hour means 300 x 12, 6 hours mean 300 x 72 and so on.
In my specific case, I would like to my steps be 30 seconds, so I came up with these structure:
1 every time 30 seconds 1 * 30s = 30s
2 every second time 1 minute 2 * 30s = 1m
4 every third time 2 minutes 4 * 30s = 2m
10 every 10th time 5 minutes 10 * 30s = 5m
20 every 20th time 10 minutes 20 * 30s = 10m
60 every 60th time 30 minutes 60 * 30s = 30m
80 every 80th time 40 minutes 80 * 30s = 40m
100 every 100th time 50 minutes 100 * 30s = 50m
120 every 120th time 1 hour 120 * 30s = 1h
240 every 240th time 2 hours 240 * 30s = 2h
360 every 360th time 3 hours 360 * 30s = 3h
RRA:AVERAGE:0.5:1:120 \
RRA:AVERAGE:0.5:2:120 \
RRA:AVERAGE:0.5:4:120 \
RRA:AVERAGE:0.5:10:288 \
RRA:AVERAGE:0.5:20:1008 \
RRA:AVERAGE:0.5:60:1440 \
RRA:AVERAGE:0.5:80:3240 \
RRA:AVERAGE:0.5:100:5184 \
RRA:AVERAGE:0.5:120:8760 \
RRA:AVERAGE:0.5:240:8760 \
RRA:AVERAGE:0.5:360:8760 \
Which means:
1 hour - 30 seconds resolution
2 hours - 1 minute resolution
4 hours - 2 minutes resolution
1 day - 5 minutes resolution
1 week - 10 minutes resolution
1 month - 30 minutes resolution
3 months - 40 minutes resolution
6 months - 50 minutes resolution
1 year - 1 hour resolution
2 year - 2 hour resolution
3 year - 3 hour resolution
Well, I hope this helps someone, that's all.

Resources