Prof. Eric A. Suess

So how should you complete your homework for this class?

Homework 5:

 Read: Chapter 7
 Do 7.3.4 Exercises 1, 2, 3, 4
 Do 7.4.1 Exercises 1, 2
 Do 7.5.1.1 Exercises 2, 3, 4, 5, 6
library(tidyverse)

7.3.4

1.

All are skewed to the right. The distributions of x and y are very similar. The distributions of z looks to be less spread out. All look to be bimodal.

I think x and y are the length and width, and z is the depth.

diamonds
diamonds %>% select(x,y,z) %>%
  ggplot(aes(x = x )) +
  geom_histogram() +
  scale_x_continuous(limits=c(0, 10)) +
  scale_y_continuous(limits=c(0, 15000))

diamonds %>% select(x,y,z) %>%
  ggplot(aes(x = y )) +
  geom_histogram() +
  scale_x_continuous(limits=c(0, 10)) +
  scale_y_continuous(limits=c(0, 15000))

diamonds %>% select(x,y,z) %>%
  ggplot(aes(x = z )) +
  geom_histogram() +
  scale_x_continuous(limits=c(0, 10)) +
  scale_y_continuous(limits=c(0, 15000))

2.

There are not prices around $1500.

The mode of the distributions is around $750.

At the lowest levels there are spikes in the prices where the diamonds are actually priced.

diamonds %>% select(price) %>% 
  ggplot(aes(x = price )) +
  geom_histogram() 

diamonds %>% select( price ) %>% 
  filter(price < 2500) %>%
  ggplot(aes(x = price )) +
  geom_histogram() 

diamonds %>% select( price ) %>% 
  filter(price < 2500) %>%
  ggplot(aes(x = price )) +
  geom_histogram(binwidth = 10, center = 0 ) 

diamonds %>% select( price ) %>% 
  filter(price < 900, price > 800) %>%
  ggplot(aes(x = price )) +
  geom_histogram(binwidth = 01, center = 0 ) 

NA

3.

There are 23 diamonds that are .99 carats and there are 1558 diamonds that are 1 carat. Rounding up is worth more money.

diamonds %>% select(carat) %>% 
  count(carat == 0.99)
diamonds %>% select(carat) %>% 
  count(carat == 1)
diamonds %>%
   filter(carat >= 0.9, carat <= 1.1) %>%
   count(carat) 
diamonds %>%
   filter(carat >= 0.9, carat <= 1.1) %>%
   count(carat) %>%
   ggplot(aes(x= carat, y = n)) +
   geom_col()

4.

The cood_cartesian function zooms in on the original histogram.

The xlim and ylim functions limits the range of the data before counting. So the histogram is made for a subset of the data.

diamonds %>% select(price) %>% 
  ggplot(aes(x = price )) +
  geom_histogram() 

diamonds %>% select(price) %>% 
  ggplot(aes(x = price )) +
  geom_histogram() +
  coord_cartesian(xlim = c(0, 5000), ylim = c(0, 10000))

diamonds %>% select(price) %>% 
  ggplot(aes(x = price )) +
  geom_histogram(binwidth = 100) +
  coord_cartesian(xlim = c(0, 5000), ylim = c(0, 10000))

diamonds %>% select(price) %>% 
  ggplot(aes(x = price )) +
  geom_histogram(binwidth = 100) +
  xlim(0, 5000) +
  ylim(0, 10000)

7.4.1

1.

For histograms missing data is removed.

For bargraphs the NAs are considered another category.

2.

The option na.rm in the mean and sum functions remove the NAs before the values of the functions are computed. NAs are not numeric values so they cannot be included in a sum calculation.

7.5.1.1

1.

The cancelled flights tend to occur later in the day, but have a wider range of scheduled departure hour.

flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes(x = cancelled, y = sched_hour)) +
  geom_boxplot() + 
  coord_flip()

2.

The most important variable is carat.

diamonds %>% select (price, carat, depth, table, x, y , z) %>%
  cor()
           price      carat       depth      table           x           y          z
price  1.0000000 0.92159130 -0.01064740  0.1271339  0.88443516  0.86542090 0.86124944
carat  0.9215913 1.00000000  0.02822431  0.1816175  0.97509423  0.95172220 0.95338738
depth -0.0106474 0.02822431  1.00000000 -0.2957785 -0.02528925 -0.02934067 0.09492388
table  0.1271339 0.18161755 -0.29577852  1.0000000  0.19534428  0.18376015 0.15092869
x      0.8844352 0.97509423 -0.02528925  0.1953443  1.00000000  0.97470148 0.97077180
y      0.8654209 0.95172220 -0.02934067  0.1837601  0.97470148  1.00000000 0.95200572
z      0.8612494 0.95338738  0.09492388  0.1509287  0.97077180  0.95200572 1.00000000
diamonds %>% select (price, carat, depth, table, x, y , z) %>%
  ggplot(aes(x = carat, y = price)) +
  geom_point()

diamonds %>% ggplot(aes(x = carat, y = price)) +
  geom_boxplot(aes(group = cut_width(carat, 0.1)))

Examining the caregorical variables.

Weak positive relationship of price with color.

Weak neagative relationship of price with clarity and cut.

diamonds %>% ggplot( aes(x = color, y = price)) +
  geom_boxplot()

diamonds %>% ggplot(aes(x = clarity, y = price)) +
  geom_boxplot()

ggplot(diamonds, aes(x = cut, y = carat)) +
  geom_boxplot()

3.

Looks the same, but x and y need to be switched for the boxploth()

flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes(x = cancelled, y = sched_hour)) +
  geom_boxplot() + 
  coord_flip()

library(ggstance)
flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes(y = cancelled, x = sched_hour)) +
  geom_boxploth()

4.

The boxes in the lvplot correspond to percentiles, every 10%.

Outliers are in the direction of the thinner percentiles.

library(lvplot)
diamonds %>% select(price, cut) %>%
  ggplot(aes(x = cut, y = price)) +
  geom_lv() + 
  coord_flip()

flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes(x = cancelled, y = sched_hour)) +
  geom_lv() + 
  coord_flip()

5.

The facted histograms are printed in the reverse order of the violin plots. I would be good to have the vertical scales the same.

flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes(x = cancelled, y = sched_hour)) +
  geom_violin() + 
  coord_flip()

flights %>% mutate(
  cancelled = is.na(dep_time),
  sched_hour = sched_dep_time %/% 100,
  sched_min  = sched_dep_time %% 100
  ) %>%
  ggplot(aes( x = sched_hour )) +
  geom_histogram() +
  facet_wrap(~ cancelled, nrow = 2) 

6.

method description
default jitters the point horizontally
tukey jitters more
tukeyDense jitters but less than tukey
frowney jitters downward
smiley jitters upward
library(ggbeeswarm)
mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_beeswarm()

mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_quasirandom()

mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_quasirandom(method = "tukey")

mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_quasirandom(method = "tukeyDense")

mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_quasirandom(method = "frowney")

mpg %>% ggplot(aes(x = reorder(class, hwy, FUN = median),y = hwy) ) +
  geom_quasirandom(method = "smiley")

LS0tCnRpdGxlOiAnU3RhdC4gNDUwIFNlY3Rpb24gMSBvciAyOiBIb21ld29yayA1JwpvdXRwdXQ6CiAgd29yZF9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKKipQcm9mLiBFcmljIEEuIFN1ZXNzKioKClNvIGhvdyBzaG91bGQgeW91IGNvbXBsZXRlIHlvdXIgaG9tZXdvcmsgZm9yIHRoaXMgY2xhc3M/CgotIEZpcnN0IHRoaW5nIHRvIGRvIGlzIHR5cGUgYWxsIG9mIHlvdXIgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHByb2JsZW1zIHlvdSBkbyBpbiB0aGUgdGV4dCBwYXJ0IG9mIHlvdXIgUiBOb3RlYm9vay4KLSBTZWNvbmQgdGhpbmcgdG8gZG8gaXMgdHlwZSBhbGwgb2YgeW91ciBSIGNvZGUgaW50byBSIGNodW5rcyB0aGF0IGNhbiBiZSBydW4uCi0gSWYgeW91IGxvYWQgdGhlIHRpZHl2ZXJzZSBpbiBhbiBSIE5vdGVib29rIGNodW5rLCBiZSBzdXJlIHRvIGluY2x1ZGUgdGhlICJtZXNzYWdlID0gRkFMU0UiIGluIHRoZSB7cn0sIHNvIHtyIG1lc3NhZ2UgPSBGQUxTRX0uCi0gTGFzdCB0aGluZyBpcyB0byBzcGVsbCBjaGVjayB5b3VyIFIgTm90ZWJvb2suICBFZGl0ID4gQ2hlY2sgU3BlbGxpbmcuLi4gb3IgaGl0IHRoZSBGNyBrZXkuCgpIb21ld29yayA1OgoKICAgICBSZWFkOiBDaGFwdGVyIDcKICAgICBEbyA3LjMuNCBFeGVyY2lzZXMgMSwgMiwgMywgNAogICAgIERvIDcuNC4xIEV4ZXJjaXNlcyAxLCAyCiAgICAgRG8gNy41LjEuMSBFeGVyY2lzZXMgMiwgMywgNCwgNSwgNgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKCiMgNy4zLjQKCiMjIDEuCgpBbGwgYXJlIHNrZXdlZCB0byB0aGUgcmlnaHQuICBUaGUgZGlzdHJpYnV0aW9ucyBvZiB4IGFuZCB5IGFyZSB2ZXJ5IHNpbWlsYXIuICBUaGUgZGlzdHJpYnV0aW9ucyBvZiB6IGxvb2tzIHRvIGJlIGxlc3Mgc3ByZWFkIG91dC4gIEFsbCBsb29rIHRvIGJlIGJpbW9kYWwuCgpJIHRoaW5rIHggYW5kIHkgYXJlIHRoZSBsZW5ndGggYW5kIHdpZHRoLCBhbmQgeiBpcyB0aGUgZGVwdGguCgpgYGB7cn0KZGlhbW9uZHMKCmRpYW1vbmRzICU+JSBzZWxlY3QoeCx5LHopICU+JQogIGdncGxvdChhZXMoeCA9IHggKSkgKwogIGdlb21faGlzdG9ncmFtKCkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHM9YygwLCAxMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMTUwMDApKQoKZGlhbW9uZHMgJT4lIHNlbGVjdCh4LHkseikgJT4lCiAgZ2dwbG90KGFlcyh4ID0geSApKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1jKDAsIDEwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9YygwLCAxNTAwMCkpCgpkaWFtb25kcyAlPiUgc2VsZWN0KHgseSx6KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB6ICkpICsKICBnZW9tX2hpc3RvZ3JhbSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMTApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsIDE1MDAwKSkKYGBgCgoKCiMjIDIuCgpUaGVyZSBhcmUgbm90IHByaWNlcyBhcm91bmQgJDE1MDAuCgpUaGUgbW9kZSBvZiB0aGUgZGlzdHJpYnV0aW9ucyBpcyBhcm91bmQgJDc1MC4KCkF0IHRoZSBsb3dlc3QgbGV2ZWxzIHRoZXJlIGFyZSBzcGlrZXMgaW4gdGhlIHByaWNlcyB3aGVyZSB0aGUgZGlhbW9uZHMgYXJlIGFjdHVhbGx5IHByaWNlZC4KCmBgYHtyfQpkaWFtb25kcyAlPiUgc2VsZWN0KHByaWNlKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcHJpY2UgKSkgKwogIGdlb21faGlzdG9ncmFtKCkgCgpkaWFtb25kcyAlPiUgc2VsZWN0KCBwcmljZSApICU+JSAKICBmaWx0ZXIocHJpY2UgPCAyNTAwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwcmljZSApKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSAKCmRpYW1vbmRzICU+JSBzZWxlY3QoIHByaWNlICkgJT4lIAogIGZpbHRlcihwcmljZSA8IDI1MDApICU+JQogIGdncGxvdChhZXMoeCA9IHByaWNlICkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwLCBjZW50ZXIgPSAwICkgCgpkaWFtb25kcyAlPiUgc2VsZWN0KCBwcmljZSApICU+JSAKICBmaWx0ZXIocHJpY2UgPCA5MDAsIHByaWNlID4gODAwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwcmljZSApKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwMSwgY2VudGVyID0gMCApIAogIApgYGAKCgojIyAzLgoKVGhlcmUgYXJlIDIzIGRpYW1vbmRzIHRoYXQgYXJlIC45OSBjYXJhdHMgYW5kIHRoZXJlIGFyZSAxNTU4IGRpYW1vbmRzIHRoYXQgYXJlIDEgY2FyYXQuICBSb3VuZGluZyB1cCBpcyB3b3J0aCBtb3JlIG1vbmV5LgoKYGBge3J9CmRpYW1vbmRzICU+JSBzZWxlY3QoY2FyYXQpICU+JSAKICBjb3VudChjYXJhdCA9PSAwLjk5KQoKZGlhbW9uZHMgJT4lIHNlbGVjdChjYXJhdCkgJT4lIAogIGNvdW50KGNhcmF0ID09IDEpCgpkaWFtb25kcyAlPiUKICAgZmlsdGVyKGNhcmF0ID49IDAuOSwgY2FyYXQgPD0gMS4xKSAlPiUKICAgY291bnQoY2FyYXQpIAoKZGlhbW9uZHMgJT4lCiAgIGZpbHRlcihjYXJhdCA+PSAwLjksIGNhcmF0IDw9IDEuMSkgJT4lCiAgIGNvdW50KGNhcmF0KSAlPiUKICAgZ2dwbG90KGFlcyh4PSBjYXJhdCwgeSA9IG4pKSArCiAgIGdlb21fY29sKCkKCmBgYAoKCiMjIDQuCgpUaGUgKmNvb2RfY2FydGVzaWFuKiBmdW5jdGlvbiB6b29tcyBpbiBvbiB0aGUgb3JpZ2luYWwgaGlzdG9ncmFtLgoKVGhlICp4bGltKiBhbmQgKnlsaW0qIGZ1bmN0aW9ucyBsaW1pdHMgdGhlIHJhbmdlIG9mIHRoZSBkYXRhIGJlZm9yZSBjb3VudGluZy4gIFNvIHRoZSBoaXN0b2dyYW0gaXMgbWFkZSBmb3IgYSBzdWJzZXQgb2YgdGhlIGRhdGEuCgpgYGB7cn0KZGlhbW9uZHMgJT4lIHNlbGVjdChwcmljZSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHByaWNlICkpICsKICBnZW9tX2hpc3RvZ3JhbSgpIAoKZGlhbW9uZHMgJT4lIHNlbGVjdChwcmljZSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHByaWNlICkpICsKICBnZW9tX2hpc3RvZ3JhbSgpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgNTAwMCksIHlsaW0gPSBjKDAsIDEwMDAwKSkKCmRpYW1vbmRzICU+JSBzZWxlY3QocHJpY2UpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBwcmljZSApKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxMDApICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgNTAwMCksIHlsaW0gPSBjKDAsIDEwMDAwKSkKCmRpYW1vbmRzICU+JSBzZWxlY3QocHJpY2UpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBwcmljZSApKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxMDApICsKICB4bGltKDAsIDUwMDApICsKICB5bGltKDAsIDEwMDAwKQpgYGAKCiMgNy40LjEKCiMjIDEuCgpGb3IgaGlzdG9ncmFtcyBtaXNzaW5nIGRhdGEgaXMgcmVtb3ZlZC4KCkZvciBiYXJncmFwaHMgdGhlIE5BcyBhcmUgY29uc2lkZXJlZCBhbm90aGVyIGNhdGVnb3J5LgoKCiMjIDIuCgpUaGUgb3B0aW9uICpuYS5ybSogaW4gdGhlICptZWFuKiBhbmQgKnN1bSogZnVuY3Rpb25zIHJlbW92ZSB0aGUgTkFzIGJlZm9yZSB0aGUgdmFsdWVzIG9mIHRoZSBmdW5jdGlvbnMgYXJlIGNvbXB1dGVkLiAgTkFzIGFyZSBub3QgbnVtZXJpYyB2YWx1ZXMgc28gdGhleSBjYW5ub3QgYmUgaW5jbHVkZWQgaW4gYSBzdW0gY2FsY3VsYXRpb24uCgojIDcuNS4xLjEKCiMjIDEuCgpUaGUgY2FuY2VsbGVkIGZsaWdodHMgdGVuZCB0byBvY2N1ciBsYXRlciBpbiB0aGUgZGF5LCBidXQgaGF2ZSBhIHdpZGVyIHJhbmdlIG9mIHNjaGVkdWxlZCBkZXBhcnR1cmUgaG91ci4KCmBgYHtyfQpsaWJyYXJ5KG55Y2ZsaWdodHMxMykKCmZsaWdodHMgJT4lIG11dGF0ZSgKICBjYW5jZWxsZWQgPSBpcy5uYShkZXBfdGltZSksCiAgc2NoZWRfaG91ciA9IHNjaGVkX2RlcF90aW1lICUvJSAxMDAsCiAgc2NoZWRfbWluICA9IHNjaGVkX2RlcF90aW1lICUlIDEwMAogICkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2FuY2VsbGVkLCB5ID0gc2NoZWRfaG91cikpICsKICBnZW9tX2JveHBsb3QoKSArIAogIGNvb3JkX2ZsaXAoKQpgYGAKCgojIyAyLgoKVGhlIG1vc3QgaW1wb3J0YW50IHZhcmlhYmxlIGlzIGNhcmF0LgoKYGBge3J9CmRpYW1vbmRzICU+JSBzZWxlY3QgKHByaWNlLCBjYXJhdCwgZGVwdGgsIHRhYmxlLCB4LCB5ICwgeikgJT4lCiAgY29yKCkKCmRpYW1vbmRzICU+JSBzZWxlY3QgKHByaWNlLCBjYXJhdCwgZGVwdGgsIHRhYmxlLCB4LCB5ICwgeikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2FyYXQsIHkgPSBwcmljZSkpICsKICBnZW9tX3BvaW50KCkKCmRpYW1vbmRzICU+JSBnZ3Bsb3QoYWVzKHggPSBjYXJhdCwgeSA9IHByaWNlKSkgKwogIGdlb21fYm94cGxvdChhZXMoZ3JvdXAgPSBjdXRfd2lkdGgoY2FyYXQsIDAuMSkpKQpgYGAKCkV4YW1pbmluZyB0aGUgY2FyZWdvcmljYWwgdmFyaWFibGVzLgoKV2VhayBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgb2YgcHJpY2Ugd2l0aCBjb2xvci4KCldlYWsgbmVhZ2F0aXZlIHJlbGF0aW9uc2hpcCBvZiBwcmljZSB3aXRoIGNsYXJpdHkgYW5kIGN1dC4KCmBgYHtyfQpkaWFtb25kcyAlPiUgZ2dwbG90KCBhZXMoeCA9IGNvbG9yLCB5ID0gcHJpY2UpKSArCiAgZ2VvbV9ib3hwbG90KCkKCmRpYW1vbmRzICU+JSBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LCB5ID0gcHJpY2UpKSArCiAgZ2VvbV9ib3hwbG90KCkKCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjdXQsIHkgPSBjYXJhdCkpICsKICBnZW9tX2JveHBsb3QoKQoKYGBgCgoKIyMgMy4KCkxvb2tzIHRoZSBzYW1lLCBidXQgeCBhbmQgeSBuZWVkIHRvIGJlIHN3aXRjaGVkIGZvciB0aGUgYm94cGxvdGgoKQoKYGBge3J9CmZsaWdodHMgJT4lIG11dGF0ZSgKICBjYW5jZWxsZWQgPSBpcy5uYShkZXBfdGltZSksCiAgc2NoZWRfaG91ciA9IHNjaGVkX2RlcF90aW1lICUvJSAxMDAsCiAgc2NoZWRfbWluICA9IHNjaGVkX2RlcF90aW1lICUlIDEwMAogICkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2FuY2VsbGVkLCB5ID0gc2NoZWRfaG91cikpICsKICBnZW9tX2JveHBsb3QoKSArIAogIGNvb3JkX2ZsaXAoKQoKbGlicmFyeShnZ3N0YW5jZSkKCmZsaWdodHMgJT4lIG11dGF0ZSgKICBjYW5jZWxsZWQgPSBpcy5uYShkZXBfdGltZSksCiAgc2NoZWRfaG91ciA9IHNjaGVkX2RlcF90aW1lICUvJSAxMDAsCiAgc2NoZWRfbWluICA9IHNjaGVkX2RlcF90aW1lICUlIDEwMAogICkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gY2FuY2VsbGVkLCB4ID0gc2NoZWRfaG91cikpICsKICBnZW9tX2JveHBsb3RoKCkKCmBgYAoKCgoKIyMgNC4KClRoZSBib3hlcyBpbiB0aGUgbHZwbG90IGNvcnJlc3BvbmQgdG8gcGVyY2VudGlsZXMsIGV2ZXJ5IDEwJS4KCk91dGxpZXJzIGFyZSBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSB0aGlubmVyIHBlcmNlbnRpbGVzLgoKYGBge3J9CmxpYnJhcnkobHZwbG90KQoKZGlhbW9uZHMgJT4lIHNlbGVjdChwcmljZSwgY3V0KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBwcmljZSkpICsKICBnZW9tX2x2KCkgKyAKICBjb29yZF9mbGlwKCkKCmZsaWdodHMgJT4lIG11dGF0ZSgKICBjYW5jZWxsZWQgPSBpcy5uYShkZXBfdGltZSksCiAgc2NoZWRfaG91ciA9IHNjaGVkX2RlcF90aW1lICUvJSAxMDAsCiAgc2NoZWRfbWluICA9IHNjaGVkX2RlcF90aW1lICUlIDEwMAogICkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2FuY2VsbGVkLCB5ID0gc2NoZWRfaG91cikpICsKICBnZW9tX2x2KCkgKyAKICBjb29yZF9mbGlwKCkKYGBgCgojIyA1LgoKVGhlIGZhY3RlZCBoaXN0b2dyYW1zIGFyZSBwcmludGVkIGluIHRoZSByZXZlcnNlIG9yZGVyIG9mIHRoZSB2aW9saW4gcGxvdHMuICBJIHdvdWxkIGJlIGdvb2QgdG8gaGF2ZSB0aGUgdmVydGljYWwgc2NhbGVzIHRoZSBzYW1lLgoKCmBgYHtyfQpmbGlnaHRzICU+JSBtdXRhdGUoCiAgY2FuY2VsbGVkID0gaXMubmEoZGVwX3RpbWUpLAogIHNjaGVkX2hvdXIgPSBzY2hlZF9kZXBfdGltZSAlLyUgMTAwLAogIHNjaGVkX21pbiAgPSBzY2hlZF9kZXBfdGltZSAlJSAxMDAKICApICU+JQogIGdncGxvdChhZXMoeCA9IGNhbmNlbGxlZCwgeSA9IHNjaGVkX2hvdXIpKSArCiAgZ2VvbV92aW9saW4oKSArIAogIGNvb3JkX2ZsaXAoKQoKZmxpZ2h0cyAlPiUgbXV0YXRlKAogIGNhbmNlbGxlZCA9IGlzLm5hKGRlcF90aW1lKSwKICBzY2hlZF9ob3VyID0gc2NoZWRfZGVwX3RpbWUgJS8lIDEwMCwKICBzY2hlZF9taW4gID0gc2NoZWRfZGVwX3RpbWUgJSUgMTAwCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKCB4ID0gc2NoZWRfaG91ciApKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgZmFjZXRfd3JhcCh+IGNhbmNlbGxlZCwgbnJvdyA9IDIpIAoKYGBgCgojIyA2LgoKbWV0aG9kIHwgZGVzY3JpcHRpb24KLS0tLS0tLXwtLS0tLS0tLS0tLS0KZGVmYXVsdCB8IGppdHRlcnMgdGhlIHBvaW50IGhvcml6b250YWxseQp0dWtleSAgIHwgaml0dGVycyBtb3JlCnR1a2V5RGVuc2UgfCBqaXR0ZXJzIGJ1dCBsZXNzIHRoYW4gdHVrZXkKZnJvd25leSB8IGppdHRlcnMgZG93bndhcmQKc21pbGV5ICB8IGppdHRlcnMgdXB3YXJkCgoKYGBge3J9CmxpYnJhcnkoZ2diZWVzd2FybSkKCm1wZyAlPiUgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihjbGFzcywgaHd5LCBGVU4gPSBtZWRpYW4pLHkgPSBod3kpICkgKwogIGdlb21fYmVlc3dhcm0oKQoKbXBnICU+JSBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyKGNsYXNzLCBod3ksIEZVTiA9IG1lZGlhbikseSA9IGh3eSkgKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSgpCgptcGcgJT4lIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoY2xhc3MsIGh3eSwgRlVOID0gbWVkaWFuKSx5ID0gaHd5KSApICsKICBnZW9tX3F1YXNpcmFuZG9tKG1ldGhvZCA9ICJ0dWtleSIpCgptcGcgJT4lIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoY2xhc3MsIGh3eSwgRlVOID0gbWVkaWFuKSx5ID0gaHd5KSApICsKICBnZW9tX3F1YXNpcmFuZG9tKG1ldGhvZCA9ICJ0dWtleURlbnNlIikKCgptcGcgJT4lIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoY2xhc3MsIGh3eSwgRlVOID0gbWVkaWFuKSx5ID0gaHd5KSApICsKICBnZW9tX3F1YXNpcmFuZG9tKG1ldGhvZCA9ICJmcm93bmV5IikKCm1wZyAlPiUgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihjbGFzcywgaHd5LCBGVU4gPSBtZWRpYW4pLHkgPSBod3kpICkgKwogIGdlb21fcXVhc2lyYW5kb20obWV0aG9kID0gInNtaWxleSIpCgpgYGAKCgoK