google spreadsheet calculation - google-apps-script

How to calculate this:
0-10 hours = 100 pr. hour
11-20 hours = 80 pr. hour
21+ hours = 70 pr. hour
If ex. I have 23 hours:
10 hours - 100 pr. hour
10 hours - 80 pr. hour
3 hours - 70 pr. hour
Is it possible to write a function in Google spreadsheet to calculate the total amount if I only have the total hours.

You can express this as a formula. Consider that there are three cases:
If more than 20 hours, rate is (10 x 100 + 10 x 80) + (hours - 20) x 70
If less than 21 hours but more than 10, rate is (10 x 100) + (hours - 10) x 80
If less than 11 hours, rate is hours x 100
If we have our hours in cell A1, here's the formula:
=if(A1>20,(A1-20)*70+1800,if(A1>10,(A1-10)*80+1000,A1*100))

I'm writing gsheet formulas for 4+years.
IMHO you need to create additional table "rates"
HoursFrom | HoursTo | Rate
0 | 10 | 100
11 | 20 | 80
21 | 9999 | 70
than you can write flexible formula that will work everywhere:
= filter(rates!C:C, rates!A:A>A1, rates!B:B
it may seem a bit more complex in the beginning, but late you will easily read your formula and you will be able to change your data in single place in your "Rates" table without searching for all formulas that refer to this data.

Yes, it's possible to write a function for this. Here is a sample code.
function amount(x) {
if(!x){
return "no hours provided";
} else {
if(x<=10){
return x*100;
} else if (x<=20){
return 10*100+(x-10)*80;
} else {
return 10*100+10*80+(x-20)*70;
}
}
}
You can use this anywhere in the spreadsheet as a custom function. e.g. if
A1 = 23;
//You can put below line in any cell. A2 is just being given as an example
A2 = amount(A1) //answer will be 2010

Related

How to collect data from multiple cells (quantity of 2) and return an output with 2 comma-separated values in one cell? AppScripts

First, I believe this question is very similar to the following one. However, I want to know if there is an alternative way to write it so that I'm only looping through 2 cells at a time?
How do I .getValues and .setValues from multiple cells in a single column?
For example, my input is:
Cell E21 = $55
Cell F21 = 1
The desired output is:
$55, 1
The current output is:
$55
This is the code I'm currently using (below). I am not confident about implementing the above linked solution because I definitely don't want to cycle or loop through any complete rows OR columns! If that solution happens to be the only option, please tell me how to write it for my purpose. In the code below, I was hoping it could be written as, "E21:F21" but that's not working! And when I experimented with .getRangeList, I got an error about not converting to Int. So, maybe this is over-communicating, but, I will note that I don't need any decimal point values. The rounded number of $55 flat is great for the first value. Thanks!
[formSheet.getRange("E21").getValue()],
[formSheet.getRange("F21").getValue()],
The answer provided below got me mostly there, but I had to have a friend translate it back to me, and ultimately this was the solution! Thanks all!
[formSheet.getRange("E21").getValue() + ", " + formSheet.getRange("F21").getValue()]
My Code:
function elfunko() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const vs = sh.getRange("A2:B" + sh.getLastRow()).getValues().map(r => [`${r[0]},${r[1]}`])
Logger.log(JSON.stringify(vs));
sh.getRange(2,4,vs.length,vs[0].length).setValues(vs)
}
My input and output:
COL1
COL2
4
12
4,12
5
19
5,19
16
4
16,4
4
18
4,18
11
12
11,12
13
15
13,15
19
7
19,7
14
10
14,10
10
6
10,6
9
18
9,18
18
9
18,9
19
10
19,10
19
4
19,4
8
9
8,9
4
4
4,4
14
19
14,19
3
16
3,16
5
18
5,18
16
19
16,19
13
5
13,5
This was the answer I ultimately used:
[formSheet.getRange("E21").getValue() + ", " +
formSheet.getRange("F21").getValue()]

How to add a loop in SSRS

I am using SSRS 2012 R2.
I need to create a loop in ssrs to calculate the compliance of ONB to LB
but with a condition, for the total bags count <= 100 it will be 27 mins. but for each additional 50 bags add 5 mins.
I tried the code below but it takes only 27 and 34 min. I want to replace 34 with a loop.
count(
iif(Fields!Duration_ONB_LB_.Value <
iif(Fields!Total_Bag_Count.Value <= "100", "27","34") ,1, Nothing))
/ count(Fields!TotalRows.Value) * 100 )
Can you please help me out in this?
I'm not sure if 'loop' is the correct term, I assume you want to just create an expression that adds 5 mins for every 50 bags (or part of).
I created a sample dataset so you can see the results, it assumes that up to 100 bags is 27 mins, 101-150 bags would be 32 mins, 151-200 bags would be 37 mins and so on...
here is the expression I used, you will need to replace the iif(Fields!Total_Bag_Count.Value <= "100", "27","34") part of your expression with this.
IIF
(
Fields!Total_Bag_Count.Value <= 100,
27,
(CEILING((Fields!Total_Bag_Count.Value -100) / 50) * 5) + 27
)
Here are the results

Best way to plot by hour by day by month in r

currently I have created the following dataframe in R but I am having trouble with my visualisation.
The Dataframe looks as follows:
date weekday dayhour amount
2017-06 0 1 100
2017-06 0 2 200
2017-06 0 3 150
2017-06 0 4 600
2017-06 0 5 75
....
2018-06 6 21 60
2018-06 6 22 90
2018-06 6 23 150
2018-06 6 24 110
The amount is the average of that weekday by hour for that month. So for example the month june in 2017 on the first hour of each monday in june has an average amount of 100.
Now the idea is to plot my data in R in several graphs which will show me the data by hour by weekday for that given month. So 12 plots with each the amount on the y axis and the hour+weekday on the x axis.
I have tried several approaches such as looping through the months and plotting them with par(mfrow = c(2,6)). Also I tried plotting them one by one. However I am still a rookie with R and I can't find any good documentation or tutorial on how to do this. For now I have only been able to stack the datapoints in one loop by weekday and not by hour by doing the following on the dataset without hours included yet:
increase = 7
for (i in (length(occupancy_by_day)/7)) {
data = head(occupancy_by_day,increase:increase+increase)
plot(average_occupancy ~ Weekday, data=data)
increase = increase + 7
}
My closest guess to the correct answer at this moment is something like this:
par(mfrow = c(2,6))
increase = 06
for (i in (length(occupancy_by_day)/30,5)) {
data = occupancy_by_day[occupancy_by_day$date == paste(c('2017-',increase)), ]
plot(amount ~ weekday, data=data)
increase = increase + 1
}
This gives me the error:
Error in plot.window(...) : need finite 'xlim' values
Does anyone know a good solution to plotting the data in R?
Thanks in advance for any help/comments!
EDIT:
priority on this post would be how to plot data by hour by weekday. I could iterate through the months manually however I would still need to plot them. A loop for each month would be added bonus. Right now I have the following:
data =occupancy_by_day[occupancy_by_day$date == '2017-06', ]
plot(Amount ~ weekday+dayhour, data=data)
This sadly only plots the data by dayhour.
ADDED DRAWING OF CONCEPT:
https://imgur.com/qKFbbmJ
ANSWER:
Eventually I did a litle workaround to plot them with:
ggplot(data = data[data$date == '2017-12', ], aes(plotstamp, Amount, group=Weekday, col=Weekday)) +
geom_line() +
geom_point() +
ggtitle("December 2017")
the plotstamp is an extra column/index I added to my DF which allowed my to plot the values continously. Then I just plotted them seperately per month.
Make similar data
I think this is the partial solution you ask for in your edit (if I understand your task correctly), but I believe you can loop through months in the same way.
The only way I could think of was to transform the dates you have to date class. I used some prepared date data but you can fix yours using the strptime() and paste() commands to match mine. Also, the data I made is only for two days.
date1 <- c(rep("2017-06-1",24),rep("2017-06-2",24))
weekday <- c(rep(0,24),rep(1,24))
dayhour <- c(1:24,1:24)
# Add dayhour to date
date <- paste(date1, dayhour, sep = " ")
date <- strptime(date, "%Y-%m-%d %H")
amount <- c(1:24,(48:25)*2)
dat <- data.frame(date,weekday,dayhour,amount)
View(dat)
plot(x=dat$date, y=dat$amount)
This is how my created data looks like.
date weekday dayhour amount
1 2017-06-01 01:00:00 0 1 1
2 2017-06-01 02:00:00 0 2 2
3 2017-06-01 03:00:00 0 3 3
4 2017-06-01 04:00:00 0 4 4
....
46 2017-06-02 22:00:00 1 22 54
47 2017-06-02 23:00:00 1 23 52
48 2017-06-03 00:00:00 1 24 50
Loop for the plot.
If you write this in an R markdown document you will get nice pages for each plot so you don't have to use par(mfrow = c(1,2)). You probably also need to fix the loop arguments to fit your data.
par(mfrow = c(1,2))
start <- 0
end <- 23
step = 1
for (i in 1:(length(dat$date)/24)) {
data <- dat[(start+step) : (end+step), ] # The parenteses at (start+step) and (end+step) are important!
plot(x = data$date, y = data$amount)
step = step + 23
}
I hope this help you.
P.S. This is the first answer I write, so feel free to edit or improve my answer.

calculate two columns in MySQL

I have a MySQL database, where I have 3 columns:
Day_hours
Day_minutes
All_day_hours
I am gonna have some different form fields in a JSP page, where I can put in how many hours I work. On a day I work in different places, that means that I need fx to put in 5 * Day_hours, Day_minutes and All_day_hours. So the problem is that I want to calculate all the hours and minutes during a day. So if I fx worked:
1 job: 2 hours 15 minutes
2 job: 3 hours 45 minutes
3 job: 1 hours 10 minutes
4 job: 4 hours 40 minutes
5 job: 3 hours 15 minutes
So that means if I calculate the column "Day_minutes" it would give me the result 125. I would like that the 125 minutes is converted to hours, so the result would be 2 hours and 5 minutes. Afterwords the Day_hours and Day_minutes have to be addéd to the column Allday_hours. So Allday_hours is the sum of Day_hours + Day_minutes
so Fx in MySQL database there is the following information for an example day:
Day_hours Day_minutes Allday_hours
1 job 2 15 2.15
2 job: 3 45 3.45
3 job: 1 10 1.10
4 job: 4 40 4.40
5 job: 3 15 3.15
So my question is, how do I calculate the Day_hours and Day_minutes to the Allday_hours, so the result in job 1 would be 2.15?
Have a good weekend.
Best Regards
Mads
You should not save something in Allday_hours as this is redundant information.
You can retrieve the data you want always (without problems) from the data you have. For example with
SELECT *, ((Day_hours*60 + Day_minutes)/60) AS Allday_hours FROM timedata...
No need to actually save them.
By the way I think it is rather odd that 2 hours plus 15 minutes add up to something like 2.15. So my query above computes something relative... if you really want to compute your value, you might use
SELECT *, (Day_hours + (Day_minutes / 100)) as Allday_hours FROM timedata
And if you really want to save this, you can use the calculations in an update statement like
UPDATE timedata SET Allday_hours = (Day_hours + (Day_minutes / 100))

How to decode some number into timeDate?

This question is sequel of this one.
So any idea how to decode this number 5252235562500 into date and time 19.11.2010 15:43 ?
I have more pairs like this and I'm thinking about some script for comparing them to find some patern. Any advice what to check and how to search for patterns ?
EDIT: I added four pairs that I curentlly have.
11.11.2010 16:23 > 5252425372575
16.11.2010 15:30 > 5252922462564
19.11.2010 15:39 > 5252231562511
19.11.2010 15:43 > 5252235562500
I think I found the solution. Instead of simply presenting the decoding algorithm I'd like to show you the reasoning.
The answer to the linked question showed that was a barcode in EAN-13 format.
It means the codes have 12 digits and 1 check digit:
11.11.2010 16:23 > 525242537257 5
16.11.2010 15:30 > 525292246256 4
19.11.2010 15:39 > 525223156251 1
19.11.2010 15:43 > 525223556250 0
The check digit can be calculated by
adding the values of the digits in the even-numbered positions: 2, 4, 6 ... (2+2+2+3+2+7=18)
multiplying this result by 3 (18*3=54)
adding the values of the digits in the odd-numbered positions: 1, 3, 5... (5+5+4+5+7+5=31)
summing the two results (54+31=85)
calculating modulo 10 and subtracting it from 10 (5-10=5)
I calculated the check digit for every code, it matched and confirmed the codes were in EAN-13 format.
According to the specification, the first two or three digits of the code could be country codes, so I tried to separate these:
11.11.2010 16:23 > 52 5242537257 5 | 525 242537257 5
16.11.2010 15:30 > 52 5292246256 4 | 525 292246256 4
19.11.2010 15:39 > 52 5223156251 1 | 525 223156251 1
19.11.2010 15:43 > 52 5223556250 0 | 525 223556250 0
The resulting numbers didn't make any sense, because the earlier time had a greater number:
5292246256 or 292246256
than the later time:
5223156251 or 223156251
At this point I suspected the time wasn't stored in binary format.
I reorganized the digits and tried to find repeating patterns.
I ended up with this layout:
11.11.2010 16:23 > 52 52 42 53 72 57 5
16.11.2010 15:30 > 52 52 92 24 62 56 4
19.11.2010 15:39 > 52 52 23 15 62 51 1
19.11.2010 15:43 > 52 52 23 55 62 50 0
This is where things got interesting...
Take a look at the 3rd and 4th row, these are the same except the 4th and 6th column.
The 4th column has 15 and 55. Translate it backwards and you get 51 and 55.
The difference of the two is 55 - 51 = 4 just like the difference of minutes 43 - 39 = 4
Subtract the minutes from code values:
55 - 43 = 12
51 - 39 = 12
It seems the 4th column encodes minutes by adding 12 and storing the digits backwards.
Now try to apply this to the 5th column:
11.11.2010 16:23 > 72 > 27
16.11.2010 15:30 > 62 > 26
19.11.2010 15:39 > 62 > 26
19.11.2010 15:43 > 62 > 26
26 - 15 = 11 and 27 - 16 = 11 so the difference for the 5th column is 11.
From then it's easy, the differences for the columns are 15, 14, 13, 12 & 11.
A few quick calculations and you get the encoding scheme:
Digits Meaning Diff.
2-1 year 15
4-3 month 14
6-5 day 13
8-7 minute 12
10-9 hour 11
Here's a simple code snippet for decoding:
union TimeFormat
{
unsigned short codearray[5];
struct
{
unsigned short year;
unsigned short month;
unsigned short day;
unsigned short minute;
unsigned short hour;
};
};
void DecodeBarcode(char *code, TimeFormat *time)
{
char buf[3]; // for atoi()
buf[2] = 0; // of course it has to be null-terminated
for (int i = 0, diff = 15; i < 5; ++i, --diff)
{
buf[0] = code[i * 2 + 1];
buf[1] = code[i * 2];
time->codearray[i] = atoi(buf) - diff;
}
time->year += 2000;
}
When you're trying to decode a foreign time format, you need two known times. Take the difference between them and see what it equates to - second, milliseconds, days, there aren't too many possibilities. Now that you have the basic time unit, you can work with one of the times and see what the origin time is.
I just had to do this last week. I had two dates:
2009-07-15 15:29:12 1247689752
2009-07-17 08:27:55 1247837275
There are lots of ways to get the difference between two dates. The easiest is probably Excel, which will display the difference in days; in this case 1.70744213. The difference between the two representations is 147523. Multiplying the number of days by the number of seconds in a day (24*60*60) also resulted in 147523, so now I know that the date is the number of seconds elapsed from some starting date.
To get the starting date, I subtract a date from itself. Again this is trivial in Excel: divide the date number by the number of seconds in a day, then subtract. In my case it comes up 1969-12-31 19:00. This seems a little odd, but I realize that my time zone is 5 hours off of UTC in the summer. This tells me that the time value is in UTC, and represents the number of seconds since 1970-01-01.
Script like this what you are thinking not make any sense, because you can by hand for example brake this in time X, then probably you will be write program for this in time 25*X and this program will be working based on checking patterns what you are define then this not make sense when you don't have thousands of algorithms this type to brake but vary in some little part.
Give some more pairs then i can tell you more, one pair is to less to know anything.