├── .gitignore ├── LICENSE ├── README.md ├── algorithm └── linked_list │ └── singly_linked_list.c ├── bak ├── c │ ├── .gitignore │ ├── active_record │ │ ├── Makefile │ │ ├── active_record.c │ │ ├── active_record.h │ │ └── main.c │ ├── person │ │ ├── Makefile │ │ ├── main.c │ │ ├── person.c │ │ └── person.h │ └── pointer │ │ └── main.c ├── concurrency │ ├── README.md │ ├── ab.sh │ ├── app │ │ ├── do1.go │ │ ├── do2.go │ │ ├── do3.go │ │ ├── do4.go │ │ ├── do5.go │ │ └── main.go │ ├── data.json │ └── payload │ │ ├── payload.go │ │ └── payload_test.go ├── go │ ├── .gitignore │ ├── bluemonday │ │ └── main.go │ ├── closure │ │ └── bench001_test.go │ ├── create │ │ └── main.go │ ├── exception │ │ └── main.go │ ├── flag │ │ └── main.go │ ├── gopath │ │ └── main.go │ ├── kagome │ │ └── main.go │ ├── main.go │ ├── mapstructure │ │ └── main.go │ ├── mymysql │ │ ├── glide.lock │ │ ├── glide.yaml │ │ └── main.go │ ├── progress │ │ └── main.go │ ├── regexp │ │ ├── bench001_test.go │ │ └── regexp.go │ ├── sendmail │ │ └── sendmail.go │ ├── time │ │ └── main.go │ ├── unmarshal │ │ └── time.go │ └── xorm │ │ └── main.go ├── php │ └── main.php └── xcode │ ├── Common.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── timeline.xctimeline │ ├── OSX.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ └── contents.xcplayground │ ├── Playground.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── iOS.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ └── contents.xcplayground ├── clojure ├── hello-world │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── doc │ │ └── intro.md │ ├── project.clj │ ├── src │ │ └── hello_world │ │ │ └── core.clj │ └── test │ │ └── hello_world │ │ └── core_test.clj └── myduct │ ├── .gitignore │ ├── README.md │ ├── dev │ ├── resources │ │ └── dev.edn │ └── src │ │ ├── cljs │ │ └── user.cljs │ │ ├── dev.clj │ │ └── user.clj │ ├── project.clj │ ├── resources │ └── myduct │ │ └── system.edn │ ├── src │ └── myduct │ │ ├── endpoint │ │ ├── example.clj │ │ └── hello.clj │ │ └── main.clj │ └── test │ └── myduct │ └── endpoint │ └── example_test.clj ├── crystal ├── fib.cr ├── hello.cr └── server.cr ├── gae ├── go-cloudsql │ ├── app.go │ └── app.yaml └── go-hello │ ├── app.go │ └── app.yaml ├── git └── hooks │ └── pre-receive ├── gke ├── clojure │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── dev │ │ ├── resources │ │ │ └── dev.edn │ │ └── src │ │ │ ├── cljs │ │ │ └── user.cljs │ │ │ ├── dev.clj │ │ │ └── user.clj │ ├── project.clj │ ├── resources │ │ └── myduct │ │ │ └── system.edn │ ├── src │ │ └── myduct │ │ │ ├── endpoint │ │ │ ├── example.clj │ │ │ └── hello.clj │ │ │ └── main.clj │ └── test │ │ └── myduct │ │ └── endpoint │ │ └── example_test.clj └── golang │ ├── Dockerfile │ ├── README.md │ ├── deployment.yaml │ ├── main.go │ └── service.yaml ├── go.mod ├── go.sum ├── go ├── ast │ └── main.go ├── aws │ ├── README.md │ ├── glide.lock │ ├── glide.yaml │ ├── s3 │ │ ├── README.md │ │ └── main.go │ └── sqs │ │ └── main.go ├── benchmark │ ├── benchmark_test.go │ ├── json_test.go │ └── slice_test.go ├── channel │ ├── main.go │ └── sample.go ├── encoding │ └── json │ │ ├── json.go │ │ └── json_test.go ├── enum │ └── main.go ├── github.com │ └── nlopes │ │ └── slack │ │ └── main.go ├── image │ └── jpeg │ │ └── main.go ├── log │ └── main.go ├── math │ └── fast_inverse_sqrt.go ├── net │ ├── http │ │ ├── httptest │ │ │ ├── handler.go │ │ │ └── handler_test.go │ │ ├── server │ │ │ └── main.go │ │ └── timeout-request │ │ │ └── main.go │ └── listen-unixdomainsocket │ │ ├── README.md │ │ ├── main.go │ │ └── nginx.conf ├── os │ ├── csv_reader.go │ ├── stdin_or_pipe.go │ └── test.csv ├── regexp │ └── main.go ├── strings │ └── strings_test.go ├── sync │ └── sync_test.go ├── tail │ └── main.go ├── text │ └── template │ │ └── main.go ├── time │ └── ambiguous_time.go ├── trick │ ├── trick.go │ └── trick_test.go └── worker │ └── main.go ├── numerical-analysis ├── integral │ ├── integral.go │ └── integral_test.go ├── internal │ ├── function.go │ └── function_test.go └── irrational │ ├── example │ └── main.go │ ├── leibniz │ ├── leibniz.go │ └── leibniz_test.go │ ├── pi.go │ └── pi_test.go ├── protobuf ├── Makefile ├── README.md ├── example │ └── main.go ├── user.pb.go └── user.proto ├── rust ├── fizzbuzz │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── hello │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── integral │ ├── .gitignore │ ├── Cargo.toml │ └── src │ └── main.rs └── shuffle ├── example └── main.go └── shuffle.go /.gitignore: -------------------------------------------------------------------------------- 1 | .glide 2 | vendor/ 3 | 4 | # Personal 5 | .envrc 6 | *.orig 7 | *.org 8 | 9 | ### OSX ### 10 | .DS_Store 11 | .AppleDouble 12 | .LSOverride 13 | 14 | # Icon must end with two \r 15 | Icon 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear on external disk 21 | .Spotlight-V100 22 | .Trashes 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | ### Windows ### 32 | # Windows image file caches 33 | Thumbs.db 34 | ehthumbs.db 35 | 36 | # Folder config file 37 | Desktop.ini 38 | 39 | # Recycle Bin used on file shares 40 | $RECYCLE.BIN/ 41 | 42 | # Windows Installer files 43 | *.cab 44 | *.msi 45 | *.msm 46 | *.msp 47 | 48 | # Windows shortcuts 49 | *.lnk 50 | 51 | ### Linux ### 52 | *~ 53 | 54 | # KDE directory preferences 55 | .directory 56 | 57 | ### vim ### 58 | [._]*.s[a-w][a-z] 59 | [._]s[a-w][a-z] 60 | *.un~ 61 | Session.vim 62 | .netrwhist 63 | *~ 64 | 65 | ### Bower ### 66 | bower_components/ 67 | 68 | ### Objective-C ### 69 | # Xcode 70 | # 71 | build/ 72 | *.pbxuser 73 | !default.pbxuser 74 | *.mode1v3 75 | !default.mode1v3 76 | *.mode2v3 77 | !default.mode2v3 78 | *.perspectivev3 79 | !default.perspectivev3 80 | xcuserdata 81 | *.xccheckout 82 | *.moved-aside 83 | DerivedData 84 | *.hmap 85 | *.ipa 86 | *.xcuserstate 87 | 88 | # CocoaPods 89 | # 90 | Pods 91 | Podfile.lock 92 | 93 | # Cartfile 94 | # 95 | Carthage 96 | Cartfile.resolved 97 | 98 | ### OSX ### 99 | .DS_Store 100 | .AppleDouble 101 | .LSOverride 102 | 103 | # Icon must end with two \r 104 | Icon 105 | 106 | # Thumbnails 107 | ._* 108 | 109 | # Files that might appear on external disk 110 | .Spotlight-V100 111 | .Trashes 112 | 113 | # Directories potentially created on remote AFP share 114 | .AppleDB 115 | .AppleDesktop 116 | Network Trash Folder 117 | Temporary Items 118 | .apdisk 119 | 120 | ### AppCode ### 121 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 122 | 123 | ## Directory-based project format 124 | .idea/ 125 | # if you remove the above rule, at least ignore user-specific stuff: 126 | # .idea/workspace.xml 127 | # .idea/tasks.xml 128 | # and these sensitive or high-churn files: 129 | # .idea/dataSources.ids 130 | # .idea/dataSources.xml 131 | # .idea/sqlDataSources.xml 132 | # .idea/dynamic.xml 133 | 134 | ## File-based project format 135 | *.ipr 136 | *.iws 137 | *.iml 138 | 139 | ## Additional for IntelliJ 140 | out/ 141 | 142 | # generated by mpeltonen/sbt-idea plugin 143 | .idea_modules/ 144 | 145 | # generated by JIRA plugin 146 | atlassian-ide-plugin.xml 147 | 148 | # generated by Crashlytics plugin (for Android Studio and Intellij) 149 | com_crashlytics_export_strings.xml 150 | 151 | ### vim ### 152 | [._]*.s[a-w][a-z] 153 | [._]s[a-w][a-z] 154 | *.un~ 155 | Session.vim 156 | .netrwhist 157 | *~ 158 | 159 | ### Emacs ### 160 | # -*- mode: gitignore; -*- 161 | *~ 162 | \#*\# 163 | /.emacs.desktop 164 | /.emacs.desktop.lock 165 | *.elc 166 | auto-save-list 167 | tramp 168 | .\#* 169 | 170 | # Org-mode 171 | .org-id-locations 172 | *_archive 173 | 174 | # flymake-mode 175 | *_flymake.* 176 | 177 | # eshell files 178 | /eshell/history 179 | /eshell/lastdir 180 | 181 | # elpa packages 182 | /elpa/ 183 | 184 | # reftex files 185 | *.rel 186 | 187 | # AUCTeX auto folder 188 | /auto/ 189 | 190 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Shintaro Kaneko 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Playground 2 | 3 | ## License 4 | 5 | [The MIT License (MIT)](http://kaneshin.mit-license.org/) 6 | 7 | ## Author 8 | 9 | [Shintaro Kaneko](https://github.com/kaneshin) 10 | -------------------------------------------------------------------------------- /algorithm/linked_list/singly_linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct node_t 5 | { 6 | struct node_t *prev; 7 | int data; 8 | } node; 9 | 10 | node* 11 | new_node(int data) 12 | { 13 | node *n = (node *)malloc(sizeof(node)); 14 | n->data = data; 15 | return n; 16 | } 17 | 18 | void 19 | free_node(node *n) 20 | { 21 | if (NULL != n) 22 | { 23 | free(n); 24 | n = NULL; 25 | } 26 | } 27 | 28 | node* 29 | append(node *prev, int data) 30 | { 31 | node *next = new_node(data); 32 | next->prev = prev; 33 | return next; 34 | } 35 | 36 | void 37 | delete_if(node *p, int data) 38 | { 39 | node *t = NULL; 40 | while (p) 41 | { 42 | if (p->data != data) 43 | { 44 | p = p->prev; 45 | continue; 46 | } 47 | 48 | 49 | } 50 | } 51 | 52 | int 53 | main(int argc, char* argv[]) 54 | { 55 | node *p = new_node(0); 56 | p = append(p, 1); 57 | p = append(p, 3); 58 | p = append(p, 3); 59 | p = append(p, 3); 60 | p = append(p, 3); 61 | p = append(p, 2); 62 | 63 | while (p) 64 | { 65 | printf("%d\n", p->data); 66 | p = p->prev; 67 | } 68 | 69 | printf("===\n"); 70 | 71 | delete_if(p, 3); 72 | 73 | while (p) 74 | { 75 | printf("%d\n", p->data); 76 | p = p->prev; 77 | } 78 | 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /bak/c/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | *.gcov 34 | *.gcda 35 | *.gcno 36 | -------------------------------------------------------------------------------- /bak/c/active_record/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = \ 2 | active_record.c \ 3 | main.c 4 | 5 | OBJS = $(subst .c,.o,$(SRCS)) 6 | 7 | CFLAGS = 8 | LIBS = 9 | TARGET = a.out 10 | 11 | all : $(TARGET) 12 | 13 | $(TARGET) : $(OBJS) 14 | gcc -o $@ $(OBJS) $(LIBS) 15 | 16 | .c.o : 17 | gcc -c $(CFLAGS) -I. $< -o $@ 18 | 19 | clean : 20 | rm -f *.o $(TARGET) 21 | -------------------------------------------------------------------------------- /bak/c/active_record/active_record.c: -------------------------------------------------------------------------------- 1 | /** 2 | * active_record.h 3 | * 4 | * Copyright (c) 2015 Shintaro Kaneko 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #include "active_record.h" 26 | 27 | #include 28 | #include 29 | 30 | struct internal_session { 31 | char *table; 32 | char *cols; 33 | char *cond; 34 | char buf[256]; 35 | }; 36 | typedef struct internal_session internal_session; 37 | 38 | session* 39 | session_get(session *self, char *table) 40 | { 41 | self->_internal->table = table; 42 | return self; 43 | } 44 | 45 | session* 46 | session_select(session *self, char *cols) 47 | { 48 | self->_internal->cols = cols; 49 | return self; 50 | } 51 | 52 | session* 53 | session_where(session *self, char *cond) 54 | { 55 | self->_internal->cond = cond; 56 | return self; 57 | } 58 | 59 | char* 60 | session_query(session *self) 61 | { 62 | sprintf(self->_internal->buf, "SELECT %s FROM %s WHERE %s", self->_internal->cols, self->_internal->table, self->_internal->cond); 63 | return self->_internal->buf; 64 | } 65 | 66 | session* 67 | new_session() 68 | { 69 | session *sess = (session *)malloc(sizeof(session)); 70 | if (sess == NULL) 71 | return NULL; 72 | 73 | internal_session *internal = (internal_session *)malloc(sizeof(internal_session)); 74 | if (internal == NULL) 75 | { 76 | free(sess); 77 | return NULL; 78 | } 79 | internal->table = NULL; 80 | internal->cols = NULL; 81 | internal->cond = NULL; 82 | sess->_internal = internal; 83 | sess->get = session_get; 84 | sess->select = session_select; 85 | sess->where = session_where; 86 | sess->query = session_query; 87 | return sess; 88 | } 89 | 90 | void 91 | free_session(session *sess) 92 | { 93 | if (sess != NULL) 94 | { 95 | if (sess->_internal != NULL) 96 | free(sess->_internal); 97 | 98 | free(sess); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /bak/c/active_record/active_record.h: -------------------------------------------------------------------------------- 1 | /** 2 | * active_record.h 3 | * 4 | * Copyright (c) 2015 Shintaro Kaneko 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | struct session { 26 | struct internal_session *_internal; 27 | 28 | struct session *(*get)(struct session *, char *); 29 | struct session *(*select)(struct session *, char *); 30 | struct session *(*where)(struct session *, char *); 31 | char *(*query)(struct session *); 32 | }; 33 | typedef struct session session; 34 | 35 | session* new_session(); 36 | void free_session(session *); 37 | -------------------------------------------------------------------------------- /bak/c/active_record/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "active_record.h" 4 | 5 | int 6 | main(int argc, char* argv[]) 7 | { 8 | session *sess = new_session(); 9 | printf("%s\n", sess->select(sess, "id,name")->where(sess, "id = 1")->get(sess, "user")->query(sess)); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /bak/c/person/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = \ 2 | main.c \ 3 | person.c 4 | 5 | OBJS = $(subst .c,.o,$(SRCS)) 6 | 7 | CFLAGS = 8 | LIBS = 9 | TARGET = a.out 10 | 11 | all : $(TARGET) 12 | 13 | $(TARGET) : $(OBJS) 14 | gcc -o $@ $(OBJS) $(LIBS) 15 | 16 | .c.o : 17 | gcc -c $(CFLAGS) -I. $< -o $@ 18 | 19 | clean : 20 | rm -f *.o $(TARGET) 21 | -------------------------------------------------------------------------------- /bak/c/person/main.c: -------------------------------------------------------------------------------- 1 | // File: main.c 2 | // Author: kaneshin 3 | 4 | #include "person.h" 5 | 6 | int 7 | main(int argc, char* argv[]) 8 | { 9 | person *p = new_person(); 10 | p->set_name(p, "kaneshin"); 11 | p->set_gender(p, GENDER_MALE); 12 | p->print(p); 13 | free_person(p); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /bak/c/person/person.c: -------------------------------------------------------------------------------- 1 | // File: person.c 2 | // Author: kaneshin 3 | 4 | #include "person.h" 5 | 6 | #include 7 | #include 8 | 9 | void person_set_name(person *, char *); 10 | void person_set_gender(person *, gender); 11 | void person_print(person *); 12 | 13 | char * 14 | gender_string(gender gen) 15 | { 16 | switch (gen) { 17 | case GENDER_NEUTRAL: 18 | return "Neutral"; 19 | case GENDER_MALE: 20 | return "Male"; 21 | case GENDER_FEMALE: 22 | return "Female"; 23 | case GENDER_UNKNOWN: 24 | return "Unknown"; 25 | } 26 | } 27 | 28 | struct _internal_person { 29 | char *name; 30 | gender gen; 31 | }; 32 | 33 | internal_person* 34 | new_internal_person() 35 | { 36 | internal_person *p = (internal_person *)malloc(sizeof(internal_person)); 37 | if (p == NULL) 38 | return NULL; 39 | 40 | p->name = NULL; 41 | p ->gen = GENDER_UNKNOWN; 42 | return p; 43 | } 44 | 45 | void 46 | free_internal_person(internal_person *p) 47 | { 48 | if (NULL != p) 49 | free(p); 50 | } 51 | 52 | person* 53 | new_person() 54 | { 55 | person *p = (person *)malloc(sizeof(person)); 56 | if (p == NULL) 57 | return NULL; 58 | 59 | internal_person *inter = new_internal_person(); 60 | if (inter == NULL) 61 | { 62 | free(p); 63 | return NULL; 64 | } 65 | 66 | p->_internal = inter; 67 | p->set_name = person_set_name; 68 | p->set_gender = person_set_gender; 69 | p->print = person_print; 70 | return p; 71 | } 72 | 73 | void 74 | free_person(person *p) 75 | { 76 | if (NULL != p->_internal) 77 | free_internal_person(p->_internal); 78 | 79 | if (NULL != p) 80 | free(p); 81 | } 82 | 83 | void 84 | person_set_name(person *self, char *name) 85 | { 86 | self->_internal->name = name; 87 | } 88 | 89 | void 90 | person_set_gender(person *self, gender gen) 91 | { 92 | self->_internal->gen = gen; 93 | } 94 | 95 | void 96 | person_print(person *self) 97 | { 98 | printf("%s %s\n", self->_internal->name, gender_string(self->_internal->gen)); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /bak/c/person/person.h: -------------------------------------------------------------------------------- 1 | // File: person.h 2 | // Author: kaneshin 3 | 4 | // gender 5 | 6 | enum _gender 7 | { 8 | GENDER_NEUTRAL, 9 | GENDER_MALE, 10 | GENDER_FEMALE, 11 | GENDER_UNKNOWN, 12 | }; 13 | typedef enum _gender gender; 14 | 15 | // person 16 | 17 | typedef struct _internal_person internal_person; 18 | 19 | struct _person { 20 | internal_person *_internal; 21 | 22 | void (*set_name)(struct _person *, char *name); 23 | void (*set_gender)(struct _person *, gender gen); 24 | void (*print)(struct _person *); 25 | }; 26 | typedef struct _person person; 27 | 28 | person* new_person(); 29 | void free_person(person *); 30 | -------------------------------------------------------------------------------- /bak/c/pointer/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | add(int *c, int a, int b) 5 | { 6 | printf("a3=%x\n", &a); 7 | printf("b3=%x\n", &b); 8 | printf("c3=%x\n", c); 9 | *c = a + b; 10 | } 11 | 12 | 13 | int 14 | main(int argc, char* argv[]) 15 | { 16 | int a = 0; 17 | int b = 0; 18 | int c = 0; 19 | a = 2; 20 | b = 3; 21 | printf("a1=%x\n", &a); 22 | printf("b1=%x\n", &b); 23 | printf("c1=%x\n", &c); 24 | add(&c, a, b); 25 | printf("%d\n", c); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /bak/concurrency/README.md: -------------------------------------------------------------------------------- 1 | # concurrency-pattern 2 | 3 | ## Run 4 | 5 | ### DO1 6 | 7 | ```shell 8 | go run ./app/main.go ./app/do1.go 2>/dev/null 9 | ``` 10 | 11 | ### DO2 12 | 13 | ```shell 14 | go run ./app/main.go ./app/do2.go 2>/dev/null 15 | ``` 16 | 17 | ### DO3 18 | 19 | ```shell 20 | MAX_QUEUES=1000000 go run ./app/main.go ./app/do3.go 2>/dev/null 21 | ``` 22 | 23 | ### DO4 24 | 25 | ```shell 26 | MAX_WORKERS=100 MAX_QUEUES=1000000 go run ./app/main.go ./app/do4.go 2>/dev/null 27 | ``` 28 | 29 | ## Apache Bench 30 | 31 | ```shell 32 | ./ab.sh 33 | ``` 34 | -------------------------------------------------------------------------------- /bak/concurrency/ab.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ab -n 2000 -c 2000 -p ./data.json -T "application/json; charset=utf-8" "http://localhost:8080/" 3 | -------------------------------------------------------------------------------- /bak/concurrency/app/do1.go: -------------------------------------------------------------------------------- 1 | // +build do1 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | 8 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 9 | ) 10 | 11 | func do(instance payload.Instance) { 12 | body, err := instance.Get() 13 | if err != nil { 14 | log.Println(err) 15 | } else { 16 | log.Printf("Get %s (%d bytes)\n", instance.URL, len(body)) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bak/concurrency/app/do2.go: -------------------------------------------------------------------------------- 1 | // +build do2 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | 8 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 9 | ) 10 | 11 | func do(instance payload.Instance) { 12 | go func() { 13 | body, err := instance.Get() 14 | if err != nil { 15 | log.Println(err) 16 | } else { 17 | log.Printf("Get %s (%d bytes)\n", instance.URL, len(body)) 18 | } 19 | }() 20 | } 21 | -------------------------------------------------------------------------------- /bak/concurrency/app/do3.go: -------------------------------------------------------------------------------- 1 | // +build do3 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | 8 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 9 | ) 10 | 11 | var queue chan payload.Instance 12 | 13 | func start() { 14 | for { 15 | select { 16 | case instance := <-queue: 17 | body, err := instance.Get() 18 | if err != nil { 19 | log.Println(err) 20 | } else { 21 | log.Printf("Get %s (%d bytes)\n", instance.URL, len(body)) 22 | } 23 | } 24 | } 25 | } 26 | 27 | func init() { 28 | queue = make(chan payload.Instance, numMaxQueues()) 29 | go start() 30 | } 31 | 32 | func do(instance payload.Instance) { 33 | queue <- instance 34 | } 35 | -------------------------------------------------------------------------------- /bak/concurrency/app/do4.go: -------------------------------------------------------------------------------- 1 | // +build do4 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | 8 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 9 | ) 10 | 11 | type ( 12 | worker struct { 13 | pool chan chan payload.Instance 14 | ch chan payload.Instance 15 | quit chan bool 16 | } 17 | dispatcher struct { 18 | maxWorkers int 19 | pool chan chan payload.Instance 20 | } 21 | ) 22 | 23 | var ( 24 | queue chan payload.Instance 25 | ) 26 | 27 | func newWorker(pool chan chan payload.Instance) worker { 28 | return worker{ 29 | pool: pool, 30 | ch: make(chan payload.Instance), 31 | quit: make(chan bool), 32 | } 33 | } 34 | 35 | // start method starts the run loop for the worker, listening for a quit channel in 36 | // case we need to stop it 37 | func (w worker) start() { 38 | go func() { 39 | for { 40 | // register the current worker into the worker queue. 41 | w.pool <- w.ch 42 | 43 | select { 44 | case instance := <-w.ch: 45 | body, err := instance.Get() 46 | if err != nil { 47 | log.Println(err) 48 | } else { 49 | log.Printf("Get %s (%d bytes)\n", instance.URL, len(body)) 50 | } 51 | 52 | case <-w.quit: 53 | // we have received a signal to stop 54 | return 55 | } 56 | } 57 | }() 58 | } 59 | 60 | // stop signals the worker to stop listening for work requests. 61 | func (w worker) stop() { 62 | go func() { 63 | w.quit <- true 64 | }() 65 | } 66 | 67 | func newDispatcher(maxWorkers int) *dispatcher { 68 | return &dispatcher{ 69 | maxWorkers: maxWorkers, 70 | pool: make(chan chan payload.Instance, maxWorkers), 71 | } 72 | } 73 | 74 | func (d *dispatcher) run() { 75 | for i := 0; i < d.maxWorkers; i++ { 76 | worker := newWorker(d.pool) 77 | worker.start() 78 | } 79 | go d.dispatch() 80 | } 81 | 82 | func (d *dispatcher) dispatch() { 83 | for { 84 | select { 85 | case instance := <-queue: 86 | // a job request has been received 87 | go func(instance payload.Instance) { 88 | // try to obtain a worker job channel that is available. 89 | // this will block until a worker is idle 90 | ch := <-d.pool 91 | 92 | // dispatch the job to the worker job channel 93 | ch <- instance 94 | }(instance) 95 | } 96 | } 97 | } 98 | 99 | func init() { 100 | queue = make(chan payload.Instance, numMaxQueues()) 101 | dispatcher := newDispatcher(numMaxWorkers()) 102 | dispatcher.run() 103 | } 104 | 105 | func do(instance payload.Instance) { 106 | queue <- instance 107 | } 108 | -------------------------------------------------------------------------------- /bak/concurrency/app/do5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "sync" 6 | "time" 7 | 8 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 9 | ) 10 | 11 | type ( 12 | Dispatcher struct { 13 | pool chan *worker 14 | queue chan interface{} 15 | wg sync.WaitGroup 16 | workers []*worker 17 | quit chan struct{} 18 | } 19 | worker struct { 20 | dispatcher *Dispatcher 21 | wait time.Duration 22 | signal chan struct{} 23 | data chan interface{} 24 | iterator func(interface{}) 25 | quit chan struct{} 26 | } 27 | DispatcherOptions struct { 28 | NumberOfWorkers int 29 | QueueCapacity int 30 | WorkerQueueCapacity int 31 | WorkerWaitDuration time.Duration 32 | Iterator func(interface{}) 33 | } 34 | ) 35 | 36 | func (d *Dispatcher) Add(v interface{}) { 37 | d.wg.Add(1) 38 | d.queue <- v 39 | } 40 | 41 | func (d *Dispatcher) SetIterator(f func(interface{})) { 42 | for _, w := range d.workers { 43 | w.iterator = f 44 | } 45 | } 46 | 47 | func (d *Dispatcher) Start() { 48 | go func() { 49 | for { 50 | select { 51 | case v, ok := <-d.queue: 52 | if !ok { 53 | return 54 | } 55 | 56 | worker := <-d.pool 57 | worker.data <- v 58 | if cap(worker.data) > 1 { 59 | worker.signal <- struct{}{} 60 | } 61 | 62 | case <-d.quit: 63 | return 64 | 65 | } 66 | } 67 | }() 68 | } 69 | 70 | func (d *Dispatcher) Wait() { 71 | d.wg.Wait() 72 | } 73 | 74 | func (d *Dispatcher) Stop(immediately bool) { 75 | if !immediately { 76 | d.Wait() 77 | } 78 | 79 | d.quit <- struct{}{} 80 | for _, w := range d.workers { 81 | w.quit <- struct{}{} 82 | } 83 | } 84 | 85 | func (d *Dispatcher) Destroy(immediately bool) { 86 | d.Stop(immediately) 87 | 88 | close(d.queue) 89 | for _, w := range d.workers { 90 | if w.signal != nil { 91 | close(w.signal) 92 | } 93 | close(w.data) 94 | } 95 | } 96 | 97 | func (w *worker) start() { 98 | 99 | if cap(w.data) > 1 { 100 | go func() { 101 | t := time.AfterFunc(w.wait, func() func() { 102 | var l sync.Mutex 103 | return func() { 104 | l.Lock() 105 | defer l.Unlock() 106 | 107 | count := len(w.data) 108 | if count == 0 { 109 | return 110 | } 111 | 112 | list := make([]interface{}, count) 113 | for i := 0; i < count; i++ { 114 | list[i] = <-w.data 115 | } 116 | if w.iterator != nil { 117 | w.iterator(list) 118 | } 119 | 120 | w.dispatcher.wg.Add(-count) 121 | } 122 | }()) 123 | 124 | if !t.Stop() { 125 | <-t.C 126 | } 127 | for { 128 | w.dispatcher.pool <- w 129 | 130 | select { 131 | case _, ok := <-w.signal: 132 | if !ok { 133 | return 134 | } 135 | if len(w.data) == cap(w.data) { 136 | t.Reset(0) 137 | } else { 138 | t.Reset(w.wait) 139 | } 140 | 141 | case <-w.quit: 142 | return 143 | 144 | } 145 | } 146 | }() 147 | } else { 148 | go func() { 149 | for { 150 | w.dispatcher.pool <- w 151 | 152 | select { 153 | case v, ok := <-w.data: 154 | if !ok { 155 | return 156 | } 157 | 158 | if w.iterator != nil { 159 | w.iterator(v) 160 | } 161 | w.dispatcher.wg.Done() 162 | 163 | case <-w.quit: 164 | return 165 | 166 | } 167 | } 168 | }() 169 | } 170 | } 171 | 172 | func NewDispatcher(opt DispatcherOptions) *Dispatcher { 173 | d := &Dispatcher{ 174 | pool: make(chan *worker, opt.NumberOfWorkers), 175 | queue: make(chan interface{}, opt.QueueCapacity), 176 | quit: make(chan struct{}), 177 | } 178 | for i := 0; i < cap(d.pool); i++ { 179 | w := worker{ 180 | dispatcher: d, 181 | wait: opt.WorkerWaitDuration, 182 | data: make(chan interface{}, opt.WorkerQueueCapacity), 183 | quit: make(chan struct{}), 184 | } 185 | if cap(w.data) > 1 { 186 | w.signal = make(chan struct{}) 187 | } 188 | d.workers = append(d.workers, &w) 189 | w.start() 190 | } 191 | if opt.Iterator != nil { 192 | d.SetIterator(opt.Iterator) 193 | } 194 | return d 195 | } 196 | 197 | var dispatcher *Dispatcher 198 | 199 | func init() { 200 | dispatcher = NewDispatcher(DispatcherOptions{ 201 | NumberOfWorkers: numMaxWorkers(), 202 | QueueCapacity: numMaxQueues(), 203 | WorkerWaitDuration: 1000 * time.Millisecond, 204 | Iterator: func(v interface{}) { 205 | instance, ok := v.(payload.Instance) 206 | if !ok { 207 | return 208 | } 209 | body, err := instance.Get() 210 | if err != nil { 211 | log.Println(err) 212 | } else { 213 | log.Printf("Get %s (%d bytes)\n", instance.URL, len(body)) 214 | } 215 | }, 216 | }) 217 | 218 | dispatcher.Start() 219 | } 220 | 221 | func do(instance payload.Instance) { 222 | dispatcher.Add(instance) 223 | } 224 | -------------------------------------------------------------------------------- /bak/concurrency/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | "os" 8 | "runtime" 9 | "strconv" 10 | "time" 11 | 12 | stats "github.com/fukata/golang-stats-api-handler" 13 | "github.com/kaneshin/playground/go/concurrency-pattern/payload" 14 | ) 15 | 16 | func init() { 17 | go func() { 18 | num := 0 19 | for { 20 | if n := runtime.NumGoroutine(); n != num { 21 | s := stats.GetStats() 22 | fmt.Printf("Stats\n") 23 | fmt.Printf(" |`-GoroutineNum: %v\n", s.GoroutineNum) 24 | fmt.Printf(" |`-Memory: Alloc %v, Mallocs %v, Frees %v\n", 25 | float64(s.MemoryAlloc)/1000.0, float64(s.MemoryMallocs)/1000.0, float64(s.MemoryFrees)/1000.0) 26 | fmt.Printf(" |`-Heap: Alloc %v, Sys %v, Idle %v\n", 27 | float64(s.HeapAlloc)/1000.0, float64(s.HeapSys)/1000.0, float64(s.HeapIdle)/1000.0) 28 | fmt.Printf(" `-GC: Num %v, PerSecond %v, Pause %v\n", s.GcNum, s.GcPerSecond, s.GcPause) 29 | num = n 30 | } 31 | time.Sleep(1000 * time.Millisecond) 32 | } 33 | }() 34 | } 35 | 36 | func main() { 37 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 38 | 39 | if r.Method != "POST" { 40 | w.WriteHeader(http.StatusMethodNotAllowed) 41 | return 42 | } 43 | 44 | // Read the body into a string for json decoding 45 | var collection payload.Collection 46 | if err := json.NewDecoder(r.Body).Decode(&collection); err != nil { 47 | w.Header().Set("Content-Type", "application/json; charset=UTF-8") 48 | w.WriteHeader(http.StatusBadRequest) 49 | w.Write([]byte(err.Error())) 50 | return 51 | } 52 | 53 | for _, instance := range collection.Instances { 54 | do(instance) 55 | } 56 | 57 | w.WriteHeader(http.StatusOK) 58 | }) 59 | 60 | http.ListenAndServe(":8080", nil) 61 | } 62 | 63 | func numMaxQueues() int { 64 | num, _ := strconv.Atoi(os.Getenv("MAX_QUEUES")) 65 | if num == 0 { 66 | num = 1 67 | } 68 | return num 69 | } 70 | 71 | func numMaxWorkers() int { 72 | num, _ := strconv.Atoi(os.Getenv("MAX_WORKERS")) 73 | if num == 0 { 74 | num = 1 75 | } 76 | return num 77 | } 78 | -------------------------------------------------------------------------------- /bak/concurrency/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "token": "foo", 4 | "instances": [{ 5 | "url": "http://placehold.it/350x100" 6 | }, 7 | { 8 | "url": "http://placehold.it/350x200" 9 | }, 10 | { 11 | "url": "http://placehold.it/350x300" 12 | }, 13 | { 14 | "url": "http://placehold.it/350x400" 15 | }, 16 | { 17 | "url": "http://placehold.it/350x500" 18 | }] 19 | } 20 | -------------------------------------------------------------------------------- /bak/concurrency/payload/payload.go: -------------------------------------------------------------------------------- 1 | package payload 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | ) 7 | 8 | // A Collection provides request object. 9 | type Collection struct { 10 | Version string `json:"version"` 11 | Token string `json:"token"` 12 | Instances []Instance `json:"instances"` 13 | } 14 | 15 | // An Instance is. 16 | type Instance struct { 17 | URL string `json:"url"` 18 | } 19 | 20 | // Get gets bytes of URL over request. 21 | func (d Instance) Get() ([]byte, error) { 22 | client := &http.Client{} 23 | 24 | resp, err := client.Get(d.URL) 25 | if err != nil { 26 | return nil, err 27 | } 28 | defer resp.Body.Close() 29 | 30 | return ioutil.ReadAll(resp.Body) 31 | } 32 | -------------------------------------------------------------------------------- /bak/concurrency/payload/payload_test.go: -------------------------------------------------------------------------------- 1 | package payload 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestInstanceGet(t *testing.T) { 12 | assert := assert.New(t) 13 | 14 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 | w.Write([]byte("hello")) 16 | })) 17 | defer server.Close() 18 | 19 | data := Instance{URL: server.URL} 20 | body, err := data.Get() 21 | assert.NoError(err) 22 | assert.Equal("hello", string(body)) 23 | } 24 | -------------------------------------------------------------------------------- /bak/go/.gitignore: -------------------------------------------------------------------------------- 1 | ### Go ### 2 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 3 | *.o 4 | *.a 5 | *.so 6 | 7 | # Folders 8 | _obj 9 | _test 10 | 11 | # Architecture specific extensions/prefixes 12 | *.[568vq] 13 | [568vq].out 14 | 15 | *.cgo1.go 16 | *.cgo2.c 17 | _cgo_defun.c 18 | _cgo_gotypes.go 19 | _cgo_export.* 20 | 21 | _testmain.go 22 | 23 | *.exe 24 | *.test 25 | *.prof 26 | 27 | -------------------------------------------------------------------------------- /bak/go/bluemonday/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/microcosm-cc/bluemonday" 7 | ) 8 | 9 | // main ... 10 | func main() { 11 | p := bluemonday.UGCPolicy() 12 | html := p.Sanitize( 13 | `Google`, 14 | ) 15 | 16 | // Output: 17 | // Google 18 | fmt.Println(html) 19 | } 20 | -------------------------------------------------------------------------------- /bak/go/closure/bench001_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Normal(n int) string { 8 | orz := map[int]string{ 9 | 1: "Golang", 10 | 2: "Clojure", 11 | 3: "Swift", 12 | } 13 | return orz[n] 14 | } 15 | 16 | var Closure = func() func(n int) string { 17 | orz := map[int]string{ 18 | 1: "Golang", 19 | 2: "Clojure", 20 | 3: "Swift", 21 | } 22 | return func(n int) string { 23 | return orz[n] 24 | } 25 | }() 26 | 27 | func BenchmarkNormal(b *testing.B) { 28 | for n := 0; n < b.N; n++ { 29 | _ = Normal(n%3 + 1) 30 | } 31 | } 32 | 33 | func BenchmarkClosure(b *testing.B) { 34 | for n := 0; n < b.N; n++ { 35 | _ = Closure(n%3 + 1) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /bak/go/create/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | pwd, err := os.Getwd() 10 | if err != nil { 11 | fmt.Println(err) 12 | os.Exit(1) 13 | } 14 | fmt.Println(pwd) 15 | } 16 | -------------------------------------------------------------------------------- /bak/go/exception/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/kaneshin/gopack/exception" 6 | ) 7 | 8 | // main ... 9 | func main() { 10 | fmt.Println("Hello world") 11 | 12 | exception.Try(func() { 13 | fmt.Println("There is no problem.") 14 | }).Catch(func(e exception.Exception) { 15 | fmt.Println("Catch exception.") 16 | }).Finally(func() { 17 | fmt.Println("Do finally.") 18 | }) 19 | 20 | exception.Try(func() { 21 | fmt.Println("There is a problem.") 22 | panic("Panic happens.") 23 | }).Catch(func(e exception.Exception) { 24 | fmt.Println("Catch exception.") 25 | }).Finally(func() { 26 | fmt.Println("Do finally.") 27 | }) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /bak/go/flag/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | fmt.Printf("%v\n", os.Args[1:]) 11 | defFoo := flag.String("foo", "", "") 12 | flag.Parse() 13 | fmt.Printf("%v\n", flag.Args()) 14 | fmt.Printf("%s\n", *defFoo) 15 | 16 | flg := flag.NewFlagSet("flag", flag.PanicOnError) 17 | mkFoo := flg.String("foo", "", "") 18 | flg.Parse(os.Args[1:]) 19 | fmt.Printf("%v\n", flg.Args()) 20 | fmt.Printf("%s\n", *mkFoo) 21 | } 22 | -------------------------------------------------------------------------------- /bak/go/gopath/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/build" 6 | "path/filepath" 7 | "reflect" 8 | ) 9 | 10 | func main() { 11 | gopaths := filepath.SplitList(build.Default.GOPATH) 12 | fmt.Println(gopaths[0]) 13 | fmt.Println(reflect.TypeOf(gopaths[0])) 14 | } 15 | -------------------------------------------------------------------------------- /bak/go/kagome/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/ikawaha/kagome" 8 | ) 9 | 10 | // main ... 11 | func main() { 12 | t := kagome.NewTokenizer() 13 | tokens := t.Tokenize("寿司が食べたい。") 14 | for _, token := range tokens { 15 | if token.Class == kagome.DUMMY { 16 | // BOS: Begin Of Sentence, EOS: End Of Sentence. 17 | // fmt.Printf("%s\n", token.Surface) 18 | continue 19 | } 20 | features := strings.Join(token.Features(), ",") 21 | fmt.Printf("%s\t%v\n", token.Surface, features) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /bak/go/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello world") 9 | } 10 | -------------------------------------------------------------------------------- /bak/go/mapstructure/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/davecgh/go-spew/spew" 5 | "github.com/mitchellh/mapstructure" 6 | ) 7 | 8 | type BodyA struct { 9 | AccessToken string `json:"access_token" mapstructure:"access_token"` 10 | Campaign string `json:"campaign"` 11 | } 12 | 13 | type BodyB struct { 14 | Access_Token string `json:"access_token"` 15 | Campaign string `json:"campaign"` 16 | } 17 | 18 | func main() { 19 | spew.Dump(process(&BodyA{})) 20 | spew.Dump(process(&BodyB{})) 21 | } 22 | 23 | func process(b interface{}) interface{} { 24 | config := &mapstructure.DecoderConfig{ 25 | WeaklyTypedInput: true, 26 | Result: b, 27 | } 28 | decoder, err := mapstructure.NewDecoder(config) 29 | if err != nil { 30 | panic(err) 31 | } 32 | query := map[string]interface{}{ 33 | "access_token": "test_token", 34 | "campaign": "test_campaign", 35 | } 36 | if err = decoder.Decode(query); err != nil { 37 | panic(err) 38 | } 39 | return b 40 | } 41 | -------------------------------------------------------------------------------- /bak/go/mymysql/glide.lock: -------------------------------------------------------------------------------- 1 | hash: 58d7455458b07eb248617fc5912c77f8b06891c6abbcbbba17ea68e7cc473d78 2 | updated: 2016-02-22T10:43:21.158755732Z 3 | imports: 4 | - name: github.com/ziutek/mymysql 5 | version: e5d54ebfda3f8a15e7b192b65c2aa10cb4fd7e04 6 | subpackages: 7 | - /godrv 8 | - godrv 9 | - '...' 10 | - mysql 11 | - thrsafe 12 | - native 13 | devImports: [] 14 | -------------------------------------------------------------------------------- /bak/go/mymysql/glide.yaml: -------------------------------------------------------------------------------- 1 | package: . 2 | import: 3 | - package: github.com/ziutek/mymysql 4 | subpackages: 5 | - /godrv 6 | - godrv 7 | - '...' 8 | -------------------------------------------------------------------------------- /bak/go/mymysql/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // Imports. 4 | import ( 5 | "database/sql" 6 | "fmt" 7 | // "github.com/ziutek/mymysql/mysql" 8 | // _ "github.com/ziutek/mymysql/native" // Native engine 9 | // _ "github.com/ziutek/mymysql/thrsafe" // Thread safe engine 10 | ) 11 | 12 | /* 13 | func main() { 14 | db := mysql.New("tcp", "", "127.0.0.1:3306", "dev", "dev", "devel") 15 | err := db.Connect() 16 | if err != nil { 17 | fmt.Println("Open;", err) 18 | } 19 | 20 | sql := "DROP SCHEMA IF EXISTS foo; CREATE SCHEMA IF NOT EXISTS foo;" 21 | _, _, err = db.Query(sql) 22 | if err != nil { 23 | fmt.Println(sql, err) 24 | } 25 | 26 | sql = "USE DATABASE foo;" 27 | _, _, err = db.Query(sql) 28 | if err != nil { 29 | fmt.Println(sql, err) 30 | } 31 | 32 | db.Close() 33 | } 34 | */ 35 | import _ "github.com/ziutek/mymysql/godrv" 36 | 37 | func main() { 38 | db, err := sql.Open("mymysql", "devel/dev/dev") 39 | if err != nil { 40 | fmt.Println("Open;", err) 41 | } 42 | 43 | sql := "DROP SCHEMA IF EXISTS foo; CREATE SCHEMA IF NOT EXISTS foo;" 44 | db.Start(sql) 45 | _, err = db.Exec(sql) 46 | if err != nil { 47 | fmt.Println(sql, err) 48 | } 49 | 50 | sql = "USE DATABASE foo;" 51 | _, err = db.Exec(sql) 52 | if err != nil { 53 | fmt.Println(sql, err) 54 | } 55 | 56 | db.Close() 57 | } 58 | -------------------------------------------------------------------------------- /bak/go/progress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func progress() { 9 | var i int8 = 0 10 | for { 11 | switch i % 4 { 12 | case 0: 13 | fmt.Print("|") 14 | case 1: 15 | fmt.Print("/") 16 | case 2: 17 | fmt.Print("-") 18 | case 3: 19 | fmt.Print("\\") 20 | i = -1 21 | } 22 | i++ 23 | time.Sleep(100 * time.Millisecond) 24 | fmt.Print("\r") 25 | } 26 | } 27 | 28 | func main() { 29 | go progress() 30 | time.Sleep(10 * time.Second) 31 | } 32 | -------------------------------------------------------------------------------- /bak/go/regexp/bench001_test.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | const ( 8 | sample = `こんにちは!こんにちは! 9 | あ し た ー 10 | あ し た - 11 | おお 12 | 13 | oo 14 | 15 | ` 16 | expected = `こんにちは!こんにちは!あしたーあした-おおoo` 17 | ) 18 | 19 | func TestWhitespaceTrim(t *testing.T) { 20 | var ( 21 | result string 22 | ) 23 | 24 | result = "" 25 | result = WhitespaceTrimByStringsFields(sample) 26 | if result != expected { 27 | t.Fatalf("Expected %v, but %v:", expected, result) 28 | } 29 | 30 | result = "" 31 | result = WhitespaceTrimByRegexp(sample) 32 | if result != expected { 33 | t.Fatalf("Expected %v, but %v:", expected, result) 34 | } 35 | } 36 | 37 | func BenchmarkStringsFields(b *testing.B) { 38 | for n := 0; n < b.N; n++ { 39 | WhitespaceTrimByStringsFields(sample) 40 | } 41 | } 42 | 43 | func BenchmarkRegexp(b *testing.B) { 44 | for n := 0; n < b.N; n++ { 45 | WhitespaceTrimByRegexp(sample) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /bak/go/regexp/regexp.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | ) 7 | 8 | var ( 9 | _ = strings.Join 10 | _ = regexp.Compile 11 | 12 | trim = regexp.MustCompile("[\r|\n| | ]") 13 | ) 14 | 15 | func WhitespaceTrimByStringsFields(msg string) string { 16 | return strings.Join(strings.Fields(msg), "") 17 | } 18 | 19 | func WhitespaceTrimByRegexp(msg string) string { 20 | return trim.ReplaceAllString(msg, "") 21 | } 22 | -------------------------------------------------------------------------------- /bak/go/sendmail/sendmail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "github.com/codegangsta/cli" 7 | "log" 8 | "net/mail" 9 | "net/smtp" 10 | "os" 11 | "strings" 12 | ) 13 | 14 | const ( 15 | SmtpUsername = "" 16 | SmtpPassword = "" 17 | SmtpHostName = "smtp.gmail.com" 18 | SmtpHostProtocol = "587" 19 | ) 20 | 21 | type SmtpData struct { 22 | From mail.Address 23 | To mail.Address 24 | Subject string 25 | Body string 26 | } 27 | 28 | func main() { 29 | app := cli.NewApp() 30 | app.Name = "sendmail" 31 | app.Usage = "Send a mail from command line." 32 | app.Version = "0.9.0" 33 | app.Author = "Shintaro Kaneko" 34 | app.Email = "kaneshin0120@gmail.com" 35 | app.Flags = []cli.Flag{ 36 | cli.StringFlag{ 37 | Name: "subject, s", 38 | Usage: "Message subject", 39 | }, 40 | cli.StringFlag{ 41 | Name: "body, b", 42 | Usage: "Message body", 43 | }, 44 | cli.StringFlag{ 45 | Name: "from, f", 46 | Usage: "RFC2047", 47 | }, 48 | cli.StringFlag{ 49 | Name: "to, t", 50 | Usage: "RFC2047", 51 | }, 52 | } 53 | app.Action = action 54 | app.Run(os.Args) 55 | } 56 | 57 | func action(c *cli.Context) { 58 | fm, fmerr := mail.ParseAddress(c.String("from")) 59 | to, toerr := mail.ParseAddress(c.String("to")) 60 | if fmerr != nil { 61 | log.Fatal(fmerr) 62 | os.Exit(1) 63 | } 64 | if toerr != nil { 65 | log.Fatal(toerr) 66 | os.Exit(1) 67 | } 68 | data := SmtpData{ 69 | *fm, 70 | *to, 71 | c.String("subject"), 72 | c.String("body"), 73 | } 74 | if err := data.sendMail(); err != nil { 75 | log.Fatal(err) 76 | os.Exit(1) 77 | } 78 | } 79 | 80 | func (d *SmtpData) sendMail() error { 81 | auth := smtp.PlainAuth( 82 | "", 83 | SmtpUsername, 84 | SmtpPassword, 85 | SmtpHostName, 86 | ) 87 | 88 | header := map[string]string{} 89 | header["From"] = d.From.String() 90 | header["To"] = d.To.String() 91 | header["Subject"] = encodeRFC2047(d.Subject) 92 | header["MIME-Version"] = "1.0" 93 | header["Content-Type"] = "text/plain; charset=\"utf-8\"" 94 | header["Content-Transfer-Encoding"] = "base64" 95 | 96 | message := "" 97 | for k, v := range header { 98 | message += fmt.Sprintf("%s: %s\r\n", k, v) 99 | } 100 | message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(d.Body)) 101 | err := smtp.SendMail( 102 | SmtpHostName+":"+SmtpHostProtocol, 103 | auth, 104 | d.From.Address, 105 | []string{d.To.Address}, 106 | []byte(message), 107 | ) 108 | return err 109 | } 110 | 111 | func encodeRFC2047(str string) string { 112 | addr := mail.Address{str, ""} 113 | return strings.Trim(strings.Trim(addr.String(), " <>"), "\"") 114 | } 115 | -------------------------------------------------------------------------------- /bak/go/time/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | t, err := time.Parse("2006-01-02T15:04:05Z", "2015-04-01T19:35:49Z") 10 | if err != nil { 11 | panic(err) 12 | } 13 | fmt.Println(t) 14 | fmt.Println(t.UnixNano()) 15 | fmt.Println(int64(time.Hour)) 16 | } 17 | -------------------------------------------------------------------------------- /bak/go/unmarshal/time.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | type ExTime struct { 10 | time.Time 11 | } 12 | 13 | func now() ExTime { 14 | return ExTime{time.Now()} 15 | } 16 | 17 | type Transaction struct { 18 | Date1 ExTime `json:"date1"` 19 | Date2 ExTime `json:"date2,integer"` 20 | Date3 ExTime `json:"date3,string"` 21 | } 22 | 23 | func main() { 24 | txn := Transaction{ 25 | Date1: now(), 26 | Date2: now(), 27 | Date3: now(), 28 | } 29 | 30 | out, _ := json.Marshal(txn) 31 | fmt.Println(string(out)) 32 | } 33 | -------------------------------------------------------------------------------- /bak/go/xorm/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-xorm/xorm/" 5 | ) 6 | 7 | func main() { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bak/php/main.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /bak/xcode/Common.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bak/xcode/OSX.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import Cocoa 4 | 5 | var str = "Hello, playground" 6 | -------------------------------------------------------------------------------- /bak/xcode/OSX.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to OSX.playground. 3 | // 4 | -------------------------------------------------------------------------------- /bak/xcode/OSX.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bak/xcode/Playground.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXFileReference section */ 10 | 79FF084A1B02ED28000D3BE5 /* OSX.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = OSX.playground; sourceTree = ""; }; 11 | 79FF084B1B02ED35000D3BE5 /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = ""; }; 12 | 79FF084C1B02ED59000D3BE5 /* Common.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Common.playground; sourceTree = ""; }; 13 | /* End PBXFileReference section */ 14 | 15 | /* Begin PBXGroup section */ 16 | 793696BF1AFB5DF50009362C = { 17 | isa = PBXGroup; 18 | children = ( 19 | 79FF084C1B02ED59000D3BE5 /* Common.playground */, 20 | 79FF084B1B02ED35000D3BE5 /* iOS.playground */, 21 | 79FF084A1B02ED28000D3BE5 /* OSX.playground */, 22 | ); 23 | sourceTree = ""; 24 | }; 25 | /* End PBXGroup section */ 26 | 27 | /* Begin PBXProject section */ 28 | 793696C01AFB5DF50009362C /* Project object */ = { 29 | isa = PBXProject; 30 | attributes = { 31 | LastUpgradeCheck = 0630; 32 | }; 33 | buildConfigurationList = 793696C31AFB5DF50009362C /* Build configuration list for PBXProject "Playground" */; 34 | compatibilityVersion = "Xcode 3.2"; 35 | developmentRegion = English; 36 | hasScannedForEncodings = 0; 37 | knownRegions = ( 38 | en, 39 | ); 40 | mainGroup = 793696BF1AFB5DF50009362C; 41 | projectDirPath = ""; 42 | projectRoot = ""; 43 | targets = ( 44 | ); 45 | }; 46 | /* End PBXProject section */ 47 | 48 | /* Begin XCBuildConfiguration section */ 49 | 793696C41AFB5DF50009362C /* Debug */ = { 50 | isa = XCBuildConfiguration; 51 | buildSettings = { 52 | }; 53 | name = Debug; 54 | }; 55 | 793696C51AFB5DF50009362C /* Release */ = { 56 | isa = XCBuildConfiguration; 57 | buildSettings = { 58 | }; 59 | name = Release; 60 | }; 61 | /* End XCBuildConfiguration section */ 62 | 63 | /* Begin XCConfigurationList section */ 64 | 793696C31AFB5DF50009362C /* Build configuration list for PBXProject "Playground" */ = { 65 | isa = XCConfigurationList; 66 | buildConfigurations = ( 67 | 793696C41AFB5DF50009362C /* Debug */, 68 | 793696C51AFB5DF50009362C /* Release */, 69 | ); 70 | defaultConfigurationIsVisible = 0; 71 | defaultConfigurationName = Release; 72 | }; 73 | /* End XCConfigurationList section */ 74 | }; 75 | rootObject = 793696C01AFB5DF50009362C /* Project object */; 76 | } 77 | -------------------------------------------------------------------------------- /bak/xcode/Playground.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /bak/xcode/iOS.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | -------------------------------------------------------------------------------- /bak/xcode/iOS.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to iOS.playground. 3 | // 4 | -------------------------------------------------------------------------------- /bak/xcode/iOS.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /clojure/hello-world/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /clojure/hello-world/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - 2016-12-17 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - 2016-12-17 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://github.com/your-name/hello-world/compare/0.1.1...HEAD 24 | [0.1.1]: https://github.com/your-name/hello-world/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /clojure/hello-world/LICENSE: -------------------------------------------------------------------------------- 1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 4 | 5 | 1. DEFINITIONS 6 | 7 | "Contribution" means: 8 | 9 | a) in the case of the initial Contributor, the initial code and 10 | documentation distributed under this Agreement, and 11 | 12 | b) in the case of each subsequent Contributor: 13 | 14 | i) changes to the Program, and 15 | 16 | ii) additions to the Program; 17 | 18 | where such changes and/or additions to the Program originate from and are 19 | distributed by that particular Contributor. A Contribution 'originates' from 20 | a Contributor if it was added to the Program by such Contributor itself or 21 | anyone acting on such Contributor's behalf. Contributions do not include 22 | additions to the Program which: (i) are separate modules of software 23 | distributed in conjunction with the Program under their own license 24 | agreement, and (ii) are not derivative works of the Program. 25 | 26 | "Contributor" means any person or entity that distributes the Program. 27 | 28 | "Licensed Patents" mean patent claims licensable by a Contributor which are 29 | necessarily infringed by the use or sale of its Contribution alone or when 30 | combined with the Program. 31 | 32 | "Program" means the Contributions distributed in accordance with this 33 | Agreement. 34 | 35 | "Recipient" means anyone who receives the Program under this Agreement, 36 | including all Contributors. 37 | 38 | 2. GRANT OF RIGHTS 39 | 40 | a) Subject to the terms of this Agreement, each Contributor hereby grants 41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 42 | reproduce, prepare derivative works of, publicly display, publicly perform, 43 | distribute and sublicense the Contribution of such Contributor, if any, and 44 | such derivative works, in source code and object code form. 45 | 46 | b) Subject to the terms of this Agreement, each Contributor hereby grants 47 | Recipient a non-exclusive, worldwide, royalty-free patent license under 48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 49 | transfer the Contribution of such Contributor, if any, in source code and 50 | object code form. This patent license shall apply to the combination of the 51 | Contribution and the Program if, at the time the Contribution is added by the 52 | Contributor, such addition of the Contribution causes such combination to be 53 | covered by the Licensed Patents. The patent license shall not apply to any 54 | other combinations which include the Contribution. No hardware per se is 55 | licensed hereunder. 56 | 57 | c) Recipient understands that although each Contributor grants the licenses 58 | to its Contributions set forth herein, no assurances are provided by any 59 | Contributor that the Program does not infringe the patent or other 60 | intellectual property rights of any other entity. Each Contributor disclaims 61 | any liability to Recipient for claims brought by any other entity based on 62 | infringement of intellectual property rights or otherwise. As a condition to 63 | exercising the rights and licenses granted hereunder, each Recipient hereby 64 | assumes sole responsibility to secure any other intellectual property rights 65 | needed, if any. For example, if a third party patent license is required to 66 | allow Recipient to distribute the Program, it is Recipient's responsibility 67 | to acquire that license before distributing the Program. 68 | 69 | d) Each Contributor represents that to its knowledge it has sufficient 70 | copyright rights in its Contribution, if any, to grant the copyright license 71 | set forth in this Agreement. 72 | 73 | 3. REQUIREMENTS 74 | 75 | A Contributor may choose to distribute the Program in object code form under 76 | its own license agreement, provided that: 77 | 78 | a) it complies with the terms and conditions of this Agreement; and 79 | 80 | b) its license agreement: 81 | 82 | i) effectively disclaims on behalf of all Contributors all warranties and 83 | conditions, express and implied, including warranties or conditions of title 84 | and non-infringement, and implied warranties or conditions of merchantability 85 | and fitness for a particular purpose; 86 | 87 | ii) effectively excludes on behalf of all Contributors all liability for 88 | damages, including direct, indirect, special, incidental and consequential 89 | damages, such as lost profits; 90 | 91 | iii) states that any provisions which differ from this Agreement are offered 92 | by that Contributor alone and not by any other party; and 93 | 94 | iv) states that source code for the Program is available from such 95 | Contributor, and informs licensees how to obtain it in a reasonable manner on 96 | or through a medium customarily used for software exchange. 97 | 98 | When the Program is made available in source code form: 99 | 100 | a) it must be made available under this Agreement; and 101 | 102 | b) a copy of this Agreement must be included with each copy of the Program. 103 | 104 | Contributors may not remove or alter any copyright notices contained within 105 | the Program. 106 | 107 | Each Contributor must identify itself as the originator of its Contribution, 108 | if any, in a manner that reasonably allows subsequent Recipients to identify 109 | the originator of the Contribution. 110 | 111 | 4. COMMERCIAL DISTRIBUTION 112 | 113 | Commercial distributors of software may accept certain responsibilities with 114 | respect to end users, business partners and the like. While this license is 115 | intended to facilitate the commercial use of the Program, the Contributor who 116 | includes the Program in a commercial product offering should do so in a 117 | manner which does not create potential liability for other Contributors. 118 | Therefore, if a Contributor includes the Program in a commercial product 119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend 120 | and indemnify every other Contributor ("Indemnified Contributor") against any 121 | losses, damages and costs (collectively "Losses") arising from claims, 122 | lawsuits and other legal actions brought by a third party against the 123 | Indemnified Contributor to the extent caused by the acts or omissions of such 124 | Commercial Contributor in connection with its distribution of the Program in 125 | a commercial product offering. The obligations in this section do not apply 126 | to any claims or Losses relating to any actual or alleged intellectual 127 | property infringement. In order to qualify, an Indemnified Contributor must: 128 | a) promptly notify the Commercial Contributor in writing of such claim, and 129 | b) allow the Commercial Contributor to control, and cooperate with the 130 | Commercial Contributor in, the defense and any related settlement 131 | negotiations. The Indemnified Contributor may participate in any such claim 132 | at its own expense. 133 | 134 | For example, a Contributor might include the Program in a commercial product 135 | offering, Product X. That Contributor is then a Commercial Contributor. If 136 | that Commercial Contributor then makes performance claims, or offers 137 | warranties related to Product X, those performance claims and warranties are 138 | such Commercial Contributor's responsibility alone. Under this section, the 139 | Commercial Contributor would have to defend claims against the other 140 | Contributors related to those performance claims and warranties, and if a 141 | court requires any other Contributor to pay any damages as a result, the 142 | Commercial Contributor must pay those damages. 143 | 144 | 5. NO WARRANTY 145 | 146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON 147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the 151 | appropriateness of using and distributing the Program and assumes all risks 152 | associated with its exercise of rights under this Agreement , including but 153 | not limited to the risks and costs of program errors, compliance with 154 | applicable laws, damage to or loss of data, programs or equipment, and 155 | unavailability or interruption of operations. 156 | 157 | 6. DISCLAIMER OF LIABILITY 158 | 159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 166 | OF SUCH DAMAGES. 167 | 168 | 7. GENERAL 169 | 170 | If any provision of this Agreement is invalid or unenforceable under 171 | applicable law, it shall not affect the validity or enforceability of the 172 | remainder of the terms of this Agreement, and without further action by the 173 | parties hereto, such provision shall be reformed to the minimum extent 174 | necessary to make such provision valid and enforceable. 175 | 176 | If Recipient institutes patent litigation against any entity (including a 177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 178 | (excluding combinations of the Program with other software or hardware) 179 | infringes such Recipient's patent(s), then such Recipient's rights granted 180 | under Section 2(b) shall terminate as of the date such litigation is filed. 181 | 182 | All Recipient's rights under this Agreement shall terminate if it fails to 183 | comply with any of the material terms or conditions of this Agreement and 184 | does not cure such failure in a reasonable period of time after becoming 185 | aware of such noncompliance. If all Recipient's rights under this Agreement 186 | terminate, Recipient agrees to cease use and distribution of the Program as 187 | soon as reasonably practicable. However, Recipient's obligations under this 188 | Agreement and any licenses granted by Recipient relating to the Program shall 189 | continue and survive. 190 | 191 | Everyone is permitted to copy and distribute copies of this Agreement, but in 192 | order to avoid inconsistency the Agreement is copyrighted and may only be 193 | modified in the following manner. The Agreement Steward reserves the right to 194 | publish new versions (including revisions) of this Agreement from time to 195 | time. No one other than the Agreement Steward has the right to modify this 196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 197 | Eclipse Foundation may assign the responsibility to serve as the Agreement 198 | Steward to a suitable separate entity. Each new version of the Agreement will 199 | be given a distinguishing version number. The Program (including 200 | Contributions) may always be distributed subject to the version of the 201 | Agreement under which it was received. In addition, after a new version of 202 | the Agreement is published, Contributor may elect to distribute the Program 203 | (including its Contributions) under the new version. Except as expressly 204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 205 | licenses to the intellectual property of any Contributor under this 206 | Agreement, whether expressly, by implication, estoppel or otherwise. All 207 | rights in the Program not expressly granted under this Agreement are 208 | reserved. 209 | 210 | This Agreement is governed by the laws of the State of New York and the 211 | intellectual property laws of the United States of America. No party to this 212 | Agreement will bring a legal action under this Agreement more than one year 213 | after the cause of action arose. Each party waives its rights to a jury trial 214 | in any resulting litigation. 215 | -------------------------------------------------------------------------------- /clojure/hello-world/README.md: -------------------------------------------------------------------------------- 1 | # hello-world 2 | 3 | FIXME: description 4 | 5 | ## Installation 6 | 7 | Download from http://example.com/FIXME. 8 | 9 | ## Usage 10 | 11 | FIXME: explanation 12 | 13 | $ java -jar hello-world-0.1.0-standalone.jar [args] 14 | 15 | ## Options 16 | 17 | FIXME: listing of options this app accepts. 18 | 19 | ## Examples 20 | 21 | ... 22 | 23 | ### Bugs 24 | 25 | ... 26 | 27 | ### Any Other Sections 28 | ### That You Think 29 | ### Might be Useful 30 | 31 | ## License 32 | 33 | Copyright © 2016 FIXME 34 | 35 | Distributed under the Eclipse Public License either version 1.0 or (at 36 | your option) any later version. 37 | -------------------------------------------------------------------------------- /clojure/hello-world/doc/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction to hello-world 2 | 3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) 4 | -------------------------------------------------------------------------------- /clojure/hello-world/project.clj: -------------------------------------------------------------------------------- 1 | (defproject hello-world "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]] 7 | :main ^:skip-aot hello-world.core 8 | :target-path "target/%s" 9 | :profiles {:uberjar {:aot :all}}) 10 | -------------------------------------------------------------------------------- /clojure/hello-world/src/hello_world/core.clj: -------------------------------------------------------------------------------- 1 | (ns hello-world.core 2 | (:gen-class)) 3 | 4 | (defn -main 5 | "I don't do a whole lot ... yet." 6 | [& args] 7 | (println "Hello, World!")) 8 | -------------------------------------------------------------------------------- /clojure/hello-world/test/hello_world/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns hello-world.core-test 2 | (:require [clojure.test :refer :all] 3 | [hello-world.core :refer :all])) 4 | 5 | (deftest a-test 6 | (testing "FIXME, I fail." 7 | (is (= 0 1)))) 8 | -------------------------------------------------------------------------------- /clojure/myduct/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /.dir-locals.el 11 | /profiles.clj 12 | /dev/resources/local.edn 13 | /dev/src/local.clj 14 | -------------------------------------------------------------------------------- /clojure/myduct/README.md: -------------------------------------------------------------------------------- 1 | # myduct 2 | 3 | FIXME: description 4 | 5 | ## Developing 6 | 7 | ### Setup 8 | 9 | When you first clone this repository, run: 10 | 11 | ```sh 12 | lein setup 13 | ``` 14 | 15 | This will create files for local configuration, and prep your system 16 | for the project. 17 | 18 | ### Environment 19 | 20 | To begin developing, start with a REPL. 21 | 22 | ```sh 23 | lein repl 24 | ``` 25 | 26 | Then load the development environment. 27 | 28 | ```clojure 29 | user=> (dev) 30 | :loaded 31 | ``` 32 | 33 | Run `go` to initiate and start the system. 34 | 35 | ```clojure 36 | dev=> (go) 37 | :started 38 | ``` 39 | 40 | By default this creates a web server at . 41 | 42 | When you make changes to your source files, use `reset` to reload any 43 | modified files and reset the server. Changes to CSS or ClojureScript 44 | files will be hot-loaded into the browser. 45 | 46 | ```clojure 47 | dev=> (reset) 48 | :reloading (...) 49 | :resumed 50 | ``` 51 | 52 | If you want to access a ClojureScript REPL, make sure that the site is loaded 53 | in a browser and run: 54 | 55 | ```clojure 56 | dev=> (cljs-repl) 57 | Waiting for browser connection... Connected. 58 | To quit, type: :cljs/quit 59 | nil 60 | cljs.user=> 61 | ``` 62 | 63 | ### Testing 64 | 65 | Testing is fastest through the REPL, as you avoid environment startup 66 | time. 67 | 68 | ```clojure 69 | dev=> (test) 70 | ... 71 | ``` 72 | 73 | But you can also run tests through Leiningen. 74 | 75 | ```sh 76 | lein test 77 | ``` 78 | 79 | ### Generators 80 | 81 | This project has several generator functions to help you create files. 82 | 83 | To create a new endpoint: 84 | 85 | ```clojure 86 | dev=> (gen/endpoint "bar") 87 | Creating file src/foo/endpoint/bar.clj 88 | Creating file test/foo/endpoint/bar_test.clj 89 | Creating directory resources/foo/endpoint/bar 90 | nil 91 | ``` 92 | 93 | To create a new component: 94 | 95 | ```clojure 96 | dev=> (gen/component "baz") 97 | Creating file src/foo/component/baz.clj 98 | Creating file test/foo/component/baz_test.clj 99 | nil 100 | ``` 101 | 102 | To create a new boundary: 103 | 104 | ```clojure 105 | dev=> (gen/boundary "quz" foo.component.baz.Baz) 106 | Creating file src/foo/boundary/quz.clj 107 | Creating file test/foo/boundary/quz_test.clj 108 | nil 109 | ``` 110 | 111 | ## Deploying 112 | 113 | FIXME: steps to deploy 114 | 115 | ## Legal 116 | 117 | Copyright © 2016 FIXME 118 | -------------------------------------------------------------------------------- /clojure/myduct/dev/resources/dev.edn: -------------------------------------------------------------------------------- 1 | {:components 2 | {:figwheel #var duct.component.figwheel/server} 3 | :config 4 | {:app 5 | {:middleware 6 | {:functions {:stacktrace #var ring.middleware.stacktrace/wrap-stacktrace} 7 | :applied ^:replace [:not-found :ring-defaults :stacktrace]}} 8 | :http 9 | {:port 3000} 10 | :figwheel 11 | {:css-dirs ["resources/myduct/public/css"] 12 | :builds 13 | [{:id "dev" 14 | :source-paths ["src" "dev"] 15 | :build-options 16 | {:optimizations :none 17 | :main "cljs.user" 18 | :asset-path "/js" 19 | :output-to "target/figwheel/myduct/public/js/main.js" 20 | :output-dir "target/figwheel/myduct/public/js" 21 | :source-map true 22 | :source-map-path "/js"}}]}}} 23 | -------------------------------------------------------------------------------- /clojure/myduct/dev/src/cljs/user.cljs: -------------------------------------------------------------------------------- 1 | (ns cljs.user 2 | (:require [devtools.core :as devtools] 3 | [figwheel.client :as figwheel])) 4 | 5 | (js/console.info "Starting in development mode") 6 | 7 | (enable-console-print!) 8 | 9 | (devtools/install!) 10 | 11 | (figwheel/start {:websocket-url "ws://localhost:3449/figwheel-ws"}) 12 | 13 | (defn log [& args] 14 | (.apply js/console.log js/console (apply array args))) 15 | -------------------------------------------------------------------------------- /clojure/myduct/dev/src/dev.clj: -------------------------------------------------------------------------------- 1 | (ns dev 2 | (:refer-clojure :exclude [test]) 3 | (:require [clojure.repl :refer :all] 4 | [clojure.pprint :refer [pprint]] 5 | [clojure.tools.namespace.repl :refer [refresh]] 6 | [clojure.java.io :as io] 7 | [com.stuartsierra.component :as component] 8 | [duct.generate :as gen] 9 | [duct.util.repl :refer [setup test cljs-repl migrate rollback]] 10 | [duct.util.system :refer [load-system]] 11 | [reloaded.repl :refer [system init start stop go reset]])) 12 | 13 | (defn new-system [] 14 | (load-system (keep io/resource ["myduct/system.edn" "dev.edn" "local.edn"]))) 15 | 16 | (when (io/resource "local.clj") 17 | (load "local")) 18 | 19 | (gen/set-ns-prefix 'myduct) 20 | 21 | (reloaded.repl/set-init! new-system) 22 | -------------------------------------------------------------------------------- /clojure/myduct/dev/src/user.clj: -------------------------------------------------------------------------------- 1 | (ns user) 2 | 3 | (defn dev 4 | "Load and switch to the 'dev' namespace." 5 | [] 6 | (require 'dev) 7 | (in-ns 'dev) 8 | :loaded) 9 | -------------------------------------------------------------------------------- /clojure/myduct/project.clj: -------------------------------------------------------------------------------- 1 | (defproject myduct "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :min-lein-version "2.0.0" 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [org.clojure/clojurescript "1.8.51"] 7 | [com.stuartsierra/component "0.3.1"] 8 | [compojure "1.5.1"] 9 | [duct "0.8.2"] 10 | [environ "1.1.0"] 11 | [ring "1.5.0"] 12 | [ring/ring-defaults "0.2.1"] 13 | [ring-jetty-component "0.3.1"]] 14 | :plugins [[lein-environ "1.0.3"] 15 | [lein-cljsbuild "1.1.2"]] 16 | :main ^:skip-aot myduct.main 17 | :target-path "target/%s/" 18 | :resource-paths ["resources" "target/cljsbuild"] 19 | :prep-tasks [["javac"] ["cljsbuild" "once"] ["compile"]] 20 | :cljsbuild 21 | {:builds 22 | [{:id "main" 23 | :jar true 24 | :source-paths ["src"] 25 | :compiler 26 | {:output-to "target/cljsbuild/myduct/public/js/main.js" 27 | :optimizations :advanced}}]} 28 | :aliases {"setup" ["run" "-m" "duct.util.repl/setup"]} 29 | :profiles 30 | {:dev [:project/dev :profiles/dev] 31 | :test [:project/test :profiles/test] 32 | :repl {:resource-paths ^:replace ["resources" "dev/resources" "target/figwheel"] 33 | :prep-tasks ^:replace [["javac"] ["compile"]]} 34 | :uberjar {:aot :all} 35 | :profiles/dev {} 36 | :profiles/test {} 37 | :project/dev {:dependencies [[duct/generate "0.8.2"] 38 | [reloaded.repl "0.2.3"] 39 | [org.clojure/tools.namespace "0.2.11"] 40 | [org.clojure/tools.nrepl "0.2.12"] 41 | [eftest "0.1.1"] 42 | [com.gearswithingears/shrubbery "0.4.1"] 43 | [kerodon "0.8.0"] 44 | [binaryage/devtools "0.8.2"] 45 | [com.cemerick/piggieback "0.2.1"] 46 | [duct/figwheel-component "0.3.3"] 47 | [figwheel "0.5.8"]] 48 | :source-paths ["dev/src"] 49 | :resource-paths ["dev/resources"] 50 | :repl-options {:init-ns user 51 | :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} 52 | :env {:port "3000"}} 53 | :project/test {}}) 54 | -------------------------------------------------------------------------------- /clojure/myduct/resources/myduct/system.edn: -------------------------------------------------------------------------------- 1 | {:components 2 | {:app #var duct.component.handler/handler-component 3 | :http #var ring.component.jetty/jetty-server} 4 | :endpoints 5 | {:example #var myduct.endpoint.example/example-endpoint 6 | :hello #var myduct.endpoint.hello/hello-endpoint} 7 | :dependencies 8 | {:http [:app] 9 | :app [:example :hello] 10 | :example []} 11 | :config 12 | {:app 13 | {:middleware 14 | {:functions 15 | {:hide-errors #var duct.middleware.errors/wrap-hide-errors 16 | :not-found #var duct.middleware.not-found/wrap-not-found 17 | :ring-defaults #var ring.middleware.defaults/wrap-defaults} 18 | :applied 19 | [:not-found :ring-defaults :hide-errors] 20 | :arguments 21 | {:not-found "Resource Not Found" 22 | :hide-errors "Internal Server Error" 23 | :ring-defaults 24 | {:params {:urlencoded true 25 | :keywordize true} 26 | :responses {:not-modified-responses true 27 | :absolute-redirects true 28 | :content-types true 29 | :default-charset "utf-8"}}}}} 30 | :http 31 | {:port http-port}}} 32 | -------------------------------------------------------------------------------- /clojure/myduct/src/myduct/endpoint/example.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.example 2 | (:require [compojure.core :refer :all])) 3 | 4 | (defn example-endpoint [config] 5 | (context "/example" [] 6 | (GET "/" [] 7 | "This is an example endpoint"))) 8 | -------------------------------------------------------------------------------- /clojure/myduct/src/myduct/endpoint/hello.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.hello 2 | (:require [compojure.core :refer :all])) 3 | 4 | (defn hello-endpoint [config] 5 | (context "/hello" [] 6 | (GET "/" [] 7 | "Hello, World!"))) 8 | -------------------------------------------------------------------------------- /clojure/myduct/src/myduct/main.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.main 2 | (:gen-class) 3 | (:require [com.stuartsierra.component :as component] 4 | [duct.util.runtime :refer [add-shutdown-hook]] 5 | [duct.util.system :refer [load-system]] 6 | [environ.core :refer [env]] 7 | [clojure.java.io :as io])) 8 | 9 | (defn -main [& args] 10 | (let [bindings {'http-port (Integer/parseInt (:port env "3000"))} 11 | system (->> (load-system [(io/resource "myduct/system.edn")] bindings) 12 | (component/start))] 13 | (add-shutdown-hook ::stop-system #(component/stop system)) 14 | (println "Started HTTP server on port" (-> system :http :port)))) 15 | -------------------------------------------------------------------------------- /clojure/myduct/test/myduct/endpoint/example_test.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.example-test 2 | (:require [com.stuartsierra.component :as component] 3 | [clojure.test :refer :all] 4 | [kerodon.core :refer :all] 5 | [kerodon.test :refer :all] 6 | [shrubbery.core :as shrub] 7 | [myduct.endpoint.example :as example])) 8 | 9 | (def handler 10 | (example/example-endpoint {})) 11 | 12 | (deftest smoke-test 13 | (testing "example page exists" 14 | (-> (session handler) 15 | (visit "/example") 16 | (has (status? 200) "page exists")))) 17 | -------------------------------------------------------------------------------- /crystal/fib.cr: -------------------------------------------------------------------------------- 1 | # fib.cr 2 | def fib(n) 3 | if n <= 1 4 | 1 5 | else 6 | fib(n - 1) + fib(n - 2) 7 | end 8 | end 9 | 10 | time = Time.now 11 | puts fib(42) 12 | puts Time.now - time 13 | -------------------------------------------------------------------------------- /crystal/hello.cr: -------------------------------------------------------------------------------- 1 | puts "hello world" 2 | -------------------------------------------------------------------------------- /crystal/server.cr: -------------------------------------------------------------------------------- 1 | require "http/server" 2 | 3 | server = HTTP::Server.new(8080) do |context| 4 | context.response.content_type = "text/plain" 5 | context.response.print "Hello world! The time is #{Time.now}" 6 | end 7 | 8 | puts "Listening on http://0.0.0.0:8080" 9 | server.listen 10 | -------------------------------------------------------------------------------- /gae/go-cloudsql/app.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "net/http" 7 | "os" 8 | 9 | _ "github.com/go-sql-driver/mysql" 10 | "google.golang.org/appengine" 11 | "google.golang.org/appengine/log" 12 | ) 13 | 14 | const dbName = "sample_db" 15 | 16 | var db *sql.DB 17 | 18 | func init() { 19 | user := os.Getenv("CLOUDSQL_USER") 20 | password := os.Getenv("CLOUDSQL_PASSWORD") 21 | connectionName := os.Getenv("CLOUDSQL_CONNECTION_NAME") 22 | 23 | var err error 24 | db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@cloudsql(%s)/", user, password, connectionName)) 25 | if err != nil { 26 | panic(err) 27 | } 28 | } 29 | 30 | func init() { 31 | _, err := db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName)) 32 | if err != nil { 33 | panic(err) 34 | } 35 | } 36 | 37 | func init() { 38 | _, err := db.Exec(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.user (%s, %s, %s)", 39 | dbName, 40 | `id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY`, 41 | `first_name VARCHAR(30) NOT NULL`, 42 | `last_name VARCHAR(30) NOT NULL`, 43 | )) 44 | if err != nil { 45 | panic(err) 46 | } 47 | } 48 | 49 | func init() { 50 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 51 | ctx := appengine.NewContext(r) 52 | 53 | switch r.Method { 54 | case http.MethodGet: 55 | rows, err := db.Query(fmt.Sprintf("SELECT first_name, last_name FROM %s.user", dbName)) 56 | if err != nil { 57 | log.Errorf(ctx, "db.Query: %v", err) 58 | return 59 | } 60 | defer rows.Close() 61 | 62 | for rows.Next() { 63 | var firstName, lastName string 64 | if err := rows.Scan(&firstName, &lastName); err != nil { 65 | log.Errorf(ctx, "rows.Scan: %v", err) 66 | continue 67 | } 68 | log.Infof(ctx, "First: %v - Last: %v", firstName, lastName) 69 | } 70 | if err := rows.Err(); err != nil { 71 | log.Errorf(ctx, "Row error: %v", err) 72 | } 73 | 74 | case http.MethodPost: 75 | r.ParseForm() 76 | firstName := r.PostForm.Get("first_name") 77 | lastName := r.PostForm.Get("last_name") 78 | 79 | _, err := db.Exec(fmt.Sprintf("INSERT INTO %s.user (first_name, last_name) VALUES (?, ?)", dbName), firstName, lastName) 80 | if err != nil { 81 | log.Errorf(ctx, "db.Query: %v", err) 82 | return 83 | } 84 | 85 | } 86 | }) 87 | } 88 | -------------------------------------------------------------------------------- /gae/go-cloudsql/app.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | runtime: go 3 | api_version: go1 4 | 5 | env_variables: 6 | CLOUDSQL_CONNECTION_NAME: 'project:region:instance' 7 | CLOUDSQL_USER: 'root' 8 | CLOUDSQL_PASSWORD: '' 9 | 10 | handlers: 11 | - url: /.* 12 | script: _go_app 13 | -------------------------------------------------------------------------------- /gae/go-hello/app.go: -------------------------------------------------------------------------------- 1 | package hello 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | func init() { 8 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 9 | switch r.Method { 10 | case http.MethodGet: 11 | w.Write([]byte("Hello, world!")) 12 | 13 | case http.MethodPost: 14 | r.ParseForm() 15 | w.Write([]byte("Hello, Text! " + r.PostForm.Get("text"))) 16 | 17 | } 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /gae/go-hello/app.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | runtime: go 3 | api_version: go1 4 | 5 | handlers: 6 | - url: /.* 7 | script: _go_app 8 | secure: always 9 | -------------------------------------------------------------------------------- /git/hooks/pre-receive: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | which aspell > /dev/null 4 | if [ ! $? -eq 0 ] ; then 5 | exit 0 6 | fi 7 | 8 | while read oldrev newrev refname 9 | do 10 | misspelled=`git log --format=%B -n 1 "$newrev" | aspell list` 11 | if [ -n "${misspelled}" ] ; then 12 | echo >&2 "Possible misspelled words in the commit message:" 13 | for e in $misspelled; do echo >&2 " - ${e}"; done 14 | exit 1 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /gke/clojure/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /.dir-locals.el 11 | /profiles.clj 12 | /dev/resources/local.edn 13 | /dev/src/local.clj 14 | -------------------------------------------------------------------------------- /gke/clojure/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clojure:alpine-onbuild 2 | MAINTAINER Shintaro Kaneko 3 | -------------------------------------------------------------------------------- /gke/clojure/README.md: -------------------------------------------------------------------------------- 1 | # myduct 2 | 3 | FIXME: description 4 | 5 | ## Developing 6 | 7 | ### Setup 8 | 9 | When you first clone this repository, run: 10 | 11 | ```sh 12 | lein setup 13 | ``` 14 | 15 | This will create files for local configuration, and prep your system 16 | for the project. 17 | 18 | ### Environment 19 | 20 | To begin developing, start with a REPL. 21 | 22 | ```sh 23 | lein repl 24 | ``` 25 | 26 | Then load the development environment. 27 | 28 | ```clojure 29 | user=> (dev) 30 | :loaded 31 | ``` 32 | 33 | Run `go` to initiate and start the system. 34 | 35 | ```clojure 36 | dev=> (go) 37 | :started 38 | ``` 39 | 40 | By default this creates a web server at . 41 | 42 | When you make changes to your source files, use `reset` to reload any 43 | modified files and reset the server. Changes to CSS or ClojureScript 44 | files will be hot-loaded into the browser. 45 | 46 | ```clojure 47 | dev=> (reset) 48 | :reloading (...) 49 | :resumed 50 | ``` 51 | 52 | If you want to access a ClojureScript REPL, make sure that the site is loaded 53 | in a browser and run: 54 | 55 | ```clojure 56 | dev=> (cljs-repl) 57 | Waiting for browser connection... Connected. 58 | To quit, type: :cljs/quit 59 | nil 60 | cljs.user=> 61 | ``` 62 | 63 | ### Testing 64 | 65 | Testing is fastest through the REPL, as you avoid environment startup 66 | time. 67 | 68 | ```clojure 69 | dev=> (test) 70 | ... 71 | ``` 72 | 73 | But you can also run tests through Leiningen. 74 | 75 | ```sh 76 | lein test 77 | ``` 78 | 79 | ### Generators 80 | 81 | This project has several generator functions to help you create files. 82 | 83 | To create a new endpoint: 84 | 85 | ```clojure 86 | dev=> (gen/endpoint "bar") 87 | Creating file src/foo/endpoint/bar.clj 88 | Creating file test/foo/endpoint/bar_test.clj 89 | Creating directory resources/foo/endpoint/bar 90 | nil 91 | ``` 92 | 93 | To create a new component: 94 | 95 | ```clojure 96 | dev=> (gen/component "baz") 97 | Creating file src/foo/component/baz.clj 98 | Creating file test/foo/component/baz_test.clj 99 | nil 100 | ``` 101 | 102 | To create a new boundary: 103 | 104 | ```clojure 105 | dev=> (gen/boundary "quz" foo.component.baz.Baz) 106 | Creating file src/foo/boundary/quz.clj 107 | Creating file test/foo/boundary/quz_test.clj 108 | nil 109 | ``` 110 | 111 | ## Deploying 112 | 113 | FIXME: steps to deploy 114 | 115 | ## Legal 116 | 117 | Copyright © 2016 FIXME 118 | -------------------------------------------------------------------------------- /gke/clojure/dev/resources/dev.edn: -------------------------------------------------------------------------------- 1 | {:components 2 | {:figwheel #var duct.component.figwheel/server} 3 | :config 4 | {:app 5 | {:middleware 6 | {:functions {:stacktrace #var ring.middleware.stacktrace/wrap-stacktrace} 7 | :applied ^:replace [:not-found :ring-defaults :stacktrace]}} 8 | :http 9 | {:port 3000} 10 | :figwheel 11 | {:css-dirs ["resources/myduct/public/css"] 12 | :builds 13 | [{:id "dev" 14 | :source-paths ["src" "dev"] 15 | :build-options 16 | {:optimizations :none 17 | :main "cljs.user" 18 | :asset-path "/js" 19 | :output-to "target/figwheel/myduct/public/js/main.js" 20 | :output-dir "target/figwheel/myduct/public/js" 21 | :source-map true 22 | :source-map-path "/js"}}]}}} 23 | -------------------------------------------------------------------------------- /gke/clojure/dev/src/cljs/user.cljs: -------------------------------------------------------------------------------- 1 | (ns cljs.user 2 | (:require [devtools.core :as devtools] 3 | [figwheel.client :as figwheel])) 4 | 5 | (js/console.info "Starting in development mode") 6 | 7 | (enable-console-print!) 8 | 9 | (devtools/install!) 10 | 11 | (figwheel/start {:websocket-url "ws://localhost:3449/figwheel-ws"}) 12 | 13 | (defn log [& args] 14 | (.apply js/console.log js/console (apply array args))) 15 | -------------------------------------------------------------------------------- /gke/clojure/dev/src/dev.clj: -------------------------------------------------------------------------------- 1 | (ns dev 2 | (:refer-clojure :exclude [test]) 3 | (:require [clojure.repl :refer :all] 4 | [clojure.pprint :refer [pprint]] 5 | [clojure.tools.namespace.repl :refer [refresh]] 6 | [clojure.java.io :as io] 7 | [com.stuartsierra.component :as component] 8 | [duct.generate :as gen] 9 | [duct.util.repl :refer [setup test cljs-repl migrate rollback]] 10 | [duct.util.system :refer [load-system]] 11 | [reloaded.repl :refer [system init start stop go reset]])) 12 | 13 | (defn new-system [] 14 | (load-system (keep io/resource ["myduct/system.edn" "dev.edn" "local.edn"]))) 15 | 16 | (when (io/resource "local.clj") 17 | (load "local")) 18 | 19 | (gen/set-ns-prefix 'myduct) 20 | 21 | (reloaded.repl/set-init! new-system) 22 | -------------------------------------------------------------------------------- /gke/clojure/dev/src/user.clj: -------------------------------------------------------------------------------- 1 | (ns user) 2 | 3 | (defn dev 4 | "Load and switch to the 'dev' namespace." 5 | [] 6 | (require 'dev) 7 | (in-ns 'dev) 8 | :loaded) 9 | -------------------------------------------------------------------------------- /gke/clojure/project.clj: -------------------------------------------------------------------------------- 1 | (defproject myduct "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :min-lein-version "2.0.0" 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [org.clojure/clojurescript "1.8.51"] 7 | [com.stuartsierra/component "0.3.1"] 8 | [compojure "1.5.1"] 9 | [duct "0.8.2"] 10 | [environ "1.1.0"] 11 | [ring "1.5.0"] 12 | [ring/ring-defaults "0.2.1"] 13 | [ring-jetty-component "0.3.1"]] 14 | :plugins [[lein-environ "1.0.3"] 15 | [lein-cljsbuild "1.1.2"]] 16 | :main ^:skip-aot myduct.main 17 | :target-path "target/%s/" 18 | :resource-paths ["resources" "target/cljsbuild"] 19 | :prep-tasks [["javac"] ["cljsbuild" "once"] ["compile"]] 20 | :cljsbuild 21 | {:builds 22 | [{:id "main" 23 | :jar true 24 | :source-paths ["src"] 25 | :compiler 26 | {:output-to "target/cljsbuild/myduct/public/js/main.js" 27 | :optimizations :advanced}}]} 28 | :aliases {"setup" ["run" "-m" "duct.util.repl/setup"]} 29 | :profiles 30 | {:dev [:project/dev :profiles/dev] 31 | :test [:project/test :profiles/test] 32 | :repl {:resource-paths ^:replace ["resources" "dev/resources" "target/figwheel"] 33 | :prep-tasks ^:replace [["javac"] ["compile"]]} 34 | :uberjar {:aot :all} 35 | :profiles/dev {} 36 | :profiles/test {} 37 | :project/dev {:dependencies [[duct/generate "0.8.2"] 38 | [reloaded.repl "0.2.3"] 39 | [org.clojure/tools.namespace "0.2.11"] 40 | [org.clojure/tools.nrepl "0.2.12"] 41 | [eftest "0.1.1"] 42 | [com.gearswithingears/shrubbery "0.4.1"] 43 | [kerodon "0.8.0"] 44 | [binaryage/devtools "0.8.2"] 45 | [com.cemerick/piggieback "0.2.1"] 46 | [duct/figwheel-component "0.3.3"] 47 | [figwheel "0.5.8"]] 48 | :source-paths ["dev/src"] 49 | :resource-paths ["dev/resources"] 50 | :repl-options {:init-ns user 51 | :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} 52 | :env {:port "3000"}} 53 | :project/test {}}) 54 | -------------------------------------------------------------------------------- /gke/clojure/resources/myduct/system.edn: -------------------------------------------------------------------------------- 1 | {:components 2 | {:app #var duct.component.handler/handler-component 3 | :http #var ring.component.jetty/jetty-server} 4 | :endpoints 5 | {:example #var myduct.endpoint.example/example-endpoint 6 | :hello #var myduct.endpoint.hello/hello-endpoint} 7 | :dependencies 8 | {:http [:app] 9 | :app [:example :hello] 10 | :example []} 11 | :config 12 | {:app 13 | {:middleware 14 | {:functions 15 | {:hide-errors #var duct.middleware.errors/wrap-hide-errors 16 | :not-found #var duct.middleware.not-found/wrap-not-found 17 | :ring-defaults #var ring.middleware.defaults/wrap-defaults} 18 | :applied 19 | [:not-found :ring-defaults :hide-errors] 20 | :arguments 21 | {:not-found "Resource Not Found" 22 | :hide-errors "Internal Server Error" 23 | :ring-defaults 24 | {:params {:urlencoded true 25 | :keywordize true} 26 | :responses {:not-modified-responses true 27 | :absolute-redirects true 28 | :content-types true 29 | :default-charset "utf-8"}}}}} 30 | :http 31 | {:port http-port}}} 32 | -------------------------------------------------------------------------------- /gke/clojure/src/myduct/endpoint/example.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.example 2 | (:require [compojure.core :refer :all])) 3 | 4 | (defn example-endpoint [config] 5 | (context "/example" [] 6 | (GET "/" [] 7 | "This is an example endpoint"))) 8 | -------------------------------------------------------------------------------- /gke/clojure/src/myduct/endpoint/hello.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.hello 2 | (:require [compojure.core :refer :all])) 3 | 4 | (defn hello-endpoint [config] 5 | (context "/hello" [] 6 | (GET "/" [] 7 | "Hello, World!"))) 8 | -------------------------------------------------------------------------------- /gke/clojure/src/myduct/main.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.main 2 | (:gen-class) 3 | (:require [com.stuartsierra.component :as component] 4 | [duct.util.runtime :refer [add-shutdown-hook]] 5 | [duct.util.system :refer [load-system]] 6 | [environ.core :refer [env]] 7 | [clojure.java.io :as io])) 8 | 9 | (defn -main [& args] 10 | (let [bindings {'http-port (Integer/parseInt (:port env "3000"))} 11 | system (->> (load-system [(io/resource "myduct/system.edn")] bindings) 12 | (component/start))] 13 | (add-shutdown-hook ::stop-system #(component/stop system)) 14 | (println "Started HTTP server on port" (-> system :http :port)))) 15 | -------------------------------------------------------------------------------- /gke/clojure/test/myduct/endpoint/example_test.clj: -------------------------------------------------------------------------------- 1 | (ns myduct.endpoint.example-test 2 | (:require [com.stuartsierra.component :as component] 3 | [clojure.test :refer :all] 4 | [kerodon.core :refer :all] 5 | [kerodon.test :refer :all] 6 | [shrubbery.core :as shrub] 7 | [myduct.endpoint.example :as example])) 8 | 9 | (def handler 10 | (example/example-endpoint {})) 11 | 12 | (deftest smoke-test 13 | (testing "example page exists" 14 | (-> (session handler) 15 | (visit "/example") 16 | (has (status? 200) "page exists")))) 17 | -------------------------------------------------------------------------------- /gke/golang/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.7.4-onbuild 2 | MAINTAINER Shintaro Kaneko 3 | -------------------------------------------------------------------------------- /gke/golang/README.md: -------------------------------------------------------------------------------- 1 | # GKE - Golang Tutorial 2 | 3 | ## Prerequisite 4 | 5 | ### Platforms 6 | 7 | - Google Cloud Platform 8 | - Container Registry 9 | 10 | ### Tools 11 | 12 | - docker 13 | - gcloud 14 | - [kubectl](http://kubernetes.io/docs/user-guide/kubectl-cheatsheet/) 15 | 16 | 17 | ## Steps 18 | 19 | ### 1. Create Dockerfile and go code 20 | 21 | Create a Dockerfile. 22 | 23 | ```docker 24 | FROM golang:1.7.3-onbuild 25 | ``` 26 | 27 | ```go 28 | package main 29 | 30 | import ( 31 | "fmt" 32 | "log" 33 | "net/http" 34 | ) 35 | 36 | func main() { 37 | 38 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 39 | fmt.Fprintf(w, "Hello, Container!") 40 | }) 41 | 42 | log.Fatal(http.ListenAndServe(":8080", nil)) 43 | } 44 | ``` 45 | 46 | ### 2. Build and Run 47 | 48 | Build a new image from Dockerfile. 49 | 50 | ```shell 51 | # Build 52 | docker build -t [docker-tag] . 53 | # e.g.) docker build -t hello-golang . 54 | 55 | # Run to make sure that the image has no problem. 56 | docker run -p 8080:8080 [docker-tag] 57 | # e.g.) docker run -p 8080:8080 hello-golang 58 | ``` 59 | 60 | ### 3. Tag 61 | 62 | Assign a new alias to the image. 63 | 64 | ```shell 65 | # Tag 66 | docker tag [docker-tag] [registry-host]/[project-id]/[docker-tag] 67 | # e.g.) docker tag us.gcr.io/xxxxxxxxx/hello-golang 68 | ``` 69 | 70 | | Registry Host | Region | 71 | | :------------ | :----- | 72 | | us.gcr.io | US | 73 | | es.gcr.io | EU | 74 | | asia.gcr.io | ASIA | 75 | | gcr.io | US (unfixed) | 76 | 77 | ### 4. Push to Container Registry 78 | 79 | ```shell 80 | gcloud docker push [registry-host]/[project-id]/[docker-tag] 81 | # e.g.) gcloud docker push us.gcr.io/xxxxxxxxx/hello-golang 82 | ``` 83 | 84 | ### 5. Deployment 85 | 86 | Create Pod or Replication Controllers on Cloud Shell. 87 | 88 | #### Login Cloud Shell 89 | 90 | Create Container Cluster on Cloud Dashboard. 91 | 92 | And then login Cloud Shell to use `kubectl`. 93 | 94 | ```shell 95 | gcloud container clusters get-credentials [cluster-name] \ 96 | --zone [cluster-zone] --project [project-id] 97 | ``` 98 | 99 | #### Create Pod or Replication Controllers 100 | 101 | ```shell 102 | # Create Pod 103 | kubectl create -f pod.yaml 104 | kubectl get pod 105 | 106 | # Create Replication Controllers 107 | kubectl create -f replication-controller.yaml 108 | kubectl get rc 109 | ``` 110 | 111 | #### Create Service 112 | 113 | ```shell 114 | kubectl create -f service.yaml 115 | kubectl get service 116 | # NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE 117 | # golang x.x.x.x x.x.x.x 80/TCP 7m 118 | # kubernetes x.x.x.x 443/TCP 26m 119 | ``` 120 | 121 | ### Deploy to GCE 122 | 123 | ```shell 124 | gcloud compute instances create [instance-name] \ 125 | --zone us-central1-b \ 126 | --image-family container-vm \ 127 | --image-project google-containers \ 128 | --machine-type n1-standard-1 \ 129 | --tags "http-server" \ 130 | --metadata-from-file google-container-manifest=pod.yaml 131 | ``` 132 | 133 | ## License 134 | 135 | [The MIT License (MIT)](http://kaneshin.mit-license.org/) 136 | 137 | ## Author 138 | 139 | [Shintaro Kaneko](https://github.com/kaneshin) 140 | -------------------------------------------------------------------------------- /gke/golang/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: helloworld 5 | labels: 6 | app: helloworld 7 | spec: 8 | replicas: 3 9 | template: 10 | metadata: 11 | labels: 12 | app: helloworld 13 | spec: 14 | containers: 15 | - name: helloworld-app 16 | image: us.gcr.io/kaneshin-co/hello-golang:latest 17 | imagePullPolicy: Always 18 | ports: 19 | - name: http-server 20 | containerPort: 8080 21 | -------------------------------------------------------------------------------- /gke/golang/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | func main() { 10 | 11 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 12 | fmt.Fprintf(w, "Hello world!") 13 | }) 14 | 15 | log.Fatal(http.ListenAndServe(":8080", nil)) 16 | } 17 | -------------------------------------------------------------------------------- /gke/golang/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: helloworld 5 | labels: 6 | app: helloworld 7 | spec: 8 | type: LoadBalancer 9 | ports: 10 | - port: 80 11 | targetPort: http-server 12 | selector: 13 | app: helloworld 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kaneshin/playground 2 | 3 | require ( 4 | github.com/davecgh/go-spew v1.1.1 // indirect 5 | github.com/golang/protobuf v1.2.0 6 | github.com/kaneshin/coding-test v0.0.0-20180915065733-aeeeb0c0a8b6 7 | github.com/pmezard/go-difflib v1.0.0 // indirect 8 | github.com/stretchr/testify v1.2.2 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= 4 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 5 | github.com/kaneshin/coding-test v0.0.0-20180915065733-aeeeb0c0a8b6 h1:ojpcvK9TbP2JtImxeRgFi40aAbBijJXcDrjIuLqxeb0= 6 | github.com/kaneshin/coding-test v0.0.0-20180915065733-aeeeb0c0a8b6/go.mod h1:rzsEljE+501HMQVXLpMflOa85Y++mt3Wl7iixSL/ZZs= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 10 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 11 | -------------------------------------------------------------------------------- /go/ast/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/ast" 6 | "go/parser" 7 | "go/token" 8 | ) 9 | 10 | //+TP 11 | type Tag struct { 12 | Name string 13 | } 14 | 15 | //+VR 16 | var fooTag = Tag{ 17 | Name: "foo", 18 | } 19 | 20 | //+VR 21 | var barTag = Tag{ 22 | Name: "bar", 23 | } 24 | 25 | //+VR 26 | var ( 27 | fooTag1 = Tag{ 28 | Name: "foo", 29 | } 30 | 31 | barTag1 = Tag{ 32 | Name: "bar", 33 | } 34 | ) 35 | 36 | func main() { 37 | fset := token.NewFileSet() 38 | f, err := parser.ParseFile(fset, "./main.go", nil, parser.ParseComments) 39 | if err != nil { 40 | return 41 | } 42 | 43 | for _, decl := range f.Decls { 44 | d, ok := decl.(*ast.GenDecl) 45 | if !ok { 46 | continue 47 | } 48 | 49 | doc := d.Doc 50 | if doc == nil { 51 | continue 52 | } 53 | 54 | for _, comment := range doc.List { 55 | switch comment.Text { 56 | case "//+VR": 57 | fmt.Printf("-- //+VR\n") 58 | for _, spec := range d.Specs { 59 | fmt.Printf("%#v\n", spec) 60 | } 61 | 62 | case "//+TP": 63 | fmt.Printf("-- //+TP\n") 64 | for _, spec := range d.Specs { 65 | fmt.Printf("%#v\n", spec) 66 | } 67 | 68 | } 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /go/aws/README.md: -------------------------------------------------------------------------------- 1 | # AWS 2 | 3 | ```shell 4 | # AWS Credentials 5 | export AWS_ACCESS_KEY_ID=[your-access-key-id] 6 | export AWS_SECRET_ACCESS_KEY=[your-secret-access-key] 7 | 8 | ## SQS 9 | export AWS_SQS_QUEUE_NAME=[your-queue-name] 10 | export AWS_SQS_QUEUE_REGION=[your-queue-region] 11 | 12 | ## S3 13 | export AWS_S3_BUCKET_NAME=[your-bucket-name] 14 | export AWS_S3_BUCKET_REGION=[your-bucket-region] 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /go/aws/glide.lock: -------------------------------------------------------------------------------- 1 | hash: 7a164b39b4b49d3111e646fa71f7368b894810469f75ec70bd17e226b1f97cf5 2 | updated: 2016-08-15T08:19:14.84238139Z 3 | imports: 4 | - name: github.com/aws/aws-sdk-go 5 | version: f80e7d0182a463dff0c0da6bbed57f21369d4346 6 | subpackages: 7 | - '...' 8 | testImports: [] 9 | -------------------------------------------------------------------------------- /go/aws/glide.yaml: -------------------------------------------------------------------------------- 1 | package: github.com/kaneshin/playground/go/aws-sqs 2 | import: 3 | - package: github.com/aws/aws-sdk-go 4 | version: ~1.4.1 5 | subpackages: 6 | - '...' 7 | -------------------------------------------------------------------------------- /go/aws/s3/README.md: -------------------------------------------------------------------------------- 1 | # s3 2 | 3 | ## Usage 4 | 5 | ```shell 6 | AWS_S3_BUCKET_NAME=[your-bucket-name] AWS_S3_BUCKET_REGION=[your-bucket-region] go run main.go --byte-range=bytes=0-1999 icon/lenna.jpg 7 | ``` 8 | -------------------------------------------------------------------------------- /go/aws/s3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "io/ioutil" 6 | "log" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/aws/aws-sdk-go/aws" 12 | "github.com/aws/aws-sdk-go/aws/credentials" 13 | "github.com/aws/aws-sdk-go/aws/session" 14 | "github.com/aws/aws-sdk-go/service/s3" 15 | ) 16 | 17 | var ( 18 | config *aws.Config 19 | name = os.Getenv("AWS_S3_BUCKET_NAME") 20 | region = os.Getenv("AWS_S3_BUCKET_REGION") 21 | byteRange = flag.String("byte-range", "", "") 22 | ) 23 | 24 | func init() { 25 | config = aws.NewConfig(). 26 | WithCredentials(credentials.NewEnvCredentials()). 27 | WithHTTPClient(http.DefaultClient). 28 | WithMaxRetries(aws.UseServiceDefaultRetries). 29 | WithLogger(aws.NewDefaultLogger()). 30 | WithLogLevel(aws.LogOff) 31 | } 32 | 33 | func main() { 34 | flag.Parse() 35 | 36 | if len(flag.Args()) == 0 { 37 | flag.Usage() 38 | os.Exit(1) 39 | } 40 | key := flag.Args()[0] 41 | 42 | // initialize the S3 service. 43 | svc := NewS3(aws.NewConfig().WithRegion(region)) 44 | input := s3.GetObjectInput{ 45 | Bucket: aws.String(name), 46 | Key: aws.String(key), 47 | } 48 | 49 | if len(*byteRange) > 0 { 50 | // Downloads the specified range bytes of an object. For more information about 51 | // the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35. 52 | // Range *string `location:"header" locationName:"Range" type:"string"` 53 | input.Range = aws.String(*byteRange) 54 | } 55 | 56 | req, output := svc.GetObjectRequest(&input) 57 | if err := req.Send(); err != nil { 58 | log.Fatalf("error %v", err) 59 | } 60 | defer output.Body.Close() 61 | 62 | tempdir, err := ioutil.TempDir("", "") 63 | if err != nil { 64 | log.Fatalf("error %v", err) 65 | } 66 | 67 | file, err := os.Create(filepath.Join(tempdir, filepath.Base(key))) 68 | if err != nil { 69 | log.Fatalf("error %v", err) 70 | } 71 | defer file.Close() 72 | 73 | // write bytes to file 74 | b, err := ioutil.ReadAll(output.Body) 75 | if _, err := file.Write(b); err != nil { 76 | log.Fatalf("error %v", err) 77 | } 78 | 79 | log.Printf("write file: %v", file.Name()) 80 | } 81 | 82 | // NewS3 creates a new instance of the S3 client with a session. 83 | // If additional configuration is needed for the client instance use the optional 84 | // aws.Config parameter to add your extra config. 85 | // 86 | // Example: 87 | // // Create a S3 client with additional configuration 88 | // svc := NewS3(aws.NewConfig().WithRegion("us-west-2")) 89 | func NewS3(c *aws.Config) *s3.S3 { 90 | sess := session.New(config, c) 91 | return s3.New(sess, config, c) 92 | } 93 | -------------------------------------------------------------------------------- /go/aws/sqs/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "strconv" 8 | "time" 9 | 10 | "github.com/aws/aws-sdk-go/aws" 11 | "github.com/aws/aws-sdk-go/aws/credentials" 12 | "github.com/aws/aws-sdk-go/aws/session" 13 | "github.com/aws/aws-sdk-go/service/sqs" 14 | ) 15 | 16 | var ( 17 | config *aws.Config 18 | name = os.Getenv("AWS_SQS_QUEUE_NAME") 19 | region = os.Getenv("AWS_SQS_QUEUE_REGION") 20 | ) 21 | 22 | func init() { 23 | config = aws.NewConfig(). 24 | WithCredentials(credentials.NewEnvCredentials()). 25 | WithHTTPClient(http.DefaultClient). 26 | WithMaxRetries(aws.UseServiceDefaultRetries). 27 | WithLogger(aws.NewDefaultLogger()). 28 | WithLogLevel(aws.LogOff) 29 | } 30 | 31 | func main() { 32 | // initialize the SQS service. 33 | svc := NewSQS(aws.NewConfig().WithRegion(region)) 34 | 35 | var url string 36 | { 37 | // Get Queue URL 38 | resp, err := svc.GetQueueUrl(&sqs.GetQueueUrlInput{ 39 | QueueName: aws.String(name), 40 | }) 41 | if err != nil { 42 | panic(err) 43 | } 44 | fmt.Printf("Queue URL: %v\n", *resp.QueueUrl) 45 | url = *resp.QueueUrl 46 | } 47 | 48 | { 49 | // Enqueue 50 | resp, err := svc.SendMessage(&sqs.SendMessageInput{ 51 | MessageBody: aws.String(time.Now().String()), 52 | DelaySeconds: aws.Int64(1), 53 | QueueUrl: aws.String(url), 54 | }) 55 | if err != nil { 56 | panic(err) 57 | } 58 | fmt.Println("Enqueue:", resp) 59 | } 60 | 61 | { 62 | // Bulk enquene 63 | input := &sqs.SendMessageBatchInput{ 64 | QueueUrl: aws.String(url), 65 | } 66 | for i := 0; i < 2; i++ { 67 | ent := &sqs.SendMessageBatchRequestEntry{ 68 | Id: aws.String(strconv.Itoa(i)), 69 | MessageBody: aws.String(time.Now().String()), 70 | } 71 | input.Entries = append(input.Entries, ent) 72 | } 73 | resp, err := svc.SendMessageBatch(input) 74 | if err != nil { 75 | panic(err) 76 | } 77 | fmt.Println("Bulk Enqueue:", resp) 78 | } 79 | 80 | var messages []*sqs.Message 81 | { 82 | // Dequeue 83 | resp, err := svc.ReceiveMessage(&sqs.ReceiveMessageInput{ 84 | MaxNumberOfMessages: aws.Int64(3), 85 | WaitTimeSeconds: aws.Int64(10), 86 | QueueUrl: aws.String(url), 87 | }) 88 | if err != nil { 89 | panic(err) 90 | } 91 | fmt.Println("Dequeue:", resp) 92 | messages = resp.Messages 93 | } 94 | 95 | { 96 | // Delete 97 | for _, msg := range messages { 98 | resp, err := svc.DeleteMessage(&sqs.DeleteMessageInput{ 99 | ReceiptHandle: aws.String(*msg.ReceiptHandle), 100 | QueueUrl: aws.String(url), 101 | }) 102 | if err != nil { 103 | panic(err) 104 | } 105 | fmt.Println("Delete:", resp) 106 | } 107 | } 108 | } 109 | 110 | // NewSQS creates a new instance of the SQS client with a session. 111 | // If additional configuration is needed for the client instance use the optional 112 | // aws.Config parameter to add your extra config. 113 | // 114 | // Example: 115 | // // Create a SQS client with additional configuration 116 | // svc := NewSQS(aws.NewConfig().WithRegion("us-west-2")) 117 | func NewSQS(c *aws.Config) *sqs.SQS { 118 | sess := session.New(config, c) 119 | return sqs.New(sess, config, c) 120 | } 121 | -------------------------------------------------------------------------------- /go/benchmark/benchmark_test.go: -------------------------------------------------------------------------------- 1 | package benchmark 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func Test_Divide(t *testing.T) { 10 | const N = 1000000 11 | tmp := float64(1) / float64(time.Millisecond) 12 | for j := 0; j < N; j++ { 13 | f1 := int64(j) / int64(time.Millisecond) 14 | f2 := int64(float64(j) * tmp) 15 | if !reflect.DeepEqual(f1, f2) { 16 | t.Fatal("Should be the same values") 17 | } 18 | } 19 | } 20 | 21 | var f int64 22 | 23 | func Benchmark_Divide(b *testing.B) { 24 | const N = 1000000 25 | b.Run("Divide", func(b *testing.B) { 26 | for i := 0; i < b.N; i++ { 27 | for j := 0; j < N; j++ { 28 | f = int64(j) / int64(time.Millisecond) 29 | } 30 | } 31 | }) 32 | 33 | b.Run("Multiple", func(b *testing.B) { 34 | t := float64(1) / float64(time.Millisecond) 35 | for i := 0; i < b.N; i++ { 36 | for j := 0; j < N; j++ { 37 | f = int64(float64(j) * t) 38 | } 39 | } 40 | }) 41 | } 42 | 43 | type Packet struct { 44 | Name string 45 | Data interface{} 46 | } 47 | 48 | var name string 49 | var data interface{} 50 | 51 | func (p Packet) Send() { 52 | name = p.Name 53 | data = p.Data 54 | } 55 | 56 | func Benchmark_PacketSend(b *testing.B) { 57 | const N = 1000000 58 | b.Run("v1", func(b *testing.B) { 59 | for i := 0; i < b.N; i++ { 60 | for j := 0; j < N; j++ { 61 | Packet{ 62 | Name: "foo", 63 | Data: "bar", 64 | }.Send() 65 | } 66 | } 67 | }) 68 | 69 | b.Run("v2", func(b *testing.B) { 70 | p := Packet{ 71 | Name: "foo", 72 | Data: "bar", 73 | } 74 | b.ResetTimer() 75 | for i := 0; i < b.N; i++ { 76 | for j := 0; j < N; j++ { 77 | p.Send() 78 | } 79 | } 80 | }) 81 | 82 | b.Run("v3", func(b *testing.B) { 83 | p := Packet{ 84 | Name: "foo", 85 | Data: "bar", 86 | } 87 | b.ResetTimer() 88 | for i := 0; i < b.N; i++ { 89 | for j := 0; j < N; j++ { 90 | p := p 91 | p.Data = j 92 | p.Send() 93 | } 94 | } 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /go/benchmark/json_test.go: -------------------------------------------------------------------------------- 1 | package benchmark 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "testing" 7 | ) 8 | 9 | func BenchmarkJSONDecode(b *testing.B) { 10 | const jsonString = `{"foo":true,"bar":1,"hoge":"hogehoge"}` 11 | 12 | b.Run("Unmarshal", func(b *testing.B) { 13 | var d map[string]interface{} 14 | b.ResetTimer() 15 | for n := 0; n < b.N; n++ { 16 | json.Unmarshal([]byte(jsonString), &d) 17 | } 18 | }) 19 | 20 | b.Run("Decoder", func(b *testing.B) { 21 | var d map[string]interface{} 22 | buf := bytes.NewBufferString(jsonString) 23 | b.ResetTimer() 24 | for n := 0; n < b.N; n++ { 25 | json.NewDecoder(buf).Decode(&d) 26 | } 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /go/benchmark/slice_test.go: -------------------------------------------------------------------------------- 1 | package benchmark 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func BenchmarkSlice(b *testing.B) { 8 | const n = 100000 9 | 10 | b.Run("None", func(b *testing.B) { 11 | for i := 0; i < b.N; i++ { 12 | b.StopTimer() 13 | var dst []int 14 | b.StartTimer() 15 | for i := 0; i < n; i++ { 16 | dst = append(dst, i) 17 | } 18 | } 19 | }) 20 | 21 | b.Run("Len", func(b *testing.B) { 22 | for i := 0; i < b.N; i++ { 23 | b.StopTimer() 24 | dst := make([]int, n) 25 | b.StartTimer() 26 | for i := 0; i < n; i++ { 27 | dst[i] = i 28 | } 29 | } 30 | }) 31 | 32 | b.Run("Cap", func(b *testing.B) { 33 | for i := 0; i < b.N; i++ { 34 | b.StopTimer() 35 | dst := make([]int, 0, n) 36 | b.StartTimer() 37 | for i := 0; i < n; i++ { 38 | dst = append(dst, i) 39 | } 40 | } 41 | }) 42 | 43 | b.Run("Len-Cap", func(b *testing.B) { 44 | for i := 0; i < b.N; i++ { 45 | b.StopTimer() 46 | dst := make([]int, n, n) 47 | b.StartTimer() 48 | for i := 0; i < n; i++ { 49 | dst[i] = i 50 | } 51 | } 52 | }) 53 | } 54 | 55 | func mergeAAndB(a, b []int) []int { 56 | ret := make([]int, 0, len(a)+len(b)) 57 | const step = 2 58 | 59 | i := 0 60 | for _, b := range b { 61 | left := i * step 62 | right := (i + 1) * step 63 | ret = append(ret, a[left:right]...) 64 | ret = append(ret, b) 65 | _ = b 66 | i++ 67 | } 68 | 69 | return append(ret, a[i*step:]...) 70 | } 71 | 72 | var c []int 73 | 74 | func BenchmarkMergeAAndB(b *testing.B) { 75 | as := []int{ 76 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 77 | } 78 | bs := []int{ 79 | 91, 92, 93, 80 | } 81 | 82 | b.ResetTimer() 83 | for i := 0; i < b.N; i++ { 84 | c = mergeAAndB(as, bs) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /go/channel/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func concat(ctx context.Context, a, b string) string { 10 | time.Sleep(2 * time.Second) 11 | time 12 | return a + " " + b 13 | } 14 | 15 | func main() { 16 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 17 | ctx1, cancel := context.WithCancel(r.Context()) 18 | 19 | var str1, str2, str3 string 20 | 21 | ctx2, _ := context.WithCancel(ctx1) 22 | go func(ctx context.Context) { 23 | str1 = concat(ctx, "Hello", "world") 24 | }(ctx2) 25 | 26 | go func(ctx context.Context) { 27 | str2 = concat(ctx, "こんにちは", "世界") 28 | }(ctx2) 29 | 30 | select { 31 | case <-ctx2.Done(): 32 | str3 = concat(ctx1, str1, str2) 33 | } 34 | 35 | w.Write([]byte(str3)) 36 | cancel() 37 | }) 38 | 39 | http.ListenAndServe(":9090", nil) 40 | } 41 | -------------------------------------------------------------------------------- /go/channel/sample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type User struct { 6 | ID int 7 | Name string 8 | } 9 | 10 | type Image struct { 11 | ID int 12 | UserID int 13 | URL string 14 | } 15 | 16 | func GetUsersByIDs(ids []int) ([]User, error) { 17 | return nil, nil 18 | } 19 | 20 | func GetImagesByIDs(ids []int) ([]Images, error) { 21 | return nil, nil 22 | } 23 | 24 | func run() error { 25 | usersCh := make(chan map[int]User) 26 | imagesCh := make(chan map[int]Image) 27 | errCh := make(chan error) 28 | 29 | targetUserIDs := []int{1, 2, 3} 30 | targetImageIDs := []int{10, 20, 30} 31 | 32 | var wg sync.WaitGroup 33 | wg.Add(1) 34 | 35 | go func() { 36 | // defer func() { wg.Done() }() 37 | 38 | for { 39 | select { 40 | case err := <-errCh: 41 | wg.Done() 42 | return 43 | } 44 | } 45 | }() 46 | 47 | go func(chan map[int]User, chan error) { 48 | users, err := GetUsersByIDs(targetUserIDs) 49 | if err != nil { 50 | errCh <- err 51 | return 52 | } 53 | 54 | um := map[int]User{} 55 | for _, u := range users { 56 | um[u.ID] = u 57 | } 58 | usersCh <- um 59 | }(usersCh, errCh) 60 | 61 | go func(chan map[int]Image, chan error) { 62 | images, err := GetImagesByIDs(targetImageIDs) 63 | if err != nil { 64 | errCh <- err 65 | return 66 | } 67 | 68 | im := map[int]Image{} 69 | for _, i := range images { 70 | im[i.UserID] = i 71 | } 72 | imagesCh <- im 73 | }(imagesCh, errCh) 74 | 75 | wg.Wait() 76 | 77 | return 0 78 | } 79 | 80 | func main() { 81 | fmt.Println(run()) 82 | } 83 | -------------------------------------------------------------------------------- /go/encoding/json/json.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | ) 7 | 8 | var meta = map[string]interface{}{ 9 | "version": "v1.0.1", 10 | } 11 | 12 | func merge_v1(v interface{}) interface{} { 13 | var data = make(map[string]interface{}) 14 | data["meta"] = meta 15 | 16 | b, err := json.Marshal(v) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | err = json.Unmarshal(b, &data) 22 | if err != nil { 23 | return err 24 | } 25 | return data 26 | } 27 | 28 | func merge_v2(v interface{}) interface{} { 29 | b, err := json.Marshal(v) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | var data map[string]interface{} 35 | err = json.Unmarshal(b, &data) 36 | if err != nil { 37 | return err 38 | } 39 | 40 | data["meta"] = meta 41 | return data 42 | } 43 | 44 | func merge_v3(v interface{}) interface{} { 45 | var buf bytes.Buffer 46 | err := json.NewEncoder(&buf).Encode(v) 47 | if err != nil { 48 | return err 49 | } 50 | 51 | var data map[string]interface{} 52 | err = json.NewDecoder(&buf).Decode(&data) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | data["meta"] = meta 58 | return data 59 | } 60 | -------------------------------------------------------------------------------- /go/encoding/json/json_test.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | type User struct { 10 | ID int `json:"id"` 11 | Name string `json:"name"` 12 | Email string `json:"email"` 13 | } 14 | 15 | func Test_merge(t *testing.T) { 16 | tests := []struct { 17 | name string 18 | input interface{} 19 | expected map[string]interface{} 20 | }{ 21 | { 22 | name: "test01", 23 | input: User{1, "test01", "test01@example.com"}, 24 | expected: map[string]interface{}{ 25 | "meta": meta, 26 | "id": 1.0, 27 | "name": "test01", 28 | "email": "test01@example.com", 29 | }, 30 | }, 31 | { 32 | name: "test02", 33 | input: map[string]interface{}{ 34 | "instances": []User{ 35 | User{1, "test01", "test01@example.com"}, 36 | User{2, "test02", "test02@example.com"}, 37 | }, 38 | }, 39 | expected: map[string]interface{}{ 40 | "meta": meta, 41 | "instances": []interface{}{ 42 | map[string]interface{}{ 43 | "id": 1.0, 44 | "name": "test01", 45 | "email": "test01@example.com", 46 | }, 47 | map[string]interface{}{ 48 | "id": 2.0, 49 | "name": "test02", 50 | "email": "test02@example.com", 51 | }, 52 | }, 53 | }, 54 | }, 55 | } 56 | 57 | for _, tt := range tests { 58 | tt := tt 59 | t.Run(tt.name, func(t *testing.T) { 60 | t.Parallel() 61 | 62 | assert := assert.New(t) 63 | assert.EqualValues(tt.expected, merge_v1(tt.input)) 64 | assert.EqualValues(tt.expected, merge_v2(tt.input)) 65 | assert.EqualValues(tt.expected, merge_v3(tt.input)) 66 | }) 67 | } 68 | } 69 | 70 | var data = map[string]interface{}{ 71 | "instances": []User{ 72 | User{1, "test01", "test01@example.com"}, 73 | User{2, "test02", "test02@example.com"}, 74 | User{3, "test03", "test03@example.com"}, 75 | User{4, "test04", "test04@example.com"}, 76 | User{5, "test05", "test05@example.com"}, 77 | User{6, "test06", "test06@example.com"}, 78 | User{7, "test07", "test07@example.com"}, 79 | User{8, "test08", "test08@example.com"}, 80 | User{9, "test09", "test09@example.com"}, 81 | User{10, "test10", "test10@example.com"}, 82 | User{11, "test11", "test11@example.com"}, 83 | User{12, "test12", "test12@example.com"}, 84 | User{13, "test13", "test13@example.com"}, 85 | User{14, "test14", "test14@example.com"}, 86 | User{15, "test15", "test15@example.com"}, 87 | User{16, "test16", "test16@example.com"}, 88 | User{17, "test17", "test17@example.com"}, 89 | User{18, "test18", "test18@example.com"}, 90 | User{19, "test19", "test19@example.com"}, 91 | User{20, "test20", "test20@example.com"}, 92 | User{21, "test21", "test21@example.com"}, 93 | User{22, "test22", "test22@example.com"}, 94 | User{23, "test23", "test23@example.com"}, 95 | User{24, "test24", "test24@example.com"}, 96 | User{25, "test25", "test25@example.com"}, 97 | User{26, "test26", "test26@example.com"}, 98 | User{27, "test27", "test27@example.com"}, 99 | User{28, "test28", "test28@example.com"}, 100 | User{29, "test29", "test29@example.com"}, 101 | User{30, "test30", "test30@example.com"}, 102 | User{31, "test31", "test31@example.com"}, 103 | User{32, "test32", "test32@example.com"}, 104 | User{33, "test33", "test33@example.com"}, 105 | User{34, "test34", "test34@example.com"}, 106 | User{35, "test35", "test35@example.com"}, 107 | User{36, "test36", "test36@example.com"}, 108 | User{37, "test37", "test37@example.com"}, 109 | User{38, "test38", "test38@example.com"}, 110 | User{39, "test39", "test39@example.com"}, 111 | User{40, "test40", "test40@example.com"}, 112 | User{41, "test41", "test41@example.com"}, 113 | User{42, "test42", "test42@example.com"}, 114 | User{43, "test43", "test43@example.com"}, 115 | User{44, "test44", "test44@example.com"}, 116 | User{45, "test45", "test45@example.com"}, 117 | User{46, "test46", "test46@example.com"}, 118 | User{47, "test47", "test47@example.com"}, 119 | User{48, "test48", "test48@example.com"}, 120 | User{49, "test49", "test49@example.com"}, 121 | User{50, "test50", "test50@example.com"}, 122 | }, 123 | } 124 | 125 | var result interface{} 126 | 127 | func Benchmark_merge(b *testing.B) { 128 | b.Run("merge_v1", func(b *testing.B) { 129 | for i := 0; i < b.N; i++ { 130 | result = merge_v1(data) 131 | } 132 | }) 133 | 134 | b.Run("merge_v2", func(b *testing.B) { 135 | for i := 0; i < b.N; i++ { 136 | result = merge_v2(data) 137 | } 138 | }) 139 | 140 | b.Run("merge_v3", func(b *testing.B) { 141 | for i := 0; i < b.N; i++ { 142 | result = merge_v3(data) 143 | } 144 | }) 145 | } 146 | -------------------------------------------------------------------------------- /go/enum/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Member int 6 | type Male Member 7 | type Female Member 8 | 9 | const ( 10 | male Member = iota 11 | female 12 | ) 13 | 14 | func NewMale() Male { 15 | return Male(male) 16 | } 17 | 18 | func NewFemale() Female { 19 | return Female(female) 20 | } 21 | 22 | type MemberInterface interface { 23 | Say() 24 | } 25 | 26 | func (m Member) Gender() string { 27 | if m == male { 28 | return "Male" 29 | } 30 | if m == female { 31 | return "Female" 32 | } 33 | return "Neutral" 34 | } 35 | 36 | func (m Male) Say() { 37 | fmt.Printf("%s, 男性振る舞い\n", Member(m).Gender()) 38 | } 39 | 40 | func (m Female) Say() { 41 | fmt.Printf("%s, 女性振る舞い\n", Member(m).Gender()) 42 | } 43 | 44 | func Print(m MemberInterface) { 45 | m.Say() 46 | } 47 | 48 | func main() { 49 | Print(NewMale()) 50 | Print(NewFemale()) 51 | 52 | NewMale().Say() 53 | NewFemale().Say() 54 | } 55 | -------------------------------------------------------------------------------- /go/github.com/nlopes/slack/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/nlopes/slack" 8 | ) 9 | 10 | func run(api *slack.Client) int { 11 | rtm := api.NewRTM() 12 | go rtm.ManageConnection() 13 | 14 | for { 15 | select { 16 | case msg := <-rtm.IncomingEvents: 17 | switch ev := msg.Data.(type) { 18 | case *slack.HelloEvent: 19 | log.Print("Hello Event") 20 | 21 | case *slack.MessageEvent: 22 | log.Printf("Message: %v\n", ev) 23 | rtm.SendMessage(rtm.NewOutgoingMessage("Hello world", ev.Channel)) 24 | 25 | case *slack.InvalidAuthEvent: 26 | log.Print("Invalid credentials") 27 | return 1 28 | 29 | } 30 | } 31 | } 32 | } 33 | 34 | func main() { 35 | api := slack.New("[YOUR-API-TOKEN]") 36 | os.Exit(run(api)) 37 | } 38 | -------------------------------------------------------------------------------- /go/image/jpeg/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | ) 9 | 10 | const ( 11 | // SOI is a marker of the start of image. 12 | SOI = 0xd8 13 | 14 | // EOI is a marker of the end of image. 15 | EOI = 0xd9 16 | 17 | // SOS is a marker of the start of scan. 18 | SOS = 0xda 19 | 20 | // SOF0 is a marker of the start of frame. 21 | // Huffman coding, Baseline JPEG 22 | SOF0 = 0xc0 23 | 24 | // APP0 is a marker of the application. 25 | APP0 = 0xe0 26 | 27 | // APP1 is a marker of the application. 28 | APP1 = 0xe1 29 | ) 30 | 31 | func validate(b []byte) bool { 32 | if len(b) < 2 { 33 | return false 34 | } 35 | return b[0] == 0xff && b[1] == SOI 36 | } 37 | 38 | func has(n byte, b []byte) bool { 39 | for i, c := range b { 40 | if c == 0xff { 41 | switch b[i+1] { 42 | case n: 43 | return true 44 | 45 | case SOS: 46 | return false 47 | 48 | } 49 | } 50 | } 51 | return false 52 | } 53 | 54 | func hasJFIF(b []byte) bool { 55 | return has(APP0, b) 56 | } 57 | 58 | func hasExif(b []byte) bool { 59 | return has(APP1, b) 60 | } 61 | 62 | func hasSOF0(b []byte) bool { 63 | return has(SOF0, b) 64 | } 65 | 66 | func main() { 67 | flag.Parse() 68 | 69 | if len(flag.Args()) == 0 { 70 | flag.Usage() 71 | os.Exit(1) 72 | } 73 | 74 | name := flag.Args()[0] 75 | data, err := ioutil.ReadFile(name) 76 | if err != nil { 77 | log.Fatalf("error %v", err) 78 | } 79 | 80 | if len(data) == 0 || !validate(data) { 81 | log.Fatalf("invalid jpeg file %v", name) 82 | } 83 | 84 | if hasJFIF(data) { 85 | log.Printf("data has JFIF Field") 86 | } 87 | 88 | if hasExif(data) { 89 | log.Printf("data has Exif Field") 90 | } 91 | 92 | if hasSOF0(data) { 93 | log.Printf("data has SOF0 Field") 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /go/log/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "time" 6 | ) 7 | 8 | func init() { 9 | log.SetFlags(log.LstdFlags) 10 | log.SetPrefix("[INFO]") 11 | } 12 | 13 | func main() { 14 | for i := 1; i <= 100; i++ { 15 | log.Printf("%v", map[string]interface{}{ 16 | "host": "127.0.0.1", 17 | "time": time.Now(), 18 | "status": 200, 19 | }) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /go/math/fast_inverse_sqrt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func FastInverseSqrt(x float32) float32 { 9 | const threehalfs = float32(1.5) 10 | 11 | x2 := x * float32(0.5) 12 | y := x 13 | i := *(*int32)(unsafe.Pointer(&y)) 14 | i = 0x5f3759df - i>>1 15 | y = *(*float32)(unsafe.Pointer(&i)) 16 | y = y * (threehalfs - (x2 * y * y)) 17 | return y 18 | } 19 | 20 | func main() { 21 | fmt.Printf("Fast inverse sqrt: %f\n", 1.0/FastInverseSqrt(2)) 22 | } 23 | -------------------------------------------------------------------------------- /go/net/http/httptest/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | ) 7 | 8 | // pingHandler returns just "pong" string. 9 | func pingHandler() func(http.ResponseWriter, *http.Request) { 10 | return func(w http.ResponseWriter, r *http.Request) { 11 | w.Header().Set("Content-Type", "text/plain") 12 | w.WriteHeader(http.StatusOK) 13 | w.Write([]byte("pong")) 14 | } 15 | } 16 | 17 | // echoHandler returns a 'msg' query parameter string. 18 | func echoHandler() func(http.ResponseWriter, *http.Request) { 19 | return func(w http.ResponseWriter, r *http.Request) { 20 | w.Header().Set("Content-Type", "text/plain") 21 | w.WriteHeader(http.StatusOK) 22 | w.Write([]byte(r.URL.Query().Get("msg"))) 23 | } 24 | } 25 | 26 | func init() { 27 | http.HandleFunc("/ping", pingHandler()) 28 | http.HandleFunc("/echo", echoHandler()) 29 | } 30 | 31 | func main() { 32 | log.Fatal(http.ListenAndServe(":8080", nil)) 33 | } 34 | -------------------------------------------------------------------------------- /go/net/http/httptest/handler_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | "net/http/httptest" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestHandler(t *testing.T) { 14 | t.Run("pingHandler", func(t *testing.T) { 15 | t.Parallel() 16 | 17 | s := httptest.NewServer(http.HandlerFunc(pingHandler())) 18 | defer s.Close() 19 | 20 | res, err := http.Get(s.URL) 21 | assert.NoError(t, err) 22 | assert.Equal(t, "text/plain", res.Header.Get("Content-Type")) 23 | assert.Equal(t, 200, res.StatusCode) 24 | defer res.Body.Close() 25 | body, err := ioutil.ReadAll(res.Body) 26 | assert.NoError(t, err) 27 | assert.Equal(t, "pong", string(body)) 28 | }) 29 | 30 | t.Run("echoHandler", func(t *testing.T) { 31 | candidates := []struct { 32 | query string 33 | expected string 34 | }{ 35 | {"", ""}, 36 | {"foo=bar", ""}, 37 | {"msg=foo", "foo"}, 38 | } 39 | for _, c := range candidates { 40 | c := c 41 | t.Run(c.query, func(t *testing.T) { 42 | t.Parallel() 43 | 44 | s := httptest.NewServer(http.HandlerFunc(echoHandler())) 45 | defer s.Close() 46 | 47 | res, err := http.Get(fmt.Sprintf("%v?%v", s.URL, c.query)) 48 | assert.NoError(t, err) 49 | assert.Equal(t, "text/plain", res.Header.Get("Content-Type")) 50 | assert.Equal(t, 200, res.StatusCode) 51 | 52 | defer res.Body.Close() 53 | body, err := ioutil.ReadAll(res.Body) 54 | assert.NoError(t, err) 55 | assert.Equal(t, c.expected, string(body)) 56 | }) 57 | } 58 | }) 59 | } 60 | 61 | func TestHandlerWithRecorder(t *testing.T) { 62 | t.Run("echoHandler", func(t *testing.T) { 63 | candidates := []struct { 64 | url string 65 | expected string 66 | }{ 67 | {"http://example.com/?", ""}, 68 | {"http://example.com/?foo=bar", ""}, 69 | {"http://example.com/?msg=foo", "foo"}, 70 | } 71 | 72 | for _, c := range candidates { 73 | c := c 74 | t.Run(c.url, func(t *testing.T) { 75 | t.Parallel() 76 | 77 | res := httptest.NewRecorder() 78 | req, err := http.NewRequest(http.MethodGet, c.url, nil) 79 | assert.NoError(t, err) 80 | 81 | handler := echoHandler() 82 | handler(res, req) 83 | 84 | assert.Equal(t, "text/plain", res.HeaderMap.Get("Content-Type")) 85 | assert.Equal(t, 200, res.Code) 86 | 87 | body, err := ioutil.ReadAll(res.Body) 88 | assert.NoError(t, err) 89 | assert.Equal(t, c.expected, string(body)) 90 | }) 91 | } 92 | }) 93 | } 94 | -------------------------------------------------------------------------------- /go/net/http/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | const csv = `id,name 8 | 1,foo 9 | 2,bar 10 | 3,baz 11 | ` 12 | 13 | func main() { 14 | http.HandleFunc("/text-plain/sample", func(w http.ResponseWriter, r *http.Request) { 15 | w.Header().Add("content-type", "text/plain") 16 | w.Write([]byte(csv)) 17 | }) 18 | 19 | http.HandleFunc("/text-html/sample", func(w http.ResponseWriter, r *http.Request) { 20 | w.Header().Add("content-type", "text/html") 21 | w.Write([]byte(csv)) 22 | }) 23 | 24 | http.HandleFunc("/text-csv/sample", func(w http.ResponseWriter, r *http.Request) { 25 | w.Header().Add("content-type", "text/csv") 26 | w.Write([]byte(csv)) 27 | }) 28 | 29 | http.HandleFunc("/octet-stream/sample", func(w http.ResponseWriter, r *http.Request) { 30 | w.Header().Add("content-type", "application/octet-stream") 31 | w.Header().Add("content-disposition", "inline; filename=\"foobar.csv\"") 32 | w.Write([]byte(csv)) 33 | }) 34 | 35 | http.ListenAndServe(":8080", nil) 36 | } 37 | -------------------------------------------------------------------------------- /go/net/http/timeout-request/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "net/http/httptest" 11 | "time" 12 | ) 13 | 14 | var ( 15 | timeout = flag.Float64("timeout", 1.0, "") 16 | load = flag.Float64("load", 0.5, "") 17 | ) 18 | 19 | func main() { 20 | flag.Parse() 21 | 22 | // start server by httptest 23 | s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 24 | w.Write([]byte("It works!")) 25 | 26 | // simulate heavy request 27 | time.Sleep(time.Duration(*load*1000) * time.Millisecond) 28 | })) 29 | 30 | // create context with timeout 31 | ctx, cancel := context.WithTimeout(context.Background(), time.Duration(*timeout*1000)*time.Millisecond) 32 | // gracefully cancel 33 | defer cancel() 34 | 35 | req, err := http.NewRequest("GET", s.URL, nil) 36 | if err != nil { 37 | log.Fatalf("error %v", err) 38 | } 39 | req.Cancel = ctx.Done() 40 | 41 | resp, err := http.DefaultClient.Do(req) 42 | if err != nil { 43 | log.Fatalf("error %v", err) 44 | } 45 | defer resp.Body.Close() 46 | 47 | b, _ := ioutil.ReadAll(resp.Body) 48 | fmt.Println(string(b)) 49 | } 50 | -------------------------------------------------------------------------------- /go/net/listen-unixdomainsocket/README.md: -------------------------------------------------------------------------------- 1 | # Listen UNIX Domain Socket 2 | 3 | ## Usage 4 | 5 | ```shell 6 | echo d /var/run/gopher 0755 `whoami` `whoami` - > /etc/tmpfiles.d/gopher.conf 7 | systemd-tmpfiles --create /etc/tmpfiles.d/gopher.conf 8 | systemctl daemon-reload 9 | 10 | go run main.go & 11 | echo -en 'GET / HTTP/1.0\r\n\r\n' | socat stdio UNIX-CONNECT:/var/run/gopher/go.sock 12 | 13 | HTTP/1.0 200 OK 14 | Date: Tue, 06 Sep 2016 16:45:16 GMT 15 | Content-Length: 9 16 | Content-Type: text/plain; charset=utf-8 17 | 18 | It works! 19 | ``` 20 | 21 | ## License 22 | 23 | [The MIT License (MIT)](http://kaneshin.mit-license.org/) 24 | 25 | ## Author 26 | 27 | [Shintaro Kaneko](https://github.com/kaneshin) 28 | 29 | -------------------------------------------------------------------------------- /go/net/listen-unixdomainsocket/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | "net/http" 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | func finalize(ln net.Listener) { 13 | if err := ln.Close(); err != nil { 14 | log.Fatalf("error %v", err) 15 | } 16 | } 17 | 18 | func main() { 19 | mux := http.NewServeMux() 20 | 21 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 22 | w.Write([]byte("It works!")) 23 | }) 24 | 25 | ln, err := net.Listen("unix", "/var/run/gopher/go.sock") 26 | if err != nil { 27 | log.Fatalf("error %v", err) 28 | } 29 | defer func(ln net.Listener) { 30 | if err := ln.Close(); err != nil { 31 | log.Fatalf("error %v", err) 32 | } 33 | }(ln) 34 | 35 | c := make(chan os.Signal, 2) 36 | go func(ln net.Listener, c chan os.Signal) { 37 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 38 | <-c 39 | if err := ln.Close(); err != nil { 40 | log.Fatalf("error %v", err) 41 | } 42 | os.Exit(1) 43 | }(ln, c) 44 | 45 | log.Fatalf("error %v", http.Serve(ln, mux)) 46 | } 47 | -------------------------------------------------------------------------------- /go/net/listen-unixdomainsocket/nginx.conf: -------------------------------------------------------------------------------- 1 | upstream backend { 2 | server unix:/var/run/gopher/go.sock; 3 | } 4 | 5 | server { 6 | listen 80; 7 | server_name go.example.com; 8 | root /var/www/html; 9 | 10 | location / { 11 | proxy_set_header X-Real-IP $remote_addr; 12 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 13 | proxy_set_header Host $http_host; 14 | proxy_redirect off; 15 | proxy_pass http://backend/; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /go/os/csv_reader.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | f, err := os.Open("test.csv") 11 | if err != nil { 12 | panic(err) 13 | } 14 | defer f.Close() 15 | 16 | records, err := csv.NewReader(f).ReadAll() 17 | if err != nil { 18 | panic(err) 19 | } 20 | 21 | for _, line := range records { 22 | fmt.Println(line) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /go/os/stdin_or_pipe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func init() { 12 | flag.Parse() 13 | } 14 | 15 | func main() { 16 | var name string 17 | if args := flag.Args(); len(args) > 0 { 18 | name = args[0] 19 | } 20 | 21 | var r io.Reader 22 | switch name { 23 | case "", "-": 24 | r = os.Stdin 25 | default: 26 | f, err := os.Open(name) 27 | if err != nil { 28 | panic(err) 29 | } 30 | defer f.Close() 31 | r = f 32 | } 33 | 34 | b, err := ioutil.ReadAll(r) 35 | if err != nil { 36 | panic(err) 37 | } 38 | fmt.Print(string(b)) 39 | } 40 | -------------------------------------------------------------------------------- /go/os/test.csv: -------------------------------------------------------------------------------- 1 | foo,bar,baz 2 | 1,2,3 3 | 2,3,4 4 | 3,4,5 5 | -------------------------------------------------------------------------------- /go/regexp/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "sync" 7 | ) 8 | 9 | var ( 10 | re *regexp.Regexp // = regexp.MustCompile("[a-z]{2}") 11 | ) 12 | 13 | func init() { 14 | re = regexp.MustCompile("[a-z]{2}") 15 | } 16 | 17 | func findAllString() []string { 18 | // re := regexp.MustCompile("[a-z]{2}") 19 | re2 := re.Copy() 20 | return re2.FindAllString("hoge", -1) 21 | } 22 | 23 | func main() { 24 | var wg sync.WaitGroup 25 | 26 | for i := 0; i < 100; i++ { 27 | wg.Add(1) 28 | go func() { 29 | fmt.Println(findAllString()) 30 | wg.Done() 31 | }() 32 | } 33 | wg.Wait() 34 | fmt.Println("Hello, playground") 35 | } 36 | -------------------------------------------------------------------------------- /go/strings/strings_test.go: -------------------------------------------------------------------------------- 1 | package benchmark 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | var str string 9 | 10 | func Benchmark_Replace(b *testing.B) { 11 | b.Run("strings.Replace", func(b *testing.B) { 12 | b.ResetTimer() 13 | for n := 0; n < b.N; n++ { 14 | str = strings.Replace(testString, `\n`, "\n", -1) 15 | } 16 | }) 17 | 18 | b.Run("strings.Replacer.Replace", func(b *testing.B) { 19 | r := strings.NewReplacer(`\n`, "\n") 20 | b.ResetTimer() 21 | for n := 0; n < b.N; n++ { 22 | str = r.Replace(testString) 23 | } 24 | }) 25 | } 26 | 27 | const testString = ` 28 | < Content-Length: 5 29 | < Content-Type: textplain; charset=utf-8 30 | < 31 | * Connection #0 to host localhost left intact 32 | Hello% 33 | \n@euclid-1% less tmpprofiling.log 34 | 07:21:02.118448 35 | 07:21:02.199631 36 | 07:21:04.337656 37 | 07:21:05.224804 38 | \n@euclid-1% tail 39 | \n@euclid-1% tail -f tmpprofiling.log 40 | 07:21:02.118448 41 | 07:21:02.199631 42 | 07:21:04.337656 43 | 07:21:05.224804 44 | 20170429 07:22:39.003091 home\nloca 45 | inplaygroundgoprofilingmain.go:23: 46 | 20170429 07:22:39.084298 home\nloca 47 | inplaygroundgoprofilingmain.go:28: 48 | < Content-Length: 5 49 | < Content-Type: textplain; charset=utf-8 50 | < 51 | * Connection #0 to host localhost left intact 52 | Hello% 53 | \n@euclid-1% less tmpprofiling.log 54 | 07:21:02.118448 55 | 07:21:02.199631 56 | 07:21:04.337656 57 | 07:21:05.224804 58 | \n@euclid-1% tail 59 | \n@euclid-1% tail -f tmpprofiling.log 60 | 07:21:02.118448 61 | 07:21:02.199631 62 | 07:21:04.337656 63 | 07:21:05.224804 64 | 20170429 07:22:39.003091 home\nloca 65 | inplaygroundgoprofilingmain.go:23: 66 | 20170429 07:22:39.084298 home\nloca 67 | inplaygroundgoprofilingmain.go:28: 68 | < Content-Length: 5 69 | < Content-Type: textplain; charset=utf-8 70 | < 71 | * Connection #0 to host localhost left intact 72 | Hello% 73 | \n@euclid-1% less tmpprofiling.log 74 | 07:21:02.118448 75 | 07:21:02.199631 76 | 07:21:04.337656 77 | 07:21:05.224804 78 | \n@euclid-1% tail 79 | \n@euclid-1% tail -f tmpprofiling.log 80 | 07:21:02.118448 81 | 07:21:02.199631 82 | 07:21:04.337656 83 | 07:21:05.224804 84 | 20170429 07:22:39.003091 home\nloca 85 | inplaygroundgoprofilingmain.go:23: 86 | 20170429 07:22:39.084298 home\nloca 87 | inplaygroundgoprofilingmain.go:28: 88 | < Content-Length: 5 89 | < Content-Type: textplain; charset=utf-8 90 | < 91 | * Connection #0 to host localhost left intact 92 | Hello% 93 | \n@euclid-1% less tmpprofiling.log 94 | 07:21:02.118448 95 | 07:21:02.199631 96 | 07:21:04.337656 97 | 07:21:05.224804 98 | \n@euclid-1% tail 99 | \n@euclid-1% tail -f tmpprofiling.log 100 | 07:21:02.118448 101 | 07:21:02.199631 102 | 07:21:04.337656 103 | 07:21:05.224804 104 | 20170429 07:22:39.003091 home\nloca 105 | inplaygroundgoprofilingmain.go:23: 106 | 20170429 07:22:39.084298 home\nloca 107 | inplaygroundgoprofilingmain.go:28: 108 | < Content-Length: 5 109 | < Content-Type: textplain; charset=utf-8 110 | < 111 | * Connection #0 to host localhost left intact 112 | Hello% 113 | \n@euclid-1% less tmpprofiling.log 114 | 07:21:02.118448 115 | 07:21:02.199631 116 | 07:21:04.337656 117 | 07:21:05.224804 118 | \n@euclid-1% tail 119 | \n@euclid-1% tail -f tmpprofiling.log 120 | 07:21:02.118448 121 | 07:21:02.199631 122 | 07:21:04.337656 123 | 07:21:05.224804 124 | 20170429 07:22:39.003091 home\nloca 125 | inplaygroundgoprofilingmain.go:23: 126 | 20170429 07:22:39.084298 home\nloca 127 | inplaygroundgoprofilingmain.go:28: 128 | < Content-Length: 5 129 | < Content-Type: textplain; charset=utf-8 130 | < 131 | * Connection #0 to host localhost left intact 132 | Hello% 133 | \n@euclid-1% less tmpprofiling.log 134 | 07:21:02.118448 135 | 07:21:02.199631 136 | 07:21:04.337656 137 | 07:21:05.224804 138 | \n@euclid-1% tail 139 | \n@euclid-1% tail -f tmpprofiling.log 140 | 07:21:02.118448 141 | 07:21:02.199631 142 | 07:21:04.337656 143 | 07:21:05.224804 144 | 20170429 07:22:39.003091 home\nloca 145 | inplaygroundgoprofilingmain.go:23: 146 | 20170429 07:22:39.084298 home\nloca 147 | inplaygroundgoprofilingmain.go:28: 148 | < Content-Length: 5 149 | < Content-Type: textplain; charset=utf-8 150 | < 151 | * Connection #0 to host localhost left intact 152 | Hello% 153 | \n@euclid-1% less tmpprofiling.log 154 | 07:21:02.118448 155 | 07:21:02.199631 156 | 07:21:04.337656 157 | 07:21:05.224804 158 | \n@euclid-1% tail 159 | \n@euclid-1% tail -f tmpprofiling.log 160 | 07:21:02.118448 161 | 07:21:02.199631 162 | 07:21:04.337656 163 | 07:21:05.224804 164 | 20170429 07:22:39.003091 home\nloca 165 | inplaygroundgoprofilingmain.go:23: 166 | 20170429 07:22:39.084298 home\nloca 167 | inplaygroundgoprofilingmain.go:28: 168 | < Content-Length: 5 169 | < Content-Type: textplain; charset=utf-8 170 | < 171 | * Connection #0 to host localhost left intact 172 | Hello% 173 | \n@euclid-1% less tmpprofiling.log 174 | 07:21:02.118448 175 | 07:21:02.199631 176 | 07:21:04.337656 177 | 07:21:05.224804 178 | \n@euclid-1% tail 179 | \n@euclid-1% tail -f tmpprofiling.log 180 | 07:21:02.118448 181 | 07:21:02.199631 182 | 07:21:04.337656 183 | 07:21:05.224804 184 | 20170429 07:22:39.003091 home\nloca 185 | inplaygroundgoprofilingmain.go:23: 186 | 20170429 07:22:39.084298 home\nloca 187 | inplaygroundgoprofilingmain.go:28: 188 | < Content-Length: 5 189 | < Content-Type: textplain; charset=utf-8 190 | < 191 | * Connection #0 to host localhost left intact 192 | Hello% 193 | \n@euclid-1% less tmpprofiling.log 194 | 07:21:02.118448 195 | 07:21:02.199631 196 | 07:21:04.337656 197 | 07:21:05.224804 198 | \n@euclid-1% tail 199 | \n@euclid-1% tail -f tmpprofiling.log 200 | 07:21:02.118448 201 | 07:21:02.199631 202 | 07:21:04.337656 203 | 07:21:05.224804 204 | 20170429 07:22:39.003091 home\nloca 205 | inplaygroundgoprofilingmain.go:23: 206 | 20170429 07:22:39.084298 home\nloca 207 | inplaygroundgoprofilingmain.go:28: 208 | < Content-Length: 5 209 | < Content-Type: textplain; charset=utf-8 210 | < 211 | * Connection #0 to host localhost left intact 212 | Hello% 213 | \n@euclid-1% less tmpprofiling.log 214 | 07:21:02.118448 215 | 07:21:02.199631 216 | 07:21:04.337656 217 | 07:21:05.224804 218 | \n@euclid-1% tail 219 | \n@euclid-1% tail -f tmpprofiling.log 220 | 07:21:02.118448 221 | 07:21:02.199631 222 | 07:21:04.337656 223 | 07:21:05.224804 224 | 20170429 07:22:39.003091 home\nloca 225 | inplaygroundgoprofilingmain.go:23: 226 | 20170429 07:22:39.084298 home\nloca 227 | inplaygroundgoprofilingmain.go:28: 228 | < Content-Length: 5 229 | < Content-Type: textplain; charset=utf-8 230 | < 231 | * Connection #0 to host localhost left intact 232 | Hello% 233 | \n@euclid-1% less tmpprofiling.log 234 | 07:21:02.118448 235 | 07:21:02.199631 236 | 07:21:04.337656 237 | 07:21:05.224804 238 | \n@euclid-1% tail 239 | \n@euclid-1% tail -f tmpprofiling.log 240 | 07:21:02.118448 241 | 07:21:02.199631 242 | 07:21:04.337656 243 | 07:21:05.224804 244 | 20170429 07:22:39.003091 home\nloca 245 | inplaygroundgoprofilingmain.go:23: 246 | 20170429 07:22:39.084298 home\nloca 247 | inplaygroundgoprofilingmain.go:28: 248 | ` 249 | -------------------------------------------------------------------------------- /go/sync/sync_test.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | import ( 4 | "strconv" 5 | "sync" 6 | "testing" 7 | ) 8 | 9 | type RWMutexMap struct { 10 | m map[interface{}]interface{} 11 | mu sync.RWMutex 12 | } 13 | 14 | func (m *RWMutexMap) Delete(key interface{}) { 15 | _, ok := m.Load(key) 16 | if !ok { 17 | return 18 | } 19 | m.mu.Lock() 20 | delete(m.m, key) 21 | m.mu.Unlock() 22 | } 23 | 24 | func (m *RWMutexMap) Load(key interface{}) (value interface{}, ok bool) { 25 | if m.m == nil { 26 | m.m = make(map[interface{}]interface{}) 27 | } 28 | 29 | m.mu.RLock() 30 | v, ok := m.m[key] 31 | m.mu.RUnlock() 32 | return v, ok 33 | } 34 | 35 | func (m *RWMutexMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { 36 | v, ok := m.Load(key) 37 | if ok { 38 | return v, true 39 | } 40 | m.Store(key, value) 41 | return value, false 42 | } 43 | 44 | func (m *RWMutexMap) Range(f func(key, value interface{}) bool) { 45 | if m.m == nil { 46 | m.m = make(map[interface{}]interface{}) 47 | } 48 | 49 | m.mu.RLock() 50 | for k, v := range m.m { 51 | if !f(k, v) { 52 | break 53 | } 54 | } 55 | m.mu.RUnlock() 56 | } 57 | 58 | func (m *RWMutexMap) Store(key, value interface{}) { 59 | if m.m == nil { 60 | m.m = make(map[interface{}]interface{}) 61 | } 62 | 63 | m.mu.Lock() 64 | m.m[key] = value 65 | m.mu.Unlock() 66 | } 67 | 68 | type Map interface { 69 | Delete(key interface{}) 70 | Load(key interface{}) (value interface{}, ok bool) 71 | LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) 72 | Range(f func(key, value interface{}) bool) 73 | Store(key, value interface{}) 74 | } 75 | 76 | func benchmark_Map(m Map) { 77 | var wg sync.WaitGroup 78 | // Store 79 | for i := 0; i < 10; i++ { 80 | wg.Add(1) 81 | go func() { 82 | defer wg.Done() 83 | for i := 0; i < 100000; i++ { 84 | m.Store(strconv.Itoa(i), i) 85 | } 86 | }() 87 | } 88 | 89 | // Range 90 | for i := 0; i < 10; i++ { 91 | wg.Add(1) 92 | go func() { 93 | defer wg.Done() 94 | for i := 0; i < 10; i++ { 95 | m.Range(func(k, v interface{}) bool { 96 | return true 97 | }) 98 | } 99 | }() 100 | } 101 | wg.Wait() 102 | 103 | // Delete 104 | for i := 0; i < 10; i++ { 105 | wg.Add(1) 106 | go func() { 107 | defer wg.Done() 108 | for i := 0; i < 100000; i++ { 109 | m.Delete(strconv.Itoa(i)) 110 | } 111 | }() 112 | } 113 | 114 | // LoadOrStore 115 | for i := 0; i < 10; i++ { 116 | wg.Add(1) 117 | go func() { 118 | defer wg.Done() 119 | for i := 0; i < 100000; i++ { 120 | m.LoadOrStore(strconv.Itoa(i), i) 121 | } 122 | }() 123 | } 124 | } 125 | 126 | func Benchmark_Map(b *testing.B) { 127 | b.Run("sync.Map", func(b *testing.B) { 128 | m := new(sync.Map) 129 | b.ResetTimer() 130 | for i := 0; i < b.N; i++ { 131 | benchmark_Map(m) 132 | } 133 | }) 134 | 135 | b.Run("sync.RWMutex", func(b *testing.B) { 136 | m := new(RWMutexMap) 137 | b.ResetTimer() 138 | for i := 0; i < b.N; i++ { 139 | benchmark_Map(m) 140 | } 141 | }) 142 | } 143 | -------------------------------------------------------------------------------- /go/tail/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "context" 6 | "flag" 7 | "fmt" 8 | "os" 9 | "os/signal" 10 | "sync" 11 | "syscall" 12 | "time" 13 | ) 14 | 15 | var ( 16 | args []string 17 | ) 18 | 19 | func init() { 20 | flag.Parse() 21 | 22 | args = flag.Args() 23 | if len(args) == 0 { 24 | fmt.Fprintln(os.Stderr, "Missing filename: specify one argument") 25 | os.Exit(1) 26 | } 27 | } 28 | 29 | func tail(c context.Context, name string) error { 30 | fi, err := os.Open(name) 31 | if err != nil { 32 | return err 33 | } 34 | defer fi.Close() 35 | 36 | const size = 10 37 | ch := make(chan string, size) 38 | 39 | // prepare 40 | scanner := bufio.NewScanner(fi) 41 | for scanner.Scan() { 42 | if len(ch) >= size { 43 | <-ch 44 | } 45 | ch <- scanner.Text() 46 | } 47 | 48 | // output 49 | go func() { 50 | for { 51 | t, ok := <-ch 52 | if !ok { 53 | return 54 | } 55 | fmt.Fprintln(os.Stdout, t) 56 | } 57 | }() 58 | 59 | var mu sync.Mutex 60 | go func() { 61 | for { 62 | if ch == nil { 63 | return 64 | } 65 | scanner := bufio.NewScanner(fi) 66 | for scanner.Scan() { 67 | mu.Lock() 68 | ch <- scanner.Text() 69 | mu.Unlock() 70 | } 71 | time.Sleep(time.Millisecond * 10) 72 | } 73 | }() 74 | 75 | <-c.Done() 76 | mu.Lock() 77 | close(ch) 78 | ch = nil 79 | mu.Unlock() 80 | return nil 81 | } 82 | 83 | func main() { 84 | var wg sync.WaitGroup 85 | 86 | c, cancel := context.WithCancel(context.Background()) 87 | for _, n := range args { 88 | wg.Add(1) 89 | go func() { 90 | defer wg.Done() 91 | tail(c, n) 92 | }() 93 | } 94 | 95 | sig := make(chan os.Signal, 1) 96 | signal.Notify(sig, syscall.SIGINT) 97 | go func() { 98 | for { 99 | s := <-sig 100 | switch s { 101 | case syscall.SIGINT: 102 | cancel() 103 | } 104 | } 105 | }() 106 | 107 | wg.Wait() 108 | time.Sleep(time.Millisecond * 300) 109 | } 110 | -------------------------------------------------------------------------------- /go/text/template/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "strings" 7 | "text/template" 8 | ) 9 | 10 | func main() { 11 | // First we create a FuncMap with which to register the function. 12 | funcMap := template.FuncMap{ 13 | // The name "title" is what the function will be called in the template text. 14 | "title": strings.Title, 15 | } 16 | 17 | // A simple template definition to test our function. 18 | // We print the input text several ways: 19 | // - the original 20 | // - title-cased 21 | // - title-cased and then printed with %q 22 | // - printed with %q and then title-cased. 23 | const templateText = ` 24 | Input: {{printf "%q" .}} 25 | Output 0: {{title .}} 26 | Output 1: {{title . | printf "%q"}} 27 | Output 2: {{printf "%q" . | title}} 28 | ` 29 | 30 | // Create a template, add the function map, and parse the text. 31 | tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText) 32 | if err != nil { 33 | log.Fatalf("parsing: %s", err) 34 | } 35 | 36 | // Run the template to verify the output. 37 | err = tmpl.Execute(os.Stdout, "the go programming language") 38 | if err != nil { 39 | log.Fatalf("execution: %s", err) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /go/time/ambiguous_time.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | const value = `{ 10 | "fixedAt": "2016-03-23T11:28:41+09:00", 11 | "registeredAt": false 12 | }` 13 | 14 | type ( 15 | AmbiguousTime struct { 16 | Raw interface{} 17 | } 18 | ) 19 | 20 | func (t AmbiguousTime) Time() time.Time { 21 | if v, ok := t.Raw.(string); ok { 22 | u, _ := time.Parse(time.RFC3339, v) 23 | return u 24 | } 25 | return time.Time{} 26 | } 27 | 28 | func (t AmbiguousTime) After(u time.Time) bool { 29 | v := t.Time() 30 | if v.IsZero() { 31 | return false 32 | } 33 | return v.After(u) 34 | } 35 | 36 | func (t AmbiguousTime) Before(u time.Time) bool { 37 | v := t.Time() 38 | if v.IsZero() { 39 | return false 40 | } 41 | return v.Before(u) 42 | } 43 | 44 | var v = struct { 45 | FixedAt interface{} `json:"fixedAt"` 46 | RegisteredAt interface{} `json:"registeredAt"` 47 | }{} 48 | 49 | func main() { 50 | fmt.Println(json.Unmarshal([]byte(value), &v)) 51 | fmt.Println(AmbiguousTime{v.FixedAt}.Time()) 52 | fmt.Println(AmbiguousTime{v.RegisteredAt}.Time()) 53 | fmt.Println(AmbiguousTime{v.FixedAt}.Before(time.Now())) 54 | fmt.Println(AmbiguousTime{v.RegisteredAt}.Before(time.Now())) 55 | fmt.Println(AmbiguousTime{v.FixedAt}.After(time.Now())) 56 | fmt.Println(AmbiguousTime{v.RegisteredAt}.After(time.Now())) 57 | } 58 | 59 | -------------------------------------------------------------------------------- /go/trick/trick.go: -------------------------------------------------------------------------------- 1 | package trick 2 | 3 | import "time" 4 | 5 | func BoolTimer(d time.Duration) func() bool { 6 | var enable bool 7 | 8 | t := time.AfterFunc(d, func() { 9 | enable = false 10 | }) 11 | 12 | return func() bool { 13 | if enable { 14 | return true 15 | } 16 | defer func() { enable = true }() 17 | 18 | t.Reset(d) 19 | return enable 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /go/trick/trick_test.go: -------------------------------------------------------------------------------- 1 | package trick 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestBoolTimer(t *testing.T) { 11 | bt := BoolTimer(time.Second) 12 | 13 | assert.False(t, bt()) 14 | assert.True(t, bt()) 15 | assert.True(t, bt()) 16 | assert.True(t, bt()) 17 | assert.True(t, bt()) 18 | assert.True(t, bt()) 19 | assert.True(t, bt()) 20 | 21 | time.Sleep(time.Second) 22 | 23 | assert.False(t, bt()) 24 | assert.True(t, bt()) 25 | assert.True(t, bt()) 26 | assert.True(t, bt()) 27 | assert.True(t, bt()) 28 | assert.True(t, bt()) 29 | assert.True(t, bt()) 30 | } 31 | -------------------------------------------------------------------------------- /go/worker/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type ( 10 | // Dispatcher represents a management workers. 11 | Dispatcher struct { 12 | pool chan *worker 13 | queue chan interface{} 14 | workers []*worker 15 | wg sync.WaitGroup 16 | quit chan struct{} 17 | } 18 | 19 | // DispatcherOptions specifies the optional parameters to the Dispatcher. 20 | DispatcherOptions struct { 21 | WorkersCount int 22 | QueueCapacity int 23 | WorkerQueueCapacity int 24 | WorkerWaitDuration time.Duration 25 | Func func(interface{}) 26 | } 27 | 28 | // worker represents the worker that executes the job. 29 | worker struct { 30 | dispatcher *Dispatcher 31 | data chan interface{} 32 | signal chan struct{} 33 | wait time.Duration 34 | fn func(interface{}) 35 | quit chan struct{} 36 | } 37 | ) 38 | 39 | // NewDispatcher returns a pointer of Dispatcher. 40 | func NewDispatcher(opt DispatcherOptions) *Dispatcher { 41 | d := &Dispatcher{ 42 | pool: make(chan *worker, opt.WorkersCount), 43 | queue: make(chan interface{}, opt.QueueCapacity), 44 | quit: make(chan struct{}), 45 | } 46 | d.workers = make([]*worker, cap(d.pool)) 47 | for i := 0; i < cap(d.pool); i++ { 48 | w := worker{ 49 | dispatcher: d, 50 | wait: opt.WorkerWaitDuration, 51 | data: make(chan interface{}, opt.WorkerQueueCapacity), 52 | quit: make(chan struct{}), 53 | } 54 | if cap(w.data) > 1 { 55 | w.signal = make(chan struct{}) 56 | } 57 | d.workers[i] = &w 58 | } 59 | if opt.Func != nil { 60 | d.SetFunc(opt.Func) 61 | } 62 | return d 63 | } 64 | 65 | // Add adds a given value to the queue of the dispatcher. 66 | func (d *Dispatcher) Add(v interface{}) { 67 | d.wg.Add(1) 68 | d.queue <- v 69 | } 70 | 71 | // SetFunc sets a function to dispatch dequeued values. 72 | func (d *Dispatcher) SetFunc(f func(interface{})) { 73 | for _, w := range d.workers { 74 | w.fn = f 75 | } 76 | } 77 | 78 | // Start starts the specified dispatcher but does not wait for it to complete. 79 | func (d *Dispatcher) Start() { 80 | for _, w := range d.workers { 81 | w.start() 82 | } 83 | go func() { 84 | for { 85 | select { 86 | case v, ok := <-d.queue: 87 | if !ok { 88 | return 89 | } 90 | 91 | worker := <-d.pool 92 | worker.data <- v 93 | if cap(worker.data) > 1 { 94 | worker.signal <- struct{}{} 95 | } 96 | 97 | case <-d.quit: 98 | return 99 | 100 | } 101 | } 102 | }() 103 | } 104 | 105 | // Wait waits for the dispatcher to exit. It must have been started by Start. 106 | func (d *Dispatcher) Wait() { 107 | d.wg.Wait() 108 | } 109 | 110 | // Stop stops the dispatcher to execute. The dispatcher stops gracefully 111 | // if the given boolean is false. 112 | func (d *Dispatcher) Stop(immediately bool) { 113 | if !immediately { 114 | d.Wait() 115 | } 116 | 117 | d.quit <- struct{}{} 118 | for _, w := range d.workers { 119 | w.quit <- struct{}{} 120 | } 121 | } 122 | 123 | // Destroy stops the dispatcher to execute and closes all channels. 124 | // The dispatcher stops gracefully if the given boolean is false. 125 | func (d *Dispatcher) Destroy(immediately bool) { 126 | d.Stop(immediately) 127 | 128 | close(d.queue) 129 | for _, w := range d.workers { 130 | if w.signal != nil { 131 | close(w.signal) 132 | } 133 | close(w.data) 134 | } 135 | } 136 | 137 | func (w *worker) newTimer() *time.Timer { 138 | t := time.AfterFunc(w.wait, func() func() { 139 | var l sync.Mutex 140 | return func() { 141 | l.Lock() 142 | defer l.Unlock() 143 | 144 | count := len(w.data) 145 | if count == 0 { 146 | return 147 | } 148 | 149 | list := make([]interface{}, count) 150 | for i := 0; i < count; i++ { 151 | list[i] = <-w.data 152 | } 153 | if w.fn != nil { 154 | w.fn(list) 155 | } 156 | 157 | w.dispatcher.wg.Add(-count) 158 | } 159 | }()) 160 | 161 | if !t.Stop() { 162 | <-t.C 163 | } 164 | 165 | return t 166 | } 167 | 168 | func (w *worker) startSingle() { 169 | for { 170 | // register the current worker into the dispatch pool 171 | w.dispatcher.pool <- w 172 | 173 | select { 174 | case v, ok := <-w.data: 175 | if !ok { 176 | // receive a close signal 177 | return 178 | } 179 | 180 | if w.fn != nil { 181 | w.fn(v) 182 | } 183 | w.dispatcher.wg.Done() 184 | 185 | case <-w.quit: 186 | // receive a signal to stop 187 | return 188 | } 189 | } 190 | } 191 | 192 | func (w *worker) startMulti() { 193 | t := w.newTimer() 194 | for { 195 | // register the current worker into the dispatch pool. 196 | w.dispatcher.pool <- w 197 | 198 | select { 199 | case _, ok := <-w.signal: 200 | if !ok { 201 | // receive a close signal 202 | return 203 | } 204 | if len(w.data) == cap(w.data) { 205 | t.Reset(0) 206 | } else { 207 | t.Reset(w.wait) 208 | } 209 | 210 | case <-w.quit: 211 | // receive a signal to stop 212 | return 213 | } 214 | } 215 | } 216 | 217 | func (w *worker) start() { 218 | if cap(w.data) > 1 { 219 | go w.startMulti() 220 | } else { 221 | go w.startSingle() 222 | } 223 | } 224 | 225 | func main() { 226 | opt := DispatcherOptions{ 227 | WorkersCount: 30, 228 | QueueCapacity: 100000, 229 | WorkerQueueCapacity: 10, 230 | WorkerWaitDuration: 1000 * time.Millisecond, 231 | Func: func(v interface{}) { 232 | time.Sleep(300 * time.Millisecond) 233 | fmt.Println(v) 234 | }, 235 | } 236 | 237 | d := NewDispatcher(opt) 238 | d.Start() 239 | 240 | for i := 0; i < 1000; i++ { 241 | d.Add(i) 242 | } 243 | 244 | d.Wait() 245 | } 246 | -------------------------------------------------------------------------------- /numerical-analysis/integral/integral.go: -------------------------------------------------------------------------------- 1 | package integral 2 | 3 | import ( 4 | "github.com/kaneshin/playground/numerical-analysis/internal" 5 | ) 6 | 7 | type ( 8 | function = internal.Function 9 | float = internal.Float 10 | ) 11 | 12 | type Interface interface { 13 | Func() function 14 | Interval() (float, float) 15 | Step() int 16 | } 17 | 18 | func Integral(data Interface) float { 19 | n := data.Step() 20 | if n <= 0 { 21 | return 0. 22 | } 23 | 24 | f := data.Func() 25 | a, b := data.Interval() 26 | if a > b { 27 | return -rectangularRule(f, b, a, n) 28 | } 29 | return rectangularRule(f, a, b, n) 30 | } 31 | 32 | func rectangularRule(f function, a, b float, n int) float { 33 | h := (b - a) / float(n) 34 | r := float(0.) 35 | 36 | // Evaluate by using midpoint formula 37 | x := a + h/2. 38 | for i := 0; i < n; i++ { 39 | r += f(x) 40 | x += h 41 | } 42 | return r * h 43 | } 44 | 45 | func trapezoidalRule(f function, a, b float, n int) float { 46 | panic("TODO: not implemented") 47 | return 0. 48 | } 49 | 50 | func simpsonRule(f function, a, b float, n int) float { 51 | panic("TODO: not implemented") 52 | return 0. 53 | } 54 | -------------------------------------------------------------------------------- /numerical-analysis/integral/integral_test.go: -------------------------------------------------------------------------------- 1 | package integral 2 | 3 | import ( 4 | "math" 5 | "testing" 6 | 7 | "github.com/kaneshin/playground/numerical-analysis/internal" 8 | ) 9 | 10 | const ( 11 | eps = 1e-3 12 | ) 13 | 14 | type impl struct { 15 | f function 16 | a, b float 17 | } 18 | 19 | func (i impl) Func() function { 20 | return i.f 21 | } 22 | 23 | func (i impl) Interval() (float, float) { 24 | return i.a, i.b 25 | } 26 | 27 | func (i impl) Step() int { 28 | return 1e+3 29 | } 30 | 31 | func TestIntegral(t *testing.T) { 32 | tests := map[string]struct { 33 | data Interface 34 | expect float 35 | }{ 36 | // http://m.wolframalpha.com/input/?i=integral_0%5E1+%28x%5E2+-+x+-1+%29 37 | "∫[0,1] F1 dx": {impl{internal.F1, 0, 1}, -7. / 6.}, 38 | // http://m.wolframalpha.com/input/?i=integral_-2%5E4+%28x%5E2+-+x+-1+%29 39 | "∫[-2,4] F1 dx": {impl{internal.F1, -2, 4}, 12.}, 40 | } 41 | 42 | for k, tt := range tests { 43 | tt := tt 44 | t.Run(k, func(t *testing.T) { 45 | result := Integral(tt.data) 46 | if !(tt.expect-eps < result && result < tt.expect+eps) { 47 | t.Errorf("want %v (±%v) but got %v", tt.expect, eps, result) 48 | } 49 | t.Logf("result %v (accuracy %v)", result, math.Abs(float64(result-tt.expect))) 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /numerical-analysis/internal/function.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | type Float float64 4 | type Function func(...Float) Float 5 | 6 | func F1(x ...Float) Float { 7 | if len(x) < 1 { 8 | return 0. 9 | } 10 | x0 := x[0] 11 | return x0*x0 - x0 - 1 12 | } 13 | 14 | func F2(x ...Float) Float { 15 | if len(x) < 2 { 16 | return 0. 17 | } 18 | x0 := x[0] 19 | x1 := x[1] 20 | return x0*x1 - x0 - x1 - 1 21 | } 22 | -------------------------------------------------------------------------------- /numerical-analysis/internal/function_test.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestFunction(t *testing.T) { 9 | var f Function 10 | 11 | tests := map[string]struct { 12 | f interface{} 13 | assignable bool 14 | }{ 15 | "F1": {F1, true}, 16 | "F2": {F2, true}, 17 | "NG": {100, false}, 18 | } 19 | 20 | for k, tt := range tests { 21 | tt := tt 22 | t.Run(k, func(t *testing.T) { 23 | ft := reflect.TypeOf(f) 24 | tft := reflect.TypeOf(tt.f) 25 | ok := tft.AssignableTo(ft) 26 | switch { 27 | case !tt.assignable && ok: 28 | t.Fatalf("This is assignable `Function' type but not expected") 29 | case tt.assignable && !ok: 30 | t.Fatalf("This is not able to be `Function' type assertion") 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /numerical-analysis/irrational/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/kaneshin/playground/numerical-analysis/irrational" 7 | _ "github.com/kaneshin/playground/numerical-analysis/irrational/leibniz" 8 | ) 9 | 10 | func main() { 11 | fmt.Println(irrational.Pi) 12 | } 13 | -------------------------------------------------------------------------------- /numerical-analysis/irrational/leibniz/leibniz.go: -------------------------------------------------------------------------------- 1 | package leibniz 2 | 3 | import ( 4 | "github.com/kaneshin/playground/numerical-analysis/internal" 5 | "github.com/kaneshin/playground/numerical-analysis/irrational" 6 | ) 7 | 8 | type ( 9 | float = internal.Float 10 | ) 11 | 12 | func init() { 13 | irrational.Pi = leibnizFormula() 14 | } 15 | 16 | func leibnizFormula() float { 17 | const n = 1000 18 | p := float(0.) 19 | 20 | for i := 0; i < n; i += 2 { 21 | p += 1. / (2.*float(i) + 1.) 22 | } 23 | for i := 1; i < n; i += 2 { 24 | p -= 1. / (2.*float(i) + 1.) 25 | } 26 | return 4. * p 27 | } 28 | -------------------------------------------------------------------------------- /numerical-analysis/irrational/leibniz/leibniz_test.go: -------------------------------------------------------------------------------- 1 | package leibniz 2 | 3 | import ( 4 | "math" 5 | "testing" 6 | ) 7 | 8 | const ( 9 | eps = 1e-3 10 | ) 11 | 12 | func Test_leibnizFormula(t *testing.T) { 13 | tests := map[string]struct { 14 | result float 15 | expect float 16 | }{ 17 | "Pi": {leibnizFormula(), math.Pi}, 18 | } 19 | 20 | for k, tt := range tests { 21 | tt := tt 22 | t.Run(k, func(t *testing.T) { 23 | if !(tt.expect-eps < tt.result && tt.result < tt.expect+eps) { 24 | t.Errorf("want %v (±%v) but got %v", tt.expect, eps, tt.result) 25 | } 26 | t.Logf("result %v (accuracy %v)", tt.result, math.Abs(float64(tt.result-tt.expect))) 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /numerical-analysis/irrational/pi.go: -------------------------------------------------------------------------------- 1 | package irrational 2 | 3 | import ( 4 | "github.com/kaneshin/playground/numerical-analysis/internal" 5 | ) 6 | 7 | type ( 8 | float = internal.Float 9 | ) 10 | 11 | var Pi float = 3.14 12 | -------------------------------------------------------------------------------- /numerical-analysis/irrational/pi_test.go: -------------------------------------------------------------------------------- 1 | package irrational 2 | 3 | import ( 4 | "math" 5 | "testing" 6 | ) 7 | 8 | const ( 9 | eps = 1e-2 10 | ) 11 | 12 | func Test_Pi(t *testing.T) { 13 | tests := map[string]struct { 14 | result float 15 | expect float 16 | }{ 17 | "Pi": {Pi, math.Pi}, 18 | } 19 | 20 | for k, tt := range tests { 21 | tt := tt 22 | t.Run(k, func(t *testing.T) { 23 | if !(tt.expect-eps < tt.result && tt.result < tt.expect+eps) { 24 | t.Errorf("want %v (±%v) but got %v", tt.expect, eps, tt.result) 25 | } 26 | t.Logf("result %v (accuracy %v)", tt.result, math.Abs(float64(tt.result-tt.expect))) 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protobuf/Makefile: -------------------------------------------------------------------------------- 1 | # PROTO_PATH=/path/to/github.com/google/protobuf/src 2 | 3 | protoc: 4 | @go get -u github.com/golang/protobuf/protoc-gen-go 5 | 6 | build: protoc 7 | @protoc --proto_path=$$PROTO_PATH --proto_path=. --go_out=. *.proto 8 | -------------------------------------------------------------------------------- /protobuf/README.md: -------------------------------------------------------------------------------- 1 | # Protocol Buffer Playground 2 | 3 | ## Build 4 | 5 | ``` 6 | $ PROTO_PATH=/path/to/github.com/google/protobuf/src make 7 | ``` 8 | -------------------------------------------------------------------------------- /protobuf/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | "github.com/golang/protobuf/proto" 8 | "github.com/kaneshin/playground/protobuf" 9 | ) 10 | 11 | func main() { 12 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 13 | user := &protobuf.User{ 14 | Id: 1, 15 | FirstName: "first name", 16 | LastName: "last name", 17 | } 18 | 19 | data, err := proto.Marshal(user) 20 | if err != nil { 21 | w.Write([]byte(err.Error())) 22 | return 23 | } 24 | w.Write(data) 25 | 26 | other := &protobuf.User{} 27 | if err := proto.Unmarshal(data, other); err != nil { 28 | w.Write([]byte(err.Error())) 29 | return 30 | } 31 | log.Print(other.String()) 32 | }) 33 | http.ListenAndServe(":8080", nil) 34 | } 35 | -------------------------------------------------------------------------------- /protobuf/user.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: user.proto 3 | 4 | package protobuf 5 | 6 | import proto "github.com/golang/protobuf/proto" 7 | import fmt "fmt" 8 | import math "math" 9 | import timestamp "github.com/golang/protobuf/ptypes/timestamp" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the proto package it is being compiled against. 18 | // A compilation error at this line likely means your copy of the 19 | // proto package needs to be updated. 20 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 21 | 22 | type User_EmailType int32 23 | 24 | const ( 25 | User_HOME User_EmailType = 0 26 | User_WORK User_EmailType = 1 27 | User_MOBILE User_EmailType = 2 28 | ) 29 | 30 | var User_EmailType_name = map[int32]string{ 31 | 0: "HOME", 32 | 1: "WORK", 33 | 2: "MOBILE", 34 | } 35 | var User_EmailType_value = map[string]int32{ 36 | "HOME": 0, 37 | "WORK": 1, 38 | "MOBILE": 2, 39 | } 40 | 41 | func (x User_EmailType) String() string { 42 | return proto.EnumName(User_EmailType_name, int32(x)) 43 | } 44 | func (User_EmailType) EnumDescriptor() ([]byte, []int) { 45 | return fileDescriptor_user_7e392db06f9e127a, []int{0, 0} 46 | } 47 | 48 | type User struct { 49 | Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 50 | FirstName string `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"` 51 | LastName string `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"` 52 | Emails []*User_Email `protobuf:"bytes,4,rep,name=emails,proto3" json:"emails,omitempty"` 53 | CreatedAt *timestamp.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` 54 | UpdatedAt *timestamp.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` 55 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 56 | XXX_unrecognized []byte `json:"-"` 57 | XXX_sizecache int32 `json:"-"` 58 | } 59 | 60 | func (m *User) Reset() { *m = User{} } 61 | func (m *User) String() string { return proto.CompactTextString(m) } 62 | func (*User) ProtoMessage() {} 63 | func (*User) Descriptor() ([]byte, []int) { 64 | return fileDescriptor_user_7e392db06f9e127a, []int{0} 65 | } 66 | func (m *User) XXX_Unmarshal(b []byte) error { 67 | return xxx_messageInfo_User.Unmarshal(m, b) 68 | } 69 | func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 70 | return xxx_messageInfo_User.Marshal(b, m, deterministic) 71 | } 72 | func (dst *User) XXX_Merge(src proto.Message) { 73 | xxx_messageInfo_User.Merge(dst, src) 74 | } 75 | func (m *User) XXX_Size() int { 76 | return xxx_messageInfo_User.Size(m) 77 | } 78 | func (m *User) XXX_DiscardUnknown() { 79 | xxx_messageInfo_User.DiscardUnknown(m) 80 | } 81 | 82 | var xxx_messageInfo_User proto.InternalMessageInfo 83 | 84 | func (m *User) GetId() int64 { 85 | if m != nil { 86 | return m.Id 87 | } 88 | return 0 89 | } 90 | 91 | func (m *User) GetFirstName() string { 92 | if m != nil { 93 | return m.FirstName 94 | } 95 | return "" 96 | } 97 | 98 | func (m *User) GetLastName() string { 99 | if m != nil { 100 | return m.LastName 101 | } 102 | return "" 103 | } 104 | 105 | func (m *User) GetEmails() []*User_Email { 106 | if m != nil { 107 | return m.Emails 108 | } 109 | return nil 110 | } 111 | 112 | func (m *User) GetCreatedAt() *timestamp.Timestamp { 113 | if m != nil { 114 | return m.CreatedAt 115 | } 116 | return nil 117 | } 118 | 119 | func (m *User) GetUpdatedAt() *timestamp.Timestamp { 120 | if m != nil { 121 | return m.UpdatedAt 122 | } 123 | return nil 124 | } 125 | 126 | type User_Email struct { 127 | Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` 128 | Type User_EmailType `protobuf:"varint,2,opt,name=type,proto3,enum=protobuf.User_EmailType" json:"type,omitempty"` 129 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 130 | XXX_unrecognized []byte `json:"-"` 131 | XXX_sizecache int32 `json:"-"` 132 | } 133 | 134 | func (m *User_Email) Reset() { *m = User_Email{} } 135 | func (m *User_Email) String() string { return proto.CompactTextString(m) } 136 | func (*User_Email) ProtoMessage() {} 137 | func (*User_Email) Descriptor() ([]byte, []int) { 138 | return fileDescriptor_user_7e392db06f9e127a, []int{0, 0} 139 | } 140 | func (m *User_Email) XXX_Unmarshal(b []byte) error { 141 | return xxx_messageInfo_User_Email.Unmarshal(m, b) 142 | } 143 | func (m *User_Email) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 144 | return xxx_messageInfo_User_Email.Marshal(b, m, deterministic) 145 | } 146 | func (dst *User_Email) XXX_Merge(src proto.Message) { 147 | xxx_messageInfo_User_Email.Merge(dst, src) 148 | } 149 | func (m *User_Email) XXX_Size() int { 150 | return xxx_messageInfo_User_Email.Size(m) 151 | } 152 | func (m *User_Email) XXX_DiscardUnknown() { 153 | xxx_messageInfo_User_Email.DiscardUnknown(m) 154 | } 155 | 156 | var xxx_messageInfo_User_Email proto.InternalMessageInfo 157 | 158 | func (m *User_Email) GetAddress() string { 159 | if m != nil { 160 | return m.Address 161 | } 162 | return "" 163 | } 164 | 165 | func (m *User_Email) GetType() User_EmailType { 166 | if m != nil { 167 | return m.Type 168 | } 169 | return User_HOME 170 | } 171 | 172 | func init() { 173 | proto.RegisterType((*User)(nil), "protobuf.User") 174 | proto.RegisterType((*User_Email)(nil), "protobuf.User.Email") 175 | proto.RegisterEnum("protobuf.User_EmailType", User_EmailType_name, User_EmailType_value) 176 | } 177 | 178 | func init() { proto.RegisterFile("user.proto", fileDescriptor_user_7e392db06f9e127a) } 179 | 180 | var fileDescriptor_user_7e392db06f9e127a = []byte{ 181 | // 290 bytes of a gzipped FileDescriptorProto 182 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xcf, 0x4b, 0xfb, 0x30, 183 | 0x18, 0xc6, 0xbf, 0xfd, 0xb1, 0x7e, 0x9b, 0x77, 0x30, 0x4a, 0xf0, 0x10, 0x2a, 0x62, 0xd9, 0xa9, 184 | 0xe0, 0xe8, 0xa0, 0x9e, 0x3c, 0x4e, 0x28, 0x28, 0x3a, 0x0b, 0x61, 0xe2, 0x71, 0x64, 0x26, 0x1b, 185 | 0x85, 0xd6, 0x96, 0x24, 0x3d, 0xec, 0xff, 0xf6, 0x0f, 0x90, 0xa6, 0x8d, 0x5e, 0x04, 0x4f, 0x49, 186 | 0x9e, 0xe7, 0xf3, 0xe4, 0x7d, 0x1f, 0x80, 0x5e, 0x09, 0x99, 0x75, 0xb2, 0xd5, 0x2d, 0x0e, 0xcd, 187 | 0x71, 0xe8, 0x8f, 0xf1, 0xf5, 0xa9, 0x6d, 0x4f, 0xb5, 0x58, 0x5b, 0x61, 0xad, 0xab, 0x46, 0x28, 188 | 0xcd, 0x9a, 0x6e, 0x44, 0x97, 0x9f, 0x2e, 0xf8, 0xaf, 0x4a, 0x48, 0xbc, 0x00, 0xb7, 0xe2, 0xc4, 189 | 0x49, 0x9c, 0xd4, 0xa3, 0x6e, 0xc5, 0xf1, 0x15, 0xc0, 0xb1, 0x92, 0x4a, 0xef, 0x3f, 0x58, 0x23, 190 | 0x88, 0x9b, 0x38, 0x29, 0xa2, 0xc8, 0x28, 0x2f, 0xac, 0x11, 0xf8, 0x12, 0x50, 0xcd, 0xac, 0xeb, 191 | 0x19, 0x37, 0x1c, 0x04, 0x63, 0xae, 0x20, 0x10, 0x0d, 0xab, 0x6a, 0x45, 0xfc, 0xc4, 0x4b, 0xe7, 192 | 0xf9, 0x45, 0x66, 0xe7, 0x67, 0xc3, 0xac, 0xac, 0x18, 0x4c, 0x3a, 0x31, 0xf8, 0x0e, 0xe0, 0x5d, 193 | 0x0a, 0xa6, 0x05, 0xdf, 0x33, 0x4d, 0x66, 0x89, 0x93, 0xce, 0xf3, 0x38, 0x1b, 0x17, 0xff, 0x09, 194 | 0xee, 0xec, 0xe2, 0x14, 0x4d, 0xf4, 0x46, 0x0f, 0xd1, 0xbe, 0xe3, 0x36, 0x1a, 0xfc, 0x1d, 0x9d, 195 | 0xe8, 0x8d, 0x8e, 0x4b, 0x98, 0x99, 0x35, 0x30, 0x81, 0xff, 0x8c, 0x73, 0x29, 0x94, 0x32, 0xed, 196 | 0x11, 0xb5, 0x4f, 0xbc, 0x02, 0x5f, 0x9f, 0xbb, 0xb1, 0xfc, 0x22, 0x27, 0xbf, 0x95, 0xd8, 0x9d, 197 | 0x3b, 0x41, 0x0d, 0xb5, 0xbc, 0x01, 0xf4, 0x2d, 0xe1, 0x10, 0xfc, 0x87, 0x72, 0x5b, 0x44, 0xff, 198 | 0x86, 0xdb, 0x5b, 0x49, 0x9f, 0x22, 0x07, 0x03, 0x04, 0xdb, 0xf2, 0xfe, 0xf1, 0xb9, 0x88, 0xdc, 199 | 0x43, 0x60, 0xfe, 0xba, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xfd, 0xf5, 0x00, 0xb6, 0x01, 200 | 0x00, 0x00, 201 | } 202 | -------------------------------------------------------------------------------- /protobuf/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package protobuf; 4 | 5 | // import "github.com/golang/protobuf/ptypes/timestamp/timestamp.proto"; 6 | import "google/protobuf/timestamp.proto"; 7 | 8 | message User { 9 | int64 id = 1; 10 | string first_name = 2; 11 | string last_name = 3; 12 | 13 | enum EmailType { 14 | HOME = 0; 15 | WORK = 1; 16 | MOBILE = 2; 17 | } 18 | message Email { 19 | string address = 1; 20 | EmailType type = 2; 21 | } 22 | repeated Email emails = 4; 23 | 24 | google.protobuf.Timestamp created_at = 5; 25 | google.protobuf.Timestamp updated_at = 6; 26 | } 27 | -------------------------------------------------------------------------------- /rust/fizzbuzz/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/rust 3 | 4 | ### Rust ### 5 | # Generated by Cargo 6 | # will have compiled files and executables 7 | /target/ 8 | 9 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 10 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 11 | # Cargo.lock 12 | 13 | # These are backup files generated by rustfmt 14 | **/*.rs.bk 15 | 16 | # End of https://www.gitignore.io/api/rust 17 | -------------------------------------------------------------------------------- /rust/fizzbuzz/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "fizzbuzz" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /rust/fizzbuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fizzbuzz" 3 | version = "0.1.0" 4 | authors = ["Shintaro Kaneko "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rust/fizzbuzz/src/main.rs: -------------------------------------------------------------------------------- 1 | fn print_fizzbuzz(n: i32) { 2 | for i in 1..(n + 1) { 3 | if i % 15 == 0 { 4 | println!("fizzbuzz"); 5 | } else if i % 3 == 0 { 6 | println!("fizz"); 7 | } else if i % 5 == 0 { 8 | println!("buzz"); 9 | } else { 10 | println!("{}", i); 11 | } 12 | } 13 | } 14 | 15 | trait FizzBuzz { 16 | fn fizzbuzz(&self); 17 | } 18 | 19 | impl FizzBuzz for i32 { 20 | fn fizzbuzz(&self) { 21 | print_fizzbuzz(*self); 22 | } 23 | } 24 | 25 | impl FizzBuzz for i64 { 26 | fn fizzbuzz(&self) { 27 | print_fizzbuzz(*self as i32); 28 | } 29 | } 30 | 31 | fn main() { 32 | (20 as i32).fizzbuzz(); 33 | (20 as i64).fizzbuzz(); 34 | } 35 | -------------------------------------------------------------------------------- /rust/hello/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/rust 3 | 4 | ### Rust ### 5 | # Generated by Cargo 6 | # will have compiled files and executables 7 | /target/ 8 | 9 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 10 | # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock 11 | # Cargo.lock 12 | 13 | # These are backup files generated by rustfmt 14 | **/*.rs.bk 15 | 16 | # End of https://www.gitignore.io/api/rust 17 | -------------------------------------------------------------------------------- /rust/hello/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "hello" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /rust/hello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | authors = ["Shintaro Kaneko "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rust/hello/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello world!"); 3 | } 4 | -------------------------------------------------------------------------------- /rust/integral/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/rust 3 | # Edit at https://www.gitignore.io/?templates=rust 4 | 5 | ### Rust ### 6 | # Generated by Cargo 7 | # will have compiled files and executables 8 | /target/ 9 | 10 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 11 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 12 | Cargo.lock 13 | 14 | # These are backup files generated by rustfmt 15 | **/*.rs.bk 16 | 17 | # End of https://www.gitignore.io/api/rust 18 | -------------------------------------------------------------------------------- /rust/integral/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "integral" 3 | version = "0.1.0" 4 | authors = ["Shintaro Kaneko "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rust/integral/src/main.rs: -------------------------------------------------------------------------------- 1 | trait Integral { 2 | fn method(&self) -> String; 3 | fn calc(&self) -> f32; 4 | fn print(&self) { 5 | println!("{}: {}", self.method(), self.calc()); 6 | } 7 | } 8 | 9 | struct Interval(f32, f32); 10 | 11 | struct MidpointRule { 12 | function: fn(f32) -> f32, 13 | interval: Interval, 14 | step: i32, 15 | } 16 | 17 | impl Integral for MidpointRule { 18 | fn method(&self) -> String { 19 | return String::from("Midpoint Rule"); 20 | } 21 | 22 | fn calc(&self) -> f32 { 23 | let a = self.interval.0; 24 | let b = self.interval.1; 25 | let n = self.step; 26 | let h = (b - a) / n as f32; 27 | let mut r = 0.0; 28 | let mut x = a + h / 2.0; 29 | 30 | for _ in 0..n { 31 | r += (self.function)(x); 32 | x += h; 33 | } 34 | return r * h; 35 | } 36 | } 37 | 38 | struct TrapezoidRule { 39 | function: fn(f32) -> f32, 40 | interval: Interval, 41 | step: i32, 42 | } 43 | 44 | impl Integral for TrapezoidRule { 45 | fn method(&self) -> String { 46 | return String::from("Trapezoid Rule"); 47 | } 48 | 49 | fn calc(&self) -> f32 { 50 | let a = self.interval.0; 51 | let b = self.interval.1; 52 | let n = self.step; 53 | let h = (b - a) / n as f32; 54 | let mut r = 0.0; 55 | let mut x = a + h; 56 | let mut y1 = (self.function)(a); 57 | 58 | for _ in 0..n { 59 | let y2 = (self.function)(x); 60 | r += y1 + y2; 61 | x += h; 62 | y1 = y2; 63 | } 64 | return r * h / 2.0; 65 | } 66 | } 67 | 68 | fn main() { 69 | fn f(x: f32) -> f32 { 70 | return x * x - x - 1.0; 71 | } 72 | 73 | MidpointRule { 74 | function: f, 75 | interval: Interval(-2.0f32, 4.0f32), 76 | step: 1000, 77 | }.print(); 78 | 79 | TrapezoidRule { 80 | function: f, 81 | interval: Interval(-2.0f32, 4.0f32), 82 | step: 1000, 83 | }.print(); 84 | } 85 | -------------------------------------------------------------------------------- /shuffle/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/kaneshin/playground/shuffle" 8 | ) 9 | 10 | type Dice []int 11 | 12 | func (d Dice) Seed() int64 { return int64(os.Getpid()) } 13 | func (d Dice) Len() int { return len(d) } 14 | func (d Dice) Swap(i, j int) { d[i], d[j] = d[j], d[i] } 15 | 16 | var dice = Dice([]int{1, 2, 3, 4, 5, 6}) 17 | 18 | func main() { 19 | fmt.Printf("%v\n", dice) 20 | shuffle.Shuffle(dice) 21 | fmt.Printf("%v\n", dice) 22 | } 23 | -------------------------------------------------------------------------------- /shuffle/shuffle.go: -------------------------------------------------------------------------------- 1 | package shuffle 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | type Interface interface { 9 | Seed() int64 10 | Len() int 11 | Swap(i, j int) 12 | } 13 | 14 | func Shuffle(data Interface) { 15 | rand.Seed(data.Seed()) 16 | n := data.Len() 17 | for i := n - 1; i >= 0; i-- { 18 | j := rand.Intn(i + 1) 19 | data.Swap(i, j) 20 | } 21 | } 22 | 23 | type IntSlice []int 24 | 25 | func (p IntSlice) Seed() int64 { return time.Now().UnixNano() } 26 | func (p IntSlice) Len() int { return len(p) } 27 | func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 28 | func (p IntSlice) Shuffle() { Shuffle(p) } 29 | 30 | type Int64Slice []int64 31 | 32 | func (p Int64Slice) Seed() int64 { return time.Now().UnixNano() } 33 | func (p Int64Slice) Len() int { return len(p) } 34 | func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 35 | func (p Int64Slice) Shuffle() { Shuffle(p) } 36 | 37 | type Float64Slice []float64 38 | 39 | func (p Float64Slice) Seed() int64 { return time.Now().UnixNano() } 40 | func (p Float64Slice) Len() int { return len(p) } 41 | func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 42 | func (p Float64Slice) Shuffle() { Shuffle(p) } 43 | --------------------------------------------------------------------------------