What is meant or being referenced by the DOLLARS, CENTS and MILLICENTS terminology in substrate? - substrate

Many substrate cryptocurrencies contain code referencing DOLLARS, CENTS and MILLICENTS, eg:
pub const UNITS: Balance = 10_000_000_000;
pub const DOLLARS: Balance = UNITS; // 10_000_000_000
pub const CENTS: Balance = DOLLARS / 100; // 100_000_000
pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000
(see:
kusama,
polkadot,
rococo,
westend)
I am struggling to grasp what these terms are meant to reference.
Because DOLLARS is originally set to the constant value of UNITS (eg: 10 billion for polkadot), my inference is that the term is meant to describe total supply at genesis. Is that correct? If so, it begs the question why the DOLLARS constant wasn't named TOTAL_SUPPLY_AT_GENESIS to avoid the ambiguity of the chosen term. Perhaps I've misunderstood what the term is referencing.
I have completely failed to develop an inference for what CENTS and MILLICENTS are supposed to represent. Because of their conventional meaning in fiat currency, I initially assumed they refer to a fractional monetary unit however, most substrate currencies assign a value to CENTS and MILLICENTS that doesn't provide logical support for that inference. eg for polkadot:
pub const CENTS: Balance = DOLLARS / 100; // 100_000_000
or kusama:
pub const CENTS: Balance = UNITS / 30_000;
I find it unfortunate that cent is used in this manner in substrate codebases since
Etymologically, the word 'cent' derives from the Latin word centum meaning hundred
(wikipedia:Cent) and don't get me started on MILLICENTS.
I would really appreciate some clarification on what these terms mean in the substrate context.

my inference is that the term is meant to describe total supply at genesis. Is that correct?
I think DOLLARS never was the total amount of token at genesis.
As far as I know DOLLARS is just a unit for an amount of token, not related to any other specific currency named dollar.
a CENTS in polkadot is DOLLARS/100 so it is logic.
in kusama, CENTS is UNITS/30_000, IMHO in this case CENTS refers to the cent of an unnamed token unit which worth: UNITS/300, but I agree is a bit weird that this unit is not named.

Related

How do you ensure accuracy when dealing with ints and doubles within conditions?

Beginner here.
How does one ensure accuracy when dealing with small margins like this? one of my test cases results in 100.9 - which obviously isn't triggering the fee increase.
The floor division works for calculating the correct fee, but I'm not sure how to handle that preceding statement. Do I need to type cast every number to a double?
if ((Math.ceil(weightPerItemInOz * numberOfItems) / 16) > 100)
fee = fee * (Math.floor((double)(weightPerItemInOz * numberOfItems) / 1000)); ```

Should I always avoid lower case class names?

The following is incompatible with the Dart Style Guide. Should I not do this? I'm extending the num class to build a unit of measure library for medical applications. Using lower case looks more elegant than Kg or Lbs. In some cases using lower case is recommended for safety i.e. mL instead of Ml.
class kg extends num {
String uom = "kg";
num _value;
lbs toLbs() => new lbs(2.20462 * _value);
}
class lbs extends num {
String uom = "lbs";
num _value;
kg toKg() => new kg(_value/2.20462);
}
For your case I might pick a unit (e.g. milligrams) and make other units multiples of it. You can use division for conversion:
const mg = 1; // The unit
const g = mg * 1000;
const kg = g * 1000;
const lb = mg * 453592;
main() {
const numPoundsPerKilogram = kg / lb;
print(numPoundsPerKilogram); // 2.20462...
const twoPounds = lb * 2;
const numGramsInTwoPounds = twoPounds / g;
print(numGramsInTwoPounds); // 907.184
}
It's best to make the unit small, so other units can be integer multiples of it (ints are arbitrary precision).
It's up to you if you use them.
There might be situations where it can be important.
One I can think of currently is when you have an open source project and you don't want to alienate potential contributors.
When you have no special reason stick with the guidelines, if you have a good reason deviate from it.
Don't use classes for units. Use them for quantities:
class Weight {
static const double LBS_PER_KG = 2.20462;
num _kg;
Weight.fromKg(this._kg);
Weight.fromLbs(lbs) {
this._kg = lbs / LBS_PER_KG;
}
get inKg => _kg;
get inLbs => LBS_PER_KG * _kg;
}
take a look at the Duration class for ideas.
Coding conventions serve to help you write quality, readable code. If you find that ignoring a certain convention helps to improve the readability, that is your decision.
However, code is rarely only seen by one pair of eyes. Other programmers will be confused when reading your code if it doesn't follow the style guide. Following coding conventions allows others to quickly dive into your code and easily understand what is going on. Of course, it is possible that you really will be the only one to ever view this code, in which case this is moot.
I would avoid deviating from the style guide in most cases, except where the advantage is very obvious. For your situation I don't the advantage outweighs the disadvantage.
I wouldn't really take those coding standards too seriously.
I think these guidelines are much more reasonable: less arbitrary, and more useful:
Java: Code Conventions
Javascript: http://javascript.crockford.com/code.html
There are many more you can choose from - pick whatever works best for you!
PS:
As long as you're talking about Dart, check out this article:
Google Dart to ultimately replace Javascript ... not!

When are numbers NOT Magic?

I have a function like this:
float_as_thousands_str_with_precision(value, precision)
If I use it like this:
float_as_thousands_str_with_precision(volts, 1)
float_as_thousands_str_with_precision(amps, 2)
float_as_thousands_str_with_precision(watts, 2)
Are those 1/2s magic numbers?
Yes, they are magic numbers. It's obvious that the numbers 1 and 2 specify precision in the code sample but not why. Why do you need amps and watts to be more precise than volts at that point?
Also, avoiding magic numbers allows you to centralize code changes rather than having to scour the code when for the literal number 2 when your precision needs to change.
I would propose something like:
HIGH_PRECISION = 3;
MED_PRECISION = 2;
LOW_PRECISION = 1;
And your client code would look like:
float_as_thousands_str_with_precision(volts, LOW_PRECISION )
float_as_thousands_str_with_precision(amps, MED_PRECISION )
float_as_thousands_str_with_precision(watts, MED_PRECISION )
Then, if in the future you do something like this:
HIGH_PRECISION = 6;
MED_PRECISION = 4;
LOW_PRECISION = 2;
All you do is change the constants...
But to try and answer the question in the OP title:
IMO the only numbers that can truly be used and not be considered "magic" are -1, 0 and 1 when used in iteration, testing lengths and sizes and many mathematical operations. Some examples where using constants would actually obfuscate code:
for (int i=0; i<someCollection.Length; i++) {...}
if (someCollection.Length == 0) {...}
if (someCollection.Length < 1) {...}
int MyRidiculousSignReversalFunction(int i) {return i * -1;}
Those are all pretty obvious examples. E.g. start and the first element and increment by one, testing to see whether a collection is empty and sign reversal... ridiculous but works as an example. Now replace all of the -1, 0 and 1 values with 2:
for (int i=2; i<50; i+=2) {...}
if (someCollection.Length == 2) {...}
if (someCollection.Length < 2) {...}
int MyRidiculousDoublinglFunction(int i) {return i * 2;}
Now you have start asking yourself: Why am I starting iteration on the 3rd element and checking every other? And what's so special about the number 50? What's so special about a collection with two elements? the doubler example actually makes sense here but you can see that the non -1, 0, 1 values of 2 and 50 immediately become magic because there's obviously something special in what they're doing and we have no idea why.
No, they aren't.
A magic number in that context would be a number that has an unexplained meaning. In your case, it specifies the precision, which clearly visible.
A magic number would be something like:
int calculateFoo(int input)
{
return 0x3557 * input;
}
You should be aware that the phrase "magic number" has multiple meanings. In this case, it specifies a number in source code, that is unexplainable by the surroundings. There are other cases where the phrase is used, for example in a file header, identifying it as a file of a certain type.
A literal numeral IS NOT a magic number when:
it is used one time, in one place, with very clear purpose based on its context
it is used with such common frequency and within such a limited context as to be widely accepted as not magic (e.g. the +1 or -1 in loops that people so frequently accept as being not magic).
some people accept the +1 of a zero offset as not magic. I do not. When I see variable + 1 I still want to know why, and ZERO_OFFSET cannot be mistaken.
As for the example scenario of:
float_as_thousands_str_with_precision(volts, 1)
And the proposed
float_as_thousands_str_with_precision(volts, HIGH_PRECISION)
The 1 is magic if that function for volts with 1 is going to be used repeatedly for the same purpose. Then sure, it's "magic" but not because the meaning is unclear, but because you simply have multiple occurences.
Paul's answer focused on the "unexplained meaning" part thinking HIGH_PRECISION = 3 explained the purpose. IMO, HIGH_PRECISION offers no more explanation or value than something like PRECISION_THREE or THREE or 3. Of course 3 is higher than 1, but it still doesn't explain WHY higher precision was needed, or why there's a difference in precision. The numerals offer every bit as much intent and clarity as the proposed labels.
Why is there a need for varying precision in the first place? As an engineering guy, I can assume there's three possible reasons: (a) a true engineering justification that the measurement itself is only valid to X precision, so therefore the display shoulld reflect that, or (b) there's only enough display space for X precision, or (c) the viewer won't care about anything higher that X precision even if its available.
Those are complex reasons difficult to capture in a constant label, and are probbaly better served by a comment (to explain why something is beng done).
IF the use of those functions were in one place, and one place only, I would not consider the numerals magic. The intent is clear.
For reference:
A literal numeral IS magic when
"Unique values with unexplained meaning or multiple occurrences which
could (preferably) be replaced with named constants." http://en.wikipedia.org/wiki/Magic_number_%28programming%29 (3rd bullet)

CInt overflow error when value exceeds 100,000+

I am brand new to programming and I am running into some trouble with CInt overflow error.
Whenever the value reaches 100,000+ I get a CInt overflow error. This was a practice exercise in my intro to programming class. As far as I can see I coded it exactly how it was done in practice, but the practice shows using values as high as 300,000.
Can someone possibly explain what I might be doing wrong?
<script language="VBscript">
Option Explicit
DIM numberofshifts, totalshift1, totalshift2, _
totalshift3, grandtotal, shiftaverage
numberofshifts=3
totalshift1 = Inputbox("How many widgets during the first shift")
totalshift2 = Inputbox("How many widgets during the second shift")
totalshift3 = Inputbox("How many widgets during the third shift")
grandtotal = cint(totalshift1) + totalshift2 + totalshift3
shiftaverage = grandtotal / numberofshifts
Document.write "The Total of the Three Shifts is " & grandtotal
Document.write "<br>The Average of the Three Shifts is " & shiftaverage
</script>
CInt can handle betweeen -32,768 and 32,767.
Use CLng instead of CInt.
MSDN Reference
Converting string data to integers may be accomplished by using CInt() CLng() or CDbl().
It is important to remember the size limitations of these data types. Different programming languages have different limitations.
Here is a link to VBScript Data Types.
Integers can handle integers from -32,768 to 32,767.
Long can handle integers from -2,147,483,648 to 2,147,483,647.
Doubles can handle numbers up to 1.79769313486232E+308, (That's a bigger number than the number of atoms in the Sun, which is 1.19 octodecillion.) They are also double floating-point precision; meaning a double can also handle extremely precise decimal points.
grandtotal = cdbl(totalshift1) + totalshift2 + totalshift3
This will eliminate the overflow problem. It won't handle the error if a user enters a non-number, but that's another topic.

Calculating IRR in ruby

Can anyone help me with a method that calculates the IRR of a series of stock trades?
Let's say the scenario is:
$10,000 of stock #1 purchased 1/1 and sold 1/7 for $11,000 (+10%)
$20,000 of stock #2 purchased 1/1 and sold 1/20 for $21,000 (+5%)
$15,000 of stock #3 purchased on 1/5 and sold 1/18 for $14,000 (-6.7%)
This should be helpful: http://www.rubyquiz.com/quiz156.html
But I couldn't figure out how to adapt any of the solutions since they assume the period of each return is over a consistent period (1 year).
I finally found exactly what I was looking for: http://rubydoc.info/gems/finance/1.1.0/Finance/Cashflow
gem install finance
To solve the scenario I posted originally:
include Finance
trans = []
trans << Transaction.new( -10000, date: Time.new(2012,1,1) )
trans << Transaction.new( 11000, date: Time.new(2012,1,7) )
trans << Transaction.new( -20000, date: Time.new(2012,1,1) )
trans << Transaction.new( 21000, date: Time.new(2012,1,20) )
trans << Transaction.new( -15000, date: Time.new(2012,1,5) )
trans << Transaction.new( 14000, date: Time.new(2012,1,18) )
trans.xirr.apr.to_f.round(2)
I also found this simple method: https://gist.github.com/1364990
However, it gave me some trouble. I tried a half dozen different test cases and one of them would raise an exception that I was never able to debug. But the xirr() method in this Finance gem worked for every test case I could throw at it.
For an investment that has an initial value and final value, as is the case with your example data that includes purchase price, sell price and a holding period, you only need to find holding period yield.
Holding period yield is calculated by subtracting 1 from holding period return
HPY = HPR - 1
HPR = final value/initial value
HPY = 11,000/10,000 - 1 = 1.1 - 1 = 0.10 = 10%
HPY = 21,000/20,000 - 1 = 1.05 - 1 = 0.05 = 5%
HPY = 14,000/15,000 - 1 = 0.9333 - 1 = -0.0667 = -6.7%
This article explains holding period return and yield
You can also annualize the holding period return and holding period yield using following formula
AHPR = HPR^(1/n)
AHPY = AHPR - 1
The above formulas only apply if you have a single period return as is the case with your example stock purchase and sale.
Yet if you had multiple returns, for example, you purchased a stock A on 1/1 for 100 and it's closing price over the next week climbed and fell to 98, 103, 101, 100, 99, 104
Then you will have to look beyond what HPR and HPY for multiple returns. In this case you can calculate ARR and GRR. Try out these online calculators for arithmetic rate of return and geometric rate of return.
But then if you had a date schedule for your investments then none of these would apply. You would then have to resort to finding IRR for irregular cash flows. IRR is the internal rate of return for periodic cash flows. For irregular cash flows such as for stock trade, the term XIRR is used. XIRR is an Excel function that calculates internal rate of return for irregular cash flows. To find XIRR you would need a series of cash flows and a date schedule for the cash flows.
Finance.ThinkAndDone.com explains IRR in much more detail than the articles you cited on RubyQuiz and Wiki. The IRR article on Think & Done explains IRR calculation with Newton Raphson method and Secant method using either the NPV equation set to 0 or the profitability index equation set to 1. The site also provides online IRR and XIRR calculators
I don't know anything about finance, but it makes sense to me that if you want to know the rate of return over 6 months, it should be the rate which equals the yearly rate when compounded twice. If you want to know the rate for 3 months, it should be the rate which equals the yearly rate when compounded 4 times, etc. This implies that converting from a yearly return rate to a rate for an arbitrary period is closely related to calculating roots. If you express the yearly return rate as a proportion of the original amount (i.e. express 20% return as 1.2, 100% return as 2.0, etc), then you can get the 6-month return rate by taking the square root of that number.
Ruby has a very handy way to calculate all kinds of complex roots: the exponentiation operator, **.
n ** 0.5 # square root
n ** (1.0/3.0) # 3rd root
...and so on.
So I think you should be able to convert a yearly rate of return to one for an arbitrary period by:
yearly_return ** (days.to_f / 365)
Likewise to convert a daily, weekly, or monthly rate or return to a yearly rate:
yearly_return = daily_return ** 365
yearly_return = weekly_return ** 52
yearly_return = monthly_return ** 12
...and so on.
As far as I can see (from reading the Wikipedia article), the IRR calculation is not actually dependent on the time period used. If you give a series of yearly cash flows as input, you get a yearly rate. If you give a series of daily cash flows as input, you get a daily rate, and so on.
I suggest you use one of the solutions you linked to to calculate IRR for daily or weekly cash flows (whatever is convenient), and convert that to a yearly rate using exponentiation. You will have to add 1 to the output of the irr() method (so that 10% return will be 1.1 rather than 0.1, etc).
Using the daily cash flows for the example you gave, you could do this to get daily IRR:
irr([-30000,0,0,0,-15000,0,11000,0,0,0,0,0,0,0,0,0,0,14000,0,21000])
You can use the Exonio library:
https://github.com/Noverde/exonio
and use it like this:
Exonio.irr([-100, 39, 59, 55, 20]) # ==> 0.28095
I believe that the main problem in order to be able to understand your scenario is the lack of a cash flow for each of the stocks, which is an essential ingredient for computing any type of IRR, without these, none of the formulas can be used. If you clarify this I can help you solve your problem
Heberto del Rio
There is new gem 'finance_math' that solves this problem very easy
https://github.com/kolosek/finance_math

Resources