This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

install.packages("tidymodels")
Installing package into ‘C:/Users/ridhi/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/tidymodels_1.1.1.zip'
Content type 'application/zip' length 90358 bytes (88 KB)
downloaded 88 KB
package ‘tidymodels’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\ridhi\AppData\Local\Temp\Rtmp8eCiVY\downloaded_packages
install.packages("kknn")
Installing package into ‘C:/Users/ridhi/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/kknn_1.3.1.zip'
Content type 'application/zip' length 324283 bytes (316 KB)
downloaded 316 KB
package ‘kknn’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\ridhi\AppData\Local\Temp\Rtmp8eCiVY\downloaded_packages
 
install.packages("rsample")
Installing package into ‘C:/Users/ridhi/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/rsample_1.2.0.zip'
Content type 'application/zip' length 533070 bytes (520 KB)
downloaded 520 KB
package ‘rsample’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\ridhi\AppData\Local\Temp\Rtmp8eCiVY\downloaded_packages
library(kknn)
library(tidymodels)
── Attaching packages ─────────────
✔ broom        1.0.5     ✔ recipes      1.0.8
✔ dials        1.2.0     ✔ rsample      1.2.0
✔ dplyr        1.1.3     ✔ tibble       3.2.1
✔ ggplot2      3.4.3     ✔ tidyr        1.3.0
✔ infer        1.0.5     ✔ tune         1.1.2
✔ modeldata    1.2.0     ✔ workflows    1.1.3
✔ parsnip      1.1.1     ✔ workflowsets 1.0.1
✔ purrr        1.0.2     ✔ yardstick    1.2.0
── Conflicts ──────────────────────
✖ purrr::discard() masks scales::discard()
✖ dplyr::filter()  masks stats::filter()
✖ dplyr::lag()     masks stats::lag()
✖ recipes::step()  masks stats::step()
• Use tidymodels_prefer() to resolve common conflicts.
library(rsample)

Modeling tasks:

1. Is this a supervised or unsupervised learning problem? Why?

This is a supervised learning problem because we have a labeled target variable (cmedv) that we want to predict based on input features.

2. There are 16 variables in this data set. Which variable is the response variable and which variables

are the predictor variables (aka features)?

- Response Variable (Target): cmedv

- Predictor Variables (Features): lon, lat, crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, lstat

3. Given the type of variable cmedv is, is this a regression or classification problem?

This is a regression problem because cmedv is a continuous numerical variable representing median house prices.

# 4. Fill in the blanks to import the Boston housing data set (boston.csv). Are there any missing values?
# What is the minimum and maximum values of cmedv? What is the average cmedv value?

boston <- readr::read_csv("boston.csv")
Rows: 506 Columns: 16── Column specification ───────────
Delimiter: ","
dbl (16): lon, lat, cmedv, crim...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
str(boston)
spc_tbl_ [506 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ lon    : num [1:506] -71 -71 -70.9 -70.9 -70.9 ...
 $ lat    : num [1:506] 42.3 42.3 42.3 42.3 42.3 ...
 $ cmedv  : num [1:506] 24 21.6 34.7 33.4 36.2 28.7 22.9 22.1 16.5 18.9 ...
 $ crim   : num [1:506] 0.00632 0.02731 0.02729 0.03237 0.06905 ...
 $ zn     : num [1:506] 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
 $ indus  : num [1:506] 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
 $ chas   : num [1:506] 0 0 0 0 0 0 0 0 0 0 ...
 $ nox    : num [1:506] 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
 $ rm     : num [1:506] 6.58 6.42 7.18 7 7.15 ...
 $ age    : num [1:506] 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
 $ dis    : num [1:506] 4.09 4.97 4.97 6.06 6.06 ...
 $ rad    : num [1:506] 1 2 2 3 3 3 5 5 5 5 ...
 $ tax    : num [1:506] 296 242 242 222 222 222 311 311 311 311 ...
 $ ptratio: num [1:506] 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
 $ b      : num [1:506] 397 397 393 395 397 ...
 $ lstat  : num [1:506] 4.98 9.14 4.03 2.94 5.33 ...
 - attr(*, "spec")=
  .. cols(
  ..   lon = col_double(),
  ..   lat = col_double(),
  ..   cmedv = col_double(),
  ..   crim = col_double(),
  ..   zn = col_double(),
  ..   indus = col_double(),
  ..   chas = col_double(),
  ..   nox = col_double(),
  ..   rm = col_double(),
  ..   age = col_double(),
  ..   dis = col_double(),
  ..   rad = col_double(),
  ..   tax = col_double(),
  ..   ptratio = col_double(),
  ..   b = col_double(),
  ..   lstat = col_double()
  .. )
 - attr(*, "problems")=<externalptr> 
# Check for missing values in the dataset
any_missing <- anyNA(boston) || any(boston == "")

# Print the result
print(paste("Any missing values in the dataset? ", any_missing))
[1] "Any missing values in the dataset?  FALSE"
# Minimum and maximum values of cmedv
min(boston$cmedv)
[1] 5
max(boston$cmedv)
[1] 50
# Average cmedv value
mean(boston$cmedv)
[1] 22.52885
# Calculate the median value for cmedv
median_cmedv <- median(boston$cmedv)

# Print the result
print(paste("Median value for cmedv: ", median_cmedv))
[1] "Median value for cmedv:  21.2"
# 5. Fill in the blanks to split the data into a training set and test set using a 70-30% split.
# Be sure to include the set.seed(123) so that your train and test sets are the same size as mine.

# Set seed for reproducibility
set.seed(123)

# Split the data into training and test sets using a 70-30% split

split <- initial_split(boston, prop = 0.7, strata = cmedv)
train <- training(split)
test <- testing(split)
# 6. How many observations are in the training set and test set?

# Number of observations in the training set
nrow(train)
[1] 352
# Number of observations in the test set
nrow(test)
[1] 154
# 7. Compare the distribution of cmedv between the training set and test set.
# Do they appear to have the same distribution or do they differ significantly?

# Ensure cmedv is numeric
train$cmedv <- as.numeric(train$cmedv)
test$cmedv <- as.numeric(test$cmedv)

# Check the class of cmedv in both training and test sets
class(train$cmedv)
[1] "numeric"
class(test$cmedv)
[1] "numeric"
library(ggplot2)

ggplot() +
  geom_histogram(data = train, aes(x = cmedv), fill = "blue", alpha = 0.5, bins = 30) +
  geom_histogram(data = test, aes(x = cmedv), fill = "green", alpha = 0.5, bins = 30) +
  labs(title = "Distribution of cmedv in Training and Test Sets",
       x = "cmedv",
       y = "Frequency") +
  scale_fill_manual(values = c("blue", "green"), name = "Dataset", labels = c("Training", "Test"))

# 8. Fill in the blanks to fit a linear regression model using the rm feature variable to predict cmedv
# and compute the RMSE on the test data. What is the test set RMSE?

# fit model
lm1 <- linear_reg() %>%
  fit(cmedv ~ rm, data = train)

# compute the RMSE on the test data
lm1 %>%
  predict(new_data = test) %>%
  bind_cols(test %>% select(cmedv)) %>%
  rmse(truth = cmedv, estimate = .pred)
NA
# 9. Fill in the blanks to fit a linear regression model using all available features to predict cmedv
# and compute the RMSE on the test data. What is the test set RMSE? Is this better than the previous model’s performance?

# fit model
lm2 <- linear_reg() %>%
  fit(cmedv ~ ., data = train)

# compute the RMSE on the test data
lm2 %>%
  predict(new_data = test) %>%
  bind_cols(test %>% select(cmedv)) %>%
  rmse(truth = cmedv, estimate = .pred)
NA
NA
# Assuming you have your training data in 'train' and test data in 'test' data frames

# Fit a K-nearest neighbor model using all available features to predict cmedv

install.packages("caret")
Installing package into ‘C:/Users/ridhi/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
also installing the dependencies ‘proxy’, ‘e1071’, ‘ModelMetrics’, ‘plyr’, ‘pROC’, ‘reshape2’

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/proxy_0.4-27.zip'
Content type 'application/zip' length 179934 bytes (175 KB)
downloaded 175 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/e1071_1.7-13.zip'
Content type 'application/zip' length 653601 bytes (638 KB)
downloaded 638 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/ModelMetrics_1.2.2.2.zip'
Content type 'application/zip' length 481603 bytes (470 KB)
downloaded 470 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/plyr_1.8.9.zip'
Content type 'application/zip' length 1163430 bytes (1.1 MB)
downloaded 1.1 MB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/pROC_1.18.4.zip'
Content type 'application/zip' length 1166047 bytes (1.1 MB)
downloaded 1.1 MB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/reshape2_1.4.4.zip'
Content type 'application/zip' length 454099 bytes (443 KB)
downloaded 443 KB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/caret_6.0-94.zip'
Content type 'application/zip' length 3577354 bytes (3.4 MB)
downloaded 3.4 MB
package ‘proxy’ successfully unpacked and MD5 sums checked
package ‘e1071’ successfully unpacked and MD5 sums checked
package ‘ModelMetrics’ successfully unpacked and MD5 sums checked
package ‘plyr’ successfully unpacked and MD5 sums checked
package ‘pROC’ successfully unpacked and MD5 sums checked
package ‘reshape2’ successfully unpacked and MD5 sums checked
package ‘caret’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\ridhi\AppData\Local\Temp\Rtmp8eCiVY\downloaded_packages
library(caret)
Loading required package: lattice

Attaching package: ‘caret’

The following objects are masked from ‘package:yardstick’:

    precision, recall,
    sensitivity, specificity

The following object is masked from ‘package:purrr’:

    lift

The following object is masked from ‘package:kknn’:

    contr.dummy
# Specify the formula for prediction, assuming 'cmedv' is the target variable
formula <- cmedv ~ .

# Fit the K-nearest neighbor model
knn_model <- train(formula, data = train, method = "kknn")

# Make predictions on the test data
predictions <- predict(knn_model, newdata = test)

# Compute RMSE on the test data
rmse_value <- sqrt(mean((predictions - test$cmedv)^2))

# Print the RMSE value
print(rmse_value)
[1] 3.251742
LS0tDQp0aXRsZTogIkNoaGFicmFfUmlkaGlfTW9kdWxlOF9MYWIiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5bW9kZWxzIikNCg0KaW5zdGFsbC5wYWNrYWdlcygia2tubiIpDQogDQppbnN0YWxsLnBhY2thZ2VzKCJyc2FtcGxlIikNCg0KbGlicmFyeShra25uKQ0KbGlicmFyeSh0aWR5bW9kZWxzKQ0KbGlicmFyeShyc2FtcGxlKQ0KYGBgDQoNCg0KDQojIE1vZGVsaW5nIHRhc2tzOg0KDQojIDEuIElzIHRoaXMgYSBzdXBlcnZpc2VkIG9yIHVuc3VwZXJ2aXNlZCBsZWFybmluZyBwcm9ibGVtPyBXaHk/DQojIFRoaXMgaXMgYSBzdXBlcnZpc2VkIGxlYXJuaW5nIHByb2JsZW0gYmVjYXVzZSB3ZSBoYXZlIGEgbGFiZWxlZCB0YXJnZXQgdmFyaWFibGUgKGNtZWR2KSB0aGF0IHdlIHdhbnQgdG8gcHJlZGljdCBiYXNlZCBvbiBpbnB1dCBmZWF0dXJlcy4NCg0KIyAyLiBUaGVyZSBhcmUgMTYgdmFyaWFibGVzIGluIHRoaXMgZGF0YSBzZXQuIFdoaWNoIHZhcmlhYmxlIGlzIHRoZSByZXNwb25zZSB2YXJpYWJsZSBhbmQgd2hpY2ggdmFyaWFibGVzDQojIGFyZSB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyAoYWthIGZlYXR1cmVzKT8NCiMgLSBSZXNwb25zZSBWYXJpYWJsZSAoVGFyZ2V0KTogY21lZHYNCiMgLSBQcmVkaWN0b3IgVmFyaWFibGVzIChGZWF0dXJlcyk6IGxvbiwgbGF0LCBjcmltLCB6biwgaW5kdXMsIGNoYXMsIG5veCwgcm0sIGFnZSwgZGlzLCByYWQsIHRheCwgcHRyYXRpbywgbHN0YXQNCg0KIyAzLiBHaXZlbiB0aGUgdHlwZSBvZiB2YXJpYWJsZSBjbWVkdiBpcywgaXMgdGhpcyBhIHJlZ3Jlc3Npb24gb3IgY2xhc3NpZmljYXRpb24gcHJvYmxlbT8NCiMgVGhpcyBpcyBhIHJlZ3Jlc3Npb24gcHJvYmxlbSBiZWNhdXNlIGNtZWR2IGlzIGEgY29udGludW91cyBudW1lcmljYWwgdmFyaWFibGUgcmVwcmVzZW50aW5nIG1lZGlhbiBob3VzZSBwcmljZXMuDQpgYGB7cn0NCiMgNC4gRmlsbCBpbiB0aGUgYmxhbmtzIHRvIGltcG9ydCB0aGUgQm9zdG9uIGhvdXNpbmcgZGF0YSBzZXQgKGJvc3Rvbi5jc3YpLiBBcmUgdGhlcmUgYW55IG1pc3NpbmcgdmFsdWVzPw0KIyBXaGF0IGlzIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcyBvZiBjbWVkdj8gV2hhdCBpcyB0aGUgYXZlcmFnZSBjbWVkdiB2YWx1ZT8NCg0KYm9zdG9uIDwtIHJlYWRyOjpyZWFkX2NzdigiYm9zdG9uLmNzdiIpDQoNCnN0cihib3N0b24pDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBDaGVjayBmb3IgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGFzZXQNCmFueV9taXNzaW5nIDwtIGFueU5BKGJvc3RvbikgfHwgYW55KGJvc3RvbiA9PSAiIikNCg0KIyBQcmludCB0aGUgcmVzdWx0DQpwcmludChwYXN0ZSgiQW55IG1pc3NpbmcgdmFsdWVzIGluIHRoZSBkYXRhc2V0PyAiLCBhbnlfbWlzc2luZykpDQoNCiMgTWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMgb2YgY21lZHYNCm1pbihib3N0b24kY21lZHYpDQoNCm1heChib3N0b24kY21lZHYpDQoNCiMgQXZlcmFnZSBjbWVkdiB2YWx1ZQ0KbWVhbihib3N0b24kY21lZHYpDQoNCiMgQ2FsY3VsYXRlIHRoZSBtZWRpYW4gdmFsdWUgZm9yIGNtZWR2DQptZWRpYW5fY21lZHYgPC0gbWVkaWFuKGJvc3RvbiRjbWVkdikNCg0KIyBQcmludCB0aGUgcmVzdWx0DQpwcmludChwYXN0ZSgiTWVkaWFuIHZhbHVlIGZvciBjbWVkdjogIiwgbWVkaWFuX2NtZWR2KSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIDUuIEZpbGwgaW4gdGhlIGJsYW5rcyB0byBzcGxpdCB0aGUgZGF0YSBpbnRvIGEgdHJhaW5pbmcgc2V0IGFuZCB0ZXN0IHNldCB1c2luZyBhIDcwLTMwJSBzcGxpdC4NCiMgQmUgc3VyZSB0byBpbmNsdWRlIHRoZSBzZXQuc2VlZCgxMjMpIHNvIHRoYXQgeW91ciB0cmFpbiBhbmQgdGVzdCBzZXRzIGFyZSB0aGUgc2FtZSBzaXplIGFzIG1pbmUuDQoNCiMgU2V0IHNlZWQgZm9yIHJlcHJvZHVjaWJpbGl0eQ0Kc2V0LnNlZWQoMTIzKQ0KDQojIFNwbGl0IHRoZSBkYXRhIGludG8gdHJhaW5pbmcgYW5kIHRlc3Qgc2V0cyB1c2luZyBhIDcwLTMwJSBzcGxpdA0KDQpzcGxpdCA8LSBpbml0aWFsX3NwbGl0KGJvc3RvbiwgcHJvcCA9IDAuNywgc3RyYXRhID0gY21lZHYpDQp0cmFpbiA8LSB0cmFpbmluZyhzcGxpdCkNCnRlc3QgPC0gdGVzdGluZyhzcGxpdCkNCg0KYGBgDQoNCmBgYHtyfQ0KIyA2LiBIb3cgbWFueSBvYnNlcnZhdGlvbnMgYXJlIGluIHRoZSB0cmFpbmluZyBzZXQgYW5kIHRlc3Qgc2V0Pw0KDQojIE51bWJlciBvZiBvYnNlcnZhdGlvbnMgaW4gdGhlIHRyYWluaW5nIHNldA0KbnJvdyh0cmFpbikNCg0KIyBOdW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGluIHRoZSB0ZXN0IHNldA0KbnJvdyh0ZXN0KQ0KDQpgYGANCg0KYGBge3J9DQojIDcuIENvbXBhcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjbWVkdiBiZXR3ZWVuIHRoZSB0cmFpbmluZyBzZXQgYW5kIHRlc3Qgc2V0Lg0KIyBEbyB0aGV5IGFwcGVhciB0byBoYXZlIHRoZSBzYW1lIGRpc3RyaWJ1dGlvbiBvciBkbyB0aGV5IGRpZmZlciBzaWduaWZpY2FudGx5Pw0KDQojIEVuc3VyZSBjbWVkdiBpcyBudW1lcmljDQp0cmFpbiRjbWVkdiA8LSBhcy5udW1lcmljKHRyYWluJGNtZWR2KQ0KdGVzdCRjbWVkdiA8LSBhcy5udW1lcmljKHRlc3QkY21lZHYpDQoNCiMgQ2hlY2sgdGhlIGNsYXNzIG9mIGNtZWR2IGluIGJvdGggdHJhaW5pbmcgYW5kIHRlc3Qgc2V0cw0KY2xhc3ModHJhaW4kY21lZHYpDQpjbGFzcyh0ZXN0JGNtZWR2KQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdCgpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZGF0YSA9IHRyYWluLCBhZXMoeCA9IGNtZWR2KSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjUsIGJpbnMgPSAzMCkgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gdGVzdCwgYWVzKHggPSBjbWVkdiksIGZpbGwgPSAiZ3JlZW4iLCBhbHBoYSA9IDAuNSwgYmlucyA9IDMwKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIGNtZWR2IGluIFRyYWluaW5nIGFuZCBUZXN0IFNldHMiLA0KICAgICAgIHggPSAiY21lZHYiLA0KICAgICAgIHkgPSAiRnJlcXVlbmN5IikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJibHVlIiwgImdyZWVuIiksIG5hbWUgPSAiRGF0YXNldCIsIGxhYmVscyA9IGMoIlRyYWluaW5nIiwgIlRlc3QiKSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIDguIEZpbGwgaW4gdGhlIGJsYW5rcyB0byBmaXQgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCB1c2luZyB0aGUgcm0gZmVhdHVyZSB2YXJpYWJsZSB0byBwcmVkaWN0IGNtZWR2DQojIGFuZCBjb21wdXRlIHRoZSBSTVNFIG9uIHRoZSB0ZXN0IGRhdGEuIFdoYXQgaXMgdGhlIHRlc3Qgc2V0IFJNU0U/DQoNCiMgZml0IG1vZGVsDQpsbTEgPC0gbGluZWFyX3JlZygpICU+JQ0KICBmaXQoY21lZHYgfiBybSwgZGF0YSA9IHRyYWluKQ0KDQojIGNvbXB1dGUgdGhlIFJNU0Ugb24gdGhlIHRlc3QgZGF0YQ0KbG0xICU+JQ0KICBwcmVkaWN0KG5ld19kYXRhID0gdGVzdCkgJT4lDQogIGJpbmRfY29scyh0ZXN0ICU+JSBzZWxlY3QoY21lZHYpKSAlPiUNCiAgcm1zZSh0cnV0aCA9IGNtZWR2LCBlc3RpbWF0ZSA9IC5wcmVkKQ0KDQpgYGANCg0KYGBge3J9DQojIDkuIEZpbGwgaW4gdGhlIGJsYW5rcyB0byBmaXQgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCB1c2luZyBhbGwgYXZhaWxhYmxlIGZlYXR1cmVzIHRvIHByZWRpY3QgY21lZHYNCiMgYW5kIGNvbXB1dGUgdGhlIFJNU0Ugb24gdGhlIHRlc3QgZGF0YS4gV2hhdCBpcyB0aGUgdGVzdCBzZXQgUk1TRT8gSXMgdGhpcyBiZXR0ZXIgdGhhbiB0aGUgcHJldmlvdXMgbW9kZWzigJlzIHBlcmZvcm1hbmNlPw0KDQojIGZpdCBtb2RlbA0KbG0yIDwtIGxpbmVhcl9yZWcoKSAlPiUNCiAgZml0KGNtZWR2IH4gLiwgZGF0YSA9IHRyYWluKQ0KDQojIGNvbXB1dGUgdGhlIFJNU0Ugb24gdGhlIHRlc3QgZGF0YQ0KbG0yICU+JQ0KICBwcmVkaWN0KG5ld19kYXRhID0gdGVzdCkgJT4lDQogIGJpbmRfY29scyh0ZXN0ICU+JSBzZWxlY3QoY21lZHYpKSAlPiUNCiAgcm1zZSh0cnV0aCA9IGNtZWR2LCBlc3RpbWF0ZSA9IC5wcmVkKQ0KDQoNCmBgYA0KYGBge3J9DQoNCiMgRml0IGEgSy1uZWFyZXN0IG5laWdoYm9yIG1vZGVsIHVzaW5nIGFsbCBhdmFpbGFibGUgZmVhdHVyZXMgdG8gcHJlZGljdCBjbWVkdg0KDQppbnN0YWxsLnBhY2thZ2VzKCJjYXJldCIpDQoNCmxpYnJhcnkoY2FyZXQpDQoNCiMgU3BlY2lmeSB0aGUgZm9ybXVsYSBmb3IgcHJlZGljdGlvbiwgYXNzdW1pbmcgJ2NtZWR2JyBpcyB0aGUgdGFyZ2V0IHZhcmlhYmxlDQpmb3JtdWxhIDwtIGNtZWR2IH4gLg0KDQojIEZpdCB0aGUgSy1uZWFyZXN0IG5laWdoYm9yIG1vZGVsDQprbm5fbW9kZWwgPC0gdHJhaW4oZm9ybXVsYSwgZGF0YSA9IHRyYWluLCBtZXRob2QgPSAia2tubiIpDQoNCiMgTWFrZSBwcmVkaWN0aW9ucyBvbiB0aGUgdGVzdCBkYXRhDQpwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KGtubl9tb2RlbCwgbmV3ZGF0YSA9IHRlc3QpDQoNCiMgQ29tcHV0ZSBSTVNFIG9uIHRoZSB0ZXN0IGRhdGENCnJtc2VfdmFsdWUgPC0gc3FydChtZWFuKChwcmVkaWN0aW9ucyAtIHRlc3QkY21lZHYpXjIpKQ0KDQojIFByaW50IHRoZSBSTVNFIHZhbHVlDQpwcmludChybXNlX3ZhbHVlKQ0KDQoNCg0KYGBgDQoNCg0K