2018/03/31

About the AR$1 pesos coins in Argentina

The dollar at twenty

Being the first days of March 2018 and considering that the dollar(US) exchange rate is US$1=AR$20 approximately, it seems to be a good opportunity to write about an observation on the coins of low denomination in Argentina. (I do not want to blame the current government, the previous government or the future government. It's just a "sociological" observation.) The value of the exchange rate varies every day a few cents, but for optimism and simplicity I will assume that it is fixed at US$1=AR$20

My theory is that when a coin is worth less than 3 or 4 cents(US), in Argentina we begin to ignore it and the coin stop circulating in the street although formally it still has value. I think that something like 3.5 cents(US) is a good threshold, and to get round numbers I am going to assume 3.33 cents(US).

(Note: Obviously this is not a serious scientific study, if you find a serious study that contradicts me, you should believe it. But speculating is free, so let's continue.)


Goodbye to the cents

In the grocery store the scales calculate the price with cents, in the supermarkets the prices still have cents, and if you pay with a credit or debit card they charge you the exact value with cents. But if you pay in cash, the value is implicitly rounded to a whole number. (Officially down, in practice it is sometimes rounded to the nearest.)

The coins of AR$0.50 and AR$0.25 are hardly used now. Once a month, one appears and I look at it with surprise. The coins of AR$0.10 and AR$0.05 are no longer used, the other day I found one in the bottom of a drawer and I realized that I have not seen them for a long time. [Note: 50% of the AR$0.10 coins are magnetic and the other 50% are not, although they look the same. It's a nice experiment to do with children who do not swallow coins, if you can find enough coins of AR$0.10.] The AR$0.01 coin never had too much use, at first there were a lot of them, they were almost octagonal, but I have not seen any of them for years.

A few years ago, when the bus was still paid by giving cash to the driver, I remember that someone dared to pay the fare with several coins below the socially accepted value. The driver accepted them as payment, he looked annoyed and threw them out the window. (Yes, it's probably illegal, but at least he threw them while the bus was parked.)

This gives us a lower bound. The AR$0.50 coin is worth US$0.025 and it has been out of use for quite some time, probably since the dollar was at AR$10 or AR$15.

The AR$0.25 coin is worth US$0.0125 and it no longer exists in practice. It is interesting to compare this with the United States customs where they still have the US$0.01 coins in circulation and people expect to pay and receive the change with the pennies.

The one peso coin

As the magic limit of US$0.0333 approaches the AR$1 coin, it is fading away. When paying at a kiosk or a business, it is expected to pay the value rounded to an integer. But if the client or cashier does not have the necessary coins, the value goes up or down by AR$1 so that it is easy to pay, perhaps with a formal comment like "I owe it to you" or "You pay it tomorrow", but nobody expects see that AR$1 again. (It is in very bad taste to pretend that one does not have coins of AR$1 to not pay that peso and take advantage of the additional rounding, first because it is probably illegal, and also because it is only one peso.) (If the difference is about AR$5 or more, the same phrases are used but the debt is expected to be paid in a few days.)

Moreover, recently, a new AR$2 coins appeared to replace the old AR$2 coins (and bills). The old model of AR$2 coin was very expensive to build, they have two colors like the euros, but inverted. The new model has a single color and is cheaper to manufacture. There are also new AR$5 coins to replace the bills. And the new AR$1 coins? They remember later and they are going to get a new model of AR$1 coins, but I do not know if they will be able to circulate for a long time.

A few years ago, suddenly there was a shortage of coins because they were used to pay for the trips in bus and they were locked inside the automatic machine in the bus. So almost all the payments had to be made in bills of AR$2, AR$5, AR$10, ... The only odd bill were the AR$5 one, and that made them special. I remember once that I had to pay in a kiosk AR$4 and I tried to pay with a AR$5 bill, but obviously they did not have a AR$1 coins to give me the change. Then they asked me if I could pay with a AR$10 bill. I did not have a AR$10 bill, but if I had a AR$20 bill that was immediately accepted. It's amazing how quickly people learned parity.

This gives us a higher bound. The AR$2 coin is worth US$0.10 and still exists. But US$0.10 is very high, I prefer to take as a bound the AR$1 coin that is equivalent to US$0.05 and it is on the edge of existence.

Principal ideals

The problem of stopping using AR$1 coins and using only those of AR$2, AR$5, AR$10 (bill), ... is that there are prices like AR11 that exist in the universe but are difficult to pay. For example AR$11 = AR$5+AR$2+AR$2+AR$2 or AR$11 = AR$10+AR$5-AR$2-AR$2. Then it is difficult to decide when it is socially acceptable to round to the nearest whole number and when to add or remove another peso so that it is an easy number to pay and give the change. The algorithm is not clear to me and probably there is not an implicit widely accepted algorithm.

I suppose that this is going to make the AR$1 coin fall into disuse softly, without a clear date when it was lost. This is probably more evident in the prices of the candy kiosks, where each item has a price that is arbitrary, distinct and easy to charge. For example if combining alfajores one get a total of AR$31, there is a slight pause to decide what to do is that AR$1 that is left hanging. (Probably the kiosk employee will offer to add a candy for AR$1, to solve the problem.)

However, in the future when we stop using the AR$2 coins and only use those of AR$5, AR$10 (bill), AR$20 (bill) ... the decisions will be much easier. All prices will be multiples of AR$5 or will be rounded up to the nearest AR$5 multiple or candies will be added up to a multiple of AR$5, without any ethical issues with the rounding. It is similar to the situation of last year where all the prices were integers and the AR$1 coin was clearly relevant.

Predictions

Let's make some predictions, assuming the limit is US$0.0333.

Estimating the years needed for these events to happen is very difficult. The official prediction of inflation for this year is 15% per year, but it is more realistic to assume that it will be a little higher. Let's say 20%. For 2019 it is more difficult to make predictions, let's say 15%. Then 10% for 2020 and then assume that it will be stabilized at 5% per year. That is, AR$20*(1.20)*(1.15)*(1.10)*(1.05)^(n-3). Making predictions in Argentina for 5 years in the future is difficult because anything can happen. And 10 years is more difficult because absolutely anything can happen. So the estimates of the years necessary to see these events are not reliable at all. They are even less reliable than all the rest of the article.


Coin that is eliminated
Exchange rate
Coins that remain
Minimum Common Multiple
Cut
Time

AR$0.50
AR$1 = US$15
1, 2, 5, ...
1
Hard
-1 year?
AR$1
AR$1 = US$30
2, 5, 10, ...
1
Soft
3 years?
AR$2
AR$1 = US$60
5, 10, 20, ...
5
Hard
17 years??
AR$5
AR$1 = US$150
10, 20, 50, ...
10
Hard
36 years???
AR$10
AR$1 = US$300
20, 50, 100, ...
10
Soft
50 years???

Hey! 50 years. I can’t believe I'm making an estimate of 50 years. I hope it has enough question marks to make it clear to everyone that it is not an accurate estimate. In a span of 50 years, absolutely anything can happen several times!

If the estimate is correct and the AR$1 coin has 3 years left of life (plus some years of zombie life until the AR$2 coin also falls), then we will probably see the new AR$1 coin design circulating.

2017/12/30

Rainbows in my home

In the rainy afternoons, at about 6 or 7 p.m. when it is close to sundown is common to see rainbows from the window of my home. Actually it is not so common, because it has to coincide the right hour, that the rain is neither too light nor too heavy so the sunlight can pass under the clouds, and I have to be at home to see it. The important things are that there are not too many buildings ahead and the window to look to the east, because the sun in the afternoon is to the west and the rainbow appears by the light that is reflected in the droplets (it is more complicated, but that gives the correct direction). (With a window to the west you should try at 6 or 7 in the morning, but it's too sleepy at that time.)



I made a scheme. Obviously it is not to scale. I think I put the colors in the correct order (the order in which they appear in the reflection, not the order in which they appear in the rainbow) (I have a probability of almost 50% of picking the correct order :)) In the photo you can see the primary and secondary rainbow, but in the diagram I drew shows only the primary one. (When I made the drawing I noticed that there has to be another upward reflection that should illuminate the clouds, I suppose that the effect in the clouds is very dim and it can’t be seen.)


In the kitchen we have a wooden ornament with a rainbow (it was for hanging things, but the hanger broke). It was left by the previous owner of the apartment and is stuck very strongly to the wall so we keep it there. Is there any relationship?


PS: If you like rainbows, check out this article about a triple rainbow near Seattle.

2017/11/06

Testing the random numbers in Racket with Random Sanity

Introduction

A few days ago I was looking at the Random Sanity project. It is a web service where you send a string of numbers supposedly at random, to see how bad is the random number generator. It doesn’t make a very exhaustive check, so it only detects cases where the generator is very bad, or cases in which the string of random numbers has already been sent.

The string consists of 64 bytes encoded in hexadecimal. For example

and the result is "
true" or "false".

The idea is to use it to test the random number generation functions in Racket and see if they pass this test.

Auxiliary constructions

random-bytes

Generates a string of bytes of length n. It is similar to crypto-random-bytes, but it uses pseudorandom numbers instead of cryptographically secure numbers. (Strange: There is no for/bytes.)

(define (random-bytes n)
  (list->bytes
   (for/list ([i (in-range n)])
     (random 256))))

with-random-seed

The seed of the pseudorandom numbers in Racket is initialized with the milliseconds near the beginning of the program. It is sometimes convenient to locally modify the seed of pseudorandom numbers without affecting the pseudorandom numbers of the rest of the program. This macro allows us to evaluate the body, fixing the seed, and after that continue with the normal pseudorandom sequence.

(define-syntax-rule (with-random-seed seed body ...)
  (parameterize ([current-pseudo-random-generator (make-pseudo-random-generator)])
    (random-seed seed)
    body ...))

Let’s try some examples

(displayln (random 10))                   ; ==> maybe 3
(with-random-seed 1234567890
  (displayln (random 10))                 ; ==>        1
  (displayln (random 10)))                ; ==>        5
(displayln (random 10))                   ; ==> maybe 2
(with-random-seed 1234567890
  (displayln (random 10))                 ; ==>        1
  (displayln (random 10)))                ; ==>        5
(displayln (random 10))                   ; ==> maybe 5

The tester

The main function is the tester, which uses a bytes string. The tester formats it and sends it via hppt to Random Sanity. Then it reads the test result and transforms it into #t or #f, which are more idiomatic. The function has very few error checks, for simplicity and for laziness.

#;(require net/http-client
           file/sha1)
 (define (test-random-bytes b)
  (let-values ([(status headers content)
                (http-sendrecv "rest.randomsanity.org"
                               (string-append "/v1/q/"
                                              (bytes->hex-string b)))])
    (let ([text (port->string content)])
      (cond
        [(string=? text "true") #t]
        [(string=? text "false") #f]
        [else (raise-result-error 'test-random-bytes
                                  "true or false"
                                  text)]))))

Some tests

All zeros # "000 ... 000"

It is not a good example of random numbers and obviously the result is #f.

(test-random-bytes (make-bytes 64 0))  ; ==> #f

Pseudo-random numbers with a fixed seed

The first time someone uses one seed the result is #t (it was me, believe me, I saw a #t) but when someone runs the program again with the same seed the sequence of pseudorandom numbers is repeated, so in all subsequent retries the result is #f. If you test another seed, you should be able to see a #t once and then #f. (Using the same seed 1234567890 in other languages will probably get a string of different bytes, so you can probably see another "true" once. More details.)

(with-random-seed 1234567890
  (test-random-bytes (random-bytes 64)))   ; ==> #f (except the first time)

Fixed seed pseudorandom numbers

Racket initializes the seed of random numbers with the milliseconds at some point near the start of the execution of the program. So every time you will get a different sequence, probably never seen before. Unless this article is an absolute success and millions of people try to run the program, it is very unlikely to be so unlucky to get a repeated seed. So you almost certainly will get #t.

(test-random-bytes (random-bytes 64))   ; ==> #t (almost sure)

Cryptographically secure numbers

For some applications it is a risk that someone else guesses the sequence. In the previous example someone could estimate when the program was run and test all the possible values of the milliseconds in a nearby range until finding the match. For these cases you can use crypto-random-bytes that generates cryptographically safe numbers. If there is no problem in the operating system or in Racket it should be (almost) impossible to find a match, and get a result that is not #t. (This is precisely the goal of Random Sanity, to detect that a serious error was accidentally introduced into the random number generator.)

#;(require racket/random)
(test-random-bytes (crypto-random-bytes 64))  ;  ==> #t

The complete program

It is necessary to use some modules, so for convenience I’ll repeat the complete program. (Some parts of the program that don´t use internet connections can be tested in PasteRack.)

#lang racket

(require net/http-client
         file/sha1
         racket/random)

(define (random-bytes n)
  (list->bytes
   (for/list ([i (in-range n)])
    (random 256))))

(define-syntax-rule (with-random-seed seed body ...)
  (parameterize ([current-pseudo-random-generator (make-pseudo-random-generator)])
    (random-seed seed)
    body ...))

(define (test-random-bytes b)
  (let-values ([(status headers content)
                (http-sendrecv "rest.randomsanity.org"
                               (string-append "/v1/q/"
                                              (bytes->hex-string b)))])
    (let ([text (port->string content)])
      (cond
        [(string=? text "true") #t]
        [(string=? text "false") #f]
        [else (raise-result-error 'test-random-bytes
                                  "true or false"
                                  text)]))))

(test-random-bytes (make-bytes 64 0))        ; ==> #f
(with-random-seed 1234567890
  (test-random-bytes (random-bytes 64)))     ; ==> #f
(test-random-bytes (random-bytes 64))        ; ==> #t
(test-random-bytes (crypto-random-bytes 64)) ; ==> #t