Email             :
RPubs            : https://rpubs.com/kentzend03/
Jurusan          : Fisika Medis
Address         : ARA Center, Matana University Tower
                         Jl. CBD Barat Kav, RT.1, Curug Sangereng, Kelapa Dua, Tangerang, Banten 15810.


1 List

List adalah struktur data pada R dan python yang mampu menyimpan lebih dari satu data, seperti array. Pada kesempatan ini, kita akan membahas cara menggunakan list di R dari yang paling sederhana sampai yang sedikit lebih kompleks.

1.1 Membentuk List

Hal terpenting yang harus dipelajari adalah bagaimana untuk membentuk list. Perhatikan contoh berikut!

list1 = list ("Velman","Wawan","Eirene","Intan","Happy")       # membuat list 5 item karakter
print(list1)                                                   # print hasil

1.2 Pengindeksan Nilai dari List

Setelah kita tahu cara membuat dan menyimpan data di dalam list, mari kita coba mengambil datanya. Listnya sama seperti array, list juga memiliki nomor indeks untuk mengakses data atau isinya.

Nomor indeks list di dalam R dimulai dari satu (1). Nomor indeks ini yang kita butuhkan untuk mengambil isi (item) dari list.

list1 = list ("Velman","Wawan", "Eirene", "Intan", "Happy")       # membuat list 5 item karakter
print(list1[1])                                                   # print nilai pada indeks 1
## [[1]]
## [1] "Velman"

1.3 Menambahkan dan Menghapus

Untuk menambahkan atau mengganti atau menghapus nilai pada suatu list bersifat mutable, artinya isinya bisa kita ubah-ubah.

list1 = list ("Velman","Wawan", "Eirene", "Intan", "Happy")       # list mula-mula
list1[5] = "Priska"                                               # mengganti Happy menjadi Priska
print(list1)                                                      # print hasil
## [[1]]
## [1] "Velman"
## 
## [[2]]
## [1] "Wawan"
## 
## [[3]]
## [1] "Eirene"
## 
## [[4]]
## [1] "Intan"
## 
## [[5]]
## [1] "Priska"

Selain cara di atas, berikut ini terdpat dua metode atau fungsi lainnya yang dapat digunakan untuk menambahkan isi atau item ke list:

list1=c(list1, "Nestor")       # menambahkan Nestor di indeks akhir list 1
list1=c("Louis",list1)         # menambahkan Louis di indeks awal list 1
print(list1)                   # print list yang sudah diganti
## [[1]]
## [1] "Louis"
## 
## [[2]]
## [1] "Velman"
## 
## [[3]]
## [1] "Wawan"
## 
## [[4]]
## [1] "Eirene"
## 
## [[5]]
## [1] "Intan"
## 
## [[6]]
## [1] "Priska"
## 
## [[7]]
## [1] "Nestor"
length(list1)
## [1] 7

2 Tuple

Tuple dalam R dan python adalah Struktur data yang digunakan untuk menyimpan sekumpulan data. Tuple bersifat immutable, artinya isi tuple tidak bisa kita ubah dan hapus. Namun, dapat kita isi dengan berbagai macam nilai dan objek sebagai berikut.

• Cara membentuk tuple

• Cara mengakses nilai tuple

• Slicing nilai tuple

• Nested Tuple

• Unpacking Sequence

Untuk membuat tuple di dalam R, anda perlu untuk menginstal packages sets sebelum menjalankan beberapa koding berikut.

library (sets)
tuple1 = tuple("Hai")
tuple2 = tuple("Hai","perkenalkan","nama","saya","Kent")
tuple2 = tuple("Hai","perkenalkan","nama","saya","Kent")
print (tuple2 [1])
## ("Hai")
tuple2 = tuple("Hai","perkenalkan","nama","saya","kent")
print(tuple2[2:5])
## ("perkenalkan", "nama", "saya", "kent")
tuple3 = c(tuple2,tuple1)
print(tuple3)
## ("Hai", "perkenalkan", "nama", "saya", "kent", "Hai")
tuple4 = rep(tuple3, 5)
print(tuple4)
## ("Hai", "perkenalkan", "nama", "saya", "kent", "Hai", "Hai",
##  "perkenalkan", "nama", "saya", "kent", "Hai", "Hai", "perkenalkan",
##  "nama", "saya", "kent", "Hai", "Hai", "perkenalkan", "nama", "saya",
##  "kent", "Hai", "Hai", "perkenalkan", "nama", "saya", "kent", "Hai")

3 Dictionary

Dictionary adalah struktur data yang bentuknya seperti kamus. Ada kata kunci kemudian ada nilainya. Kata kunci harus unik, sedangkan nilai boleh diisi dengan apa saja. Adapun perbedaan list dan tuple adalah; dictionary memiliki kunci berupa teks (bisa juga angka), sedangkan list dan tuple menggunakan indeks berupa angka saja untuk mengakses nilainya.

Untuk membentuk dictionary di dalam R sangatlah mudah, silahkan perhatikan contoh berikut.

library(Dict)
## 
## Attaching package: 'Dict'
## The following object is masked from 'package:sets':
## 
##     %>%
 kentzend30 = dict(
     Nama = "Kent Juan Nataniel Yaoisokhi Zendrato",
     umur =  as.integer (18),
     hobi = list("Reading", "Listening to Music", "Badminton"),
  menikah = FALSE,
   sosmed=tuple(facebook= "Niel",
               instagram= "Natan240734")
 )
cat("Nama saya adalah :", kentzend30$get('Nama'))
## Nama saya adalah : Kent Juan Nataniel Yaoisokhi Zendrato
print(kentzend30$get('sosmed')['facebook'])
## (facebook = "Niel")
kentzend30["Nama"] = "Kent Juan Nataniel Yaoisokhi Zendrato"
kentzend30$remove ("Nama") 
print(kentzend30$get("Nama"))
## NULL

4 Data frame

Bingkai data adalah tabel atau struktur seperti array dua dimensi dimana setiap kolom berisi nilai dari satu variabel dan setiap baris berisi satu set nilai dari setiap kolom. berikut ini adalah ciri-ciri data frame:

• Nama kolom tidak boleh kosong

• Nama baris harus unik

• Data yang disimpan dalam bingkai data dapat berupa numerik, faktor, atau tipe karakter

• Setiap kolom harus berisi jumlah item data yang sama

Berikut ini diperlihatkan contoh data frame dengan menggunakan R

df1_R <- data.frame(kode =c ( 1 : 5 ), 
                     nama =c ( " Budi " , " Andi " , " Sherly " , " Dian " , " Woody " ), 
                     gaji =c (776.7 ,  700.3 ,668.8,876.6,758.3 ) ,
            jenis_kelamin =c("L","L","P","P","L"),
                     umur =c(29,35,31,27,30),
                   alamat =c("Jakarta","Tangerang","Depok","Serang","Depok"),
              mulai_kerja = as.Date(c(" 2015-06-08 " , " 2015-03-18 " , " 2015-08-11 " , " 2015-09-21", "2015-11-04")),  
                   divisi =c ( "DS" , "DS" , "BA" , "DA" , "DS" ) ,  stringsAsFactors = F )
print(df1_R)
##   kode     nama  gaji jenis_kelamin umur    alamat mulai_kerja divisi
## 1    1    Budi  776.7             L   29   Jakarta  2015-06-08     DS
## 2    2    Andi  700.3             L   35 Tangerang  2015-03-18     DS
## 3    3  Sherly  668.8             P   31     Depok  2015-08-11     BA
## 4    4    Dian  876.6             P   27    Serang  2015-09-21     DA
## 5    5   Woody  758.3             L   30     Depok  2015-11-04     DS
typeof ( df1_R ) 
## [1] "list"
class ( df1_R )
## [1] "data.frame"
df1_R[1,5] 
## [1] 29
df1_R$nama
## [1] " Budi "   " Andi "   " Sherly " " Dian "   " Woody "
df1_R [,c('nama','jenis_kelamin')]
##       nama jenis_kelamin
## 1    Budi              L
## 2    Andi              L
## 3  Sherly              P
## 4    Dian              P
## 5   Woody              L
df1_R [ 1 : 5 ,]
##   kode     nama  gaji jenis_kelamin umur    alamat mulai_kerja divisi
## 1    1    Budi  776.7             L   29   Jakarta  2015-06-08     DS
## 2    2    Andi  700.3             L   35 Tangerang  2015-03-18     DS
## 3    3  Sherly  668.8             P   31     Depok  2015-08-11     BA
## 4    4    Dian  876.6             P   27    Serang  2015-09-21     DA
## 5    5   Woody  758.3             L   30     Depok  2015-11-04     DS
df1_R [ , 1 : 5 ]
##   kode     nama  gaji jenis_kelamin umur
## 1    1    Budi  776.7             L   29
## 2    2    Andi  700.3             L   35
## 3    3  Sherly  668.8             P   31
## 4    4    Dian  876.6             P   27
## 5    5   Woody  758.3             L   30
subset ( df1_R , select = 6 ) 
##      alamat
## 1   Jakarta
## 2 Tangerang
## 3     Depok
## 4    Serang
## 5     Depok
subset ( df1_R , select = c ( 6,7 ) ) 
##      alamat mulai_kerja
## 1   Jakarta  2015-06-08
## 2 Tangerang  2015-03-18
## 3     Depok  2015-08-11
## 4    Serang  2015-09-21
## 5     Depok  2015-11-04
subset ( df1_R , select = c ( 2 : 5 ) )
##       nama  gaji jenis_kelamin umur
## 1    Budi  776.7             L   29
## 2    Andi  700.3             L   35
## 3  Sherly  668.8             P   31
## 4    Dian  876.6             P   27
## 5   Woody  758.3             L   30
min(df1_R$gaji)
## [1] 668.8
max(df1_R$gaji)
## [1] 876.6
mean(df1_R$gaji)
## [1] 756.14
sd(df1_R$gaji)
## [1] 80.13172
summary(df1_R)
##       kode       nama                gaji       jenis_kelamin     
##  Min.   :1   Length:5           Min.   :668.8   Length:5          
##  1st Qu.:2   Class :character   1st Qu.:700.3   Class :character  
##  Median :3   Mode  :character   Median :758.3   Mode  :character  
##  Mean   :3                      Mean   :756.1                     
##  3rd Qu.:4                      3rd Qu.:776.7                     
##  Max.   :5                      Max.   :876.6                     
##       umur         alamat           mulai_kerja            divisi         
##  Min.   :27.0   Length:5           Min.   :2015-03-18   Length:5          
##  1st Qu.:29.0   Class :character   1st Qu.:2015-06-08   Class :character  
##  Median :30.0   Mode  :character   Median :2015-08-11   Mode  :character  
##  Mean   :30.4                      Mean   :2015-07-25                     
##  3rd Qu.:31.0                      3rd Qu.:2015-09-21                     
##  Max.   :35.0                      Max.   :2015-11-04

5 Ganti Nama Variabel

Salah satu hal penting lainnya yang dimiliki proses data science adalah menyimpan data ke dalam variabel. Variabel dapat diibaratkan seperti sebuah label untuk sebuah informasi. Variabel dapat juga terdiri dari beberapa informasi. Seringkali kita sebagai data scientist perlu untuk mengganti nama variabel tertentu untuk memudahkan dalam menganalisa informasi yang terkandung pada suatu data yang dimiliki.

Objek R dapat memiliki nama, yang sangat berguna untuk menulis kode yang dapat dibaca dan objek yang menggambarkan dirinya sendiri. Anda akan mempelajari cara mengganti nama kolom data frame di R menggunakan fungsi names().

rename_1<-df1_R
names(rename_1)<-c("no",
"nama",
"tgl.lahir",
"jenis kelamin",
"umur",
"alamat",
"gaji")
print(rename_1)
##   no     nama tgl.lahir jenis kelamin umur    alamat       gaji NA
## 1  1    Budi      776.7             L   29   Jakarta 2015-06-08 DS
## 2  2    Andi      700.3             L   35 Tangerang 2015-03-18 DS
## 3  3  Sherly      668.8             P   31     Depok 2015-08-11 BA
## 4  4    Dian      876.6             P   27    Serang 2015-09-21 DA
## 5  5   Woody      758.3             L   30     Depok 2015-11-04 DS
LS0tDQp0aXRsZTogIkFsZ29yaXRtYSAmIFN0cnVrdHVyIERhdGEiDQpzdWJ0aXRsZTogIlR1Z2FzIDMiDQphdXRob3I6ICJLZW50IEp1YW4gTmF0YW5pZWwgWWFvaXNva2hpIFplbmRyYXRvICgyMDIxNDUyMDAwNCkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50OiANCiAgICBodG1sX2RvY3VtZW50OiBudWxsDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IHNhbmRzdG9uZQ0KICAgIGNzczogc3R5bGUxLmNzcw0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KLS0tDQoNCg0KPGltZyBzdHlsZT0iZmxvYXQ6IHJpZ2h0OyBtYXJnaW46IDBweCAxMDBweCAwcHggMHB4OyB3aWR0aDoyNSUiIHNyYz0iZm90by5wbmciLz4gDQoNCmBgYHtyIGxvZ28sIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMzAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsb2dvLnBuZyIpDQpgYGANCg0KRW1haWwgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7Jm5ic3A7OiAga2VudC56ZW5kcmF0b0BzdHVkZW50Lm1hdGFuYXVuaXZlcnNpdHkuYWMuaWQgPGJyPg0KUlB1YnMgICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzogaHR0cHM6Ly9ycHVicy5jb20va2VudHplbmQwMy8gPGJyPg0KSnVydXNhbiAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7OiBbRmlzaWthIE1lZGlzXShodHRwczovL21hdGFuYXVuaXZlcnNpdHkuYWMuaWQvP2x5PWFjYWRlbWljJmM9c2IpIDxicj4NCkFkZHJlc3MgICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyA6IEFSQSBDZW50ZXIsIE1hdGFuYSBVbml2ZXJzaXR5IFRvd2VyIDxicj4NCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7Jm5ic3A7IEpsLiBDQkQgQmFyYXQgS2F2LCBSVC4xLCBDdXJ1ZyBTYW5nZXJlbmcsIEtlbGFwYSBEdWEsIFRhbmdlcmFuZywgQmFudGVuIDE1ODEwLg0KDQoqKioqDQoNCiMgTGlzdA0KDQpMaXN0IGFkYWxhaCBzdHJ1a3R1ciBkYXRhIHBhZGEgUiBkYW4gcHl0aG9uIHlhbmcgbWFtcHUgbWVueWltcGFuIGxlYmloIGRhcmkgc2F0dSBkYXRhLCBzZXBlcnRpIGFycmF5LiBQYWRhIGtlc2VtcGF0YW4gaW5pLCBraXRhIGFrYW4gbWVtYmFoYXMgY2FyYSBtZW5nZ3VuYWthbiBsaXN0IGRpIFIgZGFyaSB5YW5nIHBhbGluZyBzZWRlcmhhbmEgc2FtcGFpIHlhbmcgc2VkaWtpdCBsZWJpaCBrb21wbGVrcy4NCg0KIyMgTWVtYmVudHVrIExpc3QNCg0KSGFsIHRlcnBlbnRpbmcgeWFuZyBoYXJ1cyBkaXBlbGFqYXJpIGFkYWxhaCBiYWdhaW1hbmEgdW50dWsgbWVtYmVudHVrIGxpc3QuIFBlcmhhdGlrYW4gY29udG9oIGJlcmlrdXQhDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsaXN0MSA9IGxpc3QgKCJWZWxtYW4iLCJXYXdhbiIsIkVpcmVuZSIsIkludGFuIiwiSGFwcHkiKSAgICAgICAjIG1lbWJ1YXQgbGlzdCA1IGl0ZW0ga2FyYWt0ZXINCnByaW50KGxpc3QxKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcHJpbnQgaGFzaWwNCmBgYA0KDQojIyBQZW5naW5kZWtzYW4gTmlsYWkgZGFyaSBMaXN0DQoNClNldGVsYWgga2l0YSB0YWh1IGNhcmEgbWVtYnVhdCBkYW4gbWVueWltcGFuIGRhdGEgZGkgZGFsYW0gbGlzdCwgbWFyaSBraXRhIGNvYmEgbWVuZ2FtYmlsIGRhdGFueWEuIExpc3RueWEgc2FtYSBzZXBlcnRpIGFycmF5LCBsaXN0IGp1Z2EgbWVtaWxpa2kgbm9tb3IgaW5kZWtzIHVudHVrIG1lbmdha3NlcyBkYXRhIGF0YXUgaXNpbnlhLg0KDQpOb21vciBpbmRla3MgbGlzdCBkaSBkYWxhbSBSIGRpbXVsYWkgZGFyaSBzYXR1ICgxKS4gTm9tb3IgaW5kZWtzIGluaSB5YW5nIGtpdGEgYnV0dWhrYW4gdW50dWsgbWVuZ2FtYmlsIGlzaSAoaXRlbSkgZGFyaSBsaXN0Lg0KDQpgYGB7cn0NCmxpc3QxID0gbGlzdCAoIlZlbG1hbiIsIldhd2FuIiwgIkVpcmVuZSIsICJJbnRhbiIsICJIYXBweSIpICAgICAgICMgbWVtYnVhdCBsaXN0IDUgaXRlbSBrYXJha3Rlcg0KcHJpbnQobGlzdDFbMV0pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBwcmludCBuaWxhaSBwYWRhIGluZGVrcyAxDQpgYGANCg0KIyMgTWVuYW1iYWhrYW4gZGFuIE1lbmdoYXB1cw0KDQpVbnR1ayBtZW5hbWJhaGthbiBhdGF1IG1lbmdnYW50aSBhdGF1IG1lbmdoYXB1cyBuaWxhaSBwYWRhIHN1YXR1IGxpc3QgYmVyc2lmYXQgbXV0YWJsZSwgYXJ0aW55YSBpc2lueWEgYmlzYSBraXRhIHViYWgtdWJhaC4NCg0KYGBge3J9DQpsaXN0MSA9IGxpc3QgKCJWZWxtYW4iLCJXYXdhbiIsICJFaXJlbmUiLCAiSW50YW4iLCAiSGFwcHkiKSAgICAgICAjIGxpc3QgbXVsYS1tdWxhDQpsaXN0MVs1XSA9ICJQcmlza2EiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lbmdnYW50aSBIYXBweSBtZW5qYWRpIFByaXNrYQ0KcHJpbnQobGlzdDEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBwcmludCBoYXNpbA0KYGBgDQoNClNlbGFpbiBjYXJhIGRpIGF0YXMsIGJlcmlrdXQgaW5pIHRlcmRwYXQgZHVhIG1ldG9kZSBhdGF1IGZ1bmdzaSBsYWlubnlhIHlhbmcgZGFwYXQgZGlndW5ha2FuIHVudHVrIG1lbmFtYmFoa2FuIGlzaSBhdGF1IGl0ZW0ga2UgbGlzdDoNCg0KYGBge3J9DQpsaXN0MT1jKGxpc3QxLCAiTmVzdG9yIikgICAgICAgIyBtZW5hbWJhaGthbiBOZXN0b3IgZGkgaW5kZWtzIGFraGlyIGxpc3QgMQ0KbGlzdDE9YygiTG91aXMiLGxpc3QxKSAgICAgICAgICMgbWVuYW1iYWhrYW4gTG91aXMgZGkgaW5kZWtzIGF3YWwgbGlzdCAxDQpwcmludChsaXN0MSkgICAgICAgICAgICAgICAgICAgIyBwcmludCBsaXN0IHlhbmcgc3VkYWggZGlnYW50aQ0KYGBgDQoNCmBgYHtyfQ0KbGVuZ3RoKGxpc3QxKQ0KYGBgDQojIFR1cGxlDQoNClR1cGxlIGRhbGFtIFIgZGFuIHB5dGhvbiBhZGFsYWggU3RydWt0dXIgZGF0YSB5YW5nIGRpZ3VuYWthbiB1bnR1ayBtZW55aW1wYW4gc2VrdW1wdWxhbiBkYXRhLiBUdXBsZSBiZXJzaWZhdCBpbW11dGFibGUsIGFydGlueWEgaXNpIHR1cGxlIHRpZGFrIGJpc2Ega2l0YSB1YmFoIGRhbiBoYXB1cy4gTmFtdW4sIGRhcGF0IGtpdGEgaXNpIGRlbmdhbiBiZXJiYWdhaSBtYWNhbSBuaWxhaSBkYW4gb2JqZWsgc2ViYWdhaSBiZXJpa3V0Lg0KDQrigKIJQ2FyYSBtZW1iZW50dWsgdHVwbGUNCg0K4oCiCUNhcmEgbWVuZ2Frc2VzIG5pbGFpIHR1cGxlDQoNCuKAoglTbGljaW5nIG5pbGFpIHR1cGxlDQoNCuKAoglOZXN0ZWQgVHVwbGUNCg0K4oCiCVVucGFja2luZyBTZXF1ZW5jZQ0KDQpVbnR1ayBtZW1idWF0IHR1cGxlIGRpIGRhbGFtIFIsIGFuZGEgcGVybHUgdW50dWsgbWVuZ2luc3RhbCBwYWNrYWdlcyBzZXRzIHNlYmVsdW0gbWVuamFsYW5rYW4gYmViZXJhcGEga29kaW5nIGJlcmlrdXQuDQoNCmBgYHtyfQ0KbGlicmFyeSAoc2V0cykNCnR1cGxlMSA9IHR1cGxlKCJIYWkiKQ0KdHVwbGUyID0gdHVwbGUoIkhhaSIsInBlcmtlbmFsa2FuIiwibmFtYSIsInNheWEiLCJLZW50IikNCmBgYA0KDQpgYGB7cn0NCnR1cGxlMiA9IHR1cGxlKCJIYWkiLCJwZXJrZW5hbGthbiIsIm5hbWEiLCJzYXlhIiwiS2VudCIpDQpwcmludCAodHVwbGUyIFsxXSkNCg0KYGBgDQpgYGB7cn0NCnR1cGxlMiA9IHR1cGxlKCJIYWkiLCJwZXJrZW5hbGthbiIsIm5hbWEiLCJzYXlhIiwia2VudCIpDQpwcmludCh0dXBsZTJbMjo1XSkNCg0KYGBgDQpgYGB7cn0NCnR1cGxlMyA9IGModHVwbGUyLHR1cGxlMSkNCnByaW50KHR1cGxlMykNCg0KYGBgDQpgYGB7cn0NCnR1cGxlNCA9IHJlcCh0dXBsZTMsIDUpDQpwcmludCh0dXBsZTQpDQoNCmBgYA0KDQojIERpY3Rpb25hcnkNCg0KRGljdGlvbmFyeSBhZGFsYWggc3RydWt0dXIgZGF0YSB5YW5nIGJlbnR1a255YSBzZXBlcnRpIGthbXVzLiBBZGEga2F0YSBrdW5jaSBrZW11ZGlhbiBhZGEgbmlsYWlueWEuIEthdGEga3VuY2kgaGFydXMgdW5paywgc2VkYW5na2FuIG5pbGFpIGJvbGVoIGRpaXNpIGRlbmdhbiBhcGEgc2FqYS4gQWRhcHVuIHBlcmJlZGFhbiBsaXN0IGRhbiB0dXBsZSBhZGFsYWg7IGRpY3Rpb25hcnkgbWVtaWxpa2kga3VuY2kgYmVydXBhIHRla3MgKGJpc2EganVnYSBhbmdrYSksIHNlZGFuZ2thbiBsaXN0IGRhbiB0dXBsZSBtZW5nZ3VuYWthbiBpbmRla3MgYmVydXBhIGFuZ2thIHNhamEgdW50dWsgbWVuZ2Frc2VzIG5pbGFpbnlhLg0KDQpVbnR1ayBtZW1iZW50dWsgZGljdGlvbmFyeSBkaSBkYWxhbSBSIHNhbmdhdGxhaCBtdWRhaCwgc2lsYWhrYW4gcGVyaGF0aWthbiBjb250b2ggYmVyaWt1dC4NCg0KYGBge3J9DQpsaWJyYXJ5KERpY3QpDQoga2VudHplbmQzMCA9IGRpY3QoDQogICAgIE5hbWEgPSAiS2VudCBKdWFuIE5hdGFuaWVsIFlhb2lzb2toaSBaZW5kcmF0byIsDQogICAgIHVtdXIgPSAgYXMuaW50ZWdlciAoMTgpLA0KICAgICBob2JpID0gbGlzdCgiUmVhZGluZyIsICJMaXN0ZW5pbmcgdG8gTXVzaWMiLCAiQmFkbWludG9uIiksDQogIG1lbmlrYWggPSBGQUxTRSwNCiAgIHNvc21lZD10dXBsZShmYWNlYm9vaz0gIk5pZWwiLA0KICAgICAgICAgICAgICAgaW5zdGFncmFtPSAiTmF0YW4yNDA3MzQiKQ0KICkNCmBgYA0KDQoNCmBgYHtyfQ0KY2F0KCJOYW1hIHNheWEgYWRhbGFoIDoiLCBrZW50emVuZDMwJGdldCgnTmFtYScpKQ0KcHJpbnQoa2VudHplbmQzMCRnZXQoJ3Nvc21lZCcpWydmYWNlYm9vayddKQ0KDQpgYGANCmBgYHtyfQ0Ka2VudHplbmQzMFsiTmFtYSJdID0gIktlbnQgSnVhbiBOYXRhbmllbCBZYW9pc29raGkgWmVuZHJhdG8iDQoNCmBgYA0KDQoNCmBgYHtyfQ0Ka2VudHplbmQzMCRyZW1vdmUgKCJOYW1hIikgDQpwcmludChrZW50emVuZDMwJGdldCgiTmFtYSIpKQ0KDQpgYGANCg0KIyBEYXRhIGZyYW1lDQoNCkJpbmdrYWkgZGF0YSBhZGFsYWggdGFiZWwgYXRhdSBzdHJ1a3R1ciBzZXBlcnRpIGFycmF5IGR1YSBkaW1lbnNpIGRpbWFuYSBzZXRpYXAga29sb20gYmVyaXNpIG5pbGFpIGRhcmkgc2F0dSB2YXJpYWJlbCBkYW4gc2V0aWFwIGJhcmlzIGJlcmlzaSBzYXR1IHNldCBuaWxhaSBkYXJpIHNldGlhcCBrb2xvbS4gYmVyaWt1dCBpbmkgYWRhbGFoIGNpcmktY2lyaSBkYXRhIGZyYW1lOg0KDQrigKIJTmFtYSBrb2xvbSB0aWRhayBib2xlaCBrb3NvbmcNCg0K4oCiCU5hbWEgYmFyaXMgaGFydXMgdW5paw0KDQrigKIJRGF0YSB5YW5nIGRpc2ltcGFuIGRhbGFtIGJpbmdrYWkgZGF0YSBkYXBhdCBiZXJ1cGEgbnVtZXJpaywgZmFrdG9yLCBhdGF1IHRpcGUga2FyYWt0ZXINCg0K4oCiCVNldGlhcCBrb2xvbSBoYXJ1cyBiZXJpc2kganVtbGFoIGl0ZW0gZGF0YSB5YW5nIHNhbWENCg0KQmVyaWt1dCBpbmkgZGlwZXJsaWhhdGthbiBjb250b2ggZGF0YSBmcmFtZSBkZW5nYW4gbWVuZ2d1bmFrYW4gUg0KDQpgYGB7cn0NCmRmMV9SIDwtIGRhdGEuZnJhbWUoa29kZSA9YyAoIDEgOiA1ICksIA0KICAgICAgICAgICAgICAgICAgICAgbmFtYSA9YyAoICIgQnVkaSAiICwgIiBBbmRpICIgLCAiIFNoZXJseSAiICwgIiBEaWFuICIgLCAiIFdvb2R5ICIgKSwgDQogICAgICAgICAgICAgICAgICAgICBnYWppID1jICg3NzYuNyAsICA3MDAuMyAsNjY4LjgsODc2LjYsNzU4LjMgKSAsDQogICAgICAgICAgICBqZW5pc19rZWxhbWluID1jKCJMIiwiTCIsIlAiLCJQIiwiTCIpLA0KICAgICAgICAgICAgICAgICAgICAgdW11ciA9YygyOSwzNSwzMSwyNywzMCksDQogICAgICAgICAgICAgICAgICAgYWxhbWF0ID1jKCJKYWthcnRhIiwiVGFuZ2VyYW5nIiwiRGVwb2siLCJTZXJhbmciLCJEZXBvayIpLA0KICAgICAgICAgICAgICBtdWxhaV9rZXJqYSA9IGFzLkRhdGUoYygiIDIwMTUtMDYtMDggIiAsICIgMjAxNS0wMy0xOCAiICwgIiAyMDE1LTA4LTExICIgLCAiIDIwMTUtMDktMjEiLCAiMjAxNS0xMS0wNCIpKSwgIA0KICAgICAgICAgICAgICAgICAgIGRpdmlzaSA9YyAoICJEUyIgLCAiRFMiICwgIkJBIiAsICJEQSIgLCAiRFMiICkgLCAgc3RyaW5nc0FzRmFjdG9ycyA9IEYgKQ0KcHJpbnQoZGYxX1IpDQpgYGANCg0KDQpgYGB7cn0NCnR5cGVvZiAoIGRmMV9SICkgDQpjbGFzcyAoIGRmMV9SICkNCmRmMV9SWzEsNV0gDQpkZjFfUiRuYW1hDQpkZjFfUiBbLGMoJ25hbWEnLCdqZW5pc19rZWxhbWluJyldDQpkZjFfUiBbIDEgOiA1ICxdDQpkZjFfUiBbICwgMSA6IDUgXQ0KDQoNCnN1YnNldCAoIGRmMV9SICwgc2VsZWN0ID0gNiApIA0Kc3Vic2V0ICggZGYxX1IgLCBzZWxlY3QgPSBjICggNiw3ICkgKSANCnN1YnNldCAoIGRmMV9SICwgc2VsZWN0ID0gYyAoIDIgOiA1ICkgKQ0KDQptaW4oZGYxX1IkZ2FqaSkNCm1heChkZjFfUiRnYWppKQ0KbWVhbihkZjFfUiRnYWppKQ0KDQpzZChkZjFfUiRnYWppKQ0Kc3VtbWFyeShkZjFfUikNCmBgYA0KDQojIEdhbnRpIE5hbWEgVmFyaWFiZWwNCg0KU2FsYWggc2F0dSBoYWwgcGVudGluZyBsYWlubnlhIHlhbmcgZGltaWxpa2kgcHJvc2VzIGRhdGEgc2NpZW5jZSBhZGFsYWggbWVueWltcGFuIGRhdGEga2UgZGFsYW0gdmFyaWFiZWwuIFZhcmlhYmVsIGRhcGF0IGRpaWJhcmF0a2FuIHNlcGVydGkgc2VidWFoIGxhYmVsIHVudHVrIHNlYnVhaCBpbmZvcm1hc2kuIFZhcmlhYmVsIGRhcGF0IGp1Z2EgdGVyZGlyaSBkYXJpIGJlYmVyYXBhIGluZm9ybWFzaS4gU2VyaW5na2FsaSBraXRhIHNlYmFnYWkgZGF0YSBzY2llbnRpc3QgcGVybHUgdW50dWsgbWVuZ2dhbnRpIG5hbWEgdmFyaWFiZWwgdGVydGVudHUgdW50dWsgbWVtdWRhaGthbiBkYWxhbSBtZW5nYW5hbGlzYSBpbmZvcm1hc2kgeWFuZyB0ZXJrYW5kdW5nIHBhZGEgc3VhdHUgZGF0YSB5YW5nIGRpbWlsaWtpLg0KDQpPYmplayBSIGRhcGF0IG1lbWlsaWtpIG5hbWEsIHlhbmcgc2FuZ2F0IGJlcmd1bmEgdW50dWsgbWVudWxpcyBrb2RlIHlhbmcgZGFwYXQgZGliYWNhIGRhbiBvYmplayB5YW5nIG1lbmdnYW1iYXJrYW4gZGlyaW55YSBzZW5kaXJpLiBBbmRhIGFrYW4gbWVtcGVsYWphcmkgY2FyYSBtZW5nZ2FudGkgbmFtYSBrb2xvbSBkYXRhIGZyYW1lIGRpIFIgbWVuZ2d1bmFrYW4gZnVuZ3NpIG5hbWVzKCkuDQoNCmBgYHtyfQ0KcmVuYW1lXzE8LWRmMV9SDQpuYW1lcyhyZW5hbWVfMSk8LWMoIm5vIiwNCiJuYW1hIiwNCiJ0Z2wubGFoaXIiLA0KImplbmlzIGtlbGFtaW4iLA0KInVtdXIiLA0KImFsYW1hdCIsDQoiZ2FqaSIpDQpwcmludChyZW5hbWVfMSkNCg0KYGBgDQoNCg==