|
return ( 42 ) ; should be enough for anyone.
For SQL Server, how about a CLR aggregate?
|
|
|
|
|
Takes me 2 minutes to write the bloody thing in excel and it is still a kludge. The business will NOT accept 42 (and most would not know the reference, damned whippersnappers).
DBA/policy refuses to add the CLR to SQL Server.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
The Bosses where I am have now seen the performance benefits of CLR Functions in place of string manipulation in SQL (as a particularly strong argument).
I spent the last two weeks refactoring my CLR Functions so more teams can easily deploy my Library database to their servers.
By using a separate database for this library of Functions, we don't need to enable the CLR on the databases that contain data.
Then try to convince the admins that they don't need to enable backups on a database that contains no data.
The biggest issue I've encountered is in deploying updates for the Assembly, but my friendly DBA and I seem to have a working solution.
|
|
|
|
|
Got some sample data and expected result?
|
|
|
|
|
Edited the OP with some actual data.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
The percentage of change defined as ... ?
«While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it. A few hundred years later another traveler despairing as myself, may mourn the disappearance of what I may have seen, but failed to see.» Claude Levi-Strauss (Tristes Tropiques, 1955)
|
|
|
|
|
No idea how to express it in LINQ or TSQL, but I think this is the maths you're looking for (assuming the users don't mind logarithms)
Using your numbers A0 = 100, A1, A2, A3 = 126, produce A4, A5.
ratio = cube-root(A3 / A0)
A4 = A3 * ratio, etc
Disclaimer: A career in engineering taught me to think logarithmically, ratios not increments, etc.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Assuming SQL Server 2012 or later, and the existence a field in your table which defines the order in which you want to process the rows:
WITH cte As
(
SELECT
ROW_NUMBER() OVER (ORDER BY SeqNo) As RN,
(TheValue - LAG(TheValue) OVER (ORDER BY SeqNo)) / TheValue As Change
FROM
YourTable
)
SELECT
Avg(Change) As AverageChange
FROM
cte
WHERE
RN Between 1 And 4
;
Result (using decimal(20, 7) for the source column type): 0.07106985920545242
For C#, using LINQ:
double average = values.Skip(1).Take(3)
.Zip(values, (second, first) => (second - first) / second)
.Average();
Result (using decimal type): 0.0710698592054524257914088423
Result (using double type): 0.0710698592054524
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Your name is getting into my code base. I like to link back to these answers as the make excellent doco The final function...
private List<decimal> CalcAverageGrowth(List<decimal> lValues)
{
List<decimal> lResult = new List<decimal>();
decimal average = lValues.Skip(1).Take(lValues.Count - 1)
.Zip(lValues, (second, first) => (second - first) / second)
.Average();
lResult.Add(lValues.Last() + (lValues.Last() * average));
lResult.Add(lResult.Last() + (lResult.Last() * average));
return lResult;
}
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Mycroft Holmes wrote:
lValues.Skip(1).Take(lValues.Count - 1)
There's no need for the Take there. You're saying "skip one, and take the rest", which is exactly what would happen if you just said "skip 1".
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Any idea how to deal with a zero value in the source list - generates a divide by zero error. Other than filter them out.
I hate crappy data
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Taking the example below, this should do it:
Values.Select(
p =>
new
{
avg = Values.Skip(1).Take(Values.Count - 1)
.Where(x => Math.Abs(x) > double.Epsilon)
.Zip(Values, (second, first) => (second - first)/second)
.Average()
})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First();
This space for rent
|
|
|
|
|
It depends what you want the percentage change to be when one of the values is zero.
Assuming you want it to be 1 , the ternary operator should do the trick:
decimal average = lValues.Skip(1)
.Zip(lValues, (second, first) => second == 0 ? 1 : (second - first) / second)
.Average();
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
The evil side in me likes a challenge. I had a little bit of a play around and came up with this (where we assume that Values is your list of double value inputs; this copes with arbitrary lengths of Values as long as it's greater than 2):
Values.Select(
p =>
new {avg = Values.Skip(1).Where(x => index < Values.Count).Select(x => (x - Values[index++])/x).Average()})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First(); Taking inspiration from Richard's excellent answer, this can be further simplified into:
Values.Select(
p =>
new
{
avg = Values.Skip(1).Take(Values.Count - 1)
.Zip(Values, (second, first) => (second - first)/second)
.Average()
})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First();
This space for rent
modified 29-Aug-17 10:25am.
|
|
|
|
|
Dear experts
I am somewhat "c++ corrupted". With this background I'm looking for a replacement for c++ const stuff in c#.
I don't look for a solution. First and foremost, this question I ask to get an assessment of the class design from you.
What I need/I try to solve:
I have a class Spectrum (basically a vector of doubles) for which I need full access for some tasks of the app(means manipulate each value of the vector) while other tasks should only have the possibility to read the values.
public class Spectrum
{
private readonly List _values;
public double this[int lambda]
{
get
{
return _values[lambda];
}
set
{
_values[lambda] = value;
}
}
}
[Edit]
The target is to protect some data from unintentional/Programme mistaken modifications
[/Edit]
Approach I.
For a first approach I thought I introduce an interface IConstSpectrum which hides the setter and will be used where I like to return a read only Spectrum.
But like in c++ one can cast the interface and have afterwards full access (in c++ this means a dirty const_cast)
Approach II.
a.) I introduce a class ConstSpectrum ...
public class ConstSpectrum
{
protected readonly List _values;
public double this[int lambda]
{
get
{
return _values[lambda];
}
}
}
b.) ... and derive from this the full accessible spectrum
public class Spectrum: ConstSpectrum
{
public double this[int lambda]
{
set
{
_values[lambda] = value;
}
}
}
Conclusion Approach II:
Depending on the task , I would use ConstSpectrum or Spectrum. And I'm Aware returning a Spectrum as ConstSpectrum opens the door to cast again.
Questions, resp, how do you see this:
- What do you think about this design? Is it overkill?
- Is there a better or maybe more easy solution?
Thank you very much in advance.
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
You could use a protected or internal setter: that would restrict the access to classes derived from ConstSpectrum or in the same assembly respectively. There is also protected internal which allows both derived and same assembly, basically.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thank you very much for this Inputs. I will check what that means in Details.
Thanks again.
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
I read about internal (I think protected only does not help me). If I understand it correctly internal restricts the Access to the assembly (or maybe the Name space) where the class Spectrum is implemented.
So for me I think it will not help, because this class Spectrum/ConstSpectrum Needs to be available for several (a lot of) assemblies and especally also for the application itself.
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
With any approach one could also argue "but what about reflection" (or unsafe even).. just as in C++, there is no protection against intentional misuse of these classes, whether that means uncovering the "secret identity" of an object and casting to it or some more nefarious sort of "unauthorized poking around in private bits".
Hiding the existence of the setter with an interface already protects against unintentional abuse, so I would say that's enough.
|
|
|
|
|
Thank you very much. Yep, the Interface I think should really do it because as you mentioned there is always a way to break the rules.
I did this (breaking the rules) more than one times in c++ for legacy third party libraries whith bugs. In worst case I did #define privat public to make a Workaround
Thank you again.
Bruno
[Edit]
Reading this againQuote: Hiding the existence of the setter with an interface already protects against unintentional abuse, so I would say that's enough.
[/Edit]
modified 19-Jan-21 21:04pm.
|
|
|
|
|
0x01AA wrote: But like in c++ one can cast the interface and have afterwards full access (in c++ this means a dirty const_cast)
If you do not trust your users then you cannot directly expose the data at all.
It should only be exposed to the class and all public access, whether modifiable or not, should be via wrapper classes. Those wrapper classes provide appropriate methods. For the non-modifiable form the wrapper class should contain a copy of the array.
Might note that the first condition above, that of trust, I believe should be address via non-technological means via code reviews and management dictates.
|
|
|
|
|
Thank you for your reply.
Quote: you do not trust your users then you cannot directly expose the data at all.
I trust them, it is most for internal use...
... but you bring back into my mind to think more realistic/pragmatic:
The protection should be only to prevent from unintentional modification. This again in my mind tells me, my target to make it readonly more than by the help of a IConstInterface is Overkill.
Sometimes I Need to be waked up
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
Have you considered putting the core functionality in an inner class, inside the public class that exposes the operations you want people to be able to use?
This space for rent
|
|
|
|
|
Thank you for your reply.
Sorry, I don't understand. The Information of the class Spectrum should be available to anybody (read only) but only full Access for a certain "core". But I really don't like to manage Access by the help of assembly Organisation.
Can you give me some more hints how to structure this?
[Edit]I'm absolute beginner in c#[/Edit]
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
Use a "producer-consumer" pattern.
You're using "lists" anyway; create your collection and wrap it in a ReadOnlyCollection<t> for the (read-only) consumers.
(I recently switched to lists for some of my arrays when I noticed no significant difference for my requirements.)
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|