Graphite whisper losing old data - metrics

My graphite whisper databases don't store data older than 7 days old. Using the whisper-fetch.py tool I can only see data up to 1 week back (when there should be data for at least 3 weeks at this point). I'm using grafana, statsd, graphite-web, carbon and whisper.
An example of one of the metrics being truncated:
stats.counters.api.create_order.pc.chrome
This is my storage-schemas.conf:
[carbon]
pattern = ^carbon\.
retentions = 10s:6h,1min:90d
[default_1min_for_1day]
pattern = .*
retentions = 10s:6h,1min:6d,10min:5y
And here is my storage-aggregation.conf:
[min]
pattern = \.lower$
xFilesFactor = 0.1
aggregationMethod = min
[max]
pattern = \.upper(_\d+)?$
xFilesFactor = 0.1
aggregationMethod = max
[sum]
pattern = \.sum$
xFilesFactor = 0
aggregationMethod = sum
[count]
pattern = \.count$
xFilesFactor = 0
aggregationMethod = sum
[count_legacy]
pattern = ^stats_counts.*
xFilesFactor = 0
aggregationMethod = sum
[default_average]
pattern = .*
xFilesFactor = 0.3
aggregationMethod = average

I found the issue. Using whisper-info.py, the retention times were shown to be 7 days on all the old metrics, as I was witnessing. Newer metrics were being retained just fine. The current storage-schemas.conf didn't have 7 days specified anywhere... but the previous storage-schemas.conf file could have had it.
It seems graphite does not automatically update the whisper files for new retention times specified in storage-schemas.conf I used the whisper-resize.py tool to manually resize all the old metric whisper files, and now whisper-info.py shows the right retention periods.

Related

Ruby algorithms loops codewars

I got stuck with below task and spent about 3 hours trying to figure it out.
Task description: A man has a rather old car being worth $2000. He saw a secondhand car being worth $8000. He wants to keep his old car until he can buy the secondhand one.
He thinks he can save $1000 each month but the prices of his old car and of the new one decrease of 1.5 percent per month. Furthermore this percent of loss increases by 0.5 percent at the end of every two months. Our man finds it difficult to make all these calculations.
How many months will it take him to save up enough money to buy the car he wants, and how much money will he have left over?
My code so far:
def nbMonths(startPriceOld, startPriceNew, savingperMonth, percentLossByMonth)
dep_value_old = startPriceOld
mth_count = 0
total_savings = 0
dep_value_new = startPriceNew
mth_count_new = 0
while startPriceOld != startPriceNew do
if startPriceOld >= startPriceNew
return mth_count = 0, startPriceOld - startPriceNew
end
dep_value_new = dep_value_new - (dep_value_new * percentLossByMonth / 100)
mth_count_new += 1
if mth_count_new % 2 == 0
dep_value_new = dep_value_new - (dep_value_new * 0.5) / 100
end
dep_value_old = dep_value_old - (dep_value_old * percentLossByMonth / 100)
mth_count += 1
total_savings += savingperMonth
if mth_count % 2 == 0
dep_value_old = dep_value_old - (dep_value_old * 0.5) / 100
end
affordability = total_savings + dep_value_old
if affordability >= dep_value_new
return mth_count, affordability - dep_value_new
end
end
end
print nbMonths(2000, 8000, 1000, 1.5) # Expected result[6, 766])
The data are as follows.
op = 2000.0 # current old car value
np = 8000.0 # current new car price
sv = 1000.0 # annual savings
dr = 0.015 # annual depreciation, both cars (1.5%)
cr = 0.005. # additional depreciation every two years, both cars (0.5%)
After n >= 0 months the man's (let's call him "Rufus") savings plus the value of his car equal
sv*n + op*(1 - n*dr - (cr + 2*cr + 3*cr +...+ (n/2)*cr))
where n/2 is integer division. As
cr + 2*cr + 3*cr +...+ (n/2)*cr = cr*((1+2+..+n)/2) = cr*(1+n/2)*(n/2)
the expression becomes
sv*n + op*(1 - n*dr - cr*(1+(n/2))*(n/2))
Similarly, after n years the cost of the car he wants to purchase will fall to
np * (1 - n*dr - cr*(1+(n/2))*(n/2))
If we set these two expressions equal we obtain the following.
sv*n + op - op*dr*n - op*cr*(n/2) - op*cr*(n/2)**2 =
np - np*dr*n - np*cr*(n/2) - np*cr*(n/2)**2
which reduces to
cr*(np-op)*(n/2)**2 + (sv + dr*(np-op))*n + cr*(np-op)*(n/2) - (np-op) = 0
or
cr*(n/2)**2 + (sv/(np-op) + dr)*n + cr*(n/2) - 1 = 0
If we momentarily treat (n/2) as a float division, this expression reduces to a quadratic.
(cr/4)*n**2 + (sv/(np-op) + dr + cr/2)*n - 1 = 0
= a*n**2 + b*n + c = 0
where
a = cr/4 = 0.005/4 = 0.00125
b = sv/(np-op) + dr + cr/(2*a) = 1000.0/(8000-2000) + 0.015 + 0.005/2 = 0.18417
c = -1
Incidentally, Rufus doesn't have a computer, but he does have an HP 12c calculator his grandfather gave him when he was a kid, which is perfectly adequate for these simple calculations.
The roots are computed as follows.
(-b + Math.sqrt(b**2 - 4*a*c))/(2*a) #=> 5.24
(-b - Math.sqrt(b**2 - 4*a*c))/(2*a) #=> -152.58
It appears that Rufus can purchase the new vehicle (if it's still for sale) in six years. Had we been able able to solve the above equation for n/2 using integer division it might have turned out that Rufus would have had to wait longer. That’s because for a given n both cars would have depreciated less (or at least not not more), and because the car to be purchased is more expensive than the current car, the difference in values would be greater than that obtained with the float approximation for 1/n. We need to check that, however. After n years, Rufus' savings and the value of his beater will equal
sv*n + op*(1 - dr*n - cr*(1+(n/2))*(n/2))
= 1000*n + 2000*(1 - 0.015*n - 0.005*(1+(n/2))*(n/2))
For n = 6 this equals
1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
= 1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+3)*3)
= 1000*6 + 2000*0.85
= 7700
The cost of Rufus' dream car after n years will be
np * (1 - dr*n - cr*(1+(n/2))*(n/2))
= 8000 * (1 - 0.015*n - 0.005*(1+(n/2))*(n/2))
For n=6 this becomes
8000 * (1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
= 8000*0.85
= 6800
(Notice that the factor 0.85 is the same in both calculations.)
Yes, Rufus will be able to buy the car in 6 years.
def nbMonths(old, new, savings, percent)
percent = percent.fdiv(100)
current_savings = 0
months = 0
loop do
break if current_savings + old >= new
current_savings += savings
old -= old * percent
new -= new * percent
months += 1
percent += 0.005 if months.odd?
end
[months, (current_savings + old - new).round]
end

"Buying a car" Ruby codewars

I am trying to do Ruby codewars challenge and I am stuck since I pass sample tests but can't pass final one. I am getting error Expected: [8, 597], instead got: [8, 563].
Instructions :
A man has a rather old car being worth $2000. He saw a secondhand car
being worth $8000. He wants to keep his old car until he can buy the
secondhand one.
He thinks he can save $1000 each month but the prices of his old car
and of the new one decrease of 1.5 percent per month. Furthermore the
percent of loss increases by a fixed 0.5 percent at the end of every
two months.
Example of percents lost per month:
If, for example, at the end of first month the percent of loss is 1,
end of second month percent of loss is 1.5, end of third month still
1.5, end of 4th month 2 and so on ...
Can you help him? Our man finds it difficult to make all these
calculations.
How many months will it take him to save up enough money to buy the
car he wants, and how much money will he have left over?
def nbMonths(startPriceOld, startPriceNew, savingperMonth, percentLossByMonth)
months = 0
leftover = 0
currentSavings = 0
until (currentSavings + startPriceOld) >= (startPriceNew)
months += 1
months.even? ? percentLossByMonth = percentLossByMonth + 0.5 : percentLossByMonth
startPriceNew = startPriceNew * (1 - (percentLossByMonth/100))
startPriceOld = startPriceOld * (1 - (percentLossByMonth/100))
currentSavings = currentSavings + savingperMonth
end
leftover = currentSavings + startPriceOld - startPriceNew
return [months, leftover.abs.to_i]
end
I don't want to look at solutions and I don't need one here just a nudge in the right direction would be very helpful.
Also, I get that code is probably sub-optimal in a lot of ways but I have started coding 2 weeks ago so doing the best I can.
Tnx guys
Your algorithm is good. But you have two coding errors:
1) percentLossByMonth needs to be converted to float before dividing it by 100 ( 5 / 100 = 0 while (5.to_f) / 100 = 0.05 )
2) It's said in the instructions that you need to return the nearest integer of the leftover, which is leftover.round
def nbMonths(startPriceOld, startPriceNew, savingperMonth, percentLossByMonth)
months = 0
leftover = 0
currentSavings = 0
until (currentSavings + startPriceOld) >= (startPriceNew)
months += 1
percentLossByMonth += months.even? ? 0.5 : 0
startPriceNew = startPriceNew * (1 - (percentLossByMonth.to_f/100))
startPriceOld = startPriceOld * (1 - (percentLossByMonth.to_f/100))
currentSavings += savingperMonth
end
leftover = currentSavings + startPriceOld - startPriceNew
return [months, leftover.round]
end
The problem with your code has been identified, so I will just offer an alternative calculation.
r = 0.015
net_cost = 8000-2000
n = 1
months, left_over = loop do
r += 0.005 if n.even?
net_cost *= (1-r)
tot = n*1000 - net_cost
puts "n=#{n}, r=#{r}, net_cost=#{net_cost.to_i}, " +
"savings=#{(n*1000).to_i}, deficit=#{-tot.to_i}"
break [n, tot] if tot >= 0
n += 1
end
#=> [6, 766.15...]
months
#=> 6
left_over
#=> 766.15...
and prints
n=1, r=0.015, net_cost=5910, savings=1000, deficit=4910
n=2, r=0.020, net_cost=5791, savings=2000, deficit=3791
n=3, r=0.020, net_cost=5675, savings=3000, deficit=2675
n=4, r=0.025, net_cost=5534, savings=4000, deficit=1534
n=5, r=0.025, net_cost=5395, savings=5000, deficit=395
n=6, r=0.030, net_cost=5233, savings=6000, deficit=-766

How to speed up a double loop in matlab

This is a follow-up question of this question.
The following code takes an enormous amount of time to loop through. Do you have any recommendations for speeding up the process? The variable z has a size of 479x1672 and others will be around 479x12000.
z = HongKongPrices;
zmat = false(size(z));
r = size(z,1);
c = size(z,2);
for k = 1:c
for i = 5:r
if z(i,k) == z(i-4,k) && z(i,k) == z(i-3,k) && z(i,k) == z(end,k)
zmat(i-3:i,k) = 1
end
end
end
z(zmat) = NaN
I am currently running this with MatLab R2014b on an iMac with 3.2 Intel i5 and 16 GB DDR3.
You can use logical indexing here to your advantage to replace the IF-conditional statement and have a small-loop -
%// Get size parameters
[r,c] = size(z);
%// Get logical mask with ones for each column at places that satisfy the condition
%// mentioned as the IF conditional statement in the problem code
mask = z(1:r-4,:) == z(5:r,:) & z(2:r-3,:) == z(5:r,:) & ...
bsxfun(#eq,z(end,:),z(5:r,:));
%// Use logical indexing to map entire z array and set mask elements as NaNs
for k = 1:4
z([false(k,c) ; mask ; false(4-k,c)]) = NaN;
end
Benchmarking
%// Size parameters
nrows = 479;
ncols = 12000;
max_num = 10;
num_iter = 10; %// number of iterations to run each approach,
%// so that runtimes are over 1 sec mark
z_org = randi(max_num,nrows,ncols); %// random input data of specified size
disp('--------------------------------- With proposed approach')
tic
for iter = 1:num_iter
z = z_org;
[..... code from the proposed approach ...]
end
toc, clear z k mask r c
disp('--------------------------------- With original approach')
tic
for iter = 1:num_iter
z = z_org;
[..... code from the problem ...]
end
toc
Results
Case # 1: z as 479 x 1672 (num_iter = 50)
--------------------------------- With proposed approach
Elapsed time is 1.285337 seconds.
--------------------------------- With original approach
Elapsed time is 2.008256 seconds.
Case # 2: z as 479 x 12000 (num_iter = 10)
--------------------------------- With proposed approach
Elapsed time is 1.941858 seconds.
--------------------------------- With original approach
Elapsed time is 2.897006 seconds.

Algorithm needed to calculate difference between two times

I have an hour selection drop down 0-23 and minutes selection drop down 0-59 for Start time and End time respectively (so four controls).
I'm looking for an algorithm to calculate time difference using these four values.
Since they're not stored in fancy date/time selection controls, I don't think I can use any standard date/time manipulation functions.
How do I calculate the difference between the two times?
This pseudo-code gives you the algorithm to work out the difference in minutes. It assumes that, if the start time is after the end time, the start time was actually on the previous day.
const MINS_PER_HR = 60, MINS_PER_DAY = 1440
startx = starthour * MINS_PER_HR + startminute
endx = endhour * MINS_PER_HR + endminute
duration = endx - startx
if duration < 0:
duration = duration + MINS_PER_DAY
The startx and endx values are the number of minutes since midnight.
This is basically doing:
Get number of minutes from start of day for start time.
Get number of minutes from start of day for end time.
Subtract the former from the latter.
If result is negative, add number of minutes in a day.
Don't be so sure though that you can't use date/time manipulation functions. You may find that you could easily construct a date/time and calculate differences with something like:
DateTime startx = new DateTime (1, 1, 2010, starthour, startminute, 0);
DateTime endx = new DateTime (1, 1, 2010, endhour , endminute , 0);
Integer duration = DateTime.DiffSecs(endx, startx) / 60;
if (duration < 0)
duration = duration + 1440;
although it's probably not needed for your simple scenario. I'd stick with the pseudo-code I gave above unless you find yourself doing some trickier date/time manipulation.
If you then want to turn the duration (in minutes) into hours and minutes:
durHours = int(duration / 60)
durMinutes = duration % 60 // could also use duration - (durHours * 60)
This will compute duration in minutes including the year as factor
//* Assumptions:
Date is in Julian Format
startx = starthour * 60 + startminute
endx = endhour * 60 + endminute
duration = endx - startx
if duration <= 0:
duration = duration + 1440
end-if
if currday > prevday
duration = duration + ((currday-preday) - 1 * 1440)
end-if
First you need to check to see if the end time is greater than or equal to the start time to prevent any problems. To do this you first check to see if the End_Time_Hour is greater than Start_Time_Hour. If they're equal you would instead check to see if End_Time_Min is greater than or equal to Start_Time_Min.
Next you would subtract Start_Time_Hour from End_Time_Hour. Then you would subtract Start_Time_Min from End_Time_Min. If the difference of the minutes is less than 0 you would decrement the hour difference by one and add the minute difference to 60 (or 59, test that). Concat these two together and you should be all set.
$start_time_hr = 5;
$start_time_mi = 50;
$end_time_hr = 8;
$end_time_mi = 30;
$diff = (($end_time_hr*60)+$end_time_mi) - (($start_time_hr*60)+$start_time_mi);
$diff_hr = (int)($diff / 60);
$diff_mi = (int)($diff) - ($diff_hr*60);
echo $diff_hr . ':' . $diff_mi;
simple equation should help:
mindiff = 60 + endtime.min - starttime.min
hrdiff = ((mindiff/60) - 1) + endtime.hr - starttime.hr
This gives you the duration in hours and minutes
h1 = "hora1"
m1 "min1"
h2 "hora2"
m2 = "min2"
if ( m1 > m2)
{
h3 = (h2 - h1) - 1;
}
else
{
h3 = h2 - h1;
}
m1 = 60 - m1;
if (m1 + m2 >= 60)
{
m3 = 60 - (m1 + m2);
} else if (m3 < 0)
{
m3 = m3 * -1;
}
else
{
m3 = m1 + m2;
}
System.out.println("duration:" + h3 + "h" + m3 + "min");
If you have a function that returns the number of days since some start date (e.g. dayssince1900) you can just convert both dates to seconds since that start date, do the ABS(d1-d2) then convert the seconds back to whatever format you want e.g. HHHH:MM:SS
Simple e.g.
SecondsSince1900(d)
{
return dayssince1900(d)*86400
+hours(d)*3600
+minutes(d)*60
+seconds(d);
}
diff = ABS(SecondsSince1900(d1)-SecondsSince1900(d2))
return format(diff DIV 3600)+':'+format((diff DIV 60) MOD 60)+':'+format(diff MOD 60);
Hum: Not that simple if you have to take into account the leap seconds astronomers are keen to put in from time to time.

Non-linear counter

So I have a counter. It is supposed to calculate the current amount of something. To calculate this, I know the start date, and start amount, and the amount to increment the counter by each second. Easy peasy. The tricky part is that the growth is not quite linear. Every day, the increment amount increases by a set amount. I need to recreate this algorithmically - basically figure out the exact value at the current date based on the starting value, the amount incremented over time, and the amount the increment has increased over time.
My target language is Javascript, but pseudocode is fine too.
Based on AB's solution:
var now = new Date();
var startDate1 = new Date("January 1 2010");
var days1 = (now - startDate1) / 1000 / 60 / 60 / 24;
var startNumber1 = 9344747520;
var startIncrement1 = 463;
var dailyIncrementAdjustment1 = .506;
var currentIncrement = startIncrement1 + (dailyIncrementAdjustment1 * days1);
startNumber1 = startNumber1 + (days1 / 2) * (2 * startIncrement1 + (days1 - 1) * dailyIncrementAdjustment1);
Does that look reasonable to you guys?
It's a quadratic function. If t is the time passed, then it's the usual at2+bt+c, and you can figure out a,b,c by substituting the results for the first 3 seconds.
Or: use the formula for the arithmetic progression sum, where a1 is the initial increment, and d is the "set amount" you refer to. Just don't forget to add your "start amount" to what the formula gives you.
If x0 is the initial amount, d is the initial increment, and e is the "set amount" to increase the incerement, it comes to
x0 + (t/2)*(2d + (t-1)*e)
If I understand your question correctly, you have an initial value x_0, an initial increment per second of d_0 and an increment adjustment of e per day. That is, on day one the increment per second is d_0, on day two the increment per second is d_0 + e, etc.
Then, we note that the increment per second at time t is
d(t) = d_0 + floor(t / S) * e
where S is the number of seconds per day and t is the number of seconds that have elapsed since t = t_0. Then
x = x_0 + sum_{k < floor(t / S)} S * d(k) + S * (t / S - floor(t / S)) * d(t)
is the formula that you are seeking. From here, you can simplify this to
x = x_0 + S * floor(t / S) d_0 + S * e * (floor(t / S) - 1) * floor(t / S) / 2.
use strict; use warnings;
my $start = 0;
my $stop = 100;
my $current = $start;
for my $day ( 1 .. 100 ) {
$current += ($day / 10);
last unless $current < $stop;
printf "Day: %d\tLeft %.2f\n", $day, (1 - $current/$stop);
}
Output:
Day: 1 Left 1.00
Day: 2 Left 1.00
Day: 3 Left 0.99
Day: 4 Left 0.99
Day: 5 Left 0.98
...
Day: 42 Left 0.10
Day: 43 Left 0.05
Day: 44 Left 0.01

Resources