Variables

Variables hold information

Defining variables, or giving a name to values, such as the numbers you added together, allows you to store information.
You define variables using the <- operator, which means “store the value on the right in the variable on the left”, like so. You can then call it back by saying the variable name.

variable1 <- 3
variable2 <- 4
variable1
[1] 3

You can use variables in the place of the numbers they hold, and perform mathematical operations on them.

variable1 + variable2
[1] 7

As their name implies, variables can take on many values, and can change, so be careful with naming and assignment.

variable1 <- variable1 + variable2
variable1
[1] 7
variable1 <- variable1 + variable2
variable1
[1] 11

Variable types

These types of variables are numeric. However, R can also store text. These are in the form of characters. Surround characters in quotation marks to have them be character and not variable names.

char <- "a"
char
[1] "a"
# In your console, try typing 'char <- a' (no quotes) and seeing what happens

(char <- a results in an error, because a without quotes is treated as a variable name, and that variable has not been assigned yet.)

Characters variables can store strings, such as words and sentences (in fact, in R, string and character are basically interchangeable). In R, one string (everything between the quotation marks) is stored as a single unit.

char_sentence <- "My favorite food is ice cream"
char_sentence
[1] "My favorite food is ice cream"
char_variable1 <- "variable1"
char_variable1
[1] "variable1"
char_variable2 <- variable1
char_variable2
[1] 11

You can identify the type of variable (numeric, character) using is().

# Using is()
is(5)
[1] "numeric" "vector" 
# Try identifying the type of variable for char_variable1
is(char_variable1)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
# How about char_variable2?
is(char_variable2)
[1] "numeric" "vector" 
# What is going on?

Notice that the thing we assigned into char_variable1 was “variable_1” in quotes, which is just a character string, like any other, hence it’s listed as a “character” (don’t worry about the rest of this output for now). On the other hand, the thing we assigned into char_variable2 was variable_1 without quotes, which copies the contents of the variable_1 variable and stores that copy in char_variable2. We earlier assigned variable_1 to hold a number, hence char_variable2 is now also a numeric type.

You can also make numbers into strings: just put a quote around them!

num_string <- '4'
actual_num <- 4

# Try identifying the types of num_string and actual_num
is(num_string)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
is(actual_num)
[1] "numeric" "vector" 

You need to be very careful about the types of your variables. It may look like actual_num and num_string are holding the same thing, but because we’ve implicitly told R that they are of different types, they behave very differently. In the Console, try adding num_string to actual_num. What happens, and why? What is R’s cryptic message trying to tell you?

actual_num + num_string results in an error, described as ‘non-numeric argument to binary operator’; this means you’re trying to perform an operation that is done on numbers (addition) with something that’s not a number (num_string)

Functions

Adding with functions

We saw above that you can do basic arithmetic in R by just using mathematical symbols, e.g. +. But for more complicated things, programming languages use things called functions. A function is something that wraps a whole set of operations so that you can invoke those operations in a single command. You have already used another function earlier in this class, is(). Let’s take a look at another example: there’s a function, sum(), that can add numbers, just like + can. Let’s try it:

variable1
[1] 11
variable2
[1] 4
sum(variable1, variable2)
[1] 15

sum() can also take more than two inputs!

# Try using the sum function to compute the sum of 3, 4, and 6
sum(3,4,6)
[1] 13

Functions are their own type! You can try using is() to check this:

is(sum)
[1] "function"         "OptionalFunction" "PossibleMethod"  
is(is)
[1] "function"         "OptionalFunction" "PossibleMethod"  

Functions are always followed by () when you use them. When you use a function, often you are telling it to perform an operation on something else (e.g. a variable); in the examples above, we’re performing the sum() function on variable1 and variable2, and we’re performing the is() function on sum and on itself. These are called arguments, and are passed to the function inside the parentheses.

Looking at the Environment

Some functions don’t need to take any arguments. For example, you can find out what variables you have loaded in your environment at anytime using ls(). This will list all your variables, any custom functions you may have written, etc.

ls()
[1] "actual_num"     "char"           "char_sentence"  "char_variable1" "char_variable2" "num_string"    
[7] "variable1"      "variable2"     

Check out the Environment window on the top right! You can actually also see all your variables loaded in there, with a short summary of what’s in them. This is a super convenient feature of programming in Rstudio.

Combining strings

Another really useful function is the paste function; this function allows you to combine strings.

favorite_subject <- 'biology'
statement_about_subject <- 'is #'
subject_rank <- '1'

biology_quality <- paste(favorite_subject, statement_about_subject, subject_rank)

Notice that the code above didn’t print anything out. That’s because we directed the output of the paste function into a variable, biology_quality. To get R to print out the current program variable, you could just type it into your console, or you could use a function! Try googling to find an R function that prints out a variable.

# Find an R function to print out a variable, and use it to print whatever
# the biology_quality variable is storing
print(biology_quality)
[1] "biology is # 1"

You can learn about a function by reading its documentation. You can access the documentation with ?, for example, type ?paste into your console. You will see the help text pop up in the bottom right Help box in Rstudio.

? is one of the more important keys for you to know. Seriously, many issues are averted by first checking the documentation. Documentation usually has:

  • A description of the intention of the function
  • How to use it, ie where to put what arguments
  • A description of what those arguments should be
  • Details, and what value they return
  • And if you’re lucky, examples of usage

In practice, this information can sometimes be a bit dense and technical. I usually find it most useful to read the ‘description’ on top, and then scroll all the way down to the ‘examples’ section at the bottom of the help function.

Notice that when we used paste above, the function automatically put a space between our two strings. It’s often really useful to combine strings with a different character, for example, a dash. Try to read the documentation for paste() to figure out how to do this.

# Combine only the favorite_subject, statement_about_subject, and subject_rank
# variables, using a dash between them instead of a space
biology_quality_dash <-
  paste(favorite_subject, statement_about_subject, subject_rank, sep = '-')
print(biology_quality_dash)
[1] "biology-is #-1"

Things we hope you’ve learned today (and will hopefully remember next time)

LS0tCnRpdGxlOiAiSW50cm8gUiBDb3Vyc2UsIFdvcmtzaG9wIDI6IFZhcmlhYmxlcywgVHlwZXMsIGFuZCBGdW5jdGlvbnMiCnN1YnRpdGxlOiB8CiAgICB8ICAgLSB2YXJpYWJsZXMKICAgIHwgICAtIHR5cGVzCiAgICB8ICAgLSBiYXNpYyBmdW5jdGlvbnMKYXV0aG9yOgotIEV1Z2VuZSBQbGF2c2tpbgotIEdyYWNlIEF2ZWNpbGxhCi0gVG9iaSBTY2hyYWluawpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGVwdGg6IDMKICAgIHRpZHk6IHllcwogICAgdG9jOiB5ZXMKLS0tCiMgVmFyaWFibGVzCiMjIFZhcmlhYmxlcyBob2xkIGluZm9ybWF0aW9uCkRlZmluaW5nIHZhcmlhYmxlcywgb3IgZ2l2aW5nIGEgbmFtZSB0byB2YWx1ZXMsIHN1Y2ggYXMgdGhlIG51bWJlcnMgeW91IGFkZGVkIHRvZ2V0aGVyLCBhbGxvd3MgeW91IHRvIHN0b3JlIGluZm9ybWF0aW9uLiAgCllvdSBkZWZpbmUgdmFyaWFibGVzIHVzaW5nIHRoZSBgPC1gIG9wZXJhdG9yLCB3aGljaCBtZWFucyAic3RvcmUgdGhlIHZhbHVlIG9uIHRoZSByaWdodCBpbiB0aGUgdmFyaWFibGUgb24gdGhlIGxlZnQiLCBsaWtlIHNvLiBZb3UgY2FuIHRoZW4gY2FsbCBpdCBiYWNrIGJ5IHNheWluZyB0aGUgdmFyaWFibGUgbmFtZS4KYGBge3J9CnZhcmlhYmxlMSA8LSAzCnZhcmlhYmxlMiA8LSA0CnZhcmlhYmxlMQpgYGAKCllvdSBjYW4gdXNlIHZhcmlhYmxlcyBpbiB0aGUgcGxhY2Ugb2YgdGhlIG51bWJlcnMgdGhleSBob2xkLCBhbmQgcGVyZm9ybSBtYXRoZW1hdGljYWwgb3BlcmF0aW9ucyBvbiB0aGVtLgpgYGB7cn0KdmFyaWFibGUxICsgdmFyaWFibGUyCmBgYAoKQXMgdGhlaXIgbmFtZSBpbXBsaWVzLCB2YXJpYWJsZXMgY2FuIHRha2Ugb24gbWFueSB2YWx1ZXMsIGFuZCBjYW4gY2hhbmdlLCBzbyBiZSBjYXJlZnVsIHdpdGggbmFtaW5nIGFuZCBhc3NpZ25tZW50LgpgYGB7cn0KdmFyaWFibGUxIDwtIHZhcmlhYmxlMSArIHZhcmlhYmxlMgp2YXJpYWJsZTEKdmFyaWFibGUxIDwtIHZhcmlhYmxlMSArIHZhcmlhYmxlMgp2YXJpYWJsZTEKYGBgCgojIyBWYXJpYWJsZSAqdHlwZXMqClRoZXNlIHR5cGVzIG9mIHZhcmlhYmxlcyBhcmUgKm51bWVyaWMqLiBIb3dldmVyLCBSIGNhbiBhbHNvIHN0b3JlIHRleHQuIFRoZXNlIGFyZSBpbiB0aGUgZm9ybSBvZiAqY2hhcmFjdGVycyouIFN1cnJvdW5kIGNoYXJhY3RlcnMgaW4gcXVvdGF0aW9uIG1hcmtzIHRvIGhhdmUgdGhlbSBiZSBjaGFyYWN0ZXIgYW5kIG5vdCB2YXJpYWJsZSBuYW1lcy4KYGBge3J9CmNoYXIgPC0gImEiCmNoYXIKCiMgSW4geW91ciBjb25zb2xlLCB0cnkgdHlwaW5nICdjaGFyIDwtIGEnIChubyBxdW90ZXMpIGFuZCBzZWVpbmcgd2hhdCBoYXBwZW5zCmBgYAooYGNoYXIgPC0gYWAgcmVzdWx0cyBpbiBhbiBlcnJvciwgYmVjYXVzZSBgYWAgd2l0aG91dCBxdW90ZXMgaXMgdHJlYXRlZCBhcyBhIHZhcmlhYmxlIG5hbWUsIGFuZCB0aGF0IHZhcmlhYmxlIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB5ZXQuKQoKQ2hhcmFjdGVycyB2YXJpYWJsZXMgY2FuIHN0b3JlICpzdHJpbmdzKiwgc3VjaCBhcyB3b3JkcyBhbmQgc2VudGVuY2VzIChpbiBmYWN0LCBpbiBSLCAqc3RyaW5nKiBhbmQgKmNoYXJhY3RlciogYXJlIGJhc2ljYWxseSBpbnRlcmNoYW5nZWFibGUpLiBJbiBSLCBvbmUgc3RyaW5nIChldmVyeXRoaW5nIGJldHdlZW4gdGhlIHF1b3RhdGlvbiBtYXJrcykgaXMgc3RvcmVkIGFzIGEgc2luZ2xlIHVuaXQuCmBgYHtyfQpjaGFyX3NlbnRlbmNlIDwtICJNeSBmYXZvcml0ZSBmb29kIGlzIGljZSBjcmVhbSIKY2hhcl9zZW50ZW5jZQpjaGFyX3ZhcmlhYmxlMSA8LSAidmFyaWFibGUxIgpjaGFyX3ZhcmlhYmxlMQpjaGFyX3ZhcmlhYmxlMiA8LSB2YXJpYWJsZTEKY2hhcl92YXJpYWJsZTIKYGBgCgpZb3UgY2FuIGlkZW50aWZ5IHRoZSB0eXBlIG9mIHZhcmlhYmxlIChudW1lcmljLCBjaGFyYWN0ZXIpIHVzaW5nIGBpcygpYC4gCmBgYHtyfQojIFVzaW5nIGlzKCkKaXMoNSkKCiMgVHJ5IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIHZhcmlhYmxlIGZvciBjaGFyX3ZhcmlhYmxlMQppcyhjaGFyX3ZhcmlhYmxlMSkKIyBIb3cgYWJvdXQgY2hhcl92YXJpYWJsZTI/CmlzKGNoYXJfdmFyaWFibGUyKQojIFdoYXQgaXMgZ29pbmcgb24/CmBgYApOb3RpY2UgdGhhdCB0aGUgdGhpbmcgd2UgYXNzaWduZWQgaW50byAqY2hhcl92YXJpYWJsZTEqIHdhcyAidmFyaWFibGVfMSIgaW4gcXVvdGVzLCB3aGljaCBpcyBqdXN0IGEgY2hhcmFjdGVyIHN0cmluZywgbGlrZSBhbnkgb3RoZXIsIGhlbmNlIGl0J3MgbGlzdGVkIGFzIGEgImNoYXJhY3RlciIgKGRvbid0IHdvcnJ5IGFib3V0IHRoZSByZXN0IG9mIHRoaXMgb3V0cHV0IGZvciBub3cpLiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIHRoaW5nIHdlIGFzc2lnbmVkIGludG8gKmNoYXJfdmFyaWFibGUyKiB3YXMgKnZhcmlhYmxlXzEqIHdpdGhvdXQgcXVvdGVzLCB3aGljaCBjb3BpZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSAqdmFyaWFibGVfMSogdmFyaWFibGUgYW5kIHN0b3JlcyB0aGF0IGNvcHkgaW4gKmNoYXJfdmFyaWFibGUyKi4gV2UgZWFybGllciBhc3NpZ25lZCAqdmFyaWFibGVfMSogdG8gaG9sZCBhIG51bWJlciwgaGVuY2UgKmNoYXJfdmFyaWFibGUyKiBpcyBub3cgYWxzbyBhIG51bWVyaWMgdHlwZS4KCllvdSBjYW4gYWxzbyBtYWtlIG51bWJlcnMgaW50byBzdHJpbmdzOiBqdXN0IHB1dCBhIHF1b3RlIGFyb3VuZCB0aGVtIQpgYGB7cn0KbnVtX3N0cmluZyA8LSAnNCcKYWN0dWFsX251bSA8LSA0CgojIFRyeSBpZGVudGlmeWluZyB0aGUgdHlwZXMgb2YgbnVtX3N0cmluZyBhbmQgYWN0dWFsX251bQppcyhudW1fc3RyaW5nKQppcyhhY3R1YWxfbnVtKQpgYGAKCllvdSBuZWVkIHRvIGJlIHZlcnkgY2FyZWZ1bCBhYm91dCB0aGUgdHlwZXMgb2YgeW91ciB2YXJpYWJsZXMuIEl0IG1heSBsb29rIGxpa2UgKmFjdHVhbF9udW0qIGFuZCAqbnVtX3N0cmluZyogYXJlIGhvbGRpbmcgdGhlIHNhbWUgdGhpbmcsIGJ1dCBiZWNhdXNlIHdlJ3ZlIGltcGxpY2l0bHkgdG9sZCBSIHRoYXQgdGhleSBhcmUgb2YgZGlmZmVyZW50IHR5cGVzLCB0aGV5IGJlaGF2ZSB2ZXJ5IGRpZmZlcmVudGx5LiBJbiB0aGUgKipDb25zb2xlKiosIHRyeSBhZGRpbmcgKm51bV9zdHJpbmcqIHRvICphY3R1YWxfbnVtKi4gV2hhdCBoYXBwZW5zLCBhbmQgd2h5PyBXaGF0IGlzIFIncyBjcnlwdGljIG1lc3NhZ2UgdHJ5aW5nIHRvIHRlbGwgeW91PwoKYGFjdHVhbF9udW0gKyBudW1fc3RyaW5nYCByZXN1bHRzIGluIGFuIGVycm9yLCBkZXNjcmliZWQgYXMgJ25vbi1udW1lcmljIGFyZ3VtZW50IHRvIGJpbmFyeSBvcGVyYXRvcic7IHRoaXMgbWVhbnMgeW91J3JlIHRyeWluZyB0byBwZXJmb3JtIGFuIG9wZXJhdGlvbiB0aGF0IGlzIGRvbmUgb24gbnVtYmVycyAoYWRkaXRpb24pIHdpdGggc29tZXRoaW5nIHRoYXQncyBub3QgYSBudW1iZXIgKGBudW1fc3RyaW5nYCkKCgojIEZ1bmN0aW9ucwojIyBBZGRpbmcgd2l0aCBmdW5jdGlvbnMKV2Ugc2F3IGFib3ZlIHRoYXQgeW91IGNhbiBkbyBiYXNpYyBhcml0aG1ldGljIGluIFIgYnkganVzdCB1c2luZyBtYXRoZW1hdGljYWwgc3ltYm9scywgZS5nLiBgK2AuIEJ1dCBmb3IgbW9yZSBjb21wbGljYXRlZCB0aGluZ3MsIHByb2dyYW1taW5nIGxhbmd1YWdlcyB1c2UgdGhpbmdzIGNhbGxlZCAqZnVuY3Rpb25zKi4gQSBmdW5jdGlvbiBpcyBzb21ldGhpbmcgdGhhdCB3cmFwcyBhIHdob2xlIHNldCBvZiBvcGVyYXRpb25zIHNvIHRoYXQgeW91IGNhbiBpbnZva2UgdGhvc2Ugb3BlcmF0aW9ucyBpbiBhIHNpbmdsZSBjb21tYW5kLiBZb3UgaGF2ZSBhbHJlYWR5IHVzZWQgYW5vdGhlciBmdW5jdGlvbiBlYXJsaWVyIGluIHRoaXMgY2xhc3MsIGBpcygpYC4gTGV0J3MgdGFrZSBhIGxvb2sgYXQgYW5vdGhlciBleGFtcGxlOiB0aGVyZSdzIGEgZnVuY3Rpb24sIGBzdW0oKWAsIHRoYXQgY2FuIGFkZCBudW1iZXJzLCBqdXN0IGxpa2UgYCtgIGNhbi4gTGV0J3MgdHJ5IGl0OgpgYGB7cn0KdmFyaWFibGUxCnZhcmlhYmxlMgpzdW0odmFyaWFibGUxLCB2YXJpYWJsZTIpCmBgYAoKYHN1bSgpYCBjYW4gYWxzbyB0YWtlIG1vcmUgdGhhbiB0d28gaW5wdXRzIQpgYGB7cn0KIyBUcnkgdXNpbmcgdGhlIHN1bSBmdW5jdGlvbiB0byBjb21wdXRlIHRoZSBzdW0gb2YgMywgNCwgYW5kIDYKc3VtKDMsNCw2KQpgYGAKCkZ1bmN0aW9ucyBhcmUgdGhlaXIgb3duIHR5cGUhIFlvdSBjYW4gdHJ5IHVzaW5nIGBpcygpYCB0byBjaGVjayB0aGlzOgpgYGB7cn0KaXMoc3VtKQppcyhpcykKYGBgCgpGdW5jdGlvbnMgYXJlIGFsd2F5cyBmb2xsb3dlZCBieSBgKClgIHdoZW4geW91IHVzZSB0aGVtLiBXaGVuIHlvdSB1c2UgYSBmdW5jdGlvbiwgb2Z0ZW4geW91IGFyZSB0ZWxsaW5nIGl0IHRvIHBlcmZvcm0gYW4gb3BlcmF0aW9uIG9uIHNvbWV0aGluZyBlbHNlIChlLmcuIGEgdmFyaWFibGUpOyBpbiB0aGUgZXhhbXBsZXMgYWJvdmUsIHdlJ3JlIHBlcmZvcm1pbmcgdGhlIGBzdW0oKWAgZnVuY3Rpb24gb24gKnZhcmlhYmxlMSogYW5kICp2YXJpYWJsZTIqLCBhbmQgd2UncmUgcGVyZm9ybWluZyB0aGUgYGlzKClgIGZ1bmN0aW9uIG9uIGBzdW1gIGFuZCBvbiBpdHNlbGYuIFRoZXNlIGFyZSBjYWxsZWQgYXJndW1lbnRzLCBhbmQgYXJlICpwYXNzZWQqIHRvIHRoZSBmdW5jdGlvbiBpbnNpZGUgdGhlIHBhcmVudGhlc2VzLgoKIyMgTG9va2luZyBhdCB0aGUgKipFbnZpcm9ubWVudCoqClNvbWUgZnVuY3Rpb25zIGRvbid0IG5lZWQgdG8gdGFrZSBhbnkgYXJndW1lbnRzLiBGb3IgZXhhbXBsZSwgeW91IGNhbiBmaW5kIG91dCB3aGF0IHZhcmlhYmxlcyB5b3UgaGF2ZSBsb2FkZWQgaW4geW91ciAqZW52aXJvbm1lbnQqIGF0IGFueXRpbWUgdXNpbmcgYGxzKClgLiBUaGlzIHdpbGwgbGlzdCBhbGwgeW91ciB2YXJpYWJsZXMsIGFueSBjdXN0b20gZnVuY3Rpb25zIHlvdSBtYXkgaGF2ZSB3cml0dGVuLCBldGMuCmBgYHtyfQpscygpCmBgYAoKQ2hlY2sgb3V0IHRoZSAqKkVudmlyb25tZW50Kiogd2luZG93IG9uIHRoZSB0b3AgcmlnaHQhIFlvdSBjYW4gYWN0dWFsbHkgYWxzbyBzZWUgYWxsIHlvdXIgdmFyaWFibGVzIGxvYWRlZCBpbiB0aGVyZSwgd2l0aCBhIHNob3J0IHN1bW1hcnkgb2Ygd2hhdCdzIGluIHRoZW0uIFRoaXMgaXMgYSBzdXBlciBjb252ZW5pZW50IGZlYXR1cmUgb2YgcHJvZ3JhbW1pbmcgaW4gUnN0dWRpby4KCiMjIENvbWJpbmluZyBzdHJpbmdzCkFub3RoZXIgcmVhbGx5IHVzZWZ1bCBmdW5jdGlvbiBpcyB0aGUgYHBhc3RlYCBmdW5jdGlvbjsgdGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIGNvbWJpbmUgKnN0cmluZ3MqLgpgYGB7cn0KZmF2b3JpdGVfc3ViamVjdCA8LSAnYmlvbG9neScKc3RhdGVtZW50X2Fib3V0X3N1YmplY3QgPC0gJ2lzICMnCnN1YmplY3RfcmFuayA8LSAnMScKCmJpb2xvZ3lfcXVhbGl0eSA8LSBwYXN0ZShmYXZvcml0ZV9zdWJqZWN0LCBzdGF0ZW1lbnRfYWJvdXRfc3ViamVjdCwgc3ViamVjdF9yYW5rKQpgYGAKCk5vdGljZSB0aGF0IHRoZSBjb2RlIGFib3ZlIGRpZG4ndCBwcmludCBhbnl0aGluZyBvdXQuIFRoYXQncyBiZWNhdXNlIHdlIGRpcmVjdGVkIHRoZSBvdXRwdXQgb2YgdGhlIGBwYXN0ZWAgZnVuY3Rpb24gaW50byBhIHZhcmlhYmxlLCAqYmlvbG9neV9xdWFsaXR5Ki4gVG8gZ2V0IFIgdG8gcHJpbnQgb3V0IHRoZSBjdXJyZW50IHByb2dyYW0gdmFyaWFibGUsIHlvdSBjb3VsZCBqdXN0IHR5cGUgaXQgaW50byB5b3VyIGNvbnNvbGUsIG9yIHlvdSBjb3VsZCB1c2UgYSBmdW5jdGlvbiEgVHJ5IGdvb2dsaW5nIHRvIGZpbmQgYW4gUiBmdW5jdGlvbiB0aGF0IHByaW50cyBvdXQgYSB2YXJpYWJsZS4KYGBge3J9CiMgRmluZCBhbiBSIGZ1bmN0aW9uIHRvIHByaW50IG91dCBhIHZhcmlhYmxlLCBhbmQgdXNlIGl0IHRvIHByaW50IHdoYXRldmVyCiMgdGhlIGJpb2xvZ3lfcXVhbGl0eSB2YXJpYWJsZSBpcyBzdG9yaW5nCnByaW50KGJpb2xvZ3lfcXVhbGl0eSkKYGBgCgpZb3UgY2FuIGxlYXJuIGFib3V0IGEgZnVuY3Rpb24gYnkgcmVhZGluZyBpdHMgZG9jdW1lbnRhdGlvbi4gWW91IGNhbiBhY2Nlc3MgdGhlIGRvY3VtZW50YXRpb24gd2l0aCBgP2AsIGZvciBleGFtcGxlLCB0eXBlIGA/cGFzdGVgIGludG8geW91ciBjb25zb2xlLiBZb3Ugd2lsbCBzZWUgdGhlIGhlbHAgdGV4dCBwb3AgdXAgaW4gdGhlIGJvdHRvbSByaWdodCBIZWxwIGJveCBpbiBSc3R1ZGlvLgoKYD9gIGlzIG9uZSBvZiB0aGUgbW9yZSBpbXBvcnRhbnQga2V5cyBmb3IgeW91IHRvIGtub3cuIFNlcmlvdXNseSwgbWFueSBpc3N1ZXMgYXJlIGF2ZXJ0ZWQgYnkgZmlyc3QgY2hlY2tpbmcgdGhlIGRvY3VtZW50YXRpb24uIERvY3VtZW50YXRpb24gdXN1YWxseSBoYXM6IAoKKiBBIGRlc2NyaXB0aW9uIG9mIHRoZSBpbnRlbnRpb24gb2YgdGhlIGZ1bmN0aW9uCiogSG93IHRvIHVzZSBpdCwgaWUgd2hlcmUgdG8gcHV0IHdoYXQgYXJndW1lbnRzCiogQSBkZXNjcmlwdGlvbiBvZiB3aGF0IHRob3NlIGFyZ3VtZW50cyBzaG91bGQgYmUKKiBEZXRhaWxzLCBhbmQgd2hhdCB2YWx1ZSB0aGV5IHJldHVybgoqIEFuZCBpZiB5b3UncmUgbHVja3ksIGV4YW1wbGVzIG9mIHVzYWdlCgpJbiBwcmFjdGljZSwgdGhpcyBpbmZvcm1hdGlvbiBjYW4gc29tZXRpbWVzIGJlIGEgYml0IGRlbnNlIGFuZCB0ZWNobmljYWwuIEkgdXN1YWxseSBmaW5kIGl0IG1vc3QgdXNlZnVsIHRvIHJlYWQgdGhlICdkZXNjcmlwdGlvbicgb24gdG9wLCBhbmQgdGhlbiBzY3JvbGwgYWxsIHRoZSB3YXkgZG93biB0byB0aGUgJ2V4YW1wbGVzJyBzZWN0aW9uIGF0IHRoZSBib3R0b20gb2YgdGhlIGhlbHAgZnVuY3Rpb24uCgpOb3RpY2UgdGhhdCB3aGVuIHdlIHVzZWQgcGFzdGUgYWJvdmUsIHRoZSBmdW5jdGlvbiBhdXRvbWF0aWNhbGx5IHB1dCBhIHNwYWNlIGJldHdlZW4gb3VyIHR3byBzdHJpbmdzLiBJdCdzIG9mdGVuIHJlYWxseSB1c2VmdWwgdG8gY29tYmluZSBzdHJpbmdzIHdpdGggYSBkaWZmZXJlbnQgY2hhcmFjdGVyLCBmb3IgZXhhbXBsZSwgYSBkYXNoLiBUcnkgdG8gcmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgYHBhc3RlKClgIHRvIGZpZ3VyZSBvdXQgaG93IHRvIGRvIHRoaXMuCmBgYHtyfQojIENvbWJpbmUgb25seSB0aGUgZmF2b3JpdGVfc3ViamVjdCwgc3RhdGVtZW50X2Fib3V0X3N1YmplY3QsIGFuZCBzdWJqZWN0X3JhbmsKIyB2YXJpYWJsZXMsIHVzaW5nIGEgZGFzaCBiZXR3ZWVuIHRoZW0gaW5zdGVhZCBvZiBhIHNwYWNlCmJpb2xvZ3lfcXVhbGl0eV9kYXNoIDwtCiAgcGFzdGUoZmF2b3JpdGVfc3ViamVjdCwgc3RhdGVtZW50X2Fib3V0X3N1YmplY3QsIHN1YmplY3RfcmFuaywgc2VwID0gJy0nKQpwcmludChiaW9sb2d5X3F1YWxpdHlfZGFzaCkKYGBgCgojIFRoaW5ncyB3ZSBob3BlIHlvdSd2ZSBsZWFybmVkIHRvZGF5IChhbmQgd2lsbCBob3BlZnVsbHkgcmVtZW1iZXIgbmV4dCB0aW1lKQoKKiAqdmFyaWFibGVzKiBob2xkIGluZm9ybWF0aW9uCiogQmFzaWMgdHlwZXM6ICpudW1lcmljKiwgKmNoYXJhY3RlciosIGFuZCAqZnVuY3Rpb24qCiogSG93IHRvIHVzZSBmdW5jdGlvbnMsIGFuZCB3aGF0ICphcmd1bWVudHMqIGFyZQoqIEhvdyB0byB1c2UgYHN1bSgpYCwgYHBhc3RlKClgLCBgaXMoKWAKKiBIb3cgdG8gbG9vayBhdCB5b3VyICoqRW52aXJvbm1lbnQqKgo=