From J Wiki
Jump to: navigation, search

Array14 conference, calculating probabilities for non-standard poker hands, NuVoc project, code is not literature, statistical distributions code wanted, tips on writing a conference paper

Location:: Heartland

Regular monthly meeting of NYCJUG on Tuesday, February 11th, 2014.

Meeting Agenda for NYCJUG 20140211

1. Beginner's regatta: helping newbies locate concepts in J familiar to what
they already know; see "Beyond NuVoc - Rosetta Revisited".  See also "Excel-
Knowledge-Test.pdf" and "R Statistical Tables."

2. Show-and-tell: calculating probabilities for non-standard poker hands - see
"Probabilities for 'n-card' Poker Hands".

3. Advanced topics: review of talk for "7 Languages in 7 Months" meetup:

"J - the Hard Parts."

What keeps people away from or attracts them to a programming language?  See
"The alleged unreadability of J - and what to do about it", "The Semicolon
Wars", "Extreme Syntax", and "Code is not Literature".

4. Learning, teaching and promoting J, et al.: Array'14 - the ACM SIGPLAN
Workshop on Libraries, Languages and Compilers for Array Programming -
will be co-located with PLDI 2014, in Edinburgh, UK, on Friday, June 13th,
2014; see "ARRAY '14"; also, see "How to give a good research talk" and
"How to Have Your Abstract Rejected".  Maybe also


We compared the old and new vocabulary pages, discussing the pros and cons of each for introducing people to J.

By way of comparison to what some think important to know for other languages, we looked at an example test on knowledge of Excel. For another comparison we looked at all the statistical distributions that are coded in the R language to get an idea of what we need in J to be competitive with a fairly popular language like this.

Beginner's Regatta

Beyond NuVoc – Rosetta Revisited

from:  Skip Cave
to:   General forum <>
date:  Sun, Feb 9, 2014 at 1:30 AM
subject: [Jgeneral] Finding Stuff in J doc.

I was looking over NuVoc the other day, and thinking how it helped me learn the J primitives. My next thought was how I wished that we could fix the J search engine so that when newbies searched for stuff in the J wiki using traditional programming lingo, they would automatically find the J equivalent functions.

When J gave new names to all the J programming elements, it was all for good reasons. However that made it really hard to learn J by searching the wiki for programming concepts, using common programming names. When I am programming in J, I often come to a point where I know what I want to do, and I know what most other programming languages would call what I want to do. If I search for that name in the J wiki though, I usually come up empty-handed.

What we really need in NuVoc, as well as all of the J doc, is a set of common-use keywords attached to every J concept. Thus if a newbie searches for "assignment", he will get the vocabulary and dictionary pages for Is (local) and Is (global), When he searches for "indexing" he will get the Catalog pages. I could go on like this for quite a while.

Also, when newbies or anyone stumbles upon a new concept in any of the J doc, we should make it easy for that person to add new keywords to that doc page. Hopefully the keywords they add will make it easier for the next person to find that concept in the future.

So my proposal is that each NuVoc page (and all J doc pages for that matter) needs a list of keywords at (say) the bottom of the page, giving common programming names for the J concept on that page. In that way, a newbie searching for "assignment" would at least have a chance of finding what he is looking for.

However, my idea is more than just putting a list of keywords on every doc page, As has been discussed on the J mail list, Newbies who are trying to learn J, know what they are looking for, when they search for a particular concept. What If we could make it so when someone finally does find what they were looking for, they could easily add words to the keyword list on the doc page they found. They could add the words that they were using to (unsuccessfully) search for that concept. Then each doc page would start to collect keywords that people commonly use for that concept, making it much easier for newbies (and even casual J user oldies like me) to find that concept in the future.

There needs to be an easy (but controlled, and perhaps curated) way to put a new keyword on any doc page, while that page is being viewed. There needs to be a brief statement above the keyword block explaining what it is, how to add a keyword, and why one should do it.

I believe that in the long run, this keyword scheme could have a bigger impact on reducing the "steep learning curve" of J than almost any other documentation mechanism.

Skip ---

from:  Björn Helgason
date:  Sun, Feb 9, 2014 at 2:38 AM

I like the idea.

Problem with cluttering up the pages of nuvoc or voc with keywords could be avoided by adding translation index.

The index could list all common words and point to the J equivalent.

Translation table from APL, K, C, PYTHON, WHATEVER.

Example like the one Chris gave earlier how to do things in K and then in J is also great.

The more examples we get the better.

How to present them is always difficult and maybe not mix them too much to avoid further confusion.

One language to J at a time.

It would be interesting to see example table like that.

It is a sort of rosetta stone.

One complete example in language X and then the same in J.

I would like to see book about J in the Dummies series with step by step intros for beginners with easy examples.

- Björn Helgason


skype:gosiminn ---

from:  Ian Clark
date:  Sun, Feb 9, 2014 at 10:17 AM

Skip made his suggestion to me privately and I recommended him to open it up for general discussion.

The idea is brilliant in principle but raises admin problems. However the "Category" apparatus furnishes us with a neat way of doing this, with some useful x-reffing and list-building as a bonus, not to mention being prominent, well-controlled and easily searched. Chris confirms that it might work and suggests the prefix "CategoryVoc" for all such keywords, a suggestion I endorse.

The downside of having to search via Google on CategoryVocStruct or CategoryVocVariable, say, is outweighed by the fact that Moinmoin administers it all for free. The repertoire of categories is easily found on the page CategoryCategory and individual categories have a page to themselves and are easily browsed. Every NuVoc page already has a Category list at the bottom, generally containing just one entry: CategoryVoc.

I'm going to create a set of new categories, and their pages, over the next few days, based on terms familiar to C/C++ and Visual Basic programmers. Please suggest new terms at:

Once these terms are established as valid categories, please add them to wiki pages, especially NuVoc pages, as a courtesy to J newcomers.

Ian Clark ---

Examples from Other Languages

We looked at some examples of what people seem to find important features of other languages. For Excel, we looked at File:Excel-Knowledge-Test.pdf (pdf). In the case of R, we focused on the numerous statistical distributions that language makes available, as shown below. Ric Sherlock has pointed out R's contrast with J which offers only verbs for the Normal and Uniform distributions in the stats/distrib addon. However, there are also verbs for the chi squared" CDF (cumulative distribution function), as well as verbs for the Poisson distribution in the addon stats/base/distribution.

R Statistical Tables

One convenient use of R is to provide a comprehensive set of statistical tables. Functions are provided to evaluate the cumulative distribution function P(X <= x), the probability density function and the quantile function (given q, the smallest x such that P(X <= x) > q), and to simulate from the distribution.

Distribution R name additional arguments
beta beta shape1, shape2, ncp
binomial binom size, prob
Cauchy cauchy location, scale
chi-squared chisq df, ncp
exponential exp rate
F f df1, df2, ncp
gamma gamma shape, scale
geometric geom prob
hypergeometric hyper m, n, k
log-normal lnorm meanlog, sdlog
logistic logis location, scale
negative binomial nbinom size, prob
normal norm mean, sd
Poisson pois lambda
signed rank signrank n
Student’s t t df, ncp
uniform unif min, max
Weibull weibull shape, scale
Wilcoxon wilcox m, n

Prefix the name given here by ‘d’ for the density, ‘p’ for the CDF, ‘q’ for the quantile function and ‘r’ for simulation (random deviates). The first argument is x for dxxx, q for pxxx, p for qxxx and n for rxxx (except for rhyper, rsignrank and rwilcox, for which it is nn). In not quite all cases is the non-centrality parameter ncp currently available: see the on-line help for details.


Probabilities for “n-card” Poker Hands

The nCr function on most scientific calculators can be used to calculate hand frequencies; entering nCr with 52 and 5, for example, yields {\begin{matrix} {52 \choose 5}=2,598,960\end{matrix |height="32",width="176",v:shapes="_x0000_i1025",border="0"}} as above.

Derivation of frequencies of 5-card poker hands

The following computations show how the above frequencies for 5-card poker hands were determined. To understand these derivations, the reader should be familiar with the basic properties of the binomial coefficients and their interpretation as the number of ways of choosing elements from a given set. See also: sample space and event (probability theory).

Straight flush — Each straight flush is uniquely determined by its highest-ranking card. These ranks go from 5 (A-2-3-4-5) up to A (10-J-Q-K-A) in each of the 4 suits. Thus, the total number of straight flushes is: height="64",width="155"
Royal straight flush — A royal straight flush is a subset of all straight flushes in which the ace is the highest card (i.e. 10-J-Q-K-A in any of the four suits). Thus, the total number of royal straight flushes is or simply: Note: this means that the total number of non-Royal straight flushes is 36. height="64",width="177" height="64",width="86"
Four of a kind — Any one of the thirteen ranks can form the four of a kind by selecting all four of the suits in that rank. The final card can have any one of the twelve remaining ranks, and any suit. Thus, the total number of four-of-a-kinds is: height="64",width="271"
Full house — The full house comprises a triple (three of a kind) and a pair. The triple can be any one of the thirteen ranks, and consists of three of the four suits. The pair can be any one of the remaining twelve ranks, and consists of two of the four suits. Thus, the total number of full houses is: height="64",width="294"
Flush — The flush contains any five of the thirteen ranks, all of which belong to one of the four suits, minus the 40 straight flushes. Thus, the total number of flushes is: height="64",width="245"
Straight — The straight consists of any one of the ten possible sequences of five consecutive cards, from 5-4-3-2-A to A-K-Q-J-10. Each of these five cards can have any one of the four suits. Finally, as with the flush, the 40 straight flushes must be excluded, giving: height="68",width="267"
Three of a kind — Any of the thirteen ranks can form the three of a kind, which can contain any three of the four suits. The remaining two cards can have any two of the remaining twelve ranks, and each can have any of the four suits. Thus, the total number of three-of-a-kinds is: {{/jwiki/action/content//jwiki/action/content/NYCJUG201402-3oK.png%3Faction%3Dcontent?action=content|{13 \choose 1}{4 \choose 3}{12 \choose 2}{4 \choose 1}^{2}=54,912|height="68",width="315"}}
Two pair — The pairs can have any two of the thirteen ranks, and each pair can have two of the four suits. The final card can have any one of the eleven remaining ranks, and any suit. Thus, the total number of two-pairs is: height="68",width="328"
Pair — The pair can have any one of the thirteen ranks, and any two of the four suits. The remaining three cards can have any three of the remaining twelve ranks, and each can have any of the four suits. Thus, the total number of pair hands is: ' height="68",width="350"
No pair — A no-pair hand contains five of the thirteen ranks, discounting the ten possible straights, and each card can have any of the four suits, discounting the four possible flushes. Alternatively, a no-pair hand is any hand that does not fall into one of the above categories; that is, the complement of the union of all the above hands, where the universe is any way to choose five out of 52 cards. Thus, the total number of no-pair hands is: height="76",width="629"
Any five card poker hand — The total number of five card hands that can be drawn from a deck of cards is found using a combination selecting five cards, in any order where n refers to the number of items that can be selected and r to the sample size; the "!" is the factorial operator: [[File:NYCJUG201402-any5CardPokerHand.png height="64",width="563",v:shapes="_x0000_i1037",border="0"]]

Frequency of 7-card poker hands

In some popular variations of poker, a player uses the best five-card poker hand out of seven cards. The frequencies are calculated in a manner similar to that shown for 5-card hands, except additional complications arise due to the extra two cards in the 7-card poker hand. The total number of distinct 7-card hands is {\begin{matrix}{52 \choose 7}=133,784,560\end{matrix |height="32",width="200",v:shapes="_x0000_i1038",border="0"}} . It is notable that the probability of a no-pair hand is less than the probability of a one-pair or two-pair hand.

The Ace-high straight flush or royal flush is slightly more frequent (4324) than the lower straight flushes (4140 each) because the remaining two cards can have any value; a King-high straight flush, for example, cannot have the Ace of its suit in the hand (as that would make it ace-high instead).

Hand Frequency Probability Cumulative Odds
Royal flush 4,324 0.0032% 0.0032% 30,939 : 1
Straight flush (excl. royal flush) 37,260 0.0279% 0.0311% 3,589.6 : 1
Four of a kind 224,848 0.168% 0.199% 594 : 1
Full house 3,473,184 2.60% 2.80% 37.5 : 1
Flush 4,047,644 3.03% 5.82% 32.1 : 1
Straight 6,180,020 4.62% 10.4% 20.6 : 1
Three of a kind 6,461,620 4.83% 15.3% 19.7 : 1
Two pair 31,433,400 23.5% 38.8% 3.26 : 1
One pair 58,627,800 43.8% 82.6% 1.28 : 1
No pair 23,294,460 17.4% 100% 4.74 : 1
Total 133,784,560 100% 100% 0 : 1

6-Card Poker Hands

The explanation above is fine as far as it goes – except for the arbitrary and unnecessary separation of “royal flush” from other kinds of “straight flushes” – but fails to address a topic on which I’ve recently spent time: elaborating an extended series of poker hands.

This was suggested by the frustration of having the “hand” 3-pair in any of the various games allowing more than five cards in a player’s hand. In normal, five-card poker, “3-pair” is not a hand; at best it’s no more than a lowly 2-pair. A preliminary effort at placing its likelihood in the spectrum of 5-card hands put it higher than 3-of-a-kind.

This same effort also pointed to the existence of other 6-card hands: pair-of-triplets, 6-card straights, flushes, and straight-flushes, as well as what I call a “super full-house”: 4-of-a-kind and a pair. The question is where these rank in relation to the traditional 5-card hands, so I embarked on figuring this out through a combination of probability calculations and simulations.

First, I reviewed code I’d already written for 5-card hands. The final version of this code enumerated all possible hands and applied code to classify each type of hand down to the fine level at which any two hands could be ranked relatively.



This approach gave us a 2598960 x 2 table of (hand, sub-type). The code to do this looks like this:

NB.* initPokerVars: initialize poker variables from scratch.

initPokerVars=: 3 : 0
   h5=: 5 AllCombos 52
   h5=: h5{"1~/:"(1) 13|h5      NB. Order each hand by card rank.
   6!:2 'whall=. (isNothing"1 h5),.(isPair"1 h5),.(is2Pair"1 h5),.(is3ok"1 h5),.(isOnlyStraight"1 h5),.(isOnlyFlush"1 h5),.(isFullHouse"1 h5),.(is4ok"1 h5),.isStraightFlush"1 h5'

   HANDRANKS=: rankAllHands whall;<h5
   RH5=: HANDGV{h5
   CHORDH5=: RH5{a.
   equihand=. -.*./"(1) 0,2=/\|:HANDRATED
   EQUIRANK=: +/\equihand
   lens=. 2-~/\I. equihand,1
   EQHANDRANK=: lens#I. equihand


AllCombos=: 4 : 0
NB.* AllCombos: make mat of all possible distinct y things taken x at a time.
   comb=. ,.basis=. i.y
   while. 0<x=. <:x do.
       maxs=. >./"1 comb
       newcol=. maxs rmlt&.><basis
       lens=. ;#&.>newcol
       comb=. (lens#comb),.;newcol

And the code to categorize hands looks like this:

isNothing=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   'suit rank'=. /:~&.><"1 y
NB. >1 suit,    and    no duplicates,
   rc=. (1~:#~.suit)*.(#rank)=#~.rank
NB. and >1 apart, including special case of low Ace.
   rc=. rc*.-.(1*./ . =2-~/\rank)+.1*./ . =2-~/\/:~(rank=12)}rank,:_1

isAnyFlush=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.

isOnlyFlush=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   (isAnyFlush y)*.-.isAnyStraight y       NB. Not straight flush

isAnyStraight=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   rc=. _1 *./ . =2-/\/:~rnk=. 1{y
   if. 12 e. rnk do.
       rc=. rc +. _1 *./ . =2-/\/:~(rnk=12)}rnk,:_1

isOnlyStraight=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   (isAnyStraight y)*.-.isAnyFlush y       NB. Not straight flush

isPair=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
NB.   1=+/2=/\/:~1{y
   1 1 1 2-:/:~;#&.>(1,2~:/\/:~rnk)<;.1 rnk=. 1{y

is2Pair=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
NB.   2=#~.rnk#~0,~2=/\rnk=. /:~1{y
   1 2 2-:/:~;#&.>(1,2~:/\/:~rnk)<;.1 rnk=. 1{y

is3ok=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   1 1 3-:/:~;#&.>(1,2~:/\/:~rnk)<;.1 rnk=. 1{y

isFullHouse=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
NB.   0 1 1 1-:/:~2=/\/:~1{y
   2 3-:/:~;#&.>(1,2~:/\/:~rnk)<;.1 rnk=. 1{y

is4ok=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   1 4-:/:~;#&.>(1,2~:/\/:~rnk)<;.1 rnk=. 1{y

isStraightFlush=: 3 : 0
   if. 2~:#$y do. y=. suitRank y end.
   (isAnyFlush y)*.isAnyStraight y         NB. Is straight and flush.

NB. suitRank=: |:@((4 13)&#:)
suitRank=: 3 : 0
NB.* suitRank: convert nums: 2 rows: suit, rank or 2 rows->nums 0-51.
   if. 2=#$y do. 13#.|:y
   else. |:@((4 13)&#:)y

Classification of 5-card Hands

   $~.|:HANDRATED      NB. Number of distinct hand type, subtypes
7464 2
8 2860
   0 2861#:_5{.HRi     NB. Int vec version of HANDRATED: same relative ranking
8  8
8 10
8 10
8 10
8 10

   $HR=: |:0 2861#: HRi                 NB. Hands ranked: 0{major, 1{minor
2 2598960
   +/htp=. 1,2~:/\0{HR                  NB. Hand-type partition
   ]nht=. ;$&.>htp<;.(1)1{HR            NB. number of each hand type
1302540 1098240 123552 54912 10200 5108 3744 624 40
   ]npt=. ;($@~.)&.>htp<;.(1) 1{HR      NB. number subtypes per hand type
1277 2860 858 858 10 1277 156 156 10
   pcts=. 100*&.>1E_7 roundNums pht,.(+/\pht=. nht%+/nht),.|.+/\(|.nht)%+/nht
   pcts=. pcts,.]&.>0.1 roundNums %pht
   htstats=. HANDTYPE,.]&.>nht,.npt,.>pcts
   tit=. 'Hand Type';'# Type';'# Sub-type';'% Type';'Cum. %';'Rev. Cum. %';'Type/Hands'
   tots=. ('Total';]&.>+/>_3}."1}."1 htstats),3$<' - '
|Hand Type     |# Type |# Sub-type|% Type  |Cum. %  |Rev. Cum. %|Type/Hands|
|nothing       |1302540|1277      |50.11774|50.11774|100        |2         |
|pair          |1098240|2860      |42.2569 |92.37464|49.88226   |2.4       |
|2-pair        |123552 |858       |4.7539  |97.12854|7.62536    |21        |
|3-of-a-kind   |54912  |858       |2.11285 |99.24139|2.87146    |47.3      |
|straight      |10200  |10        |0.39246 |99.63385|0.75861    |254.8     |
|flush         |5108   |1277      |0.19654 |99.83039|0.36615    |508.8     |
|full house    |3744   |156       |0.14406 |99.97445|0.16961    |694.2     |
|4-of-a-kind   |624    |156       |0.02401 |99.99846|0.02555    |4165      |
|straight flush|40     |10        |0.00154 |100     |0.00154    |64974     |
|Total         |2598960|7462      |100     | -      | -         | -        |

Revisiting Hand Ranking

Here’s my initial revamping of the hand classification code to generalize it for 6-card (and up) hands within an arbitrarily large hand.

NB.* nPoker.ijs: poker hand recognition extended beyond 5-card hans.

coclass 'npoker'

suitRank=: 3 : 0
NB.* suitRank: convert nums: 2 rows: suit, rank or 2 rows->nums 0-51.
   if. 2=#$y do. 13#.|:y
   else. |:@((4 13)&#:)y

isPair=: 1 = 2 +/ .= [: #/.~ 13 | ]
TisPair_tests_=: 3 : 0
   assert. isPair 13#.|: 0 1 2 0 1,: 0 0 2 3 4
   assert. isPair 13#.|: 0 1 2 0 1 2,: 0 0 2 3 4 5

is2Pair=: 2 = 2 +/ .= [: #/.~ 13 | ]
is3ok=: 1 = 3 +/ .= [: #/.~ 13 | ]

NB. Some utilities for straights.
ptn1Block=: -. +. ] ~: 0 , }:  NB. Partition blocks of 1s
maxConsecIncs=: [: >: [: >./ [: +/&> [: (ptn1Block <;.1 ]) [: (1 = 2 -~/\ ]) ([:/:~ ~.)
NB. Simply enumerate straights by rank (card value) – abandoned.
S5=: /:~"1 (13 | i. +/~ [: i. 15 - ])5
S6=: /:~"1 (13 | i. +/~ [: i. 15 - ])6
n56Straight=: 13 : '>./0,5 6#~(S5;S6) e.~ &></:~~.1{suitRank y'"1
nStraight=: [: {. 5 6 #~ 5 6 = maxConsecIncs
n56Straight=: (([: nStraight 13 | ]) * 0 = nStraight)"1
Tn56Straight_tests_=: 3 : 0
   assert. 5=n56Straight 13#.|:0 1 2 0 1,:i.5
   assert. 6=n56Straight 13#.|:0 1 2 0 1 2,:i.6
   assert. -.5=n56Straight 13#.|:0,:i.5   NB. straight flush
   assert. -.6=n56Straight 13#.|:0,:i.6   NB. straight flush

isnFlush=: 13 : '{.0,~5 6#~5 6 e. ([: >./ [: #/.~ 0 { suitRank) y'"1
isFH=: ([: +./ 2 3 E. [: /:~ [: #/.~ 13 | ])"1
is4ok=: (1 = 4 +/ .= [: #/.~ 13 | ])"1

NB. New 6-card hands...
isTripPair=: (3 = 2 +/ .= [: #/.~ 13 | ])"1
isPairoTrips=: (2 = 3 +/ .= [: #/.~ 13 | ])"1
NB. super-full-house: 6-card version= 4ok+pair
isSFH=: [: +./ 2 4 E. [: /:~ [: #/.~ 13 | ]
n56SF=: ([: {. 5 6 #~ 5 6 = nStraight)"1
egUse=: 0 : 0
NB. Example run:
   6!:2 'cts=. 3 : ''+/(isPair,is2Pair,is3ok,(5=n56Straight),(5=isnFlush),isFH,isTripPair,(6=n56Straight),is4ok,(6=isnFlush),(5=n56SF),isPairoTrips,isSFH,(6=n56SF))"1 ] 6?&>2035852$52''^:(i.10)]'''''
NB. Example display:
   ht=. <;._1 ',isPair,is2Pair,is3ok,(5=n56Straight),(5=isnFlush),isFH,isTripPair,(6=n56Straight),is4ok,(6=isnFlush),(5=n56SF),isPairoTrips,isSFH,(6=n56SF)'
   (9j7":&.>nn%20358520),.~(<"0 nn),.~ht [ nn=. +/cts

coclass 'tests'
coinsert 'npoker'
coclass 'base'
coinsert 'npoker'
smoutput egUse_npoker_

Here’s a test of this code for the well-known case of 5-card hands in 5-cards. It doesn’t look sufficiently close to what’s expected to be believable, so there’s work to be done on these new classifiers.

   (9j7":&.>nn%25989600),.~(<"0 nn),.~ht [ nn=. +/;cts
New Code (*10) # hands Portion Old Code # hands
isPair 9913587 0.3814444 pair 1098240
is2Pair 1108969 0.0426697 2-pair 123552
is3ok 528778 0.0203458 3-of-a-kind 54912
(5=n56Straight) 82596 0.0031780 straight 10200
(5=isnFlush) 46304 0.0017816 flush 5108
isFH 33686 0.0012961 full house 3744
isTripPair 0 0.0000000
(6=n56Straight) 0 0.0000000
is4ok 5558 0.0002139 4-of-a-kind 624
(6=isnFlush) 0 0.0000000
(5=n56SF) 427 0.0000164 straight flush 40
isPairoTrips 0 0.0000000
isSFH 0 0.0000000
(6=n56SF) 0 0.0000000

Advanced topics

Learning, teaching and promoting J


-- Devon McCormick <<DateTime(2015-01-04T15:46:34-0200)>>