From 957812f20b09d41fd88a557973cacb3c60077ac9 Mon Sep 17 00:00:00 2001 From: Stanislav Chernyshev Date: Sat, 9 Aug 2025 10:53:13 +0300 Subject: [PATCH] =?UTF-8?q?2-=D0=B5=20=D0=B8=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- {part_2/2.5.1 => part_1/1.10/1.10.1}/1.go | 0 {part_2/2.5.1 => part_1/1.10/1.10.1}/2.go | 0 {part_2/2.5.1 => part_1/1.10/1.10.1}/3.go | 0 {part_2/2.5.1 => part_1/1.10/1.10.1}/4.go | 0 {part_2/2.5.1 => part_1/1.10/1.10.1}/5.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/1.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/2.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/3.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/4.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/5.go | 0 {part_2/2.5.2 => part_1/1.10/1.10.2}/6.go | 0 {part_2/2.6 => part_1/1.11}/1.go | 0 part_1/1.11/10.go | 11 + part_1/1.11/11.go | 24 ++ {part_2/2.6 => part_1/1.11}/2.go | 0 {part_2/2.6 => part_1/1.11}/3.go | 0 {part_2/2.6 => part_1/1.11}/4.go | 0 {part_2/2.6 => part_1/1.11}/5.go | 0 {part_2/2.6 => part_1/1.11}/6.go | 0 part_1/1.11/7.go | 22 ++ part_2/2.6/9.go => part_1/1.11/8.go | 2 + part_1/1.11/9.go | 13 ++ {part_2/2.7 => part_1/1.12}/1.go | 0 {part_2/2.7 => part_1/1.12}/2.go | 0 {part_2/2.7 => part_1/1.12}/3.go | 0 part_1/1.13/1.go | 13 ++ part_1/1.13/10.go | 17 ++ part_1/1.13/2.go | 11 + part_1/1.13/3.go | 12 + part_1/1.13/4.go | 11 + part_1/1.13/5.go | 9 + part_1/1.13/6.go | 11 + part_1/1.13/7.go | 25 ++ part_1/1.13/8.go | 18 ++ part_1/1.13/9.go | 14 ++ part_1/1.14/1.go | 18 ++ part_1/1.14/10.go | 8 + part_1/1.14/11.go | 8 + part_1/1.14/12.go | 11 + part_1/1.14/13.go | 8 + part_1/1.14/14.go | 11 + part_1/1.14/15.go | 9 + part_1/1.14/2.go | 15 ++ part_1/1.14/3.go | 12 + part_1/1.14/4.go | 23 ++ part_1/1.14/5.go | 25 ++ part_1/1.14/6.go | 21 ++ part_1/1.14/7.go | 46 ++++ part_1/1.14/8.go | 73 ++++++ part_1/1.14/9.go | 8 + part_1/1.15/1.go | 31 +++ part_1/1.15/10.go | 13 ++ part_1/1.15/11.go | 33 +++ part_1/1.15/12.go | 13 ++ part_1/1.15/13.go | 16 ++ part_1/1.15/14.go | 15 ++ part_1/1.15/15.go | 21 ++ part_1/1.15/16.go | 43 ++++ part_1/1.15/2.go | 16 ++ part_1/1.15/3.go | 9 + part_1/1.15/4.go | 10 + part_1/1.15/5.go | 39 ++++ part_1/1.15/6.go | 24 ++ part_1/1.15/7.go | 24 ++ part_1/1.15/8.go | 13 ++ part_1/1.15/9.go | 15 ++ part_1/1.16/1.go | 24 ++ part_1/1.16/2.go | 15 ++ part_1/1.16/3.go | 54 +++++ part_1/1.16/4.go | 42 ++++ part_1/1.16/5.go | 25 ++ part_1/1.16/6.go | 29 +++ part_1/1.16/7.go | 20 ++ part_1/1.17/1.go | 46 ++++ part_2/2.1/2.1.1/1.go | 19 ++ part_2/2.1/2.1.1/2.go | 19 ++ part_2/2.1/2.1.1/3.go | 19 ++ {part_3/3.2 => part_2/2.1/2.1.1}/4.go | 0 {part_3/3.2 => part_2/2.1/2.1.1}/5.go | 0 {part_3/3.11 => part_2/2.1/2.1.10}/1.go | 0 {part_3/3.11 => part_2/2.1/2.1.10}/2.go | 0 part_2/2.1/2.1.10/3.go | 13 ++ {part_3/3.3 => part_2/2.1/2.1.2}/1.go | 0 {part_3/3.3 => part_2/2.1/2.1.2}/2.go | 0 {part_3/3.4 => part_2/2.1/2.1.3}/1.go | 0 {part_3/3.4 => part_2/2.1/2.1.3}/2.go | 0 {part_3/3.4 => part_2/2.1/2.1.3}/3.go | 0 {part_3/3.4 => part_2/2.1/2.1.3}/4.go | 0 {part_3/3.5 => part_2/2.1/2.1.4}/1.go | 0 {part_3/3.6 => part_2/2.1/2.1.5}/1.go | 0 {part_3/3.6 => part_2/2.1/2.1.5}/2.go | 0 {part_3/3.7 => part_2/2.1/2.1.6}/1.go | 0 {part_3/3.8 => part_2/2.1/2.1.7}/1.go | 0 {part_3/3.8 => part_2/2.1/2.1.7}/2.go | 0 part_2/2.1/2.1.7/3.go | 33 +++ part_2/2.1/2.1.8/1.go | 16 ++ part_2/2.1/2.1.8/2.go | 20 ++ part_2/2.1/2.1.9/1.go | 20 ++ part_2/2.1/2.1.9/2.go | 25 ++ .../2.2/2.2.1-2.2.2}/golang/first/go.mod | 0 .../2.2/2.2.1-2.2.2}/golang/first/go.sum | 0 .../2.2/2.2.1-2.2.2}/golang/first/main.go | 0 .../2.2/2.2.6}/golang/first/go.mod | 0 .../2.2/2.2.6}/golang/first/go.sum | 0 .../2.2/2.2.6}/golang/first/main.go | 0 .../golang/first/utils/uuid_convertor.go | 0 .../golang/first/another_package/mypack.go | 0 .../2.2/2.2.7}/golang/first/go.mod | 0 .../2.2/2.2.7}/golang/first/go.sum | 0 .../2.2/2.2.7}/golang/first/main.go | 0 .../golang/first/utils/uuid_convertor.go | 0 .../golang/first/another_package/mypack.go | 0 .../2.2/2.2.8}/golang/first/go.mod | 0 .../2.2/2.2.8}/golang/first/go.sum | 0 .../2.2/2.2.8}/golang/first/main.go | 0 .../golang/first/utils/uuid_convertor.go | 0 .../2.2/2.2.8}/golang/second/float.go | 0 .../2.2/2.2.8}/golang/second/go.mod | 0 .../2.2/2.2.8}/golang/second/integer.go | 0 .../golang/testing/calculator/calculator.go | 0 .../2.3/2.3.1}/golang/testing/go.mod | 0 .../2.3/2.3.1}/golang/testing/main.go | 0 .../golang/testing/test/calculator_test.go | 0 .../golang/testing/calculator/calculator.go | 0 .../2.3/2.3.2}/golang/testing/go.mod | 0 .../2.3/2.3.2}/golang/testing/main.go | 0 .../golang/testing/test/calculator_test.go | 0 .../golang/testing/calculator/calculator.go | 0 .../2.3/2.3.3}/golang/testing/go.mod | 0 .../2.3/2.3.3}/golang/testing/main.go | 0 .../golang/testing/test/calculator_test.go | 0 .../golang/testing/calculator/calculator.go | 0 .../calculator/calculator_bench_test.go | 0 .../testing/calculator/calculator_test.go | 0 .../2.3/2.3.4}/golang/testing/go.mod | 0 .../2.3/2.3.4}/golang/testing/main.go | 0 .../golang/testing/calculator/calculator.go | 0 .../testing/calculator/calculator_test.go | 0 .../2.3/2.3.5}/golang/testing/go.mod | 0 .../2.3/2.3.5}/golang/testing/main.go | 0 {part_11/11.6 => part_2/2.3/2.3.6}/1.go | 0 part_2/2.6/7.go | 14 -- part_2/2.6/8.go | 11 - part_3/3.1/1.go | 19 +- part_3/3.1/10.go | 20 ++ part_3/3.1/11.go | 21 ++ part_3/3.1/2.go | 27 ++- .../3.1/3.1.7}/golang/factory/go.mod | 0 .../3.1/3.1.7}/golang/factory/main.go | 0 .../3.1/3.1.7}/golang/factory/shape/shape.go | 0 part_3/3.1/3.go | 16 +- part_3/3.1/4.go | 19 +- part_3/3.1/5.go | 34 ++- part_3/3.1/6.go | 27 ++- part_3/3.1/7.go | 41 +++- part_3/3.1/8.go | 33 ++- part_3/3.1/9.go | 50 ++-- part_3/3.10/1.go | 25 +- {part_5/5.10 => part_3/3.10}/10.go | 0 part_3/3.10/2.go | 22 +- {part_5/5.10 => part_3/3.10}/3.go | 0 {part_5/5.10 => part_3/3.10}/4.go | 0 {part_5/5.10 => part_3/3.10}/5.go | 0 {part_5/5.10 => part_3/3.10}/6.go | 0 {part_5/5.10 => part_3/3.10}/7.go | 0 {part_5/5.10 => part_3/3.10}/8.go | 0 {part_5/5.10 => part_3/3.10}/9.go | 0 part_3/3.2/1.go | 31 +-- part_3/3.2/2.go | 36 +-- part_3/3.2/3.go | 36 +-- .../5.3 => part_3/3.3}/golang/factory/go.mod | 0 .../5.3 => part_3/3.3}/golang/factory/main.go | 0 .../3.3}/golang/factory/shape/shape.go | 0 .../5.4 => part_3/3.4}/golang/factory/go.mod | 0 .../5.4 => part_3/3.4}/golang/factory/main.go | 0 .../3.4}/golang/factory/shape/shape.go | 0 .../5.6 => part_3/3.6}/golang/factory/go.mod | 0 .../5.6 => part_3/3.6}/golang/factory/main.go | 0 .../3.6}/golang/factory/shape/rectangle.go | 0 .../3.6}/golang/factory/shape/shape.go | 0 .../5.7 => part_3/3.7}/golang/factory/go.mod | 0 .../5.7 => part_3/3.7}/golang/factory/main.go | 0 .../3.7}/golang/factory/shape/ishape.go | 0 .../3.7}/golang/factory/shape/rectangle.go | 0 .../3.7}/golang/factory/shape/shape.go | 0 .../3.7}/golang/factory/shape/triangle.go | 0 .../3.8}/golang/car_factory/go.mod | 0 .../3.8}/golang/car_factory/main.go | 0 .../3.8}/golang/car_factory/vehicle/car.go | 0 .../vehicle/motor/avtovaz_motor.go | 0 .../vehicle/motor/hyundai_motor.go | 0 .../car_factory/vehicle/motor/imotor.go | 0 .../golang/car_factory/vehicle/motor/motor.go | 0 part_3/3.9/1.go | 12 +- part_3/3.9/2.go | 19 +- {part_5/5.9 => part_3/3.9}/3.go | 0 {part_5/5.9 => part_3/3.9}/4.go | 0 {part_5/5.9 => part_3/3.9}/5.go | 0 {part_5/5.9 => part_3/3.9}/6.go | 0 {part_6/6.1 => part_4/4.1}/1.go | 0 {part_6/6.1 => part_4/4.1}/2.go | 0 {part_6/6.2 => part_4/4.2}/1.go | 0 {part_6/6.3 => part_4/4.3}/1.go | 0 {part_6/6.4 => part_4/4.4}/1.go | 0 {part_6/6.4 => part_4/4.4}/2.go | 0 {part_6/6.5 => part_4/4.5}/1.go | 0 {part_6/6.5 => part_4/4.5}/2.go | 0 {part_6/6.5 => part_4/4.5}/3.go | 0 {part_6/6.6 => part_4/4.6}/1.go | 0 {part_6/6.7 => part_4/4.7}/1.go | 0 {part_6/6.8 => part_4/4.8}/1.go | 0 {part_6/6.9 => part_4/4.9}/1.go | 0 part_5/5.1/1.go | 22 +- part_5/5.1/10.go | 24 +- {part_7/7.1 file => part_5/5.1}/11.go | 0 {part_7/7.1 file => part_5/5.1}/12.go | 0 {part_7/7.1 file => part_5/5.1}/13.go | 0 {part_7/7.1 file => part_5/5.1}/14.go | 0 {part_7/7.1 file => part_5/5.1}/15.go | 0 {part_7/7.1 file => part_5/5.1}/16.go | 0 {part_7/7.1 file => part_5/5.1}/17.go | 0 {part_7/7.1 file => part_5/5.1}/18.go | 0 {part_7/7.1 file => part_5/5.1}/19.go | 0 part_5/5.1/2.go | 36 ++- {part_7/7.1 file => part_5/5.1}/20.go | 0 part_5/5.1/3.go | 27 +-- part_5/5.1/4.go | 24 +- part_5/5.1/5.go | 30 ++- part_5/5.1/6.go | 47 ++-- part_5/5.1/7.go | 44 ++-- part_5/5.1/8.go | 48 ++-- part_5/5.1/9.go | 32 +-- part_5/5.10/1.go | 21 -- part_5/5.10/2.go | 13 -- part_5/5.2/1.go | 29 +-- {part_7/7.2 dir => part_5/5.2}/10.go | 0 {part_7/7.2 dir => part_5/5.2}/11.go | 0 {part_7/7.2 dir => part_5/5.2}/12.go | 0 part_5/5.2/2.go | 34 +-- part_5/5.2/3.go | 55 +++-- {part_7/7.2 dir => part_5/5.2}/4.go | 0 {part_7/7.2 dir => part_5/5.2}/5.go | 0 {part_7/7.2 dir => part_5/5.2}/6.go | 0 {part_7/7.2 dir => part_5/5.2}/7.go | 0 {part_7/7.2 dir => part_5/5.2}/8.go | 0 {part_7/7.2 dir => part_5/5.2}/9.go | 0 part_5/5.3/1.go | 30 +++ part_5/5.3/2.go | 36 +++ part_5/5.3/3.go | 31 +++ part_5/5.3/4.go | 43 ++++ part_5/5.3/5.go | 33 +++ part_5/5.3/6.go | 33 +++ part_5/5.3/7.go | 54 +++++ part_5/5.3/8.go | 32 +++ part_5/5.3/filmography/go.mod | 3 + part_5/5.3/filmography/imdb/actor.go | 8 + part_5/5.3/filmography/imdb/genre.go | 5 + part_5/5.3/filmography/imdb/movie.go | 13 ++ part_5/5.3/filmography/imdb/review.go | 7 + part_5/5.3/filmography/main.go | 33 +++ part_5/5.3/filmography/movie.json | 52 +++++ part_5/5.3/filmography/output.json | 52 +++++ part_5/5.6/go_dotenv/dotenv/dotenv.go | 162 +++++++++++++ part_5/5.6/go_dotenv/go.mod | 3 + part_5/5.6/go_dotenv/main.go | 40 ++++ part_5/5.6/my_app/go.mod | 3 + part_5/5.6/my_app/main.go | 24 ++ part_5/5.6/my_compile_app/go.mod | 3 + part_5/5.6/my_compile_app/main.go | 12 + part_5/5.6/my_embed_app/embed_config.json | 6 + part_5/5.6/my_embed_app/go.mod | 3 + part_5/5.6/my_embed_app/main.go | 32 +++ part_5/5.9/1.go | 8 - part_5/5.9/2.go | 19 -- part_5/go_database/.vscode/launch.json | 14 ++ part_5/go_database/database/database.go | 218 ++++++++++++++++++ part_5/go_database/database/i_attribute.go | 8 + part_5/go_database/database/table.go | 155 +++++++++++++ part_5/go_database/database/user.go | 132 +++++++++++ part_5/go_database/go.mod | 3 + part_5/go_database/main.go | 16 ++ part_5/go_database/menu.go | 214 +++++++++++++++++ part_5/go_database/suai.txt | 5 + part_5/go_database/unecon.txt | 4 + part_5/go_json_store/go.mod | 3 + part_5/go_json_store/jsonstore/json_file.go | 62 +++++ part_5/go_json_store/jsonstore/json_store.go | 200 ++++++++++++++++ part_5/go_json_store/main.go | 167 ++++++++++++++ part_5/go_json_store/store.json | 19 ++ .../6.1}/golang/todo/.vscode/launch.json | 0 .../8.1 => part_6/6.1}/golang/todo/db/db.go | 2 +- .../6.1}/golang/todo/db/db_definition.go | 0 .../6.1}/golang/todo/db/models.go | 0 part_6/6.1/golang/todo/db/projects_crud.go | 92 ++++++++ part_6/6.1/golang/todo/db/tasks_crud.go | 129 +++++++++++ {part_8/8.1 => part_6/6.1}/golang/todo/go.mod | 0 {part_8/8.1 => part_6/6.1}/golang/todo/go.sum | 0 .../6.1/golang/todo}/main.go | 3 + .../6.1/golang/todo}/menu/menu.go | 15 +- .../6.1/golang/todo}/menu/project_handlers.go | 12 +- .../6.1/golang/todo}/menu/task_handlers.go | 24 +- .../8.1 => part_6/6.1}/golang/todo/todo.db | Bin part_6/6.2/golang/todo_gorm/db/db.go | 94 ++++++++ .../6.2/golang/todo_gorm}/db/db_definition.go | 0 .../6.2}/golang/todo_gorm/db/models.go | 0 .../6.2}/golang/todo_gorm/db/projects_crud.go | 6 +- .../6.2}/golang/todo_gorm/db/tasks_crud.go | 28 ++- .../6.2}/golang/todo_gorm/go.mod | 0 .../6.2}/golang/todo_gorm/go.sum | 0 .../6.2/golang/todo_gorm}/main.go | 0 .../6.2/golang/todo_gorm}/menu/menu.go | 0 .../todo_gorm}/menu/project_handlers.go | 0 .../golang/todo_gorm}/menu/task_handlers.go | 0 .../6.2}/golang/todo_gorm/todo.db | Bin 16384 -> 20480 bytes .../6.3}/golang/todo_transaction/go.mod | 0 .../6.3}/golang/todo_transaction/go.sum | 0 .../6.3}/golang/todo_transaction/main.go | 0 .../6.3}/golang/todo_transaction/todo.db | Bin part_7/7.1 file/1.go | 16 -- part_7/7.1 file/10.go | 15 -- part_7/7.1 file/2.go | 19 -- part_7/7.1 file/3.go | 17 -- part_7/7.1 file/4.go | 14 -- part_7/7.1 file/5.go | 20 -- part_7/7.1 file/6.go | 23 -- part_7/7.1 file/7.go | 29 --- part_7/7.1 file/8.go | 28 --- part_7/7.1 file/9.go | 22 -- {part_9/9.10 => part_7/7.10}/fan-in.go | 0 {part_9/9.10 => part_7/7.10}/fan-out.go | 0 {part_9/9.10 => part_7/7.10}/generator.go | 0 {part_9/9.10 => part_7/7.10}/pipeline.go | 0 {part_9/9.10 => part_7/7.10}/queuing.go | 0 {part_9/9.10 => part_7/7.10}/workerpool.go | 0 part_7/7.2 dir/1.go | 15 -- part_7/7.2 dir/2.go | 15 -- part_7/7.2 dir/3.go | 48 ---- part_7/7.3 json/1.go | 36 --- part_7/7.3 json/2.go | 38 --- part_7/7.3 json/3.go | 31 --- part_7/7.3 json/4.go | 36 --- part_7/7.3 json/5.go | 36 --- part_7/7.3 json/6.go | 81 ------- part_7/7.3 json/7.go | 38 --- part_7/7.3 json/8.go | 38 --- {part_9/9.3 => part_7/7.3}/1.go | 0 {part_9/9.3 => part_7/7.3}/2.go | 0 {part_9/9.3 => part_7/7.3}/3.go | 0 {part_9/9.3 => part_7/7.3}/4.go | 0 {part_9/9.4 => part_7/7.4}/1.go | 0 {part_9/9.4 => part_7/7.4}/2.go | 0 {part_9/9.4 => part_7/7.4}/3.go | 0 {part_9/9.5 => part_7/7.5}/1.go | 0 {part_9/9.5 => part_7/7.5}/10.go | 0 {part_9/9.5 => part_7/7.5}/11.go | 0 {part_9/9.5 => part_7/7.5}/12.go | 0 {part_9/9.5 => part_7/7.5}/13.go | 0 {part_9/9.5 => part_7/7.5}/14.go | 0 {part_9/9.5 => part_7/7.5}/15.go | 0 {part_9/9.5 => part_7/7.5}/2.go | 7 +- {part_9/9.5 => part_7/7.5}/3.go | 0 {part_9/9.5 => part_7/7.5}/4.go | 0 {part_9/9.5 => part_7/7.5}/5.go | 0 {part_9/9.5 => part_7/7.5}/6.go | 0 {part_9/9.5 => part_7/7.5}/7.go | 0 {part_9/9.5 => part_7/7.5}/8.go | 0 {part_9/9.5 => part_7/7.5}/9.go | 0 {part_9/9.6 => part_7/7.6}/1.go | 0 part_9/9.7/2.go => part_7/7.7/1.go | 0 part_9/9.7/1.go => part_7/7.7/2.go | 0 {part_9/9.7 => part_7/7.7}/3.go | 0 part_7/7.7/4.go | 128 ++++++++++ {part_9/9.8 => part_7/7.8}/1.go | 0 {part_9/9.8 => part_7/7.8}/2.go | 0 {part_9/9.9 => part_7/7.9}/1.go | 0 {part_9/9.9 => part_7/7.9}/2.go | 0 part_8/8.1/golang/todo/db/projects_crud.go | 68 ------ part_8/8.1/golang/todo/db/tasks_crud.go | 96 -------- .../10.1 => part_8/8.1}/udp/client/client.go | 0 {part_10/10.1 => part_8/8.1}/udp/go.mod | 0 {part_10/10.1 => part_8/8.1}/udp/main.go | 0 .../10.1 => part_8/8.1}/udp/server/server.go | 0 part_8/8.2/golang/todo_gorm/db/db.go | 112 --------- .../10.2 => part_8/8.2}/tcp/client/client.go | 0 {part_10/10.2 => part_8/8.2}/tcp/go.mod | 0 {part_10/10.2 => part_8/8.2}/tcp/main.go | 0 .../10.2 => part_8/8.2}/tcp/server/server.go | 0 .../8.3}/tcp-chat/client/client.go | 0 {part_10/10.3 => part_8/8.3}/tcp-chat/go.mod | 0 {part_10/10.3 => part_8/8.3}/tcp-chat/main.go | 0 .../8.3}/tcp-chat/server/server.go | 0 .../golang/todo-service/.vscode/settings.json | 0 .../8.4}/golang/todo-service/db/db.go | 0 .../golang/todo-service}/db/db_definition.go | 0 .../8.4}/golang/todo-service/db/models.go | 0 .../golang/todo-service/db/projects_crud.go | 0 .../8.4}/golang/todo-service/db/tasks_crud.go | 0 .../8.4}/golang/todo-service/go.mod | 0 .../8.4}/golang/todo-service/go.sum | 0 .../8.4}/golang/todo-service/main.go | 0 .../golang/todo-service/service/api_models.go | 0 .../todo-service/service/api_project.go | 0 .../golang/todo-service/service/api_task.go | 0 .../golang/todo-service/service/logger.go | 0 .../golang/todo-service/service/routers.go | 0 .../golang/todo-service/todo-service-api.yml | 0 .../8.4}/golang/todo-service/todo.db | Bin 408 files changed, 4280 insertions(+), 1441 deletions(-) rename {part_2/2.5.1 => part_1/1.10/1.10.1}/1.go (100%) rename {part_2/2.5.1 => part_1/1.10/1.10.1}/2.go (100%) rename {part_2/2.5.1 => part_1/1.10/1.10.1}/3.go (100%) rename {part_2/2.5.1 => part_1/1.10/1.10.1}/4.go (100%) rename {part_2/2.5.1 => part_1/1.10/1.10.1}/5.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/1.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/2.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/3.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/4.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/5.go (100%) rename {part_2/2.5.2 => part_1/1.10/1.10.2}/6.go (100%) rename {part_2/2.6 => part_1/1.11}/1.go (100%) create mode 100644 part_1/1.11/10.go create mode 100644 part_1/1.11/11.go rename {part_2/2.6 => part_1/1.11}/2.go (100%) rename {part_2/2.6 => part_1/1.11}/3.go (100%) rename {part_2/2.6 => part_1/1.11}/4.go (100%) rename {part_2/2.6 => part_1/1.11}/5.go (100%) rename {part_2/2.6 => part_1/1.11}/6.go (100%) create mode 100644 part_1/1.11/7.go rename part_2/2.6/9.go => part_1/1.11/8.go (66%) create mode 100644 part_1/1.11/9.go rename {part_2/2.7 => part_1/1.12}/1.go (100%) rename {part_2/2.7 => part_1/1.12}/2.go (100%) rename {part_2/2.7 => part_1/1.12}/3.go (100%) create mode 100644 part_1/1.13/1.go create mode 100644 part_1/1.13/10.go create mode 100644 part_1/1.13/2.go create mode 100644 part_1/1.13/3.go create mode 100644 part_1/1.13/4.go create mode 100644 part_1/1.13/5.go create mode 100644 part_1/1.13/6.go create mode 100644 part_1/1.13/7.go create mode 100644 part_1/1.13/8.go create mode 100644 part_1/1.13/9.go create mode 100644 part_1/1.14/1.go create mode 100644 part_1/1.14/10.go create mode 100644 part_1/1.14/11.go create mode 100644 part_1/1.14/12.go create mode 100644 part_1/1.14/13.go create mode 100644 part_1/1.14/14.go create mode 100644 part_1/1.14/15.go create mode 100644 part_1/1.14/2.go create mode 100644 part_1/1.14/3.go create mode 100644 part_1/1.14/4.go create mode 100644 part_1/1.14/5.go create mode 100644 part_1/1.14/6.go create mode 100644 part_1/1.14/7.go create mode 100644 part_1/1.14/8.go create mode 100644 part_1/1.14/9.go create mode 100644 part_1/1.15/1.go create mode 100644 part_1/1.15/10.go create mode 100644 part_1/1.15/11.go create mode 100644 part_1/1.15/12.go create mode 100644 part_1/1.15/13.go create mode 100644 part_1/1.15/14.go create mode 100644 part_1/1.15/15.go create mode 100644 part_1/1.15/16.go create mode 100644 part_1/1.15/2.go create mode 100644 part_1/1.15/3.go create mode 100644 part_1/1.15/4.go create mode 100644 part_1/1.15/5.go create mode 100644 part_1/1.15/6.go create mode 100644 part_1/1.15/7.go create mode 100644 part_1/1.15/8.go create mode 100644 part_1/1.15/9.go create mode 100644 part_1/1.16/1.go create mode 100644 part_1/1.16/2.go create mode 100644 part_1/1.16/3.go create mode 100644 part_1/1.16/4.go create mode 100644 part_1/1.16/5.go create mode 100644 part_1/1.16/6.go create mode 100644 part_1/1.16/7.go create mode 100644 part_1/1.17/1.go create mode 100644 part_2/2.1/2.1.1/1.go create mode 100644 part_2/2.1/2.1.1/2.go create mode 100644 part_2/2.1/2.1.1/3.go rename {part_3/3.2 => part_2/2.1/2.1.1}/4.go (100%) rename {part_3/3.2 => part_2/2.1/2.1.1}/5.go (100%) rename {part_3/3.11 => part_2/2.1/2.1.10}/1.go (100%) rename {part_3/3.11 => part_2/2.1/2.1.10}/2.go (100%) create mode 100644 part_2/2.1/2.1.10/3.go rename {part_3/3.3 => part_2/2.1/2.1.2}/1.go (100%) rename {part_3/3.3 => part_2/2.1/2.1.2}/2.go (100%) rename {part_3/3.4 => part_2/2.1/2.1.3}/1.go (100%) rename {part_3/3.4 => part_2/2.1/2.1.3}/2.go (100%) rename {part_3/3.4 => part_2/2.1/2.1.3}/3.go (100%) rename {part_3/3.4 => part_2/2.1/2.1.3}/4.go (100%) rename {part_3/3.5 => part_2/2.1/2.1.4}/1.go (100%) rename {part_3/3.6 => part_2/2.1/2.1.5}/1.go (100%) rename {part_3/3.6 => part_2/2.1/2.1.5}/2.go (100%) rename {part_3/3.7 => part_2/2.1/2.1.6}/1.go (100%) rename {part_3/3.8 => part_2/2.1/2.1.7}/1.go (100%) rename {part_3/3.8 => part_2/2.1/2.1.7}/2.go (100%) create mode 100644 part_2/2.1/2.1.7/3.go create mode 100644 part_2/2.1/2.1.8/1.go create mode 100644 part_2/2.1/2.1.8/2.go create mode 100644 part_2/2.1/2.1.9/1.go create mode 100644 part_2/2.1/2.1.9/2.go rename {part_4/4.1-4.2 => part_2/2.2/2.2.1-2.2.2}/golang/first/go.mod (100%) rename {part_4/4.1-4.2 => part_2/2.2/2.2.1-2.2.2}/golang/first/go.sum (100%) rename {part_4/4.1-4.2 => part_2/2.2/2.2.1-2.2.2}/golang/first/main.go (100%) rename {part_4/4.6 => part_2/2.2/2.2.6}/golang/first/go.mod (100%) rename {part_4/4.6 => part_2/2.2/2.2.6}/golang/first/go.sum (100%) rename {part_4/4.6 => part_2/2.2/2.2.6}/golang/first/main.go (100%) rename {part_4/4.6 => part_2/2.2/2.2.6}/golang/first/utils/uuid_convertor.go (100%) rename {part_4/4.7 => part_2/2.2/2.2.7}/golang/first/another_package/mypack.go (100%) rename {part_4/4.7 => part_2/2.2/2.2.7}/golang/first/go.mod (100%) rename {part_4/4.7 => part_2/2.2/2.2.7}/golang/first/go.sum (100%) rename {part_4/4.7 => part_2/2.2/2.2.7}/golang/first/main.go (100%) rename {part_4/4.7 => part_2/2.2/2.2.7}/golang/first/utils/uuid_convertor.go (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/first/another_package/mypack.go (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/first/go.mod (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/first/go.sum (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/first/main.go (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/first/utils/uuid_convertor.go (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/second/float.go (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/second/go.mod (100%) rename {part_4/4.8 => part_2/2.2/2.2.8}/golang/second/integer.go (100%) rename {part_11/11.1 => part_2/2.3/2.3.1}/golang/testing/calculator/calculator.go (100%) rename {part_11/11.1 => part_2/2.3/2.3.1}/golang/testing/go.mod (100%) rename {part_11/11.1 => part_2/2.3/2.3.1}/golang/testing/main.go (100%) rename {part_11/11.1 => part_2/2.3/2.3.1}/golang/testing/test/calculator_test.go (100%) rename {part_11/11.2 => part_2/2.3/2.3.2}/golang/testing/calculator/calculator.go (100%) rename {part_11/11.2 => part_2/2.3/2.3.2}/golang/testing/go.mod (100%) rename {part_11/11.2 => part_2/2.3/2.3.2}/golang/testing/main.go (100%) rename {part_11/11.2 => part_2/2.3/2.3.2}/golang/testing/test/calculator_test.go (100%) rename {part_11/11.3 => part_2/2.3/2.3.3}/golang/testing/calculator/calculator.go (100%) rename {part_11/11.3 => part_2/2.3/2.3.3}/golang/testing/go.mod (100%) rename {part_11/11.3 => part_2/2.3/2.3.3}/golang/testing/main.go (100%) rename {part_11/11.3 => part_2/2.3/2.3.3}/golang/testing/test/calculator_test.go (100%) rename {part_11/11.4 => part_2/2.3/2.3.4}/golang/testing/calculator/calculator.go (100%) rename {part_11/11.4 => part_2/2.3/2.3.4}/golang/testing/calculator/calculator_bench_test.go (100%) rename {part_11/11.4 => part_2/2.3/2.3.4}/golang/testing/calculator/calculator_test.go (100%) rename {part_11/11.4 => part_2/2.3/2.3.4}/golang/testing/go.mod (100%) rename {part_11/11.4 => part_2/2.3/2.3.4}/golang/testing/main.go (100%) rename {part_11/11.5 => part_2/2.3/2.3.5}/golang/testing/calculator/calculator.go (100%) rename {part_11/11.5 => part_2/2.3/2.3.5}/golang/testing/calculator/calculator_test.go (100%) rename {part_11/11.5 => part_2/2.3/2.3.5}/golang/testing/go.mod (100%) rename {part_11/11.5 => part_2/2.3/2.3.5}/golang/testing/main.go (100%) rename {part_11/11.6 => part_2/2.3/2.3.6}/1.go (100%) delete mode 100644 part_2/2.6/7.go delete mode 100644 part_2/2.6/8.go create mode 100644 part_3/3.1/10.go create mode 100644 part_3/3.1/11.go rename {part_5/5.1/5.1.7 => part_3/3.1/3.1.7}/golang/factory/go.mod (100%) rename {part_5/5.1/5.1.7 => part_3/3.1/3.1.7}/golang/factory/main.go (100%) rename {part_5/5.1/5.1.7 => part_3/3.1/3.1.7}/golang/factory/shape/shape.go (100%) rename {part_5/5.10 => part_3/3.10}/10.go (100%) rename {part_5/5.10 => part_3/3.10}/3.go (100%) rename {part_5/5.10 => part_3/3.10}/4.go (100%) rename {part_5/5.10 => part_3/3.10}/5.go (100%) rename {part_5/5.10 => part_3/3.10}/6.go (100%) rename {part_5/5.10 => part_3/3.10}/7.go (100%) rename {part_5/5.10 => part_3/3.10}/8.go (100%) rename {part_5/5.10 => part_3/3.10}/9.go (100%) rename {part_5/5.3 => part_3/3.3}/golang/factory/go.mod (100%) rename {part_5/5.3 => part_3/3.3}/golang/factory/main.go (100%) rename {part_5/5.3 => part_3/3.3}/golang/factory/shape/shape.go (100%) rename {part_5/5.4 => part_3/3.4}/golang/factory/go.mod (100%) rename {part_5/5.4 => part_3/3.4}/golang/factory/main.go (100%) rename {part_5/5.4 => part_3/3.4}/golang/factory/shape/shape.go (100%) rename {part_5/5.6 => part_3/3.6}/golang/factory/go.mod (100%) rename {part_5/5.6 => part_3/3.6}/golang/factory/main.go (100%) rename {part_5/5.6 => part_3/3.6}/golang/factory/shape/rectangle.go (100%) rename {part_5/5.6 => part_3/3.6}/golang/factory/shape/shape.go (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/go.mod (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/main.go (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/shape/ishape.go (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/shape/rectangle.go (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/shape/shape.go (100%) rename {part_5/5.7 => part_3/3.7}/golang/factory/shape/triangle.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/go.mod (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/main.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/vehicle/car.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/vehicle/motor/avtovaz_motor.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/vehicle/motor/hyundai_motor.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/vehicle/motor/imotor.go (100%) rename {part_5/5.8 => part_3/3.8}/golang/car_factory/vehicle/motor/motor.go (100%) rename {part_5/5.9 => part_3/3.9}/3.go (100%) rename {part_5/5.9 => part_3/3.9}/4.go (100%) rename {part_5/5.9 => part_3/3.9}/5.go (100%) rename {part_5/5.9 => part_3/3.9}/6.go (100%) rename {part_6/6.1 => part_4/4.1}/1.go (100%) rename {part_6/6.1 => part_4/4.1}/2.go (100%) rename {part_6/6.2 => part_4/4.2}/1.go (100%) rename {part_6/6.3 => part_4/4.3}/1.go (100%) rename {part_6/6.4 => part_4/4.4}/1.go (100%) rename {part_6/6.4 => part_4/4.4}/2.go (100%) rename {part_6/6.5 => part_4/4.5}/1.go (100%) rename {part_6/6.5 => part_4/4.5}/2.go (100%) rename {part_6/6.5 => part_4/4.5}/3.go (100%) rename {part_6/6.6 => part_4/4.6}/1.go (100%) rename {part_6/6.7 => part_4/4.7}/1.go (100%) rename {part_6/6.8 => part_4/4.8}/1.go (100%) rename {part_6/6.9 => part_4/4.9}/1.go (100%) rename {part_7/7.1 file => part_5/5.1}/11.go (100%) rename {part_7/7.1 file => part_5/5.1}/12.go (100%) rename {part_7/7.1 file => part_5/5.1}/13.go (100%) rename {part_7/7.1 file => part_5/5.1}/14.go (100%) rename {part_7/7.1 file => part_5/5.1}/15.go (100%) rename {part_7/7.1 file => part_5/5.1}/16.go (100%) rename {part_7/7.1 file => part_5/5.1}/17.go (100%) rename {part_7/7.1 file => part_5/5.1}/18.go (100%) rename {part_7/7.1 file => part_5/5.1}/19.go (100%) rename {part_7/7.1 file => part_5/5.1}/20.go (100%) delete mode 100644 part_5/5.10/1.go delete mode 100644 part_5/5.10/2.go rename {part_7/7.2 dir => part_5/5.2}/10.go (100%) rename {part_7/7.2 dir => part_5/5.2}/11.go (100%) rename {part_7/7.2 dir => part_5/5.2}/12.go (100%) rename {part_7/7.2 dir => part_5/5.2}/4.go (100%) rename {part_7/7.2 dir => part_5/5.2}/5.go (100%) rename {part_7/7.2 dir => part_5/5.2}/6.go (100%) rename {part_7/7.2 dir => part_5/5.2}/7.go (100%) rename {part_7/7.2 dir => part_5/5.2}/8.go (100%) rename {part_7/7.2 dir => part_5/5.2}/9.go (100%) create mode 100644 part_5/5.3/1.go create mode 100644 part_5/5.3/2.go create mode 100644 part_5/5.3/3.go create mode 100644 part_5/5.3/4.go create mode 100644 part_5/5.3/5.go create mode 100644 part_5/5.3/6.go create mode 100644 part_5/5.3/7.go create mode 100644 part_5/5.3/8.go create mode 100644 part_5/5.3/filmography/go.mod create mode 100644 part_5/5.3/filmography/imdb/actor.go create mode 100644 part_5/5.3/filmography/imdb/genre.go create mode 100644 part_5/5.3/filmography/imdb/movie.go create mode 100644 part_5/5.3/filmography/imdb/review.go create mode 100644 part_5/5.3/filmography/main.go create mode 100644 part_5/5.3/filmography/movie.json create mode 100644 part_5/5.3/filmography/output.json create mode 100644 part_5/5.6/go_dotenv/dotenv/dotenv.go create mode 100644 part_5/5.6/go_dotenv/go.mod create mode 100644 part_5/5.6/go_dotenv/main.go create mode 100644 part_5/5.6/my_app/go.mod create mode 100644 part_5/5.6/my_app/main.go create mode 100644 part_5/5.6/my_compile_app/go.mod create mode 100644 part_5/5.6/my_compile_app/main.go create mode 100644 part_5/5.6/my_embed_app/embed_config.json create mode 100644 part_5/5.6/my_embed_app/go.mod create mode 100644 part_5/5.6/my_embed_app/main.go delete mode 100644 part_5/5.9/1.go delete mode 100644 part_5/5.9/2.go create mode 100644 part_5/go_database/.vscode/launch.json create mode 100644 part_5/go_database/database/database.go create mode 100644 part_5/go_database/database/i_attribute.go create mode 100644 part_5/go_database/database/table.go create mode 100644 part_5/go_database/database/user.go create mode 100644 part_5/go_database/go.mod create mode 100644 part_5/go_database/main.go create mode 100644 part_5/go_database/menu.go create mode 100644 part_5/go_database/suai.txt create mode 100644 part_5/go_database/unecon.txt create mode 100644 part_5/go_json_store/go.mod create mode 100644 part_5/go_json_store/jsonstore/json_file.go create mode 100644 part_5/go_json_store/jsonstore/json_store.go create mode 100644 part_5/go_json_store/main.go create mode 100644 part_5/go_json_store/store.json rename {part_8/8.1 => part_6/6.1}/golang/todo/.vscode/launch.json (100%) rename {part_8/8.1 => part_6/6.1}/golang/todo/db/db.go (97%) rename {part_8/8.1 => part_6/6.1}/golang/todo/db/db_definition.go (100%) rename {part_8/8.1 => part_6/6.1}/golang/todo/db/models.go (100%) create mode 100644 part_6/6.1/golang/todo/db/projects_crud.go create mode 100644 part_6/6.1/golang/todo/db/tasks_crud.go rename {part_8/8.1 => part_6/6.1}/golang/todo/go.mod (100%) rename {part_8/8.1 => part_6/6.1}/golang/todo/go.sum (100%) rename {part_8/8.2/golang/todo_gorm => part_6/6.1/golang/todo}/main.go (55%) rename {part_8/8.2/golang/todo_gorm => part_6/6.1/golang/todo}/menu/menu.go (71%) rename {part_8/8.2/golang/todo_gorm => part_6/6.1/golang/todo}/menu/project_handlers.go (65%) rename {part_8/8.2/golang/todo_gorm => part_6/6.1/golang/todo}/menu/task_handlers.go (73%) rename {part_8/8.1 => part_6/6.1}/golang/todo/todo.db (100%) create mode 100644 part_6/6.2/golang/todo_gorm/db/db.go rename {part_10/10.4/golang/todo-service => part_6/6.2/golang/todo_gorm}/db/db_definition.go (100%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/db/models.go (100%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/db/projects_crud.go (73%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/db/tasks_crud.go (50%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/go.mod (100%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/go.sum (100%) rename {part_8/8.1/golang/todo => part_6/6.2/golang/todo_gorm}/main.go (100%) rename {part_8/8.1/golang/todo => part_6/6.2/golang/todo_gorm}/menu/menu.go (100%) rename {part_8/8.1/golang/todo => part_6/6.2/golang/todo_gorm}/menu/project_handlers.go (100%) rename {part_8/8.1/golang/todo => part_6/6.2/golang/todo_gorm}/menu/task_handlers.go (100%) rename {part_8/8.2 => part_6/6.2}/golang/todo_gorm/todo.db (75%) rename {part_8/8.3 => part_6/6.3}/golang/todo_transaction/go.mod (100%) rename {part_8/8.3 => part_6/6.3}/golang/todo_transaction/go.sum (100%) rename {part_8/8.3 => part_6/6.3}/golang/todo_transaction/main.go (100%) rename {part_8/8.3 => part_6/6.3}/golang/todo_transaction/todo.db (100%) delete mode 100644 part_7/7.1 file/1.go delete mode 100644 part_7/7.1 file/10.go delete mode 100644 part_7/7.1 file/2.go delete mode 100644 part_7/7.1 file/3.go delete mode 100644 part_7/7.1 file/4.go delete mode 100644 part_7/7.1 file/5.go delete mode 100644 part_7/7.1 file/6.go delete mode 100644 part_7/7.1 file/7.go delete mode 100644 part_7/7.1 file/8.go delete mode 100644 part_7/7.1 file/9.go rename {part_9/9.10 => part_7/7.10}/fan-in.go (100%) rename {part_9/9.10 => part_7/7.10}/fan-out.go (100%) rename {part_9/9.10 => part_7/7.10}/generator.go (100%) rename {part_9/9.10 => part_7/7.10}/pipeline.go (100%) rename {part_9/9.10 => part_7/7.10}/queuing.go (100%) rename {part_9/9.10 => part_7/7.10}/workerpool.go (100%) delete mode 100644 part_7/7.2 dir/1.go delete mode 100644 part_7/7.2 dir/2.go delete mode 100644 part_7/7.2 dir/3.go delete mode 100644 part_7/7.3 json/1.go delete mode 100644 part_7/7.3 json/2.go delete mode 100644 part_7/7.3 json/3.go delete mode 100644 part_7/7.3 json/4.go delete mode 100644 part_7/7.3 json/5.go delete mode 100644 part_7/7.3 json/6.go delete mode 100644 part_7/7.3 json/7.go delete mode 100644 part_7/7.3 json/8.go rename {part_9/9.3 => part_7/7.3}/1.go (100%) rename {part_9/9.3 => part_7/7.3}/2.go (100%) rename {part_9/9.3 => part_7/7.3}/3.go (100%) rename {part_9/9.3 => part_7/7.3}/4.go (100%) rename {part_9/9.4 => part_7/7.4}/1.go (100%) rename {part_9/9.4 => part_7/7.4}/2.go (100%) rename {part_9/9.4 => part_7/7.4}/3.go (100%) rename {part_9/9.5 => part_7/7.5}/1.go (100%) rename {part_9/9.5 => part_7/7.5}/10.go (100%) rename {part_9/9.5 => part_7/7.5}/11.go (100%) rename {part_9/9.5 => part_7/7.5}/12.go (100%) rename {part_9/9.5 => part_7/7.5}/13.go (100%) rename {part_9/9.5 => part_7/7.5}/14.go (100%) rename {part_9/9.5 => part_7/7.5}/15.go (100%) rename {part_9/9.5 => part_7/7.5}/2.go (56%) rename {part_9/9.5 => part_7/7.5}/3.go (100%) rename {part_9/9.5 => part_7/7.5}/4.go (100%) rename {part_9/9.5 => part_7/7.5}/5.go (100%) rename {part_9/9.5 => part_7/7.5}/6.go (100%) rename {part_9/9.5 => part_7/7.5}/7.go (100%) rename {part_9/9.5 => part_7/7.5}/8.go (100%) rename {part_9/9.5 => part_7/7.5}/9.go (100%) rename {part_9/9.6 => part_7/7.6}/1.go (100%) rename part_9/9.7/2.go => part_7/7.7/1.go (100%) rename part_9/9.7/1.go => part_7/7.7/2.go (100%) rename {part_9/9.7 => part_7/7.7}/3.go (100%) create mode 100644 part_7/7.7/4.go rename {part_9/9.8 => part_7/7.8}/1.go (100%) rename {part_9/9.8 => part_7/7.8}/2.go (100%) rename {part_9/9.9 => part_7/7.9}/1.go (100%) rename {part_9/9.9 => part_7/7.9}/2.go (100%) delete mode 100644 part_8/8.1/golang/todo/db/projects_crud.go delete mode 100644 part_8/8.1/golang/todo/db/tasks_crud.go rename {part_10/10.1 => part_8/8.1}/udp/client/client.go (100%) rename {part_10/10.1 => part_8/8.1}/udp/go.mod (100%) rename {part_10/10.1 => part_8/8.1}/udp/main.go (100%) rename {part_10/10.1 => part_8/8.1}/udp/server/server.go (100%) delete mode 100644 part_8/8.2/golang/todo_gorm/db/db.go rename {part_10/10.2 => part_8/8.2}/tcp/client/client.go (100%) rename {part_10/10.2 => part_8/8.2}/tcp/go.mod (100%) rename {part_10/10.2 => part_8/8.2}/tcp/main.go (100%) rename {part_10/10.2 => part_8/8.2}/tcp/server/server.go (100%) rename {part_10/10.3 => part_8/8.3}/tcp-chat/client/client.go (100%) rename {part_10/10.3 => part_8/8.3}/tcp-chat/go.mod (100%) rename {part_10/10.3 => part_8/8.3}/tcp-chat/main.go (100%) rename {part_10/10.3 => part_8/8.3}/tcp-chat/server/server.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/.vscode/settings.json (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/db/db.go (100%) rename part_8/{8.2/golang/todo_gorm => 8.4/golang/todo-service}/db/db_definition.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/db/models.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/db/projects_crud.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/db/tasks_crud.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/go.mod (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/go.sum (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/main.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/service/api_models.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/service/api_project.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/service/api_task.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/service/logger.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/service/routers.go (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/todo-service-api.yml (100%) rename {part_10/10.4 => part_8/8.4}/golang/todo-service/todo.db (100%) diff --git a/README.md b/README.md index c337695..0f4a217 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# Репозиторий книги [Основы Go: Community edition 1-е издание](https://boosty.to/madteacher/posts/fbd0739f-20ba-4a6f-afe8-ac2fee2c8f8f?share=post_link) +# Репозиторий книги "Основы Go: Community edition" +- В главной ветке приведен исходный код [1-го издания книги]*[ссылка добавится позже]*, и курса на Stepik ["Основы Go"](https://stepik.org/a/236054) +- В ветке [сommunity_edition](https://github.com/MADTeacher/go_basics/tree/сommunity_edition) находится исходный код для бесплатной версии книги [«Основы Go: Community edition»](https://boosty.to/madteacher/posts/fbd0739f-20ba-4a6f-afe8-ac2fee2c8f8f?share=post_link) + + +## Автор книги и его тг-канал +- **Станислав Чернышев** (автор "Основы Dart", "Основы Go" и других книг, идейный вдохновитель и технический редактор "Основы Flutter"). Веду тг-канал ["MADTeacher"](https://t.me/+FfxRnFhth7IyNDBi), где делюсь своими мыслями по творящемуся в образовании, мире IT и Dart/Flutter diff --git a/part_2/2.5.1/1.go b/part_1/1.10/1.10.1/1.go similarity index 100% rename from part_2/2.5.1/1.go rename to part_1/1.10/1.10.1/1.go diff --git a/part_2/2.5.1/2.go b/part_1/1.10/1.10.1/2.go similarity index 100% rename from part_2/2.5.1/2.go rename to part_1/1.10/1.10.1/2.go diff --git a/part_2/2.5.1/3.go b/part_1/1.10/1.10.1/3.go similarity index 100% rename from part_2/2.5.1/3.go rename to part_1/1.10/1.10.1/3.go diff --git a/part_2/2.5.1/4.go b/part_1/1.10/1.10.1/4.go similarity index 100% rename from part_2/2.5.1/4.go rename to part_1/1.10/1.10.1/4.go diff --git a/part_2/2.5.1/5.go b/part_1/1.10/1.10.1/5.go similarity index 100% rename from part_2/2.5.1/5.go rename to part_1/1.10/1.10.1/5.go diff --git a/part_2/2.5.2/1.go b/part_1/1.10/1.10.2/1.go similarity index 100% rename from part_2/2.5.2/1.go rename to part_1/1.10/1.10.2/1.go diff --git a/part_2/2.5.2/2.go b/part_1/1.10/1.10.2/2.go similarity index 100% rename from part_2/2.5.2/2.go rename to part_1/1.10/1.10.2/2.go diff --git a/part_2/2.5.2/3.go b/part_1/1.10/1.10.2/3.go similarity index 100% rename from part_2/2.5.2/3.go rename to part_1/1.10/1.10.2/3.go diff --git a/part_2/2.5.2/4.go b/part_1/1.10/1.10.2/4.go similarity index 100% rename from part_2/2.5.2/4.go rename to part_1/1.10/1.10.2/4.go diff --git a/part_2/2.5.2/5.go b/part_1/1.10/1.10.2/5.go similarity index 100% rename from part_2/2.5.2/5.go rename to part_1/1.10/1.10.2/5.go diff --git a/part_2/2.5.2/6.go b/part_1/1.10/1.10.2/6.go similarity index 100% rename from part_2/2.5.2/6.go rename to part_1/1.10/1.10.2/6.go diff --git a/part_2/2.6/1.go b/part_1/1.11/1.go similarity index 100% rename from part_2/2.6/1.go rename to part_1/1.11/1.go diff --git a/part_1/1.11/10.go b/part_1/1.11/10.go new file mode 100644 index 0000000..bd36b87 --- /dev/null +++ b/part_1/1.11/10.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + s := "Hello" + + for i := 0; i < len(s); i++ { + fmt.Printf("Byte index: %d, Symbol: %c\n", i, s[i]) + } +} diff --git a/part_1/1.11/11.go b/part_1/1.11/11.go new file mode 100644 index 0000000..949def2 --- /dev/null +++ b/part_1/1.11/11.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func main() { + + for i := 0; i < 5; i++ { + fmt.Printf("%d ", i) + } + fmt.Println() + + // или + for i := range 5 { + fmt.Printf("%d ", i) + } + fmt.Println() + + // или + i := 0 + for range 5 { + fmt.Printf("%d ", i) + i++ + } +} diff --git a/part_2/2.6/2.go b/part_1/1.11/2.go similarity index 100% rename from part_2/2.6/2.go rename to part_1/1.11/2.go diff --git a/part_2/2.6/3.go b/part_1/1.11/3.go similarity index 100% rename from part_2/2.6/3.go rename to part_1/1.11/3.go diff --git a/part_2/2.6/4.go b/part_1/1.11/4.go similarity index 100% rename from part_2/2.6/4.go rename to part_1/1.11/4.go diff --git a/part_2/2.6/5.go b/part_1/1.11/5.go similarity index 100% rename from part_2/2.6/5.go rename to part_1/1.11/5.go diff --git a/part_2/2.6/6.go b/part_1/1.11/6.go similarity index 100% rename from part_2/2.6/6.go rename to part_1/1.11/6.go diff --git a/part_1/1.11/7.go b/part_1/1.11/7.go new file mode 100644 index 0000000..6e05036 --- /dev/null +++ b/part_1/1.11/7.go @@ -0,0 +1,22 @@ +package main + +import "fmt" + +func main() { + array := [4]int{2, 5, 6, 0} + for i, v := range array { + // i - номер индекса элемента + // v – копия значения, хранящаяся по индексу i + v += 3 + fmt.Printf("%d) %d || ", i, v) + } + // 0) 5 || 1) 8 || 2) 9 || 3) 3 || + fmt.Println() + fmt.Println(array) // [2 5 6 0] + + // изменение значения элемента коллекции + for i := range array { + array[i] += 3 + } + fmt.Println(array) // [5 8 9 3] +} diff --git a/part_2/2.6/9.go b/part_1/1.11/8.go similarity index 66% rename from part_2/2.6/9.go rename to part_1/1.11/8.go index c6d21d2..c74c71d 100644 --- a/part_2/2.6/9.go +++ b/part_1/1.11/8.go @@ -10,6 +10,8 @@ func main() { } for i, v := range myMap { + // i - ключ + // v – копия значения, хранящаяся по ключу i fmt.Printf("key = %d, value = %s\n", i, v) } } diff --git a/part_1/1.11/9.go b/part_1/1.11/9.go new file mode 100644 index 0000000..357a360 --- /dev/null +++ b/part_1/1.11/9.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + s := "Привет" + + for i, r := range s { + // i - номер индекса, где располагается первый байт символа + // v – копия символа приведенная к типу Rune + fmt.Printf("Rune index: %d, Rune: %c (Hex: %x)\n", i, r, r) + } +} diff --git a/part_2/2.7/1.go b/part_1/1.12/1.go similarity index 100% rename from part_2/2.7/1.go rename to part_1/1.12/1.go diff --git a/part_2/2.7/2.go b/part_1/1.12/2.go similarity index 100% rename from part_2/2.7/2.go rename to part_1/1.12/2.go diff --git a/part_2/2.7/3.go b/part_1/1.12/3.go similarity index 100% rename from part_2/2.7/3.go rename to part_1/1.12/3.go diff --git a/part_1/1.13/1.go b/part_1/1.13/1.go new file mode 100644 index 0000000..1ee559c --- /dev/null +++ b/part_1/1.13/1.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + var val1 int8 = 5 + var val2 int16 = 500 + rez1 := int16(val1) + val2 + // rez2 := val1 + val2 + // invalid operation: val1 + val2 (mismatched types int8 and int16) + + fmt.Println(rez1) // 505 +} diff --git a/part_1/1.13/10.go b/part_1/1.13/10.go new file mode 100644 index 0000000..435e369 --- /dev/null +++ b/part_1/1.13/10.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +func main() { + myBool := true + var value int + if myBool { + value = 1 + } else { + value = 0 + } + fmt.Println("Value = ", value) // Value = 1 + + myBool2 := value == 1 + fmt.Println("myBool2 value = ", myBool2) // myBool2 value = true +} diff --git a/part_1/1.13/2.go b/part_1/1.13/2.go new file mode 100644 index 0000000..655b184 --- /dev/null +++ b/part_1/1.13/2.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + var val1 int8 = 5 + var val2 int16 = 500 + rez1 := val1 + int8(val2) + fmt.Println(rez1) // –7 + fmt.Println(int8(val2)) // –12 +} diff --git a/part_1/1.13/3.go b/part_1/1.13/3.go new file mode 100644 index 0000000..f64b911 --- /dev/null +++ b/part_1/1.13/3.go @@ -0,0 +1,12 @@ +package main + +import "fmt" + +func main() { + var val1 int = 5 + var val2 float32 = 5.32 + fmt.Printf("%.1f\n", float32(val1)) // 5.0, + // Printf рассматривается в следующем разделе + + fmt.Println(int(val2)) // 5 +} diff --git a/part_1/1.13/4.go b/part_1/1.13/4.go new file mode 100644 index 0000000..beb422f --- /dev/null +++ b/part_1/1.13/4.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + var val1 uint8 = 5 // от 0 до 255 + var val2 uint8 = 255 + fmt.Println(val2 + val1) // 4 + rez1 := uint16(val1) + uint16(val2) + fmt.Println(rez1) // 260 +} diff --git a/part_1/1.13/5.go b/part_1/1.13/5.go new file mode 100644 index 0000000..b3c01ba --- /dev/null +++ b/part_1/1.13/5.go @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func main() { + var val1 uint8 = 255 // 1111 1111 в двоичной системе счисления + val2 := int8(val1) + fmt.Println(val2) //–1, что =1111 1111 в двоичной системе счисления +} diff --git a/part_1/1.13/6.go b/part_1/1.13/6.go new file mode 100644 index 0000000..cd8c83a --- /dev/null +++ b/part_1/1.13/6.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + val1 := 4 / 3 + fmt.Println(val1) // 1 + + val2 := 4.0 / 3 + fmt.Println(val2) // 1.3333333333333333 +} diff --git a/part_1/1.13/7.go b/part_1/1.13/7.go new file mode 100644 index 0000000..f7aa5ea --- /dev/null +++ b/part_1/1.13/7.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "reflect" + "strconv" +) + +func main() { + val1 := 33 + var str string = strconv.Itoa(val1) + fmt.Println(str) // 33 + val2, err := strconv.Atoi(str) + if err == nil { // если получилось преобразовать, то err == nil + fmt.Println(val2) // 33 + fmt.Println(reflect.TypeOf(val2)) // int + } + val2, err = strconv.Atoi("ee") + if err != nil { + fmt.Println(val2) // 0 + } + + val3 := 100 + fmt.Println("Rezult: " + strconv.Itoa(val3)) // Rezult: 100 +} diff --git a/part_1/1.13/8.go b/part_1/1.13/8.go new file mode 100644 index 0000000..86889fb --- /dev/null +++ b/part_1/1.13/8.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "reflect" + "strconv" +) + +func main() { + val1 := 33.321 + str1 := strconv.FormatFloat(val1, 'f', –1, 64) + // равносильно + str2 := fmt.Sprintf("%.3f", val1) + fmt.Println(reflect.TypeOf(str2) , str2) // string 33.321 + fmt.Println(reflect.TypeOf(str1), str1) // string 33.321 + val2, _ := strconv.ParseFloat(str2, 64) + fmt.Println(reflect.TypeOf(val2), val2) // float64 33.321 +} diff --git a/part_1/1.13/9.go b/part_1/1.13/9.go new file mode 100644 index 0000000..60abe1a --- /dev/null +++ b/part_1/1.13/9.go @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + str1 := "hello" + fmt.Println(str1) // hello + + byteArray := []byte(str1) + fmt.Println(byteArray) // [104 101 108 108 111] + + str2 := string(byteArray) + fmt.Println(str2) // hello +} diff --git a/part_1/1.14/1.go b/part_1/1.14/1.go new file mode 100644 index 0000000..43e0aff --- /dev/null +++ b/part_1/1.14/1.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + var cityName string + var age int + fmt.Print("Введите название города, в котором проживаете: ") + fmt.Fscan(os.Stdin, &cityName) + + fmt.Print("Введите возраст города: ") + fmt.Fscan(os.Stdin, &age) + + fmt.Println(cityName, age) +} diff --git a/part_1/1.14/10.go b/part_1/1.14/10.go new file mode 100644 index 0000000..29a6c8f --- /dev/null +++ b/part_1/1.14/10.go @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + fmt.Print(4, 5.13, "Oo") + fmt.Print(10) // 4 5.13Oo10 +} diff --git a/part_1/1.14/11.go b/part_1/1.14/11.go new file mode 100644 index 0000000..9fc4978 --- /dev/null +++ b/part_1/1.14/11.go @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + value := 20 + fmt.Printf("Value = %v", value) // Value = 20 +} diff --git a/part_1/1.14/12.go b/part_1/1.14/12.go new file mode 100644 index 0000000..32c2848 --- /dev/null +++ b/part_1/1.14/12.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + value1 := 20 + var value2 float32 = 4.33 + value3 := "O" + fmt.Printf("Type value1 = %T, value2 = %T, value3 = %T", value1, value2, value3) + // Type value1 = int, value2 = float32, value3 = string +} diff --git a/part_1/1.14/13.go b/part_1/1.14/13.go new file mode 100644 index 0000000..c0a2700 --- /dev/null +++ b/part_1/1.14/13.go @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + value := 20 + fmt.Printf("Value1 = %v%%", value) // Value1 = 20% +} diff --git a/part_1/1.14/14.go b/part_1/1.14/14.go new file mode 100644 index 0000000..f2f8d52 --- /dev/null +++ b/part_1/1.14/14.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + value := 173.000473 + fmt.Printf("Value = %f\n", value) // Value = 173.000473 + fmt.Printf("Value = %.f\n", value) // Value = 173 + fmt.Printf("Value = %.5f\n", value) // Value = 173.00047 + fmt.Printf("Value = %2.2f\n", value) // Value = 173.00 +} diff --git a/part_1/1.14/15.go b/part_1/1.14/15.go new file mode 100644 index 0000000..1cea360 --- /dev/null +++ b/part_1/1.14/15.go @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func main() { + value := 173.000473 + str := fmt.Sprintf("Value = %x", value) + fmt.Printf("str = %q\n", str) +} diff --git a/part_1/1.14/2.go b/part_1/1.14/2.go new file mode 100644 index 0000000..c0c31c9 --- /dev/null +++ b/part_1/1.14/2.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + var cityName string + var age int + fmt.Println("Введите название города, в котором проживаете и его возраст: ") + fmt.Fscan(os.Stdin, &cityName, &age) + + fmt.Println(cityName, age) +} diff --git a/part_1/1.14/3.go b/part_1/1.14/3.go new file mode 100644 index 0000000..464cd4e --- /dev/null +++ b/part_1/1.14/3.go @@ -0,0 +1,12 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + var value1, value2 string + fmt.Fscan(os.Stdin, &value1, &value2) + fmt.Println(value1, value2) +} diff --git a/part_1/1.14/4.go b/part_1/1.14/4.go new file mode 100644 index 0000000..6feff34 --- /dev/null +++ b/part_1/1.14/4.go @@ -0,0 +1,23 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func main() { + // Создаем буфер для чтения из стандартного потока ввода + reader := bufio.NewReader(os.Stdin) + + // Считываем первую строку до указанного символа, + // где '\n' - символ конца строки + нажатый Enter + line1, err := reader.ReadString('\n') + if err != nil { // считали строку? + return + } + // Удаляем лишние пробелы + line1 = strings.TrimSpace(line1) + fmt.Println(line1) // 3 7 8 9 8 7 6 7 +} diff --git a/part_1/1.14/5.go b/part_1/1.14/5.go new file mode 100644 index 0000000..c5745fa --- /dev/null +++ b/part_1/1.14/5.go @@ -0,0 +1,25 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func main() { + // Создаем буфер для чтения из стандартного потока ввода + reader := bufio.NewReader(os.Stdin) + + // Считываем первую строку до указанного символа, + // где '\n' - символ конца строки + нажатый Enter + for range 2 { // код в теле цикла for будет выполнен 2 раза + line1, err := reader.ReadString('|') + if err != nil { + return + } + // Удаляем лишние пробелы + line1 = strings.TrimSpace(line1) + fmt.Println(line1) + } +} diff --git a/part_1/1.14/6.go b/part_1/1.14/6.go new file mode 100644 index 0000000..ccd03d4 --- /dev/null +++ b/part_1/1.14/6.go @@ -0,0 +1,21 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func main() { + // Создаем сканер для чтения из стандартного потока ввода + scanner := bufio.NewScanner(os.Stdin) + + if scanner.Scan() { // ожидаем ввод данных + // если данные прочитаны успешно, выполнится код + // тела оператора if + input := scanner.Text() // Считываем строку + input = strings.TrimSpace(input) + fmt.Println(input) + } +} diff --git a/part_1/1.14/7.go b/part_1/1.14/7.go new file mode 100644 index 0000000..5c111b4 --- /dev/null +++ b/part_1/1.14/7.go @@ -0,0 +1,46 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +func main() { + scanner := bufio.NewScanner(os.Stdin) + fmt.Println("Введите целые числа, разделенные пробелами:") + + // Считываем одну строку ввода + scanner.Scan() + input := scanner.Text() + + // Разбиваем строку на срез строк, + // используя в качестве разделителя символ пробела + fields := strings.Fields(input) + + var mySlice []int + // Преобразуем каждое элемент среза fields в целое число + for _, field := range fields { + n, err := strconv.Atoi(field) + if err != nil { + fmt.Println("Ошибка преобразования:", field) + return + } + mySlice = append(mySlice, n) + } + + // Удаляем дубликаты + var result []int + seen := make(map[int]bool) + for _, num := range mySlice { // Перебираем элементы среза + if !seen[num] { // Если элемент еще не встречался + seen[num] = true + // Добавляем элемент в результирующий срез + result = append(result, num) + } + } + + fmt.Println("Срез без дубликатов:", result) +} diff --git a/part_1/1.14/8.go b/part_1/1.14/8.go new file mode 100644 index 0000000..4951a93 --- /dev/null +++ b/part_1/1.14/8.go @@ -0,0 +1,73 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +func main() { + scanner := bufio.NewScanner(os.Stdin) + var keys []int + var values []string + + // Чтение ключей + if !scanner.Scan() { // если произошла ошибка + return // завершаем выполнение программы + } + keyParts := strings.Fields(scanner.Text()) + // преобразование в целочисленный срез + for _, part := range keyParts { + num, err := strconv.Atoi(part) + if err != nil { + fmt.Println("Ошибка в ключах:", part) + return + } + keys = append(keys, num) + } + + // Чтение значений + if !scanner.Scan() { + return + } + values = strings.Fields(scanner.Text()) + + // Проверка на то, что количество ключей и значений совпадает + if len(keys) != len(values) { + fmt.Println("Количество ключей и значений не совпадает") + return + } + + // Чтение числа A + if !scanner.Scan() { + return + } + a, err := strconv.Atoi(scanner.Text()) + if err != nil || a == 0 { + fmt.Println("Некорректное число A") + return + } + + // Создание и заполнение таблицы + data := make(map[int]string) + for i := range keys { + data[keys[i]] = values[i] + } + + // Поиск ключей для удаления + var toDelete []int + for k := range data { + if k%a == 0 { + toDelete = append(toDelete, k) + } + } + + // Удаление элементов + for _, k := range toDelete { + delete(data, k) + } + + fmt.Println(data) +} diff --git a/part_1/1.14/9.go b/part_1/1.14/9.go new file mode 100644 index 0000000..03cc295 --- /dev/null +++ b/part_1/1.14/9.go @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + fmt.Println(4, 5.13, "Oo") // 4 5.13 Oo + fmt.Println(10) // 10 +} diff --git a/part_1/1.15/1.go b/part_1/1.15/1.go new file mode 100644 index 0000000..f3d8da1 --- /dev/null +++ b/part_1/1.15/1.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := " !my string! " + + // удяляем пробелы с обеих сторон + fmt.Println(strings.TrimSpace(str)) // !my string! + + // удяляем заданные символы в начале и в конце строки + fmt.Println(strings.Trim(str, " ")) // !my string! + fmt.Println(strings.Trim(str, " !")) // my string + + // удяляем заданные символы в начале строки + fmt.Println(strings.TrimLeft(str, " ")) // !my string! + fmt.Println(strings.TrimLeft(str, " m!")) // y string! + + // удяляем заданные символы в конце строки + fmt.Println(strings.TrimRight(str, " ")) // !my string! + fmt.Println(strings.TrimRight(str, "n!g ")) // !my stri + + // удяляем заданный символ или подстроку в начале строки + fmt.Println(strings.TrimPrefix(str, " !my")) // string! + + // удяляем заданный символ или подстроку в конце строки + fmt.Println(strings.TrimSuffix(str, "g! ")) // !my strin +} diff --git a/part_1/1.15/10.go b/part_1/1.15/10.go new file mode 100644 index 0000000..41975b7 --- /dev/null +++ b/part_1/1.15/10.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str1 := "Hi, my dear friend!!!" + fmt.Printf("%t\n", strings.Contains(str1, "i")) // true + fmt.Printf("%t\n", strings.Contains(str1, "my")) // true + fmt.Printf("%t\n", strings.Contains(str1, "?")) // false +} diff --git a/part_1/1.15/11.go b/part_1/1.15/11.go new file mode 100644 index 0000000..3c783e9 --- /dev/null +++ b/part_1/1.15/11.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hello mad world!" + before, after, found := strings.Cut(str, " ") + fmt.Printf("before: %s, after: %s, found: %t \n", before, after, found) + // before: Hello, after: mad world!, found: true + + before, after, found = strings.Cut(str, "6") + fmt.Printf("before: %s, after: %s, found: %t \n", before, after, found) + // before: Hello mad world!, after: , found: false + + after, found = strings.CutPrefix(str, "He") + fmt.Printf("after: %s, found: %t \n", after, found) + // after: llo mad world!, found: true + + after, found = strings.CutPrefix(str, "yello") + fmt.Printf("after: %s, found: %t \n", after, found) + // after: Hello mad world!, found: false + + before, found = strings.CutSuffix(str, "!") + fmt.Printf("before: %s, found: %t \n", before, found) + // before: Hello mad world, found: true + + before, found = strings.CutSuffix(str, "?") + fmt.Printf("before: %s, found: %t \n", before, found) + // before: Hello mad world!, found: false +} diff --git a/part_1/1.15/12.go b/part_1/1.15/12.go new file mode 100644 index 0000000..9781cb1 --- /dev/null +++ b/part_1/1.15/12.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hello mad world!" + fmt.Println(strings.EqualFold(str, "hello mad world!")) // true + fmt.Println(strings.EqualFold(str, "HELLO mad world!")) // true + fmt.Println(strings.EqualFold(str, "Oo")) // false +} diff --git a/part_1/1.15/13.go b/part_1/1.15/13.go new file mode 100644 index 0000000..39ec5a5 --- /dev/null +++ b/part_1/1.15/13.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hello mad world!" + fmt.Println(strings.HasPrefix(str, "He")) // true + fmt.Println(strings.HasPrefix(str, "he")) // false + fmt.Println(strings.HasPrefix(str, "mad")) // false + + fmt.Println(strings.HasSuffix(str, "!")) // true + fmt.Println(strings.HasSuffix(str, "mad")) // false +} diff --git a/part_1/1.15/14.go b/part_1/1.15/14.go new file mode 100644 index 0000000..f545cc4 --- /dev/null +++ b/part_1/1.15/14.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hello mad world!" + fmt.Println(strings.Index(str, "l")) // 2 + fmt.Println(strings.Index(str, "W")) // -1 + + fmt.Println(strings.LastIndex(str, "l")) // 13 + fmt.Println(strings.LastIndex(str, "W")) // -1 +} diff --git a/part_1/1.15/15.go b/part_1/1.15/15.go new file mode 100644 index 0000000..a2076ca --- /dev/null +++ b/part_1/1.15/15.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "slices" + "strings" +) + +func main() { + fmt.Println(strings.Join([]string{"a", "b", "c"}, " ")) + // a b c + + fmt.Println(strings.Join([]string{"a", "b", "c"}, "-")) + // a-b-c + + // инвертирование строки + str := "Hello!" + splitStr := strings.Split(str, "") + slices.Reverse(splitStr) + fmt.Println(strings.Join(splitStr, "")) // !olleH +} diff --git a/part_1/1.15/16.go b/part_1/1.15/16.go new file mode 100644 index 0000000..877403d --- /dev/null +++ b/part_1/1.15/16.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + var b strings.Builder + + // Write - записывает байты (строку) в Builder + n, err := b.Write([]byte("Hello, ")) + if err != nil { // проверка на успешное завершение операции + panic(err) + } + fmt.Printf("After Write: %q (bytes written: %d)\n", b.String(), n) + + // WriteString - записывает строку + n, _ = b.WriteString("world") + fmt.Printf("After WriteString: %q (bytes written: %d)\n", b.String(), n) + + // WriteByte - записывает один байт (символ) + b.WriteByte('!') + fmt.Printf("After WriteByte: %q\n", b.String()) + + // WriteRune - записывает один Unicode-символ + n, _ = b.WriteRune('🌍') + fmt.Printf("After WriteRune: %q (bytes written: %d)\n", b.String(), n) + + // Len - возвращает текущую длину строки + fmt.Printf("Current length: %d\n", b.Len()) + + // Cap - возвращает текущую емкость внутреннего буфера + fmt.Printf("Current capacity: %d\n", b.Cap()) + + // Grow - увеличивает емкость буфера структуры Builder + b.Grow(100) + fmt.Printf("After Grow(100), new capacity: %d\n", b.Cap()) + + // Reset - очищает содержимое буфера Builder-а + b.Reset() + fmt.Printf("After Reset: %q, length: %d\n", b.String(), b.Len()) +} diff --git a/part_1/1.15/2.go b/part_1/1.15/2.go new file mode 100644 index 0000000..eef8f6e --- /dev/null +++ b/part_1/1.15/2.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str1 := "Hi, my dear friend!!!" + str2 := strings.ToUpper(str1) + fmt.Println(str2) // HI, MY DEAR FRIEND!!! + fmt.Println(str1) // Hi, my dear friend!!! + + fmt.Println(strings.ToLower(str2)) // hi, my dear friend!!! + fmt.Println(strings.ToTitle(str1)) // HI, MY DEAR FRIEND!!! +} diff --git a/part_1/1.15/3.go b/part_1/1.15/3.go new file mode 100644 index 0000000..58459e6 --- /dev/null +++ b/part_1/1.15/3.go @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func main() { + str1 := "Hi, my dear friend!!!" + fmt.Println("Символы с 1 по 5: " + str1[:5]) + fmt.Println("Символы с 4: " + str1[4:]) +} diff --git a/part_1/1.15/4.go b/part_1/1.15/4.go new file mode 100644 index 0000000..f1aeddd --- /dev/null +++ b/part_1/1.15/4.go @@ -0,0 +1,10 @@ +package main + +import "fmt" + +func main() { + str1 := "Hi, my маленький friend!!!" + runes := []rune(str1) + substr := string(runes[4:16]) + fmt.Println(substr) // my маленький +} diff --git a/part_1/1.15/5.go b/part_1/1.15/5.go new file mode 100644 index 0000000..9463ebd --- /dev/null +++ b/part_1/1.15/5.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "++Hello++ненаглядные++Гофферы!++" + + // Разбиваем строку на срезы по указанному разделителю + splitRes := strings.Split(str, "++") + fmt.Print("Split(s, \"++\"): ") + fmt.Printf("%q\n", splitRes) + + // Разбиваем строку на срезы по указанному разделителю, + // сохраняя сам разделитель в конце каждого элемента + // (кроме последнего) + splitAfterRes := strings.SplitAfter(str, "++") + fmt.Print("\nSplitAfter(s, \"++\"): ") + fmt.Printf("%q\n", splitAfterRes) + + // Разбиваем строку на срезы по указанному разделителю, + // с ограничением на количество подстрок (n). n = 3 означает, + // что результат будет содержать не более 3 элементов + splitNRes := strings.SplitN(str, "++", 3) + fmt.Print("\nSplitN(s, \"++\", 3): ") + fmt.Printf("%q\n", splitNRes) + + // при n = 0 результат будет nil - [] + splitNRes = strings.SplitN(str, "++", 0) + fmt.Print("\nSplitN(s, \"++\", 0): ") + fmt.Printf("%q\n", splitNRes) + + // при n = -1 результат будет содержать все подстроки + splitNRes = strings.SplitN(str, "++", -1) + fmt.Print("\nSplitN(s, \"++\", -1): ") + fmt.Printf("%q\n", splitNRes) +} diff --git a/part_1/1.15/6.go b/part_1/1.15/6.go new file mode 100644 index 0000000..3f44b25 --- /dev/null +++ b/part_1/1.15/6.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + // Разбиваем строку на срезы по любым пробельным символам: + // пробел, табуляция, перенос строки и т.д. + str1 := " Йо is бедствие " + fieldsRes := strings.Fields(str1) + fmt.Print("\nFields(str1): ") + fmt.Printf("%q\n", fieldsRes) + + // Разбиваем строку на срезы и задаем + // пользовательскую функцию для определения разделителя + str2 := "A+B+++C+DE++F" + fieldsFuncRes := strings.FieldsFunc(str2, func(r rune) bool { + return r == '+' // '+' - разделитель + }) + fmt.Print("\nFieldsFunc(str2, '+'): ") + fmt.Printf("%q\n", fieldsFuncRes) +} diff --git a/part_1/1.15/7.go b/part_1/1.15/7.go new file mode 100644 index 0000000..3ca5ebe --- /dev/null +++ b/part_1/1.15/7.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hi, my dear friend!!!" + newStr := strings.Replace(str, "d", "&", 1) + fmt.Println(newStr) // Hi, my &ear friend!!! + + // замена всех вхождений символа + fmt.Println(strings.ReplaceAll(str, " ", "_")) + // Hi,_my_dear_friend!!! + + // замена подстроки + fmt.Println(strings.ReplaceAll(str, "dear", "good")) + // Hi, my good friend!!! + + // удаление подстроки или символа + fmt.Println(strings.ReplaceAll(str, "dear", "")) + // Hi, my friend!!! +} diff --git a/part_1/1.15/8.go b/part_1/1.15/8.go new file mode 100644 index 0000000..cc9cd86 --- /dev/null +++ b/part_1/1.15/8.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str := "Hi, my dear friend!!!" + fmt.Printf("Длина строки: %d\n", len(str)) // Длина строки: 21 + fmt.Printf("Символов 'i' – %d", strings.Count(str, "i")) + // Символов 'i' – 2 +} diff --git a/part_1/1.15/9.go b/part_1/1.15/9.go new file mode 100644 index 0000000..239c95f --- /dev/null +++ b/part_1/1.15/9.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + str1 := "Hi, my dear friend!!!" + str2 := "Hi, my dear friend!!!" + str3 := "Hi, my dear friend!!" + fmt.Println(strings.Compare(str1, str2)) // 0 + fmt.Println(strings.Compare(str1, str3)) // 1 + fmt.Println(strings.Compare(str3, str1)) // –1 +} diff --git a/part_1/1.16/1.go b/part_1/1.16/1.go new file mode 100644 index 0000000..7b1f8c5 --- /dev/null +++ b/part_1/1.16/1.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + mySlice := []int{1, 2, 3, 4, 5, 6, 7} + + // Поэлементно обходим срез в формате индекс:значение + fmt.Printf("All: ") + for i, v := range slices.All(mySlice) { + fmt.Printf(" %d:%d |", i, v) + } + fmt.Println() + + // Поэлементно обходим срез в обратном порядке + fmt.Printf("Backward: ") + for i, v := range slices.Backward(mySlice) { + fmt.Printf(" %d:%d |", i, v) + } + fmt.Println() +} diff --git a/part_1/1.16/2.go b/part_1/1.16/2.go new file mode 100644 index 0000000..d850681 --- /dev/null +++ b/part_1/1.16/2.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + mySlice := []int{1, 2, 3, 4, 5, 6, 7} + + // Разбиваем срез на подсрезы размером 3 + for subSlice := range slices.Chunk(mySlice, 3) { + fmt.Println(subSlice) + } +} diff --git a/part_1/1.16/3.go b/part_1/1.16/3.go new file mode 100644 index 0000000..190816e --- /dev/null +++ b/part_1/1.16/3.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + base := []int{1, 2, 3, 4, 5, 6} + fmt.Println("Исходный срез:", base) // Исходный срез: [1 2 3 4 5 6] + + // Вставка элементов в срез в указанную позицию. + // В нашем случае, начиная с 3-го индекса вставляем 99 и 100 + inserted := slices.Insert(base, 3, 99, 100) + fmt.Println("Insert: ", inserted) // Insert: [1 2 3 99 100 4 5 6] + + // Копирование среза + cloned := slices.Clone(base) + base[0] = 100 + fmt.Println("Оригинал:", base) // Оригинал: [100 2 3 4 5 6] + fmt.Println("Клон: ", cloned) // Клон: [1 2 3 4 5 6] + + // Объединение срезов + parts := []int{7, 8, 9} + concatenated := slices.Concat(base, parts) + fmt.Println("Concat: ", concatenated) //Concat: [100 2 3 4 5 6 7 8 9] + + // Удаляем диапазон с i-го по j-й индекс + deleted := slices.Clone(base) + deleted = slices.Delete(deleted, 2, 5) + fmt.Println("Delete: ", deleted) // Delete: [100 2 6] + + // Удаляем по условию через лямбда-функцию. + // В нашем случае удаляются элементы, у которых значение кратно 2 + filtered := slices.Clone(base) + filtered = slices.DeleteFunc(filtered, func(n int) bool { + return n%2 == 0 + }) + fmt.Println("DeleteFunc: ", filtered) // DeleteFunc: [3 5] + + // Повторение среза указанное количество раз (например, 2) + repeated := slices.Repeat(base, 2) + fmt.Println("Repeat: ", repeated) // [100 2 3 4 5 6 100 2 3 4 5 6] + + // С i-го до j-го индекса значения + // элементов поменяются на 97,98,99 + replaced := slices.Replace(base, 1, 4, 97, 98, 99) + fmt.Println("Replace: ", replaced) // Replace: [100 97 98 99 5 6] + + // Инвертируем порядок элементов среза + reversed := slices.Clone(base) + slices.Reverse(reversed) + fmt.Println("Reverse: ", reversed) // Reverse: [6 5 99 98 97 100] +} diff --git a/part_1/1.16/4.go b/part_1/1.16/4.go new file mode 100644 index 0000000..918e923 --- /dev/null +++ b/part_1/1.16/4.go @@ -0,0 +1,42 @@ +package main + +import ( + "cmp" + "fmt" + "slices" +) + +func main() { + numbers := []int{5, 2, 6, 3, 1, 4} + words := []string{"banana", "apple", "cherry", "date"} + + // Сортировка среза + slices.Sort(numbers) + fmt.Println("Sort (int):", numbers) // Sort (int): [1 2 3 4 5 6] + + slices.Sort(words) + fmt.Println("Sort (string):", words) // [apple banana cherry date] + + // Настраиваемая сортировка через лямбда-функцию + mixed := []int{30, 15, 42, 7, 25} + + // Функция должна возвращать: + // -1 если первый̆ аргумент меньше второго, + // 0 если аргументы равны, + // 1 если первый̆ аргумент больше второго + // за нас это может рассчитать cmp.Compare + slices.SortFunc(mixed, func(a, b int) int { + // Сортировка по последней цифре + return cmp.Compare(a%10, b%10) + }) + fmt.Println("SortFunc: ", mixed) // SortFunc: [30 42 15 25 7] + + // Проверка на то, что элементы среза отсортированы + sortedCheck := []int{1, 3, 5, 7, 9} + fmt.Printf("IsSorted(%v): %t\n", sortedCheck, + slices.IsSorted(sortedCheck)) // IsSorted([1 3 5 7 9]): true + + unsortedCheck := []int{2, 1, 3, 4} + fmt.Printf("IsSorted(%v): %t\n", unsortedCheck, + slices.IsSorted(unsortedCheck)) // IsSorted([2 1 3 4]): false +} diff --git a/part_1/1.16/5.go b/part_1/1.16/5.go new file mode 100644 index 0000000..bf6068a --- /dev/null +++ b/part_1/1.16/5.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + mySlice := []int{1, 2, 3, 4, 5, 6} + + // BinarySearch принимает на вход срез и значение, + // которое нужно найти. Работает только с отсортированными срезами + index, found := slices.BinarySearch(mySlice, 4) + fmt.Printf("BinarySearch(4): index=%d, found=%t\n", index, found) + // BinarySearch(4): index=3, found=true + + index, found = slices.BinarySearch(mySlice, 7) + fmt.Printf("BinarySearch(7): index=%d, found=%t\n", index, found) + // BinarySearch(7): index=6, found=false + + // Ищем индекс первого вхождения элемента + data := []int{5, 2, 5, 3, 5} + fmt.Println(slices.Index(data, 5)) // 0 + fmt.Println(slices.Index(data, 7)) // -1 +} diff --git a/part_1/1.16/6.go b/part_1/1.16/6.go new file mode 100644 index 0000000..29b6e43 --- /dev/null +++ b/part_1/1.16/6.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + // Проверка наличия элемента с таким значением в срезе + numbers := []int{1, 2, 3, 4, 5} + fmt.Println(slices.Contains(numbers, 3)) // true + fmt.Println(slices.Contains(numbers, 6)) // false + + // Лексикографическое сравнение срезов + a := []int{1, 2, 3} + b := []int{1, 2, 4} + + fmt.Println(slices.Compare(a, b)) // -1 (a < b) + fmt.Println(slices.Compare(b, a)) // 1 (b > a) + fmt.Println(slices.Compare(a, a)) // 0 (equal) + + // Проверка срезов на равенство + x := []int{1, 2, 3} + y := []int{1, 2, 3} + z := []int{3, 2, 1} + + fmt.Println(slices.Equal(x, y)) // true + fmt.Println(slices.Equal(x, z)) // false +} diff --git a/part_1/1.16/7.go b/part_1/1.16/7.go new file mode 100644 index 0000000..2e62c19 --- /dev/null +++ b/part_1/1.16/7.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "slices" +) + +func main() { + // Удаление последовательных дубликатов + values := []int{1, 1, 2, 3, 3, 3, 4, 5, 5, 6, 1} + compacted := slices.Compact(values) + fmt.Println("Compact:", compacted) // Compact: [1 2 3 4 5 6 1] + + // Поиск максимума + values = []int{5, 2, 9, 1, 7} + fmt.Println("Max:", slices.Max(values)) // Max: 9 + + // Поиск минимума + fmt.Println("Min:", slices.Min(values)) // Min: 1 +} diff --git a/part_1/1.17/1.go b/part_1/1.17/1.go new file mode 100644 index 0000000..ab06ebc --- /dev/null +++ b/part_1/1.17/1.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "maps" +) + +func main() { + original := map[string]int{ + "1": 5, + "2": 3, + "3": 7, + } + + // Создание копии таблицы + cloned := maps.Clone(original) + + // Копирование элементов из одной таблицы в другую + dest := map[string]int{"x": 1} + maps.Copy(dest, original) // копируем элементы original в dest + fmt.Println("Copy: ", dest) // Copy: map[1:5 2:3 3:7 x:1] + + // Удаление элементов таблицы по условию + filtered := maps.Clone(original) + maps.DeleteFunc(filtered, func(key string, value int) bool { + return value < 5 // удаляем элементы, где значение <5 + }) + fmt.Println("DeleteFunc: ", filtered) // DeleteFunc: map[1:5 3:7] + + // Cравнение таблиц + fmt.Println(maps.Equal(original, cloned)) // false + fmt.Println(maps.Equal(original, original)) // true + + // Итерация по ключам + fmt.Print("Keys: ") + for k := range maps.Keys(original) { + fmt.Print(" ", k) // Keys: 1 2 3 + } + fmt.Println() + + // Итерация по значениям + fmt.Print("Values: ") + for v := range maps.Values(original) { + fmt.Print(" ", v) // Values: 3 7 5 + } +} diff --git a/part_2/2.1/2.1.1/1.go b/part_2/2.1/2.1.1/1.go new file mode 100644 index 0000000..684f2df --- /dev/null +++ b/part_2/2.1/2.1.1/1.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + array := [4]float64{2.4, 5.6, 8.1, 9.22} + myFunc(array) + fmt.Printf("Array in main: %v\n", array) +} + +func myFunc(array [4]float64) { + for i := range array { + array[i] += 2.33 + } + fmt.Printf("Array in myFunc: %v\n", array) +} + +// Array in myFunc: [4.73 7.93 10.43 11.55] +// Array in main: [2.4 5.6 8.1 9.22] diff --git a/part_2/2.1/2.1.1/2.go b/part_2/2.1/2.1.1/2.go new file mode 100644 index 0000000..0682392 --- /dev/null +++ b/part_2/2.1/2.1.1/2.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + array := [4]float64{2.4, 5.6, 8.1, 9.22} + myFunc(&array) + fmt.Printf("Array in main: %v\n", array) +} + +func myFunc(array *[4]float64) { + for i := range array { + array[i] += 2.33 + } + fmt.Printf("Array in myFunc: %v\n", *array) +} + +// Array in myFunc: [4.73 7.93 10.43 11.55] +// Array in main: [4.73 7.93 10.43 11.55] diff --git a/part_2/2.1/2.1.1/3.go b/part_2/2.1/2.1.1/3.go new file mode 100644 index 0000000..fc1dc99 --- /dev/null +++ b/part_2/2.1/2.1.1/3.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + array := []float64{2.4, 5.6, 8.1, 9.22} + myFunc(&array) + fmt.Printf("Array in main: %v\n", array) +} + +func myFunc(array *[]float64) { + for i := range *array { + (*array)[i] += 1.5 + } + fmt.Printf("Array in myFunc: %v\n", *array) +} + +// Array in myFunc: [3.9 7.1 9.6 10.72] +// Array in main: [3.9 7.1 9.6 10.72] diff --git a/part_3/3.2/4.go b/part_2/2.1/2.1.1/4.go similarity index 100% rename from part_3/3.2/4.go rename to part_2/2.1/2.1.1/4.go diff --git a/part_3/3.2/5.go b/part_2/2.1/2.1.1/5.go similarity index 100% rename from part_3/3.2/5.go rename to part_2/2.1/2.1.1/5.go diff --git a/part_3/3.11/1.go b/part_2/2.1/2.1.10/1.go similarity index 100% rename from part_3/3.11/1.go rename to part_2/2.1/2.1.10/1.go diff --git a/part_3/3.11/2.go b/part_2/2.1/2.1.10/2.go similarity index 100% rename from part_3/3.11/2.go rename to part_2/2.1/2.1.10/2.go diff --git a/part_2/2.1/2.1.10/3.go b/part_2/2.1/2.1.10/3.go new file mode 100644 index 0000000..3c5e46e --- /dev/null +++ b/part_2/2.1/2.1.10/3.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func add(a, b int) int { + defer fmt.Println("defer") // выполнится перед return + fmt.Println("without defer") + return a + b +} + +func main() { + fmt.Println(add(42, 13)) +} diff --git a/part_3/3.3/1.go b/part_2/2.1/2.1.2/1.go similarity index 100% rename from part_3/3.3/1.go rename to part_2/2.1/2.1.2/1.go diff --git a/part_3/3.3/2.go b/part_2/2.1/2.1.2/2.go similarity index 100% rename from part_3/3.3/2.go rename to part_2/2.1/2.1.2/2.go diff --git a/part_3/3.4/1.go b/part_2/2.1/2.1.3/1.go similarity index 100% rename from part_3/3.4/1.go rename to part_2/2.1/2.1.3/1.go diff --git a/part_3/3.4/2.go b/part_2/2.1/2.1.3/2.go similarity index 100% rename from part_3/3.4/2.go rename to part_2/2.1/2.1.3/2.go diff --git a/part_3/3.4/3.go b/part_2/2.1/2.1.3/3.go similarity index 100% rename from part_3/3.4/3.go rename to part_2/2.1/2.1.3/3.go diff --git a/part_3/3.4/4.go b/part_2/2.1/2.1.3/4.go similarity index 100% rename from part_3/3.4/4.go rename to part_2/2.1/2.1.3/4.go diff --git a/part_3/3.5/1.go b/part_2/2.1/2.1.4/1.go similarity index 100% rename from part_3/3.5/1.go rename to part_2/2.1/2.1.4/1.go diff --git a/part_3/3.6/1.go b/part_2/2.1/2.1.5/1.go similarity index 100% rename from part_3/3.6/1.go rename to part_2/2.1/2.1.5/1.go diff --git a/part_3/3.6/2.go b/part_2/2.1/2.1.5/2.go similarity index 100% rename from part_3/3.6/2.go rename to part_2/2.1/2.1.5/2.go diff --git a/part_3/3.7/1.go b/part_2/2.1/2.1.6/1.go similarity index 100% rename from part_3/3.7/1.go rename to part_2/2.1/2.1.6/1.go diff --git a/part_3/3.8/1.go b/part_2/2.1/2.1.7/1.go similarity index 100% rename from part_3/3.8/1.go rename to part_2/2.1/2.1.7/1.go diff --git a/part_3/3.8/2.go b/part_2/2.1/2.1.7/2.go similarity index 100% rename from part_3/3.8/2.go rename to part_2/2.1/2.1.7/2.go diff --git a/part_2/2.1/2.1.7/3.go b/part_2/2.1/2.1.7/3.go new file mode 100644 index 0000000..53c2134 --- /dev/null +++ b/part_2/2.1/2.1.7/3.go @@ -0,0 +1,33 @@ +package main + +import "fmt" + +type InputFunc func(int, int) int +type OutputFunc func(int) int + +func myClosure(a, b int, foo InputFunc) OutputFunc { + return func(value int) int { + return value - foo(a, b) + } +} + +func main() { + globalValue := 99 + mainFunc := func(a, b int) int { + globalValue-- + fmt.Printf("globalValue: %d, ", globalValue) + if a < b { + return globalValue - a + b + } + return -globalValue + b*a + } + + calculation := myClosure(3, 5, mainFunc) + fmt.Println(calculation(3)) + fmt.Println(calculation(2)) + calculation = myClosure(6, -2, mainFunc) + fmt.Println(calculation(3)) + fmt.Println(calculation(7)) + + fmt.Println("Final globalValue:", globalValue) +} diff --git a/part_2/2.1/2.1.8/1.go b/part_2/2.1/2.1.8/1.go new file mode 100644 index 0000000..dca5369 --- /dev/null +++ b/part_2/2.1/2.1.8/1.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func sumElem(slice []int) int { + fmt.Println(slice) + if len(slice) <= 1 { + return slice[0] + } + return slice[0] + sumElem(slice[1:]) +} + +func main() { + mySlice := []int{2, 5, 22, 9, 0} + fmt.Println(sumElem(mySlice)) +} diff --git a/part_2/2.1/2.1.8/2.go b/part_2/2.1/2.1.8/2.go new file mode 100644 index 0000000..5238ff4 --- /dev/null +++ b/part_2/2.1/2.1.8/2.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func sumElem(slice []int) int { + fmt.Println(slice) + if len(slice) <= 1 { + return slice[0] + } + return anotherFunction(slice) +} + +func anotherFunction(slice []int) int { + return slice[0] + sumElem(slice[1:]) +} + +func main() { + mySlice := []int{2, 5, 22, 9, 0} + fmt.Println(sumElem(mySlice)) +} diff --git a/part_2/2.1/2.1.9/1.go b/part_2/2.1/2.1.9/1.go new file mode 100644 index 0000000..6d91ceb --- /dev/null +++ b/part_2/2.1/2.1.9/1.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func createGenerator(start int, end int) chan int { + ch := make(chan int, end-start) + go func(ch chan int) { + for i := start; i <= end; i++ { + ch <- i // помещение значения в канал + } + close(ch) + }(ch) + return ch +} + +func main() { + for it := range createGenerator(1, 10) { + fmt.Printf("%d || ", it) + } +} diff --git a/part_2/2.1/2.1.9/2.go b/part_2/2.1/2.1.9/2.go new file mode 100644 index 0000000..691185c --- /dev/null +++ b/part_2/2.1/2.1.9/2.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +func createGenerator(start int, end int) chan int { + ch := make(chan int, end-start) + go func(ch chan int) { + for i := start; i <= end; i++ { + ch <- i // помещение значения в канал + } + close(ch) + }(ch) + return ch +} + +func main() { + generator := createGenerator(4, 8) + for { + value := <-generator // распаковка значения из канала в переменную + fmt.Printf("%d || ", value) + if len(generator) <= 0 { // проверка на выход из бесконечного цикла + break + } + } +} diff --git a/part_4/4.1-4.2/golang/first/go.mod b/part_2/2.2/2.2.1-2.2.2/golang/first/go.mod similarity index 100% rename from part_4/4.1-4.2/golang/first/go.mod rename to part_2/2.2/2.2.1-2.2.2/golang/first/go.mod diff --git a/part_4/4.1-4.2/golang/first/go.sum b/part_2/2.2/2.2.1-2.2.2/golang/first/go.sum similarity index 100% rename from part_4/4.1-4.2/golang/first/go.sum rename to part_2/2.2/2.2.1-2.2.2/golang/first/go.sum diff --git a/part_4/4.1-4.2/golang/first/main.go b/part_2/2.2/2.2.1-2.2.2/golang/first/main.go similarity index 100% rename from part_4/4.1-4.2/golang/first/main.go rename to part_2/2.2/2.2.1-2.2.2/golang/first/main.go diff --git a/part_4/4.6/golang/first/go.mod b/part_2/2.2/2.2.6/golang/first/go.mod similarity index 100% rename from part_4/4.6/golang/first/go.mod rename to part_2/2.2/2.2.6/golang/first/go.mod diff --git a/part_4/4.6/golang/first/go.sum b/part_2/2.2/2.2.6/golang/first/go.sum similarity index 100% rename from part_4/4.6/golang/first/go.sum rename to part_2/2.2/2.2.6/golang/first/go.sum diff --git a/part_4/4.6/golang/first/main.go b/part_2/2.2/2.2.6/golang/first/main.go similarity index 100% rename from part_4/4.6/golang/first/main.go rename to part_2/2.2/2.2.6/golang/first/main.go diff --git a/part_4/4.6/golang/first/utils/uuid_convertor.go b/part_2/2.2/2.2.6/golang/first/utils/uuid_convertor.go similarity index 100% rename from part_4/4.6/golang/first/utils/uuid_convertor.go rename to part_2/2.2/2.2.6/golang/first/utils/uuid_convertor.go diff --git a/part_4/4.7/golang/first/another_package/mypack.go b/part_2/2.2/2.2.7/golang/first/another_package/mypack.go similarity index 100% rename from part_4/4.7/golang/first/another_package/mypack.go rename to part_2/2.2/2.2.7/golang/first/another_package/mypack.go diff --git a/part_4/4.7/golang/first/go.mod b/part_2/2.2/2.2.7/golang/first/go.mod similarity index 100% rename from part_4/4.7/golang/first/go.mod rename to part_2/2.2/2.2.7/golang/first/go.mod diff --git a/part_4/4.7/golang/first/go.sum b/part_2/2.2/2.2.7/golang/first/go.sum similarity index 100% rename from part_4/4.7/golang/first/go.sum rename to part_2/2.2/2.2.7/golang/first/go.sum diff --git a/part_4/4.7/golang/first/main.go b/part_2/2.2/2.2.7/golang/first/main.go similarity index 100% rename from part_4/4.7/golang/first/main.go rename to part_2/2.2/2.2.7/golang/first/main.go diff --git a/part_4/4.7/golang/first/utils/uuid_convertor.go b/part_2/2.2/2.2.7/golang/first/utils/uuid_convertor.go similarity index 100% rename from part_4/4.7/golang/first/utils/uuid_convertor.go rename to part_2/2.2/2.2.7/golang/first/utils/uuid_convertor.go diff --git a/part_4/4.8/golang/first/another_package/mypack.go b/part_2/2.2/2.2.8/golang/first/another_package/mypack.go similarity index 100% rename from part_4/4.8/golang/first/another_package/mypack.go rename to part_2/2.2/2.2.8/golang/first/another_package/mypack.go diff --git a/part_4/4.8/golang/first/go.mod b/part_2/2.2/2.2.8/golang/first/go.mod similarity index 100% rename from part_4/4.8/golang/first/go.mod rename to part_2/2.2/2.2.8/golang/first/go.mod diff --git a/part_4/4.8/golang/first/go.sum b/part_2/2.2/2.2.8/golang/first/go.sum similarity index 100% rename from part_4/4.8/golang/first/go.sum rename to part_2/2.2/2.2.8/golang/first/go.sum diff --git a/part_4/4.8/golang/first/main.go b/part_2/2.2/2.2.8/golang/first/main.go similarity index 100% rename from part_4/4.8/golang/first/main.go rename to part_2/2.2/2.2.8/golang/first/main.go diff --git a/part_4/4.8/golang/first/utils/uuid_convertor.go b/part_2/2.2/2.2.8/golang/first/utils/uuid_convertor.go similarity index 100% rename from part_4/4.8/golang/first/utils/uuid_convertor.go rename to part_2/2.2/2.2.8/golang/first/utils/uuid_convertor.go diff --git a/part_4/4.8/golang/second/float.go b/part_2/2.2/2.2.8/golang/second/float.go similarity index 100% rename from part_4/4.8/golang/second/float.go rename to part_2/2.2/2.2.8/golang/second/float.go diff --git a/part_4/4.8/golang/second/go.mod b/part_2/2.2/2.2.8/golang/second/go.mod similarity index 100% rename from part_4/4.8/golang/second/go.mod rename to part_2/2.2/2.2.8/golang/second/go.mod diff --git a/part_4/4.8/golang/second/integer.go b/part_2/2.2/2.2.8/golang/second/integer.go similarity index 100% rename from part_4/4.8/golang/second/integer.go rename to part_2/2.2/2.2.8/golang/second/integer.go diff --git a/part_11/11.1/golang/testing/calculator/calculator.go b/part_2/2.3/2.3.1/golang/testing/calculator/calculator.go similarity index 100% rename from part_11/11.1/golang/testing/calculator/calculator.go rename to part_2/2.3/2.3.1/golang/testing/calculator/calculator.go diff --git a/part_11/11.1/golang/testing/go.mod b/part_2/2.3/2.3.1/golang/testing/go.mod similarity index 100% rename from part_11/11.1/golang/testing/go.mod rename to part_2/2.3/2.3.1/golang/testing/go.mod diff --git a/part_11/11.1/golang/testing/main.go b/part_2/2.3/2.3.1/golang/testing/main.go similarity index 100% rename from part_11/11.1/golang/testing/main.go rename to part_2/2.3/2.3.1/golang/testing/main.go diff --git a/part_11/11.1/golang/testing/test/calculator_test.go b/part_2/2.3/2.3.1/golang/testing/test/calculator_test.go similarity index 100% rename from part_11/11.1/golang/testing/test/calculator_test.go rename to part_2/2.3/2.3.1/golang/testing/test/calculator_test.go diff --git a/part_11/11.2/golang/testing/calculator/calculator.go b/part_2/2.3/2.3.2/golang/testing/calculator/calculator.go similarity index 100% rename from part_11/11.2/golang/testing/calculator/calculator.go rename to part_2/2.3/2.3.2/golang/testing/calculator/calculator.go diff --git a/part_11/11.2/golang/testing/go.mod b/part_2/2.3/2.3.2/golang/testing/go.mod similarity index 100% rename from part_11/11.2/golang/testing/go.mod rename to part_2/2.3/2.3.2/golang/testing/go.mod diff --git a/part_11/11.2/golang/testing/main.go b/part_2/2.3/2.3.2/golang/testing/main.go similarity index 100% rename from part_11/11.2/golang/testing/main.go rename to part_2/2.3/2.3.2/golang/testing/main.go diff --git a/part_11/11.2/golang/testing/test/calculator_test.go b/part_2/2.3/2.3.2/golang/testing/test/calculator_test.go similarity index 100% rename from part_11/11.2/golang/testing/test/calculator_test.go rename to part_2/2.3/2.3.2/golang/testing/test/calculator_test.go diff --git a/part_11/11.3/golang/testing/calculator/calculator.go b/part_2/2.3/2.3.3/golang/testing/calculator/calculator.go similarity index 100% rename from part_11/11.3/golang/testing/calculator/calculator.go rename to part_2/2.3/2.3.3/golang/testing/calculator/calculator.go diff --git a/part_11/11.3/golang/testing/go.mod b/part_2/2.3/2.3.3/golang/testing/go.mod similarity index 100% rename from part_11/11.3/golang/testing/go.mod rename to part_2/2.3/2.3.3/golang/testing/go.mod diff --git a/part_11/11.3/golang/testing/main.go b/part_2/2.3/2.3.3/golang/testing/main.go similarity index 100% rename from part_11/11.3/golang/testing/main.go rename to part_2/2.3/2.3.3/golang/testing/main.go diff --git a/part_11/11.3/golang/testing/test/calculator_test.go b/part_2/2.3/2.3.3/golang/testing/test/calculator_test.go similarity index 100% rename from part_11/11.3/golang/testing/test/calculator_test.go rename to part_2/2.3/2.3.3/golang/testing/test/calculator_test.go diff --git a/part_11/11.4/golang/testing/calculator/calculator.go b/part_2/2.3/2.3.4/golang/testing/calculator/calculator.go similarity index 100% rename from part_11/11.4/golang/testing/calculator/calculator.go rename to part_2/2.3/2.3.4/golang/testing/calculator/calculator.go diff --git a/part_11/11.4/golang/testing/calculator/calculator_bench_test.go b/part_2/2.3/2.3.4/golang/testing/calculator/calculator_bench_test.go similarity index 100% rename from part_11/11.4/golang/testing/calculator/calculator_bench_test.go rename to part_2/2.3/2.3.4/golang/testing/calculator/calculator_bench_test.go diff --git a/part_11/11.4/golang/testing/calculator/calculator_test.go b/part_2/2.3/2.3.4/golang/testing/calculator/calculator_test.go similarity index 100% rename from part_11/11.4/golang/testing/calculator/calculator_test.go rename to part_2/2.3/2.3.4/golang/testing/calculator/calculator_test.go diff --git a/part_11/11.4/golang/testing/go.mod b/part_2/2.3/2.3.4/golang/testing/go.mod similarity index 100% rename from part_11/11.4/golang/testing/go.mod rename to part_2/2.3/2.3.4/golang/testing/go.mod diff --git a/part_11/11.4/golang/testing/main.go b/part_2/2.3/2.3.4/golang/testing/main.go similarity index 100% rename from part_11/11.4/golang/testing/main.go rename to part_2/2.3/2.3.4/golang/testing/main.go diff --git a/part_11/11.5/golang/testing/calculator/calculator.go b/part_2/2.3/2.3.5/golang/testing/calculator/calculator.go similarity index 100% rename from part_11/11.5/golang/testing/calculator/calculator.go rename to part_2/2.3/2.3.5/golang/testing/calculator/calculator.go diff --git a/part_11/11.5/golang/testing/calculator/calculator_test.go b/part_2/2.3/2.3.5/golang/testing/calculator/calculator_test.go similarity index 100% rename from part_11/11.5/golang/testing/calculator/calculator_test.go rename to part_2/2.3/2.3.5/golang/testing/calculator/calculator_test.go diff --git a/part_11/11.5/golang/testing/go.mod b/part_2/2.3/2.3.5/golang/testing/go.mod similarity index 100% rename from part_11/11.5/golang/testing/go.mod rename to part_2/2.3/2.3.5/golang/testing/go.mod diff --git a/part_11/11.5/golang/testing/main.go b/part_2/2.3/2.3.5/golang/testing/main.go similarity index 100% rename from part_11/11.5/golang/testing/main.go rename to part_2/2.3/2.3.5/golang/testing/main.go diff --git a/part_11/11.6/1.go b/part_2/2.3/2.3.6/1.go similarity index 100% rename from part_11/11.6/1.go rename to part_2/2.3/2.3.6/1.go diff --git a/part_2/2.6/7.go b/part_2/2.6/7.go deleted file mode 100644 index bf8cd6e..0000000 --- a/part_2/2.6/7.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import "fmt" - -func main() { - array := [4]int{2, 5, 6, 0} - for i, v := range array { - v += 3 - fmt.Printf("%d) %d || ", i, v) - } - // 0) 5 || 1) 8 || 2) 9 || 3) 3 || - fmt.Println() - fmt.Println(array) // [2 5 6 0] -} diff --git a/part_2/2.6/8.go b/part_2/2.6/8.go deleted file mode 100644 index a0e0a02..0000000 --- a/part_2/2.6/8.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import "fmt" - -func main() { - array := [4]int{2, 5, 6, 0} - for i := range array { - array[i] += 3 - } - fmt.Println(array) // [5 8 9 3] -} diff --git a/part_3/3.1/1.go b/part_3/3.1/1.go index b1a70c1..6956f14 100644 --- a/part_3/3.1/1.go +++ b/part_3/3.1/1.go @@ -2,14 +2,15 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - hello() // вызов функции hello - fmt.Println("exit") + var emp employee + emp2 := employee{} + fmt.Println(emp, emp2) // { 0 } { 0 } } - -func hello() { - fmt.Println("Hello World!") -} - -// Hello World! -// exit diff --git a/part_3/3.1/10.go b/part_3/3.1/10.go new file mode 100644 index 0000000..49f6eef --- /dev/null +++ b/part_3/3.1/10.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +type point struct { + x int + y int +} + +func checkOutput(first, second int, check bool) { + fmt.Printf("point%d == point%d - %t\n", first, second, check) +} + +func main() { + point1 := point{10, 20} + point2 := point{10, 20} + point3 := point{x: 2, y: 43} + checkOutput(1, 2, point1 == point2) + checkOutput(2, 3, point2 == point3) +} diff --git a/part_3/3.1/11.go b/part_3/3.1/11.go new file mode 100644 index 0000000..7101a06 --- /dev/null +++ b/part_3/3.1/11.go @@ -0,0 +1,21 @@ +package main + +import "fmt" + +type point struct { + x int + y int +} + +type shape struct { + name string + center point +} + +func main() { + myShape := shape{ + name: "Cube", + center: point{x: 10, y: 6}, + } + fmt.Printf("%+v\n", myShape) // {name:Cube center:{x:10 y:6}} +} diff --git a/part_3/3.1/2.go b/part_3/3.1/2.go index 9e9b046..c2ec339 100644 --- a/part_3/3.1/2.go +++ b/part_3/3.1/2.go @@ -2,14 +2,25 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - add(3, 5) -} + emp1 := employee{ + name: "Alex", + age: 25, + departmentName: "R&D", + position: "Assistant", + } + emp2 := employee{ + name: "Tom", + position: "Intern", + } -func add(a int, b int) { - fmt.Println(a + b) // 8 + fmt.Println(emp1) // {Alex R&D 25 Assistant} + fmt.Println(emp2) // {Tom 0 Intern} } - -// func add(a, b int) { -// fmt.Println(a + b) -// } diff --git a/part_5/5.1/5.1.7/golang/factory/go.mod b/part_3/3.1/3.1.7/golang/factory/go.mod similarity index 100% rename from part_5/5.1/5.1.7/golang/factory/go.mod rename to part_3/3.1/3.1.7/golang/factory/go.mod diff --git a/part_5/5.1/5.1.7/golang/factory/main.go b/part_3/3.1/3.1.7/golang/factory/main.go similarity index 100% rename from part_5/5.1/5.1.7/golang/factory/main.go rename to part_3/3.1/3.1.7/golang/factory/main.go diff --git a/part_5/5.1/5.1.7/golang/factory/shape/shape.go b/part_3/3.1/3.1.7/golang/factory/shape/shape.go similarity index 100% rename from part_5/5.1/5.1.7/golang/factory/shape/shape.go rename to part_3/3.1/3.1.7/golang/factory/shape/shape.go diff --git a/part_3/3.1/3.go b/part_3/3.1/3.go index 35b053d..3175b39 100644 --- a/part_3/3.1/3.go +++ b/part_3/3.1/3.go @@ -2,12 +2,16 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - userInfo(3, 5, "Alex") -} + emp3 := employee{"Alex", "R&D", 25, "Assistant"} // ok + // emp3 := employee{"Alex", "R&D"} – ошибка!!! -func userInfo(age, exp int, name string) { - fmt.Printf("User name: %s, age: %d, exp years: %d", name, age, exp) + fmt.Println(emp3) // {Alex R&D 25 Assistant} } - -// User name: Alex, age: 3, exp years: 5 diff --git a/part_3/3.1/4.go b/part_3/3.1/4.go index b3c3ebd..ef8f21a 100644 --- a/part_3/3.1/4.go +++ b/part_3/3.1/4.go @@ -2,10 +2,21 @@ package main import "fmt" -func main() { - fmt.Println(userInfo(3, 5, "Alex")) // User name: Alex, age: 3, exp years: 5 +type employee struct { + name string + departmentName string + age uint8 + position string } -func userInfo(age, exp int, name string) string { - return fmt.Sprintf("User name: %s, age: %d, exp year: %d", name, age, exp) +func main() { + emp2 := employee{ + name: "Tom", + position: "Intern", + } + emp2.age = 22 + emp2.departmentName = "R&D" + fmt.Println(emp2) // {Tom R&D 22 Intern} + emp2.position = "Engineer" + fmt.Println(emp2) // {Tom R&D 22 Engineer} } diff --git a/part_3/3.1/5.go b/part_3/3.1/5.go index 4ecaca1..870544e 100644 --- a/part_3/3.1/5.go +++ b/part_3/3.1/5.go @@ -2,23 +2,21 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - rez, check := add(10, 8) - fmt.Printf("a + b = %d, a > b = %t", rez, check) + emp2 := employee{ + name: "Tom", + position: "Intern", + } + emp2.age = 22 + emp2.departmentName = "R&D" + fmt.Printf("%+v\n", emp2) // {name:Tom departmentName:R&D age:22 position:Intern} + emp2.position = "Engineer" + fmt.Printf("%+v\n", emp2) // {name:Tom departmentName:R&D age:22 position:Engineer} } - -func add(a, b int) (int, bool) { - return a + b, a > b -} - -// a + b = 18, a > b = true - -// func main() { -// rez := add(10, 8) // assignment mismatch: 1 variable but add returns 2 values -// fmt.Printf("a + b = %d", rez) -// } - -// func main() { -// rez, _ := add(10, 8) -// fmt.Printf("a + b = %d", rez) // a + b = 18 -// } diff --git a/part_3/3.1/6.go b/part_3/3.1/6.go index eb66397..5b1e1fc 100644 --- a/part_3/3.1/6.go +++ b/part_3/3.1/6.go @@ -2,16 +2,21 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - rez, check := add(10, 8) - fmt.Printf("a + b = %d, a > b = %t", rez, check) + emp2 := employee{ + name: "Tom", + position: "Intern", + } + emp2.age = 22 + emp2.departmentName = "R&D" + fmt.Printf("%+v\n", emp2.age) // 22 + employeeAge := emp2.age + fmt.Println(employeeAge) // 22 } - -func add(a, b int) (rez int, check bool) { - rez = a + b - check = a > b - return // аналогично return rez, check - -} - -// a + b = 18, a > b = true diff --git a/part_3/3.1/7.go b/part_3/3.1/7.go index 64e7c0d..7253df4 100644 --- a/part_3/3.1/7.go +++ b/part_3/3.1/7.go @@ -2,16 +2,37 @@ package main import "fmt" +type employee struct { + name string + departmentName string + age uint8 + position string +} + func main() { - fmt.Printf("Sum = %d", myFunc(3, 5, 9, 25, -10)) -} - -func myFunc(values ...int) (sum int) { - // переменную values рассматриваем как срез []int - for _, value := range values { - sum += value + emp2 := employee{ + name: "Tom", + position: "Intern", } - return -} + empPoint := &emp2 // первый способ через оператор & + empPoint1 := &employee{ // второй способ через оператор & + name: "Maxim", + position: "Intern", + age: 18, + } + // изменение значений полей через указатель на структуру + (*empPoint).departmentName = "R&D" + // тоже самое, что + empPoint.age = 23 + empPoint1.departmentName = "R&D" + fmt.Printf("%+v\n", *empPoint) // {name:Tom departmentName:R&D age:23 position:Intern} + fmt.Printf("%+v\n", *empPoint1) // {name:Maxim departmentName:R&D age:18 position:Intern} -// Sum = 32 + empPoint2 := new(employee) // использование ключевого слова new + fmt.Printf("%+v\n", *empPoint2) // {name: departmentName: age:0 position:} + empPoint2.departmentName = "Oo" + empPoint2.name = "Alex" + empPoint2.position = "Engineer" + empPoint2.age = 40 + fmt.Printf("%+v\n", *empPoint2) // {name:Alex departmentName:Oo age:40 position:Engineer} +} diff --git a/part_3/3.1/8.go b/part_3/3.1/8.go index 4eb7871..531b645 100644 --- a/part_3/3.1/8.go +++ b/part_3/3.1/8.go @@ -2,13 +2,28 @@ package main import "fmt" -func main() { - sum := func(values ...int) (sum int) { // объявление функции - // переменную values рассматриваем как срез []int - for _, value := range values { - sum += value - } - return - }(3, 5, 9, 25, -10) // вызов функции - fmt.Printf("Sum = %d", sum) // Sum = 32 +type employee struct { + name string + string // первое анонимное поле + uint8 // второе анонимное поле + position string +} + +func main() { + emp := employee{ + name: "Tom", + position: "Intern", + } + emp1 := employee{ + name: "Alex", + position: "Intern", + uint8: 17, + string: "R&D", + } + // присваиваем значение анонимному полю + emp.uint8 = 22 + emp.string = "R&D" + fmt.Printf("%+v\n", emp1) //{name:Alex string:R&D uint8:17 position:Intern} + fmt.Printf("%+v\n", emp) // {name:Tom string:R&D uint8:22 position:Intern} + fmt.Printf("%+v\n", emp.uint8) // 22 - вывод значения анонимного поля } diff --git a/part_3/3.1/9.go b/part_3/3.1/9.go index ad982ae..2c16d8a 100644 --- a/part_3/3.1/9.go +++ b/part_3/3.1/9.go @@ -1,34 +1,34 @@ package main -import ( - "fmt" - "math/rand" - "time" -) +import "fmt" -// генератор случайных чисел -var generator = rand.New(rand.NewSource(time.Now().UnixNano())) - -func sliceCreator1(size int16) (slice *[]int16) { - slice = new([]int16) - *slice = make([]int16, size, size+10) - for i := range *slice { - (*slice)[i] += int16(generator.Int()) - } - return +type employee struct { + name string + age uint8 } -func sliceCreator2(size int16) *[]int16 { - slice := make([]int16, size, size+10) - for i := range slice { - slice[i] += int16(generator.Int()) - } - return &slice +func valueFunc(emp employee) { + emp.name = "O_O" + fmt.Printf("Copy value: %+v\n", emp) +} + +func pointFunc(emp *employee) { + emp.name = "^_^" + fmt.Printf("Point to value: %+v\n", emp) } func main() { - slice := sliceCreator1(7) - fmt.Println(*slice) // [-22201 -30245 6682 28346 23159 -28589 16762] - slice = sliceCreator2(5) - fmt.Println(*slice) // [3896 28732 -30834 1722 -14725] + emp := employee{ + name: "Tom", + age: 45, + } + newEmployee := emp + newEmployee.age = 22 + fmt.Printf("newEmployee = %+v\n", newEmployee) + fmt.Printf("emp = %+v\n", emp) + + valueFunc(emp) // передача в функцию по значению + fmt.Printf("emp = %+v\n", emp) + pointFunc(&emp) // передача в функцию по указателю + fmt.Printf("emp = %+v\n", emp) } diff --git a/part_3/3.10/1.go b/part_3/3.10/1.go index 6d91ceb..85957aa 100644 --- a/part_3/3.10/1.go +++ b/part_3/3.10/1.go @@ -2,19 +2,20 @@ package main import "fmt" -func createGenerator(start int, end int) chan int { - ch := make(chan int, end-start) - go func(ch chan int) { - for i := start; i <= end; i++ { - ch <- i // помещение значения в канал - } - close(ch) - }(ch) - return ch +func SumInt(a, b int) int { + return a + b +} + +func SumFloat(a, b float64) float64 { + return a + b +} + +func SumString(a, b string) string { + return a + b } func main() { - for it := range createGenerator(1, 10) { - fmt.Printf("%d || ", it) - } + fmt.Println(SumFloat(10.3, 45.1)) // 55.4 + fmt.Println(SumInt(10, 45)) // 55 + fmt.Println(SumString("^_", "^")) // ^_^ } diff --git a/part_5/5.10/10.go b/part_3/3.10/10.go similarity index 100% rename from part_5/5.10/10.go rename to part_3/3.10/10.go diff --git a/part_3/3.10/2.go b/part_3/3.10/2.go index 691185c..af8f917 100644 --- a/part_3/3.10/2.go +++ b/part_3/3.10/2.go @@ -2,24 +2,12 @@ package main import "fmt" -func createGenerator(start int, end int) chan int { - ch := make(chan int, end-start) - go func(ch chan int) { - for i := start; i <= end; i++ { - ch <- i // помещение значения в канал - } - close(ch) - }(ch) - return ch +func Sum[T int | float64 | string](a, b T) T { + return a + b } func main() { - generator := createGenerator(4, 8) - for { - value := <-generator // распаковка значения из канала в переменную - fmt.Printf("%d || ", value) - if len(generator) <= 0 { // проверка на выход из бесконечного цикла - break - } - } + fmt.Println(Sum(10.3, 45.1)) // 55.4 + fmt.Println(Sum(10, 45)) // 55 + fmt.Println(Sum("^_", "^")) // ^_^ } diff --git a/part_5/5.10/3.go b/part_3/3.10/3.go similarity index 100% rename from part_5/5.10/3.go rename to part_3/3.10/3.go diff --git a/part_5/5.10/4.go b/part_3/3.10/4.go similarity index 100% rename from part_5/5.10/4.go rename to part_3/3.10/4.go diff --git a/part_5/5.10/5.go b/part_3/3.10/5.go similarity index 100% rename from part_5/5.10/5.go rename to part_3/3.10/5.go diff --git a/part_5/5.10/6.go b/part_3/3.10/6.go similarity index 100% rename from part_5/5.10/6.go rename to part_3/3.10/6.go diff --git a/part_5/5.10/7.go b/part_3/3.10/7.go similarity index 100% rename from part_5/5.10/7.go rename to part_3/3.10/7.go diff --git a/part_5/5.10/8.go b/part_3/3.10/8.go similarity index 100% rename from part_5/5.10/8.go rename to part_3/3.10/8.go diff --git a/part_5/5.10/9.go b/part_3/3.10/9.go similarity index 100% rename from part_5/5.10/9.go rename to part_3/3.10/9.go diff --git a/part_3/3.2/1.go b/part_3/3.2/1.go index 684f2df..71b174d 100644 --- a/part_3/3.2/1.go +++ b/part_3/3.2/1.go @@ -2,18 +2,23 @@ package main import "fmt" +type RUB uint // пользовательский именованный тип RUB + +const RUB2USD uint = 61 +const RUB2EUR uint = 65 + +//связываем тип RUB с методом конвертации рублей в доллары +func (r RUB) convertRUB2USD() uint { + return uint(r) / RUB2USD +} + +//связываем тип RUB с методом конвертации рублей в евро +func (r RUB) convertRUB2EUR() uint { + return uint(r) / RUB2EUR +} + func main() { - array := [4]float64{2.4, 5.6, 8.1, 9.22} - myFunc(array) - fmt.Printf("Array in main: %v\n", array) + var rub RUB = 3475 + fmt.Printf("%d рублей примерно = %d долларов\n", rub, rub.convertRUB2USD()) + fmt.Printf("%d рублей примерно = %d евро\n", rub, rub.convertRUB2EUR()) } - -func myFunc(array [4]float64) { - for i := range array { - array[i] += 2.33 - } - fmt.Printf("Array in myFunc: %v\n", array) -} - -// Array in myFunc: [4.73 7.93 10.43 11.55] -// Array in main: [2.4 5.6 8.1 9.22] diff --git a/part_3/3.2/2.go b/part_3/3.2/2.go index 0682392..46e03a6 100644 --- a/part_3/3.2/2.go +++ b/part_3/3.2/2.go @@ -2,18 +2,28 @@ package main import "fmt" +type RUB uint // пользовательский именованный тип RUB + +const RUB2USD uint = 61 +const RUB2EUR uint = 65 + +//связываем тип RUB с методом конвертации рублей в доллары +func (r RUB) convertRUB2USD() uint { + return uint(r) / RUB2USD +} + +//связываем тип RUB с методом конвертации рублей в евро +func (r RUB) convertRUB2EUR() uint { + return uint(r) / RUB2EUR +} + +func (r RUB) setNewValue(rub RUB) { + r = rub + fmt.Printf("В кошельке теперь %d рублей\n", r) +} + func main() { - array := [4]float64{2.4, 5.6, 8.1, 9.22} - myFunc(&array) - fmt.Printf("Array in main: %v\n", array) + var rub RUB = 3475 + rub.setNewValue(9000) + fmt.Printf("В кошельке на самом деле %d рублей\n", rub) } - -func myFunc(array *[4]float64) { - for i := range array { - array[i] += 2.33 - } - fmt.Printf("Array in myFunc: %v\n", *array) -} - -// Array in myFunc: [4.73 7.93 10.43 11.55] -// Array in main: [4.73 7.93 10.43 11.55] diff --git a/part_3/3.2/3.go b/part_3/3.2/3.go index fc1dc99..6d341a5 100644 --- a/part_3/3.2/3.go +++ b/part_3/3.2/3.go @@ -2,18 +2,28 @@ package main import "fmt" +type RUB uint // пользовательский именованный тип RUB + +const RUB2USD uint = 61 +const RUB2EUR uint = 65 + +//связываем тип RUB с методом конвертации рублей в доллары +func (r RUB) convertRUB2USD() uint { + return uint(r) / RUB2USD +} + +//связываем тип RUB с методом конвертации рублей в евро +func (r RUB) convertRUB2EUR() uint { + return uint(r) / RUB2EUR +} + +func (r *RUB) setNewValue(rub RUB) { + *r = rub + fmt.Printf("В кошельке теперь %d рублей\n", *r) +} + func main() { - array := []float64{2.4, 5.6, 8.1, 9.22} - myFunc(&array) - fmt.Printf("Array in main: %v\n", array) + var rub RUB = 3475 + rub.setNewValue(9000) + fmt.Printf("В кошельке на самом деле %d рублей\n", rub) } - -func myFunc(array *[]float64) { - for i := range *array { - (*array)[i] += 1.5 - } - fmt.Printf("Array in myFunc: %v\n", *array) -} - -// Array in myFunc: [3.9 7.1 9.6 10.72] -// Array in main: [3.9 7.1 9.6 10.72] diff --git a/part_5/5.3/golang/factory/go.mod b/part_3/3.3/golang/factory/go.mod similarity index 100% rename from part_5/5.3/golang/factory/go.mod rename to part_3/3.3/golang/factory/go.mod diff --git a/part_5/5.3/golang/factory/main.go b/part_3/3.3/golang/factory/main.go similarity index 100% rename from part_5/5.3/golang/factory/main.go rename to part_3/3.3/golang/factory/main.go diff --git a/part_5/5.3/golang/factory/shape/shape.go b/part_3/3.3/golang/factory/shape/shape.go similarity index 100% rename from part_5/5.3/golang/factory/shape/shape.go rename to part_3/3.3/golang/factory/shape/shape.go diff --git a/part_5/5.4/golang/factory/go.mod b/part_3/3.4/golang/factory/go.mod similarity index 100% rename from part_5/5.4/golang/factory/go.mod rename to part_3/3.4/golang/factory/go.mod diff --git a/part_5/5.4/golang/factory/main.go b/part_3/3.4/golang/factory/main.go similarity index 100% rename from part_5/5.4/golang/factory/main.go rename to part_3/3.4/golang/factory/main.go diff --git a/part_5/5.4/golang/factory/shape/shape.go b/part_3/3.4/golang/factory/shape/shape.go similarity index 100% rename from part_5/5.4/golang/factory/shape/shape.go rename to part_3/3.4/golang/factory/shape/shape.go diff --git a/part_5/5.6/golang/factory/go.mod b/part_3/3.6/golang/factory/go.mod similarity index 100% rename from part_5/5.6/golang/factory/go.mod rename to part_3/3.6/golang/factory/go.mod diff --git a/part_5/5.6/golang/factory/main.go b/part_3/3.6/golang/factory/main.go similarity index 100% rename from part_5/5.6/golang/factory/main.go rename to part_3/3.6/golang/factory/main.go diff --git a/part_5/5.6/golang/factory/shape/rectangle.go b/part_3/3.6/golang/factory/shape/rectangle.go similarity index 100% rename from part_5/5.6/golang/factory/shape/rectangle.go rename to part_3/3.6/golang/factory/shape/rectangle.go diff --git a/part_5/5.6/golang/factory/shape/shape.go b/part_3/3.6/golang/factory/shape/shape.go similarity index 100% rename from part_5/5.6/golang/factory/shape/shape.go rename to part_3/3.6/golang/factory/shape/shape.go diff --git a/part_5/5.7/golang/factory/go.mod b/part_3/3.7/golang/factory/go.mod similarity index 100% rename from part_5/5.7/golang/factory/go.mod rename to part_3/3.7/golang/factory/go.mod diff --git a/part_5/5.7/golang/factory/main.go b/part_3/3.7/golang/factory/main.go similarity index 100% rename from part_5/5.7/golang/factory/main.go rename to part_3/3.7/golang/factory/main.go diff --git a/part_5/5.7/golang/factory/shape/ishape.go b/part_3/3.7/golang/factory/shape/ishape.go similarity index 100% rename from part_5/5.7/golang/factory/shape/ishape.go rename to part_3/3.7/golang/factory/shape/ishape.go diff --git a/part_5/5.7/golang/factory/shape/rectangle.go b/part_3/3.7/golang/factory/shape/rectangle.go similarity index 100% rename from part_5/5.7/golang/factory/shape/rectangle.go rename to part_3/3.7/golang/factory/shape/rectangle.go diff --git a/part_5/5.7/golang/factory/shape/shape.go b/part_3/3.7/golang/factory/shape/shape.go similarity index 100% rename from part_5/5.7/golang/factory/shape/shape.go rename to part_3/3.7/golang/factory/shape/shape.go diff --git a/part_5/5.7/golang/factory/shape/triangle.go b/part_3/3.7/golang/factory/shape/triangle.go similarity index 100% rename from part_5/5.7/golang/factory/shape/triangle.go rename to part_3/3.7/golang/factory/shape/triangle.go diff --git a/part_5/5.8/golang/car_factory/go.mod b/part_3/3.8/golang/car_factory/go.mod similarity index 100% rename from part_5/5.8/golang/car_factory/go.mod rename to part_3/3.8/golang/car_factory/go.mod diff --git a/part_5/5.8/golang/car_factory/main.go b/part_3/3.8/golang/car_factory/main.go similarity index 100% rename from part_5/5.8/golang/car_factory/main.go rename to part_3/3.8/golang/car_factory/main.go diff --git a/part_5/5.8/golang/car_factory/vehicle/car.go b/part_3/3.8/golang/car_factory/vehicle/car.go similarity index 100% rename from part_5/5.8/golang/car_factory/vehicle/car.go rename to part_3/3.8/golang/car_factory/vehicle/car.go diff --git a/part_5/5.8/golang/car_factory/vehicle/motor/avtovaz_motor.go b/part_3/3.8/golang/car_factory/vehicle/motor/avtovaz_motor.go similarity index 100% rename from part_5/5.8/golang/car_factory/vehicle/motor/avtovaz_motor.go rename to part_3/3.8/golang/car_factory/vehicle/motor/avtovaz_motor.go diff --git a/part_5/5.8/golang/car_factory/vehicle/motor/hyundai_motor.go b/part_3/3.8/golang/car_factory/vehicle/motor/hyundai_motor.go similarity index 100% rename from part_5/5.8/golang/car_factory/vehicle/motor/hyundai_motor.go rename to part_3/3.8/golang/car_factory/vehicle/motor/hyundai_motor.go diff --git a/part_5/5.8/golang/car_factory/vehicle/motor/imotor.go b/part_3/3.8/golang/car_factory/vehicle/motor/imotor.go similarity index 100% rename from part_5/5.8/golang/car_factory/vehicle/motor/imotor.go rename to part_3/3.8/golang/car_factory/vehicle/motor/imotor.go diff --git a/part_5/5.8/golang/car_factory/vehicle/motor/motor.go b/part_3/3.8/golang/car_factory/vehicle/motor/motor.go similarity index 100% rename from part_5/5.8/golang/car_factory/vehicle/motor/motor.go rename to part_3/3.8/golang/car_factory/vehicle/motor/motor.go diff --git a/part_3/3.9/1.go b/part_3/3.9/1.go index dca5369..d258ca5 100644 --- a/part_3/3.9/1.go +++ b/part_3/3.9/1.go @@ -2,15 +2,7 @@ package main import "fmt" -func sumElem(slice []int) int { - fmt.Println(slice) - if len(slice) <= 1 { - return slice[0] - } - return slice[0] + sumElem(slice[1:]) -} - func main() { - mySlice := []int{2, 5, 22, 9, 0} - fmt.Println(sumElem(mySlice)) + var myInterface interface{} + fmt.Printf("%v", myInterface) // } diff --git a/part_3/3.9/2.go b/part_3/3.9/2.go index 5238ff4..8fd06d4 100644 --- a/part_3/3.9/2.go +++ b/part_3/3.9/2.go @@ -2,19 +2,18 @@ package main import "fmt" -func sumElem(slice []int) int { - fmt.Println(slice) - if len(slice) <= 1 { - return slice[0] - } - return anotherFunction(slice) +type shape struct { + name string } -func anotherFunction(slice []int) int { - return slice[0] + sumElem(slice[1:]) +func (s *shape) getName() string { + return s.name } func main() { - mySlice := []int{2, 5, 22, 9, 0} - fmt.Println(sumElem(mySlice)) + var firstInterface interface{} = shape{name: "Cube"} + var secondInterface interface{} = "Oo" + + fmt.Printf("%+v\n", firstInterface) // {name:Cube} + fmt.Printf("%+v\n", secondInterface) // Oo } diff --git a/part_5/5.9/3.go b/part_3/3.9/3.go similarity index 100% rename from part_5/5.9/3.go rename to part_3/3.9/3.go diff --git a/part_5/5.9/4.go b/part_3/3.9/4.go similarity index 100% rename from part_5/5.9/4.go rename to part_3/3.9/4.go diff --git a/part_5/5.9/5.go b/part_3/3.9/5.go similarity index 100% rename from part_5/5.9/5.go rename to part_3/3.9/5.go diff --git a/part_5/5.9/6.go b/part_3/3.9/6.go similarity index 100% rename from part_5/5.9/6.go rename to part_3/3.9/6.go diff --git a/part_6/6.1/1.go b/part_4/4.1/1.go similarity index 100% rename from part_6/6.1/1.go rename to part_4/4.1/1.go diff --git a/part_6/6.1/2.go b/part_4/4.1/2.go similarity index 100% rename from part_6/6.1/2.go rename to part_4/4.1/2.go diff --git a/part_6/6.2/1.go b/part_4/4.2/1.go similarity index 100% rename from part_6/6.2/1.go rename to part_4/4.2/1.go diff --git a/part_6/6.3/1.go b/part_4/4.3/1.go similarity index 100% rename from part_6/6.3/1.go rename to part_4/4.3/1.go diff --git a/part_6/6.4/1.go b/part_4/4.4/1.go similarity index 100% rename from part_6/6.4/1.go rename to part_4/4.4/1.go diff --git a/part_6/6.4/2.go b/part_4/4.4/2.go similarity index 100% rename from part_6/6.4/2.go rename to part_4/4.4/2.go diff --git a/part_6/6.5/1.go b/part_4/4.5/1.go similarity index 100% rename from part_6/6.5/1.go rename to part_4/4.5/1.go diff --git a/part_6/6.5/2.go b/part_4/4.5/2.go similarity index 100% rename from part_6/6.5/2.go rename to part_4/4.5/2.go diff --git a/part_6/6.5/3.go b/part_4/4.5/3.go similarity index 100% rename from part_6/6.5/3.go rename to part_4/4.5/3.go diff --git a/part_6/6.6/1.go b/part_4/4.6/1.go similarity index 100% rename from part_6/6.6/1.go rename to part_4/4.6/1.go diff --git a/part_6/6.7/1.go b/part_4/4.7/1.go similarity index 100% rename from part_6/6.7/1.go rename to part_4/4.7/1.go diff --git a/part_6/6.8/1.go b/part_4/4.8/1.go similarity index 100% rename from part_6/6.8/1.go rename to part_4/4.8/1.go diff --git a/part_6/6.9/1.go b/part_4/4.9/1.go similarity index 100% rename from part_6/6.9/1.go rename to part_4/4.9/1.go diff --git a/part_5/5.1/1.go b/part_5/5.1/1.go index 6956f14..76c4e2a 100644 --- a/part_5/5.1/1.go +++ b/part_5/5.1/1.go @@ -1,16 +1,16 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "fmt" + "log" + "os" +) func main() { - var emp employee - emp2 := employee{} - fmt.Println(emp, emp2) // { 0 } { 0 } + file, err := os.Create("test.txt") + if err != nil { + log.Fatal(err) + } + fmt.Println(file) + file.Close() // закрытие файла } diff --git a/part_5/5.1/10.go b/part_5/5.1/10.go index 7101a06..530d620 100644 --- a/part_5/5.1/10.go +++ b/part_5/5.1/10.go @@ -1,21 +1,15 @@ package main -import "fmt" - -type point struct { - x int - y int -} - -type shape struct { - name string - center point -} +import ( + "fmt" + "log" + "os" +) func main() { - myShape := shape{ - name: "Cube", - center: point{x: 10, y: 6}, + data, err := os.ReadFile("pirates.txt") + if err != nil { + log.Fatal(err) } - fmt.Printf("%+v\n", myShape) // {name:Cube center:{x:10 y:6}} + fmt.Println(string(data)) } diff --git a/part_7/7.1 file/11.go b/part_5/5.1/11.go similarity index 100% rename from part_7/7.1 file/11.go rename to part_5/5.1/11.go diff --git a/part_7/7.1 file/12.go b/part_5/5.1/12.go similarity index 100% rename from part_7/7.1 file/12.go rename to part_5/5.1/12.go diff --git a/part_7/7.1 file/13.go b/part_5/5.1/13.go similarity index 100% rename from part_7/7.1 file/13.go rename to part_5/5.1/13.go diff --git a/part_7/7.1 file/14.go b/part_5/5.1/14.go similarity index 100% rename from part_7/7.1 file/14.go rename to part_5/5.1/14.go diff --git a/part_7/7.1 file/15.go b/part_5/5.1/15.go similarity index 100% rename from part_7/7.1 file/15.go rename to part_5/5.1/15.go diff --git a/part_7/7.1 file/16.go b/part_5/5.1/16.go similarity index 100% rename from part_7/7.1 file/16.go rename to part_5/5.1/16.go diff --git a/part_7/7.1 file/17.go b/part_5/5.1/17.go similarity index 100% rename from part_7/7.1 file/17.go rename to part_5/5.1/17.go diff --git a/part_7/7.1 file/18.go b/part_5/5.1/18.go similarity index 100% rename from part_7/7.1 file/18.go rename to part_5/5.1/18.go diff --git a/part_7/7.1 file/19.go b/part_5/5.1/19.go similarity index 100% rename from part_7/7.1 file/19.go rename to part_5/5.1/19.go diff --git a/part_5/5.1/2.go b/part_5/5.1/2.go index c842986..5f817ad 100644 --- a/part_5/5.1/2.go +++ b/part_5/5.1/2.go @@ -1,29 +1,19 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "fmt" + "log" + "os" +) func main() { - emp1 := employee{ - name: "Alex", - age: 25, - departmentName: "R&D", - position: "Assistant", + fileInfo, err := os.Stat("test.txt") + if err != nil { + log.Fatal(err) } - emp2 := employee{ - name: "Tom", - position: "Intern", - } - emp3 := employee{"Alex", "R&D", 25, "Assistant"} // ok - // emp3 := employee{"Alex", "R&D"} – ошибка!!! - - fmt.Println(emp1) // {Alex R&D 25 Assistant} - fmt.Println(emp2) // {Tom 0 Intern} - fmt.Println(emp3) // {Alex R&D 25 Assistant} + fmt.Println("File name:", fileInfo.Name()) + fmt.Println("Size in bytes:", fileInfo.Size()) + fmt.Println("Permissions:", fileInfo.Mode()) + fmt.Println("Last modified:", fileInfo.ModTime()) + fmt.Println("Is Directory: ", fileInfo.IsDir()) } diff --git a/part_7/7.1 file/20.go b/part_5/5.1/20.go similarity index 100% rename from part_7/7.1 file/20.go rename to part_5/5.1/20.go diff --git a/part_5/5.1/3.go b/part_5/5.1/3.go index ef8f21a..0979981 100644 --- a/part_5/5.1/3.go +++ b/part_5/5.1/3.go @@ -1,22 +1,17 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "log" + "os" +) func main() { - emp2 := employee{ - name: "Tom", - position: "Intern", + originalPath := "test.txt" + newPath := "../test2.txt" // переместит файл на уровень выше с именем test2.txt + // можно также оставить старое имя у перемещаемого файла - test.txt + // newPath := "test2.txt" // переименование файла в текущей директории + err := os.Rename(originalPath, newPath) + if err != nil { + log.Fatal(err) } - emp2.age = 22 - emp2.departmentName = "R&D" - fmt.Println(emp2) // {Tom R&D 22 Intern} - emp2.position = "Engineer" - fmt.Println(emp2) // {Tom R&D 22 Engineer} } diff --git a/part_5/5.1/4.go b/part_5/5.1/4.go index 870544e..d0bed69 100644 --- a/part_5/5.1/4.go +++ b/part_5/5.1/4.go @@ -1,22 +1,14 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "log" + "os" +) func main() { - emp2 := employee{ - name: "Tom", - position: "Intern", + pathToFile := "test.txt" + err := os.Remove(pathToFile) + if err != nil { + log.Fatal(err) } - emp2.age = 22 - emp2.departmentName = "R&D" - fmt.Printf("%+v\n", emp2) // {name:Tom departmentName:R&D age:22 position:Intern} - emp2.position = "Engineer" - fmt.Printf("%+v\n", emp2) // {name:Tom departmentName:R&D age:22 position:Engineer} } diff --git a/part_5/5.1/5.go b/part_5/5.1/5.go index 5b1e1fc..b099084 100644 --- a/part_5/5.1/5.go +++ b/part_5/5.1/5.go @@ -1,22 +1,20 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "fmt" + "log" + "os" +) func main() { - emp2 := employee{ - name: "Tom", - position: "Intern", + pathToFile := "pirates.txt" + fileInfo, err := os.Stat(pathToFile) + if err != nil { + if os.IsNotExist(err) { + log.Fatal("File does not exist.") + os.Exit(1) // выход из приложения со статусом 1 + } } - emp2.age = 22 - emp2.departmentName = "R&D" - fmt.Printf("%+v\n", emp2.age) // 22 - employeeAge := emp2.age - fmt.Println(employeeAge) // 22 + fmt.Println("File does exist!") + fmt.Println("File information:", fileInfo) } diff --git a/part_5/5.1/6.go b/part_5/5.1/6.go index 7253df4..f2006bb 100644 --- a/part_5/5.1/6.go +++ b/part_5/5.1/6.go @@ -1,38 +1,23 @@ package main -import "fmt" - -type employee struct { - name string - departmentName string - age uint8 - position string -} +import ( + "fmt" + "log" + "os" +) func main() { - emp2 := employee{ - name: "Tom", - position: "Intern", + firstText := "Пятнадцать человек на сундук мертвеца,\n" + secondText := "Йо-хо-хо, и бутылка рома," + file, err := os.Create("pirates.txt") + if err != nil { + log.Fatal(err) } - empPoint := &emp2 // первый способ через оператор & - empPoint1 := &employee{ // второй способ через оператор & - name: "Maxim", - position: "Intern", - age: 18, - } - // изменение значений полей через указатель на структуру - (*empPoint).departmentName = "R&D" - // тоже самое, что - empPoint.age = 23 - empPoint1.departmentName = "R&D" - fmt.Printf("%+v\n", *empPoint) // {name:Tom departmentName:R&D age:23 position:Intern} - fmt.Printf("%+v\n", *empPoint1) // {name:Maxim departmentName:R&D age:18 position:Intern} + defer file.Close() - empPoint2 := new(employee) // использование ключевого слова new - fmt.Printf("%+v\n", *empPoint2) // {name: departmentName: age:0 position:} - empPoint2.departmentName = "Oo" - empPoint2.name = "Alex" - empPoint2.position = "Engineer" - empPoint2.age = 40 - fmt.Printf("%+v\n", *empPoint2) // {name:Alex departmentName:Oo age:40 position:Engineer} + // функция WriteString преобразует string в []byte, после чего записывает в файл + file.WriteString(firstText) + // ручное приведение типа string в []byte и запись данных в файл + file.Write([]byte(secondText)) + fmt.Println("Text was wrote to file") } diff --git a/part_5/5.1/7.go b/part_5/5.1/7.go index 531b645..5b7f4ba 100644 --- a/part_5/5.1/7.go +++ b/part_5/5.1/7.go @@ -1,29 +1,29 @@ package main -import "fmt" - -type employee struct { - name string - string // первое анонимное поле - uint8 // второе анонимное поле - position string -} +import ( + "fmt" + "io" + "log" + "os" +) func main() { - emp := employee{ - name: "Tom", - position: "Intern", + file, err := os.Open("pirates.txt") + if err != nil { + log.Fatal(err) } - emp1 := employee{ - name: "Alex", - position: "Intern", - uint8: 17, - string: "R&D", + defer file.Close() + + file.WriteString("jgjgjg") // ничего в файл не добавится!!! + data := make([]byte, 128) + for { + length, err := file.Read(data) + fmt.Printf("Reading %d byte\n", length) + if err == io.EOF { // достигли конца файла? + break + } } - // присваиваем значение анонимному полю - emp.uint8 = 22 - emp.string = "R&D" - fmt.Printf("%+v\n", emp1) //{name:Alex string:R&D uint8:17 position:Intern} - fmt.Printf("%+v\n", emp) // {name:Tom string:R&D uint8:22 position:Intern} - fmt.Printf("%+v\n", emp.uint8) // 22 - вывод значения анонимного поля + fmt.Println(string(data)) + + fmt.Println("Text was read from file") } diff --git a/part_5/5.1/8.go b/part_5/5.1/8.go index 2c16d8a..d8e425a 100644 --- a/part_5/5.1/8.go +++ b/part_5/5.1/8.go @@ -1,34 +1,28 @@ package main -import "fmt" - -type employee struct { - name string - age uint8 -} - -func valueFunc(emp employee) { - emp.name = "O_O" - fmt.Printf("Copy value: %+v\n", emp) -} - -func pointFunc(emp *employee) { - emp.name = "^_^" - fmt.Printf("Point to value: %+v\n", emp) -} +import ( + "fmt" + "io" + "log" + "os" +) func main() { - emp := employee{ - name: "Tom", - age: 45, + file, err := os.Open("pirates.txt") + if err != nil { + log.Fatal(err) } - newEmployee := emp - newEmployee.age = 22 - fmt.Printf("newEmployee = %+v\n", newEmployee) - fmt.Printf("emp = %+v\n", emp) + defer file.Close() - valueFunc(emp) // передача в функцию по значению - fmt.Printf("emp = %+v\n", emp) - pointFunc(&emp) // передача в функцию по указателю - fmt.Printf("emp = %+v\n", emp) + tempData := make([]byte, 32) + data := []byte{} + for { + length, err := file.Read(tempData) + fmt.Printf("Reading %d byte\n", length) + if err == io.EOF { // достигли конца файла? + break + } + data = append(data, tempData...) + } + fmt.Println(string(data)) } diff --git a/part_5/5.1/9.go b/part_5/5.1/9.go index 49f6eef..e5b6201 100644 --- a/part_5/5.1/9.go +++ b/part_5/5.1/9.go @@ -1,20 +1,22 @@ package main -import "fmt" - -type point struct { - x int - y int -} - -func checkOutput(first, second int, check bool) { - fmt.Printf("point%d == point%d - %t\n", first, second, check) -} +import ( + "fmt" + "io/ioutil" + "log" + "os" +) func main() { - point1 := point{10, 20} - point2 := point{10, 20} - point3 := point{x: 2, y: 43} - checkOutput(1, 2, point1 == point2) - checkOutput(2, 3, point2 == point3) + file, err := os.Open("pirates.txt") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + data, err := ioutil.ReadAll(file) + if err != nil { + log.Fatal(err) + } + fmt.Println(string(data)) } diff --git a/part_5/5.10/1.go b/part_5/5.10/1.go deleted file mode 100644 index 85957aa..0000000 --- a/part_5/5.10/1.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import "fmt" - -func SumInt(a, b int) int { - return a + b -} - -func SumFloat(a, b float64) float64 { - return a + b -} - -func SumString(a, b string) string { - return a + b -} - -func main() { - fmt.Println(SumFloat(10.3, 45.1)) // 55.4 - fmt.Println(SumInt(10, 45)) // 55 - fmt.Println(SumString("^_", "^")) // ^_^ -} diff --git a/part_5/5.10/2.go b/part_5/5.10/2.go deleted file mode 100644 index af8f917..0000000 --- a/part_5/5.10/2.go +++ /dev/null @@ -1,13 +0,0 @@ -package main - -import "fmt" - -func Sum[T int | float64 | string](a, b T) T { - return a + b -} - -func main() { - fmt.Println(Sum(10.3, 45.1)) // 55.4 - fmt.Println(Sum(10, 45)) // 55 - fmt.Println(Sum("^_", "^")) // ^_^ -} diff --git a/part_5/5.2/1.go b/part_5/5.2/1.go index 71b174d..111f707 100644 --- a/part_5/5.2/1.go +++ b/part_5/5.2/1.go @@ -1,24 +1,15 @@ package main -import "fmt" - -type RUB uint // пользовательский именованный тип RUB - -const RUB2USD uint = 61 -const RUB2EUR uint = 65 - -//связываем тип RUB с методом конвертации рублей в доллары -func (r RUB) convertRUB2USD() uint { - return uint(r) / RUB2USD -} - -//связываем тип RUB с методом конвертации рублей в евро -func (r RUB) convertRUB2EUR() uint { - return uint(r) / RUB2EUR -} +import ( + "fmt" + "log" + "os" +) func main() { - var rub RUB = 3475 - fmt.Printf("%d рублей примерно = %d долларов\n", rub, rub.convertRUB2USD()) - fmt.Printf("%d рублей примерно = %d евро\n", rub, rub.convertRUB2EUR()) + err := os.Mkdir("myDir", 0777) + if err != nil { + log.Fatal(err) + } + fmt.Println("Directory created") } diff --git a/part_7/7.2 dir/10.go b/part_5/5.2/10.go similarity index 100% rename from part_7/7.2 dir/10.go rename to part_5/5.2/10.go diff --git a/part_7/7.2 dir/11.go b/part_5/5.2/11.go similarity index 100% rename from part_7/7.2 dir/11.go rename to part_5/5.2/11.go diff --git a/part_7/7.2 dir/12.go b/part_5/5.2/12.go similarity index 100% rename from part_7/7.2 dir/12.go rename to part_5/5.2/12.go diff --git a/part_5/5.2/2.go b/part_5/5.2/2.go index 46e03a6..b6b4272 100644 --- a/part_5/5.2/2.go +++ b/part_5/5.2/2.go @@ -1,29 +1,15 @@ package main -import "fmt" - -type RUB uint // пользовательский именованный тип RUB - -const RUB2USD uint = 61 -const RUB2EUR uint = 65 - -//связываем тип RUB с методом конвертации рублей в доллары -func (r RUB) convertRUB2USD() uint { - return uint(r) / RUB2USD -} - -//связываем тип RUB с методом конвертации рублей в евро -func (r RUB) convertRUB2EUR() uint { - return uint(r) / RUB2EUR -} - -func (r RUB) setNewValue(rub RUB) { - r = rub - fmt.Printf("В кошельке теперь %d рублей\n", r) -} +import ( + "fmt" + "log" + "os" +) func main() { - var rub RUB = 3475 - rub.setNewValue(9000) - fmt.Printf("В кошельке на самом деле %d рублей\n", rub) + err := os.Remove("myDir") + if err != nil { + log.Fatal(err) + } + fmt.Println("Directory removed") } diff --git a/part_5/5.2/3.go b/part_5/5.2/3.go index 6d341a5..1fb6f5a 100644 --- a/part_5/5.2/3.go +++ b/part_5/5.2/3.go @@ -1,29 +1,48 @@ package main -import "fmt" +import ( + "fmt" + "log" + "os" + "path/filepath" +) -type RUB uint // пользовательский именованный тип RUB +const tempFileName = "myTempFile.dat" +const tempDirName = "myTempDir" -const RUB2USD uint = 61 -const RUB2EUR uint = 65 - -//связываем тип RUB с методом конвертации рублей в доллары -func (r RUB) convertRUB2USD() uint { - return uint(r) / RUB2USD +func printPath(path string, err error) string { + if err != nil { + log.Fatal(err) + } + fmt.Println("TempDir created with path: ", path) + return path } -//связываем тип RUB с методом конвертации рублей в евро -func (r RUB) convertRUB2EUR() uint { - return uint(r) / RUB2EUR -} +func createdFile(path string) { + filepath := filepath.Join(path, tempFileName) + myFile, err := os.Create(filepath) + if err != nil { + log.Fatal(err) + } + defer myFile.Close() + fmt.Println("TempFile created with path: ", filepath) + fmt.Println() -func (r *RUB) setNewValue(rub RUB) { - *r = rub - fmt.Printf("В кошельке теперь %d рублей\n", *r) } func main() { - var rub RUB = 3475 - rub.setNewValue(9000) - fmt.Printf("В кошельке на самом деле %d рублей\n", rub) + os.Mkdir(tempDirName, 0777) + + path := printPath(os.MkdirTemp(tempDirName, "*")) // случайное имя временного каталога + createdFile(path) + + path = printPath(os.MkdirTemp(tempDirName, "temp*dir")) // имя с использованием шаблона + createdFile(path) + + path = printPath(os.MkdirTemp(tempDirName, "tempdir")) // имя с использованием шаблона + createdFile(path) + // создание временного каталога со случайным именем + // в системной директории для временных файлов + path = printPath(os.MkdirTemp("", "*")) + createdFile(path) } diff --git a/part_7/7.2 dir/4.go b/part_5/5.2/4.go similarity index 100% rename from part_7/7.2 dir/4.go rename to part_5/5.2/4.go diff --git a/part_7/7.2 dir/5.go b/part_5/5.2/5.go similarity index 100% rename from part_7/7.2 dir/5.go rename to part_5/5.2/5.go diff --git a/part_7/7.2 dir/6.go b/part_5/5.2/6.go similarity index 100% rename from part_7/7.2 dir/6.go rename to part_5/5.2/6.go diff --git a/part_7/7.2 dir/7.go b/part_5/5.2/7.go similarity index 100% rename from part_7/7.2 dir/7.go rename to part_5/5.2/7.go diff --git a/part_7/7.2 dir/8.go b/part_5/5.2/8.go similarity index 100% rename from part_7/7.2 dir/8.go rename to part_5/5.2/8.go diff --git a/part_7/7.2 dir/9.go b/part_5/5.2/9.go similarity index 100% rename from part_7/7.2 dir/9.go rename to part_5/5.2/9.go diff --git a/part_5/5.3/1.go b/part_5/5.3/1.go new file mode 100644 index 0000000..7939dac --- /dev/null +++ b/part_5/5.3/1.go @@ -0,0 +1,30 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" +) + +type Actor struct { + Name string + Age int + FilmsAmount int + AboutActor string +} + +func main() { + actor := Actor{ + Name: "Tom Hanks", + Age: 65, + FilmsAmount: 50, + AboutActor: "Tom Hanks is an actor...", + } + + actorJson, err := json.Marshal(actor) + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(actorJson)) +} diff --git a/part_5/5.3/2.go b/part_5/5.3/2.go new file mode 100644 index 0000000..7677527 --- /dev/null +++ b/part_5/5.3/2.go @@ -0,0 +1,36 @@ +package main + +import ( + "encoding/json" + "log" + "os" +) + +type Actor struct { + Name string + Age int + FilmsAmount int + AboutActor string +} + +func main() { + actor := Actor{ + Name: "Tom Hanks", + Age: 65, + FilmsAmount: 50, + AboutActor: "Tom Hanks is an actor...", + } + + actorJson, err := json.MarshalIndent(actor, "", " ") + if err != nil { + log.Fatal(err) + } + + myFile, err := os.Create("actor.json") + if err != nil { + log.Fatal(err) + } + + myFile.Write(actorJson) + defer myFile.Close() +} diff --git a/part_5/5.3/3.go b/part_5/5.3/3.go new file mode 100644 index 0000000..52ad44e --- /dev/null +++ b/part_5/5.3/3.go @@ -0,0 +1,31 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +type Actor struct { + Name string + Age int + FilmsAmount int + AboutActor string +} + +func main() { + actor := &Actor{} + + data, err := os.ReadFile("actor.json") + if err != nil { + log.Fatal(err) + } + + err = json.Unmarshal(data, actor) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%+v", *actor) +} diff --git a/part_5/5.3/4.go b/part_5/5.3/4.go new file mode 100644 index 0000000..455a303 --- /dev/null +++ b/part_5/5.3/4.go @@ -0,0 +1,43 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +type Actor struct { + Name string + Age int + FilmsAmount int + AboutActor *string +} + +func main() { + actor := &Actor{} + + data, err := os.ReadFile("actor.json") + if err != nil { + log.Fatal(err) + } + + err = json.Unmarshal(data, actor) + if err != nil { + log.Fatal(err) + } + + // Выводим данные, прочитанные из файла + fmt.Print("Deserialized data: ") + fmt.Printf("%+v\n", *actor) + + actorJson, err := json.MarshalIndent(actor, "", " ") // сериализация + if err != nil { + log.Fatal(err) + } + + // Выводим сериализованные данные + fmt.Println() + fmt.Println("Serialized data:") + fmt.Println(string(actorJson)) +} diff --git a/part_5/5.3/5.go b/part_5/5.3/5.go new file mode 100644 index 0000000..2bccca6 --- /dev/null +++ b/part_5/5.3/5.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" +) + +type Actor struct { + // имя поля при сериализации/десериализации + Name string `json:"name"` + Age int `json:"age"` + // имя тега может отличаться от имени поля структуры + FilmsAmount int `json:"films_amount"` + AboutActor *string `json:"about"` +} + +func main() { + aboutStr := "Tom Hanks is an actor..." + actor := Actor{ + Name: "Tom Hanks", + Age: 65, + FilmsAmount: 50, + AboutActor: &aboutStr, + } + + actorJson, err := json.MarshalIndent(actor, "", " ") + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(actorJson)) +} diff --git a/part_5/5.3/6.go b/part_5/5.3/6.go new file mode 100644 index 0000000..0cfe61e --- /dev/null +++ b/part_5/5.3/6.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" +) + +type Actor struct { + // имя поля при сериализации/десериализации + Name string `json:"name"` + Age int `json:"-"` + // имя тега может отличаться от имени поля структуры + FilmsAmount int `json:"-"` + AboutActor *string `json:"about"` +} + +func main() { + aboutStr := "Tom Hanks is an actor..." + actor := Actor{ + Name: "Tom Hanks", + Age: 65, + FilmsAmount: 50, + AboutActor: &aboutStr, + } + + actorJson, err := json.MarshalIndent(actor, "", " ") + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(actorJson)) +} diff --git a/part_5/5.3/7.go b/part_5/5.3/7.go new file mode 100644 index 0000000..e890e6e --- /dev/null +++ b/part_5/5.3/7.go @@ -0,0 +1,54 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" +) + +type Actor struct { + // имя поля при сериализации/десериализации + Name string `json:"name"` + Age int `json:"age"` + // имя тега может отличаться от имени поля структуры + FilmsAmount int `json:"films_amount,omitempty"` + AboutActor *string `json:",omitempty"` +} + +func ActorToBytes(actor Actor) []byte { + actorJson, err := json.MarshalIndent(actor, "", " ") + if err != nil { + log.Fatal(err) + } + return actorJson +} + +func main() { + aboutStr := "Tom Hanks is an actor..." + // поле FilmsAmount проинициализируется значением + // по умолчанию + actor := Actor{ + Name: "Tom Hanks", + Age: 65, + AboutActor: &aboutStr, + } + + actorJson := ActorToBytes(actor) + // Выводим сериализованные данные + fmt.Println() + fmt.Println("First serialized data:") + fmt.Println(string(actorJson)) + + // поле AboutActor и Age проинициализируются значением + // по умолчанию + actor = Actor{ + Name: "Tom Hanks", + FilmsAmount: 150, + } + + actorJson = ActorToBytes(actor) + // Выводим сериализованные данные + fmt.Println() + fmt.Println("Second serialized data:") + fmt.Println(string(actorJson)) +} diff --git a/part_5/5.3/8.go b/part_5/5.3/8.go new file mode 100644 index 0000000..c4e96e2 --- /dev/null +++ b/part_5/5.3/8.go @@ -0,0 +1,32 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +type Actor struct { + // имя поля при сериализации/десериализации + Name string `json:"name"` + Age int `json:"age"` + // имя тега может отличаться от имени поля структуры + FilmsAmount int `json:"films_amount,omitempty"` + AboutActor *string `json:",omitempty"` +} + +func main() { + actorJson := map[string]any{} + + data, err := os.ReadFile("actor.json") + if err != nil { + log.Fatal(err) + } + + err = json.Unmarshal(data, &actorJson) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", actorJson) +} diff --git a/part_5/5.3/filmography/go.mod b/part_5/5.3/filmography/go.mod new file mode 100644 index 0000000..49d142a --- /dev/null +++ b/part_5/5.3/filmography/go.mod @@ -0,0 +1,3 @@ +module filmography + +go 1.24.3 diff --git a/part_5/5.3/filmography/imdb/actor.go b/part_5/5.3/filmography/imdb/actor.go new file mode 100644 index 0000000..678d838 --- /dev/null +++ b/part_5/5.3/filmography/imdb/actor.go @@ -0,0 +1,8 @@ +package imdb + +type Actor struct { + Name string `json:"name"` + Age int `json:"age"` + FilmsAmount int `json:"filmsAmount"` + AboutActor string `json:"aboutActor"` +} diff --git a/part_5/5.3/filmography/imdb/genre.go b/part_5/5.3/filmography/imdb/genre.go new file mode 100644 index 0000000..a83ee23 --- /dev/null +++ b/part_5/5.3/filmography/imdb/genre.go @@ -0,0 +1,5 @@ +package imdb + +type Genre struct { + Types []string `json:"types"` +} diff --git a/part_5/5.3/filmography/imdb/movie.go b/part_5/5.3/filmography/imdb/movie.go new file mode 100644 index 0000000..a435ea7 --- /dev/null +++ b/part_5/5.3/filmography/imdb/movie.go @@ -0,0 +1,13 @@ +package imdb + +type Movie struct { + Name string `json:"name"` + Budget int `json:"budget"` + Actors []Actor `json:"actors"` + CriticsRating float64 `json:"criticsRating"` + AudienceRating float64 `json:"audienceRating"` + Year int `json:"year"` + Country string `json:"country"` + Genre Genre `json:"genre"` + Reviews []Review `json:"reviews"` +} diff --git a/part_5/5.3/filmography/imdb/review.go b/part_5/5.3/filmography/imdb/review.go new file mode 100644 index 0000000..e6b7ad8 --- /dev/null +++ b/part_5/5.3/filmography/imdb/review.go @@ -0,0 +1,7 @@ +package imdb + +type Review struct { + Name string `json:"name"` + Text string `json:"text"` + Rating int `json:"rating"` +} diff --git a/part_5/5.3/filmography/main.go b/part_5/5.3/filmography/main.go new file mode 100644 index 0000000..f5ad9d2 --- /dev/null +++ b/part_5/5.3/filmography/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "filmography/imdb" + "fmt" + "log" + "os" +) + +func main() { + movie := &imdb.Movie{} + data, err := os.ReadFile("movie.json") + if err != nil { + log.Fatal(err) + } + + err = json.Unmarshal(data, &movie) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", movie) + + // записать в файл output.json + data, err = json.MarshalIndent(movie, "", " ") + if err != nil { + log.Fatal(err) + } + err = os.WriteFile("output.json", data, 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/part_5/5.3/filmography/movie.json b/part_5/5.3/filmography/movie.json new file mode 100644 index 0000000..24b5c26 --- /dev/null +++ b/part_5/5.3/filmography/movie.json @@ -0,0 +1,52 @@ +{ + "name": "Prevozmogun", + "budget": 2000000, + "actors": [ + { + "name": "Alexey", + "age": 25, + "filmsAmount": 3, + "aboutActor": "2 academy awards" + }, + { + "name": "Max", + "age": 33, + "filmsAmount": 2, + "aboutActor": "Very good actor" + }, + { + "name": "Natalya", + "age": 18, + "filmsAmount": 1, + "aboutActor": "Rising star" + } + ], + "criticsRating": 7.5, + "audienceRating": 8.5, + "year": 2019, + "country": "Russia", + "genre": { + "types": [ + "Comedy", + "Drama", + "Romance" + ] + }, + "reviews": [ + { + "name": "Igor", + "text": "I love this movie", + "rating": 10 + }, + { + "name": "John", + "text": "I hate this movie", + "rating": 1 + }, + { + "name": "Stas", + "text": "I like this movie", + "rating": 7 + } + ] +} \ No newline at end of file diff --git a/part_5/5.3/filmography/output.json b/part_5/5.3/filmography/output.json new file mode 100644 index 0000000..24d23b6 --- /dev/null +++ b/part_5/5.3/filmography/output.json @@ -0,0 +1,52 @@ +{ + "name": "Prevozmogun", + "budget": 2000000, + "actors": [ + { + "name": "Alexey", + "age": 25, + "filmsAmount": 3, + "aboutActor": "2 academy awards" + }, + { + "name": "Max", + "age": 33, + "filmsAmount": 2, + "aboutActor": "Very good actor" + }, + { + "name": "Natalya", + "age": 18, + "filmsAmount": 1, + "aboutActor": "Rising star" + } + ], + "criticsRating": 7.5, + "audienceRating": 8.5, + "year": 2019, + "country": "Russia", + "genre": { + "types": [ + "Comedy", + "Drama", + "Romance" + ] + }, + "reviews": [ + { + "name": "Igor", + "text": "I love this movie", + "rating": 10 + }, + { + "name": "John", + "text": "I hate this movie", + "rating": 1 + }, + { + "name": "Stas", + "text": "I like this movie", + "rating": 7 + } + ] +} \ No newline at end of file diff --git a/part_5/5.6/go_dotenv/dotenv/dotenv.go b/part_5/5.6/go_dotenv/dotenv/dotenv.go new file mode 100644 index 0000000..8e580e2 --- /dev/null +++ b/part_5/5.6/go_dotenv/dotenv/dotenv.go @@ -0,0 +1,162 @@ +package dotenv + +import ( + "bufio" + "errors" + "fmt" + "maps" + "os" + "regexp" + "strconv" + "strings" +) + +type DotEnv struct { + env map[string]interface{} +} + +// Регулярные выражения для int и bool +var ( + intPattern = regexp.MustCompile(`^-?\d+$`) + boolPattern = regexp.MustCompile(`^(?i:true|false)$`) +) + +// Создаем новый экземпляр DotEnv +// platformEnv указывает, загружать ли переменные из окружения ОС +func NewDotEnv(platformEnv bool) *DotEnv { + d := &DotEnv{env: make(map[string]interface{})} + if platformEnv { + d.env = mergeMaps(d.env, loadPlatformEnv()) + } + return d +} + +// Загружаем переменные из .env файлов +func (d *DotEnv) Load(paths ...string) error { + if len(paths) == 0 { + paths = []string{".env"} + } + for _, path := range paths { + file, err := os.Open(path) + if err != nil { + return fmt.Errorf(".env file not found: %s", path) + } + defer file.Close() + + localEnv, err := loadLocalEnv(file) + if err != nil { + return err + } + d.env = mergeMaps(d.env, localEnv) + } + return nil +} + +// Возвращает значение переменной окружения по ключу +func (d *DotEnv) GetValue(key string) (interface{}, error) { + val, ok := d.env[key] + if !ok { + return nil, fmt.Errorf("key not found: %s", key) + } + return val, nil +} + +// Возвращает значение переменной окружения по ключу, +// приведенное к int. Если значение не является int, +// возвращается ошибка. +func (d *DotEnv) GetInt(key string) (int, error) { + val, ok := d.env[key] + if !ok { + return 0, fmt.Errorf("key not found: %s", key) + } + i, ok := val.(int) + if !ok { + return 0, fmt.Errorf("value for key %s is not an int", key) + } + return i, nil +} + +// Возвращает значение переменной окружения по ключу, +// приведенное к bool. Если значение не является bool, +// возвращается ошибка. +func (d *DotEnv) GetBool(key string) (bool, error) { + val, ok := d.env[key] + if !ok { + return false, fmt.Errorf("key not found: %s", key) + } + b, ok := val.(bool) + if !ok { + return false, fmt.Errorf("value for key %s is not a bool", key) + } + return b, nil +} + +// Возвращает значение переменной окружения по ключу, +// приведенное к string. +func (d *DotEnv) GetString(key string) (string, error) { + val, ok := d.env[key] + if !ok { + return "", fmt.Errorf("key not found: %s", key) + } + s, ok := val.(string) + if !ok { + return "", fmt.Errorf("value for key %s is not a string", key) + } + return s, nil +} + +// Преобразование таблицы из переменных окружения ОС +func loadPlatformEnv() map[string]interface{} { + config := make(map[string]interface{}) + for _, value := range os.Environ() { + parts := strings.SplitN(value, "=", 2) + if len(parts) != 2 { + continue + } + k := parts[0] + v := parts[1] + + config[k] = parseValue(v) + } + return config +} + +// Загрузка из локального .env файла +func loadLocalEnv(file *os.File) (map[string]interface{}, error) { + scanner := bufio.NewScanner(file) + config := make(map[string]interface{}) + + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + return nil, errors.New("invalid line in .env file: " + line) + } + key := strings.TrimSpace(parts[0]) + val := strings.TrimSpace(parts[1]) + config[key] = parseValue(val) + } + return config, nil +} + +// Парсинг строки в int, bool или string +func parseValue(val string) interface{} { + if intPattern.MatchString(val) { + if i, err := strconv.Atoi(val); err == nil { + return i + } + } + if boolPattern.MatchString(val) { + return strings.ToLower(val) == "true" + } + return val +} + +// Объединение двух map +func mergeMaps(a, b map[string]interface{}) map[string]interface{} { + maps.Copy(a, b) + return a +} diff --git a/part_5/5.6/go_dotenv/go.mod b/part_5/5.6/go_dotenv/go.mod new file mode 100644 index 0000000..a0f3fb6 --- /dev/null +++ b/part_5/5.6/go_dotenv/go.mod @@ -0,0 +1,3 @@ +module go_dotenv + +go 1.24.0 diff --git a/part_5/5.6/go_dotenv/main.go b/part_5/5.6/go_dotenv/main.go new file mode 100644 index 0000000..6294737 --- /dev/null +++ b/part_5/5.6/go_dotenv/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "go_dotenv/dotenv" + "log" +) + +func main() { + env := dotenv.NewDotEnv(false) + + err := env.Load(".env") + if err != nil { + log.Fatal(err) + } + + adminID, err := env.GetInt("ADMIN_ID") + if err != nil { + log.Fatal(err) + } + fmt.Println(adminID) + + adminPassword, err := env.GetString("ADMIN_PASSWORD") + if err != nil { + log.Fatal(err) + } + fmt.Println(adminPassword) + + adminMode, err := env.GetBool("ADMIN_MODE") + if err != nil { + log.Fatal(err) + } + fmt.Println(adminMode) + + adminEmail, err := env.GetString("ADMIN_EMAIL") + if err != nil { + log.Fatal(err) + } + fmt.Println(adminEmail) +} diff --git a/part_5/5.6/my_app/go.mod b/part_5/5.6/my_app/go.mod new file mode 100644 index 0000000..ae0f2c8 --- /dev/null +++ b/part_5/5.6/my_app/go.mod @@ -0,0 +1,3 @@ +module my_app + +go 1.24.0 diff --git a/part_5/5.6/my_app/main.go b/part_5/5.6/my_app/main.go new file mode 100644 index 0000000..d7b26ac --- /dev/null +++ b/part_5/5.6/my_app/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "flag" + "fmt" +) + +func main() { + // конфигурируем флаги: + // Первый аргумент - название флага + // Второй - значение по умолчанию + // Третий - описание того, что делает флаг + myStr := flag.String("str", "value", "StrFlag description") + myInt := flag.Int("int", 0, "IntFlag description") + myBool := flag.Bool("bool", false, "BoolFlag description") + + // Запускаем парсинг флагов, подаваемых в командной строке + flag.Parse() + + // используем флаги + fmt.Println("String flag:", *myStr) + fmt.Println("Int flag:", *myInt) + fmt.Println("Bool flag:", *myBool) +} diff --git a/part_5/5.6/my_compile_app/go.mod b/part_5/5.6/my_compile_app/go.mod new file mode 100644 index 0000000..7b9e614 --- /dev/null +++ b/part_5/5.6/my_compile_app/go.mod @@ -0,0 +1,3 @@ +module my_compile_app + +go 1.24.0 diff --git a/part_5/5.6/my_compile_app/main.go b/part_5/5.6/my_compile_app/main.go new file mode 100644 index 0000000..c0435f7 --- /dev/null +++ b/part_5/5.6/my_compile_app/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "fmt" +) + +var VersionType = "dev" +var Version = "0.0.1" + +func main() { + fmt.Printf("Version: %s (%s)\n", Version, VersionType) +} diff --git a/part_5/5.6/my_embed_app/embed_config.json b/part_5/5.6/my_embed_app/embed_config.json new file mode 100644 index 0000000..84c3aca --- /dev/null +++ b/part_5/5.6/my_embed_app/embed_config.json @@ -0,0 +1,6 @@ +{ + "debug": true, + "offset": 10, + "version": "0.0.1", + "app_name": "StaskoGo" +} diff --git a/part_5/5.6/my_embed_app/go.mod b/part_5/5.6/my_embed_app/go.mod new file mode 100644 index 0000000..687b6c5 --- /dev/null +++ b/part_5/5.6/my_embed_app/go.mod @@ -0,0 +1,3 @@ +module my_embed_app + +go 1.24.0 diff --git a/part_5/5.6/my_embed_app/main.go b/part_5/5.6/my_embed_app/main.go new file mode 100644 index 0000000..29a37ab --- /dev/null +++ b/part_5/5.6/my_embed_app/main.go @@ -0,0 +1,32 @@ +package main + +import ( + _ "embed" + "encoding/json" + "fmt" + "log" +) + +//go:embed embed_config.json +var configData []byte + +type Config struct { + Debug bool `json:"debug"` + Offset int `json:"offset"` + AppName string `json:"app_name"` + Version string `json:"version"` +} + +func getConfig() Config { + var config Config + err := json.Unmarshal(configData, &config) + if err != nil { + log.Fatal(err) + } + return config +} + +func main() { + config := getConfig() + fmt.Println(config) +} diff --git a/part_5/5.9/1.go b/part_5/5.9/1.go deleted file mode 100644 index d258ca5..0000000 --- a/part_5/5.9/1.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -import "fmt" - -func main() { - var myInterface interface{} - fmt.Printf("%v", myInterface) // -} diff --git a/part_5/5.9/2.go b/part_5/5.9/2.go deleted file mode 100644 index 8fd06d4..0000000 --- a/part_5/5.9/2.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import "fmt" - -type shape struct { - name string -} - -func (s *shape) getName() string { - return s.name -} - -func main() { - var firstInterface interface{} = shape{name: "Cube"} - var secondInterface interface{} = "Oo" - - fmt.Printf("%+v\n", firstInterface) // {name:Cube} - fmt.Printf("%+v\n", secondInterface) // Oo -} diff --git a/part_5/go_database/.vscode/launch.json b/part_5/go_database/.vscode/launch.json new file mode 100644 index 0000000..c147665 --- /dev/null +++ b/part_5/go_database/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "version": "0.2.0", + "configurations": [ + + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}", + "console": "integratedTerminal" + } + ] +} diff --git a/part_5/go_database/database/database.go b/part_5/go_database/database/database.go new file mode 100644 index 0000000..be61653 --- /dev/null +++ b/part_5/go_database/database/database.go @@ -0,0 +1,218 @@ +package database + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" +) + +type DBType int + +const ( + SUAI DBType = iota + UNECON +) + +type Database struct { + PathToSuaiDB string + PathToUneconDB string + SuaiUsers *Table[*User] + UneconUsers *Table[*User] +} + +func NewDatabase(pathToSuaiDB, pathToUneconDB string) *Database { + db := &Database{ + PathToSuaiDB: pathToSuaiDB, + PathToUneconDB: pathToUneconDB, + } + + if _, err := os.Stat(pathToSuaiDB); os.IsNotExist(err) { + dir := filepath.Dir(pathToSuaiDB) + if err := os.MkdirAll(dir, 0755); err != nil { + fmt.Println("Error creating directory:", err) + } + + file, err := os.Create(pathToSuaiDB) + if err != nil { + fmt.Println("Error creating file:", err) + } + file.Close() + db.SuaiUsers = NewTable[*User]("suai") + } else { + db.SuaiUsers = db.openTable(pathToSuaiDB, "suai") + } + + if _, err := os.Stat(pathToUneconDB); os.IsNotExist(err) { + dir := filepath.Dir(pathToUneconDB) + if err := os.MkdirAll(dir, 0755); err != nil { + fmt.Println("Error creating directory:", err) + } + + file, err := os.Create(pathToUneconDB) + if err != nil { + fmt.Println("Error creating file:", err) + } + file.Close() + db.UneconUsers = NewTable[*User]("unecon") + } else { + db.UneconUsers = db.openTable(pathToUneconDB, "unecon") + } + + return db +} + +func (db *Database) openTable(filePath, tableName string) *Table[*User] { + table := NewTable[*User](tableName) + + file, err := os.Open(filePath) + if err != nil { + fmt.Println("Error opening file:", err) + return table + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + data := strings.Split(line, ",") + if len(data) >= 7 { + id, _ := strconv.Atoi(data[0]) + yearOfBirth, _ := strconv.Atoi(data[2]) + + user := NewUser( + id, + data[1], + yearOfBirth, + data[3], + data[4], + data[5], + data[6], + ) + + table.Insert(user) + } + } + + return table +} + +func (db *Database) Save(dbType DBType) { + var filePath string + var users *Table[*User] + + switch dbType { + case SUAI: + filePath = db.PathToSuaiDB + users = db.SuaiUsers + case UNECON: + filePath = db.PathToUneconDB + users = db.UneconUsers + } + + file, err := os.Create(filePath) + if err != nil { + fmt.Println("Error opening file for writing:", err) + return + } + defer file.Close() + + writer := bufio.NewWriter(file) + users.ForEach(func(user *User) { + line := fmt.Sprintf("%d,%s,%d,%s,%s,%s,%s\n", + user.ID(), + user.Nickname(), + user.YearOfBirth(), + user.Email(), + user.Phone(), + user.AccessLevel(), + user.PasswordHash(), + ) + writer.WriteString(line) + }) + writer.Flush() +} + +func (db *Database) Insert(user *User, dbType DBType) bool { + var filePath string + var isOk bool + + switch dbType { + case SUAI: + filePath = db.PathToSuaiDB + isOk = db.SuaiUsers.Insert(user) + case UNECON: + filePath = db.PathToUneconDB + isOk = db.UneconUsers.Insert(user) + } + + if !isOk { + return false + } + + file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + fmt.Println("Error opening file for appending:", err) + return false + } + defer file.Close() + + line := fmt.Sprintf("%d,%s,%d,%s,%s,%s,%s\n", + user.ID(), + user.Nickname(), + user.YearOfBirth(), + user.Email(), + user.Phone(), + user.AccessLevel(), + user.PasswordHash(), + ) + + if _, err := file.WriteString(line); err != nil { + fmt.Println("Error writing to file:", err) + return false + } + + return true +} + +func (db *Database) Selection(dbType DBType, + attribute, value string) *Table[*User] { + switch dbType { + case SUAI: + return db.SuaiUsers.Selection(attribute, value) + case UNECON: + return db.UneconUsers.Selection(attribute, value) + default: + return NewTable[*User]("empty") + } +} + +func (db *Database) Intersect(attribute, value string) *Table[*User] { + return db.SuaiUsers.Intersect(attribute, value, db.UneconUsers) +} + +func (db *Database) Union() *Table[*User] { + return db.SuaiUsers.Union(db.UneconUsers) +} + +func (db *Database) Remove(id string, dbType DBType) { + switch dbType { + case SUAI: + db.SuaiUsers.Remove(id) + fmt.Println(db.SuaiUsers) + case UNECON: + db.UneconUsers.Remove(id) + fmt.Println(db.UneconUsers) + } +} + +func (db *Database) ShowDB(dbType DBType) { + switch dbType { + case SUAI: + fmt.Println(db.SuaiUsers) + case UNECON: + fmt.Println(db.UneconUsers) + } +} diff --git a/part_5/go_database/database/i_attribute.go b/part_5/go_database/database/i_attribute.go new file mode 100644 index 0000000..fea218c --- /dev/null +++ b/part_5/go_database/database/i_attribute.go @@ -0,0 +1,8 @@ +package database + +type IAttribute interface { + Check(attribute, value string) bool + Change(attribute, value string) bool + + String() string +} diff --git a/part_5/go_database/database/table.go b/part_5/go_database/database/table.go new file mode 100644 index 0000000..23f9bfa --- /dev/null +++ b/part_5/go_database/database/table.go @@ -0,0 +1,155 @@ +package database + +import ( + "fmt" + "strconv" + "strings" +) + +type Node[T IAttribute] struct { + Data T + Next *Node[T] +} + +type Table[T IAttribute] struct { + head *Node[T] + tail *Node[T] + Title string +} + +func NewTable[T IAttribute](title string) *Table[T] { + return &Table[T]{Title: title} +} + +func (t *Table[T]) First() T { + if t.head != nil { + return t.head.Data + } + var zero T + return zero +} + +func (t *Table[T]) Last() T { + if t.tail != nil { + return t.tail.Data + } + var zero T + return zero +} + +func (t *Table[T]) Contains(data T) bool { + user, ok := any(data).(*User) + if !ok { + return false + } + + temp := t.head + for temp != nil { + if temp.Data.Check(FieldID, strconv.Itoa(user.ID())) { + return true + } + temp = temp.Next + } + return false +} + +func (t *Table[T]) Insert(data T) bool { + if t.Contains(data) { + return false + } + node := &Node[T]{Data: data} + if t.head == nil { + t.head = node + t.tail = node + } else { + t.tail.Next = node + t.tail = node + } + return true +} + +func (t *Table[T]) Remove(id string) { + var prev *Node[T] + curr := t.head + + for curr != nil { + if curr.Data.Check("id", id) { + if prev == nil { + t.head = curr.Next + if t.head == nil { + t.tail = nil + } + } else { + prev.Next = curr.Next + if prev.Next == nil { + t.tail = prev + } + } + return + } + prev = curr + curr = curr.Next + } +} + +func (t *Table[T]) Intersect(attribute, value string, + other *Table[T]) *Table[T] { + + newTable := NewTable[T](fmt.Sprintf("%s-%s", t.Title, other.Title)) + + for temp := t.head; temp != nil; temp = temp.Next { + if temp.Data.Check(attribute, value) { + newTable.Insert(temp.Data) + } + } + for temp := other.head; temp != nil; temp = temp.Next { + if temp.Data.Check(attribute, value) && + !newTable.Contains(temp.Data) { + newTable.Insert(temp.Data) + } + } + return newTable +} + +func (t *Table[T]) Union(other *Table[T]) *Table[T] { + newTable := NewTable[T](fmt.Sprintf("%s-%s", t.Title, other.Title)) + + for temp := t.head; temp != nil; temp = temp.Next { + newTable.Insert(temp.Data) + } + for temp := other.head; temp != nil; temp = temp.Next { + if !newTable.Contains(temp.Data) { + newTable.Insert(temp.Data) + } + } + return newTable +} + +func (t *Table[T]) Selection(attribute, value string) *Table[T] { + newTable := NewTable[T](t.Title + "-new") + + for temp := t.head; temp != nil; temp = temp.Next { + if temp.Data.Check(attribute, value) { + newTable.Insert(temp.Data) + } + } + return newTable +} + +func (t *Table[T]) ForEach(action func(T)) { + for temp := t.head; temp != nil; temp = temp.Next { + action(temp.Data) + } +} + +func (t *Table[T]) String() string { + var sb strings.Builder + sb.WriteString(fmt.Sprintf("%s%s%s\n", strings.Repeat("*", 10), + t.Title, strings.Repeat("*", 10))) + + for temp := t.head; temp != nil; temp = temp.Next { + sb.WriteString(fmt.Sprintf("%s\n", temp.Data.String())) + } + + return sb.String() +} diff --git a/part_5/go_database/database/user.go b/part_5/go_database/database/user.go new file mode 100644 index 0000000..9c17ddc --- /dev/null +++ b/part_5/go_database/database/user.go @@ -0,0 +1,132 @@ +package database + +import ( + "fmt" + "strconv" + "strings" +) + +type AccessLevel = string + +const ( + Student AccessLevel = "S" + Teacher AccessLevel = "T" + Admin AccessLevel = "A" +) + +func AcsessLevelFromString(s string) AccessLevel { + switch strings.ToUpper(s) { + case "T": + return Teacher + case "A": + return Admin + default: + return Student + } +} + +type UserTableField = string + +const ( + FieldID UserTableField = "id" + FieldNickname UserTableField = "nickname" + FieldYearOfBirth UserTableField = "yearOfBirth" + FieldEmail UserTableField = "email" + FieldPhone UserTableField = "phone" + FieldAccessLevel UserTableField = "accessLevel" + FieldPasswordHash UserTableField = "passwordHash" +) + +type User struct { + id int + nickname string + yearOfBirth int + email string + phone string + accessLevel AccessLevel + passwordHash string +} + +func NewUser( + id int, + nickname string, + yearOfBirth int, + email string, + phone string, + accessLevel string, + passwordHash string, +) *User { + return &User{ + id: id, + nickname: nickname, + yearOfBirth: yearOfBirth, + email: email, + phone: phone, + accessLevel: AcsessLevelFromString(accessLevel), + passwordHash: passwordHash, + } +} + +func (u *User) ID() int { return u.id } +func (u *User) Nickname() string { return u.nickname } +func (u *User) YearOfBirth() int { return u.yearOfBirth } +func (u *User) Email() string { return u.email } +func (u *User) Phone() string { return u.phone } +func (u *User) AccessLevel() string { return u.accessLevel } +func (u *User) PasswordHash() string { return u.passwordHash } + +func (u *User) Change(attr, value string) bool { + switch attr { + case FieldNickname: + u.nickname = value + case FieldYearOfBirth: + v, err := strconv.Atoi(value) + if err != nil { + return false + } + u.yearOfBirth = v + case FieldEmail: + u.email = value + case FieldPhone: + u.phone = value + case FieldAccessLevel: + u.accessLevel = AcsessLevelFromString(value) + case FieldPasswordHash: + u.passwordHash = value + default: + return false + } + return true +} + +func (u *User) Check(attr, value string) bool { + switch attr { + case FieldID: + v, err := strconv.Atoi(value) + return err == nil && u.id == v + case FieldNickname: + return u.nickname == value + case FieldYearOfBirth: + v, err := strconv.Atoi(value) + return err == nil && u.yearOfBirth == v + case FieldEmail: + return u.email == value + case FieldPhone: + return u.phone == value + case FieldAccessLevel: + return u.accessLevel == value + case FieldPasswordHash: + return u.passwordHash == value + default: + return false + } +} + +func (u *User) String() string { + return fmt.Sprintf( + "User(id: %d, nickname: %s, yearOfBirth: %d, "+ + "email: %s, phone: %s, acsessLevel: %s, passwordHash: %s)", + u.id, u.nickname, u.yearOfBirth, u.email, + u.phone, u.accessLevel, u.passwordHash, + ) +} diff --git a/part_5/go_database/go.mod b/part_5/go_database/go.mod new file mode 100644 index 0000000..a529276 --- /dev/null +++ b/part_5/go_database/go.mod @@ -0,0 +1,3 @@ +module go_database + +go 1.24 diff --git a/part_5/go_database/main.go b/part_5/go_database/main.go new file mode 100644 index 0000000..90e7c4b --- /dev/null +++ b/part_5/go_database/main.go @@ -0,0 +1,16 @@ +package main + +import ( + db "go_database/database" + "path/filepath" +) + +func main() { + db := db.NewDatabase( + filepath.Join(".", "suai.txt"), + filepath.Join(".", "unecon.txt"), + ) + + menu := NewMenu(db) + menu.Loop() +} diff --git a/part_5/go_database/menu.go b/part_5/go_database/menu.go new file mode 100644 index 0000000..d4f6da6 --- /dev/null +++ b/part_5/go_database/menu.go @@ -0,0 +1,214 @@ +package main + +import ( + "bufio" + "fmt" + db "go_database/database" + "os" + "strconv" + "strings" +) + +type Menu struct { + database *db.Database + reader *bufio.Reader +} + +func NewMenu(db *db.Database) *Menu { + return &Menu{ + database: db, + reader: bufio.NewReader(os.Stdin), + } +} + +func (m *Menu) Loop() { + for { + m.PrintMenu() + input, _ := m.reader.ReadString('\n') + input = strings.TrimSpace(input) + + fmt.Println(strings.Repeat("x", 25)) + + switch input { + case "1": + m.AddUser() + case "2": + m.RemoveUser() + case "3": + m.ChangeUser() + case "4": + m.ShowUsers() + case "5": + m.Intersect() + case "6": + m.Union() + case "7": + m.SaveAndExit() + return + case "8": + return + } + } +} + +func (m *Menu) PrintMenu() { + fmt.Println("1. Add User") + fmt.Println("2. Remove User") + fmt.Println("3. Change User") + fmt.Println("4. Show Users") + fmt.Println("5. Intersect Table") + fmt.Println("6. Union Table") + fmt.Println("7. Save and Exit") + fmt.Println("8. Exit") +} + +func (m *Menu) readInput(prompt string) string { + fmt.Print(prompt) + input, _ := m.reader.ReadString('\n') + return strings.TrimSpace(input) +} + +func (m *Menu) AddUser() { + try := func() bool { + idStr := m.readInput("Enter id: ") + id, err := strconv.Atoi(idStr) + if err != nil { + fmt.Println("Invalid ID format") + return false + } + + nickname := m.readInput("Enter nickname: ") + + yearStr := m.readInput("Enter year of birth: ") + yearOfBirth, err := strconv.Atoi(yearStr) + if err != nil { + fmt.Println("Invalid year format") + return false + } + + email := m.readInput("Enter email: ") + phone := m.readInput("Enter phone: ") + passwordHash := m.readInput("Enter password hash: ") + accessLevel := m.readInput("Access level (A - Admin, " + + "T - Teacher, S - Student): ") + + user := db.NewUser( + id, + nickname, + yearOfBirth, + email, + phone, + accessLevel, + passwordHash, + ) + + dbTypeStr := m.readInput("Add user to DB (S - SUAI, U - Unecon): ") + dbTypeStr = strings.ToUpper(dbTypeStr) + + switch dbTypeStr { + case "S": + m.database.Insert(user, db.SUAI) + m.database.ShowDB(db.SUAI) + case "U": + m.database.Insert(user, db.UNECON) + m.database.ShowDB(db.UNECON) + default: + fmt.Println("(ノ-_-)ノ ミ ┴┴") + return false + } + + return true + } + + if !try() { + fmt.Println("WTF!!!!") + } +} + +func (m *Menu) RemoveUser() { + dbTypeStr := m.readInput("Select DB (S - SUAI, U - Unecon): ") + dbTypeStr = strings.ToUpper(dbTypeStr) + + var dbType db.DBType + + switch dbTypeStr { + case "S": + dbType = db.SUAI + m.database.ShowDB(db.SUAI) + case "U": + dbType = db.UNECON + m.database.ShowDB(db.UNECON) + default: + fmt.Println("(ノ-_-)ノ ミ ┴┴") + return + } + + id := m.readInput("Enter id: ") + m.database.Remove(id, dbType) + m.database.ShowDB(dbType) +} + +func (m *Menu) ChangeUser() { + dbTypeStr := m.readInput("Select DB (S - SUAI, U - Unecon): ") + dbTypeStr = strings.ToUpper(dbTypeStr) + + var dbType db.DBType + + switch dbTypeStr { + case "S": + dbType = db.SUAI + m.database.ShowDB(db.SUAI) + case "U": + dbType = db.UNECON + m.database.ShowDB(db.UNECON) + default: + fmt.Println("(ノ-_-)ノ ミ ┴┴") + return + } + + id := m.readInput("Enter id: ") + + userTable := m.database.Selection(dbType, "id", id) + user := userTable.First() + if user == nil { + fmt.Println("User not found!") + return + } + + field := m.readInput("Enter field: ") + newValue := m.readInput("Enter new value: ") + user.Change(field, newValue) + + m.database.ShowDB(dbType) +} + +func (m *Menu) ShowUsers() { + dbTypeStr := m.readInput("Select DB (S - SUAI, U - Unecon): ") + dbTypeStr = strings.ToUpper(dbTypeStr) + + switch dbTypeStr { + case "S": + m.database.ShowDB(db.SUAI) + case "U": + m.database.ShowDB(db.UNECON) + default: + fmt.Println("(ノ-_-)ノ ミ ┴┴") + } +} + +func (m *Menu) Intersect() { + field := m.readInput("Enter field: ") + value := m.readInput("Enter intersect value: ") + result := m.database.Intersect(field, value) + fmt.Println(result) +} + +func (m *Menu) Union() { + result := m.database.Union() + fmt.Println(result) +} + +func (m *Menu) SaveAndExit() { + m.database.Save(db.SUAI) + m.database.Save(db.UNECON) +} diff --git a/part_5/go_database/suai.txt b/part_5/go_database/suai.txt new file mode 100644 index 0000000..abf3301 --- /dev/null +++ b/part_5/go_database/suai.txt @@ -0,0 +1,5 @@ +0,MADTeacher,1989,stasko@gmail.ru,+7xxxxxxx,T,adFF +1,Alex,1990,al@gmail.ru,+7x2x5xxx,A,adadFFxzxc +2,Max,2005,mmm@gmail.ru,+7xx654xx,S,20AFBB +3,Jack,2006,jj@gmail.ru,+7xx657xx,S,41FDF +5,FF,1999,mad@tr.ri,+7xx654xx,S,Hdndgu2397123 diff --git a/part_5/go_database/unecon.txt b/part_5/go_database/unecon.txt new file mode 100644 index 0000000..d2ac2d4 --- /dev/null +++ b/part_5/go_database/unecon.txt @@ -0,0 +1,4 @@ +0,Jack,2007,gf@gmail.ru,+7xx624xx,S,20AAAB +1,MADTeacher,1989,stasko@gmail.ru,+7xxxxxxx,T,adFF +2,Stas,1994,st@gmail.ru,+7x2x2xxx,A,adaFBB +6,Max,2009,mv@gmail.ru,+7xx657xx,S,41FDF diff --git a/part_5/go_json_store/go.mod b/part_5/go_json_store/go.mod new file mode 100644 index 0000000..0de6696 --- /dev/null +++ b/part_5/go_json_store/go.mod @@ -0,0 +1,3 @@ +module go_json_store + +go 1.20 diff --git a/part_5/go_json_store/jsonstore/json_file.go b/part_5/go_json_store/jsonstore/json_file.go new file mode 100644 index 0000000..13d064c --- /dev/null +++ b/part_5/go_json_store/jsonstore/json_file.go @@ -0,0 +1,62 @@ +package jsonstore + +import ( + "encoding/json" + "io" + "os" + "path/filepath" +) + +type JSONFile struct { + Path string +} + +func NewJSONFile(path string) *JSONFile { + dir := filepath.Dir(path) + if _, err := os.Stat(dir); os.IsNotExist(err) { + os.MkdirAll(dir, 0755) + } + return &JSONFile{Path: path} +} + +func (j *JSONFile) Read() map[string]any { + file, err := os.Open(j.Path) + if err != nil { + if os.IsNotExist(err) { + return make(map[string]any) + } + return make(map[string]any) + } + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + return make(map[string]any) + } + + if len(data) == 0 { + return make(map[string]any) + } + + var result map[string]any + err = json.Unmarshal(data, &result) + if err != nil { + return make(map[string]any) + } + + return result +} + +func (j *JSONFile) Write(data map[string]any) error { + dir := filepath.Dir(j.Path) + if _, err := os.Stat(dir); os.IsNotExist(err) { + os.MkdirAll(dir, 0755) + } + + jsonData, err := json.MarshalIndent(data, "", " ") + if err != nil { + return err + } + + return os.WriteFile(j.Path, jsonData, 0644) +} diff --git a/part_5/go_json_store/jsonstore/json_store.go b/part_5/go_json_store/jsonstore/json_store.go new file mode 100644 index 0000000..917e248 --- /dev/null +++ b/part_5/go_json_store/jsonstore/json_store.go @@ -0,0 +1,200 @@ +package jsonstore + +import ( + "encoding/json" + "os" + "reflect" +) + +type JSONStore struct { + filePath string + values map[string]interface{} +} + +func NewJSONStore(path string) *JSONStore { + return &JSONStore{ + filePath: path, + } +} + +func (js *JSONStore) load() map[string]interface{} { + if js.values != nil { + return js.values + } + + content, err := os.ReadFile(js.filePath) + if err != nil { + js.values = make(map[string]interface{}) + return js.values + } + + var data map[string]interface{} + if err := json.Unmarshal(content, &data); err != nil { + js.values = make(map[string]interface{}) + return js.values + } + js.values = data + return js.values +} + +func (js *JSONStore) Contains(key string) bool { + _, ok := js.load()[key] + return ok +} + +func (js *JSONStore) Keys() []string { + keys := make([]string, 0) + for k := range js.load() { + keys = append(keys, k) + } + return keys +} + +func (js *JSONStore) Values() []interface{} { + values := make([]interface{}, 0) + for _, v := range js.load() { + values = append(values, v) + } + return values +} + +func (js *JSONStore) GetValue(key string) interface{} { + return js.load()[key] +} + +func (js *JSONStore) GetBool(key string) *bool { + if v, ok := js.GetValue(key).(bool); ok { + return &v + } + return nil +} + +func (js *JSONStore) GetInt(key string) *int { + // Т.к. все числа по умолчанию декодируются как float64, + // то сначала приводим к float64 + if f, ok := js.GetValue(key).(float64); ok { + i := int(f) + return &i + } + return nil +} + +func (js *JSONStore) GetFloat(key string) *float64 { + if v, ok := js.GetValue(key).(float64); ok { + return &v + } + return nil +} + +func (js *JSONStore) GetString(key string) *string { + if v, ok := js.GetValue(key).(string); ok { + return &v + } + return nil +} + +// Метод возвращает по ключу срез []interface{}. +// Если значение хранится как []interface{}, возвращаем его напрямую. +// Если значение хранится как []string, []int или []float64, +// преобразуем каждый элемент к interface{} для совместимости +// с Go JSON API. Это обеспечивает универсальный доступ к массивам +// любого типа, сохраненным в JSON. +func (js *JSONStore) GetList(key string) []interface{} { + // Получаем значение по ключу + val := js.GetValue(key) + // Если значение отсутствует, возвращаем nil + if val == nil { + return nil + } + // Если это уже []interface{} (тип, который возвращает + // json.Unmarshal), возвращаем напрямую + if v, ok := val.([]interface{}); ok { + return v + } + // Если это []string, преобразуем каждый элемент к interface{} + if v, ok := val.([]string); ok { + // Создаем новый срез с типом []interface{} + result := make([]interface{}, len(v)) + // Преобразуем каждый элемент []string в interface{} + for i, s := range v { + result[i] = s + } + return result + } + // Если это []int, преобразуем каждый элемент к interface{} + if v, ok := val.([]int); ok { + // Создаем новый срез с типом []interface{} + result := make([]interface{}, len(v)) + // Преобразуем каждый элемент []int в interface{} + for i, n := range v { + result[i] = n + } + return result + } + // Если это []float64 (тип, который возвращает json.Unmarshal), + // преобразуем каждый элемент к interface{} + if v, ok := val.([]float64); ok { + // Создаем новый срез с типом []interface{} + result := make([]interface{}, len(v)) + // Преобразуем каждый элемент []float64 в interface{} + for i, n := range v { + result[i] = n + } + return result + } + // Если тип не поддерживается, возвращаем nil + return nil +} + +func (js *JSONStore) GetMap(key string) map[string]interface{} { + val := js.GetValue(key) + if val == nil { + return nil + } + if m, ok := val.(map[string]interface{}); ok { + return m + } + // Попробуем привести через json, если тип не совпал + if b, err := json.Marshal(val); err == nil { + var m map[string]interface{} + if err := json.Unmarshal(b, &m); err == nil { + return m + } + } + return nil +} + +func (js *JSONStore) ValueEquals(a, b interface{}) bool { + return reflect.DeepEqual(a, b) +} + +func (js *JSONStore) SetValue(key string, value interface{}) { + + values := js.load() + oldVal := values[key] + if value == nil { + delete(values, key) + js.save(values) + } else if oldVal == nil || !js.ValueEquals(oldVal, value) { + values[key] = value + js.save(values) + } +} + +func (js *JSONStore) ResetValue(key string) { + + values := js.load() + if _, exists := values[key]; exists { + delete(values, key) + js.save(values) + } +} + +func (js *JSONStore) save(data map[string]interface{}) { + bytes, err := json.MarshalIndent(data, "", " ") + if err != nil { + return + } + _ = os.WriteFile(js.filePath, bytes, 0644) + js.values = data +} diff --git a/part_5/go_json_store/main.go b/part_5/go_json_store/main.go new file mode 100644 index 0000000..e0b6c32 --- /dev/null +++ b/part_5/go_json_store/main.go @@ -0,0 +1,167 @@ +package main + +import ( + "fmt" + + "go_json_store/jsonstore" +) + +func main() { + store := jsonstore.NewJSONStore("store.json") + store.SetValue("map", map[string]int{"a": 1, "b": 2}) + store.SetValue("strList", []string{"a", "b", "c"}) + store.SetValue("intList", []int{1, 2, 3}) + + // Получение и приведение типов + rawStrList := store.GetList("strList") + var strList []string + for _, v := range rawStrList { + if s, ok := v.(string); ok { + strList = append(strList, s) + } + } + + rawIntList := store.GetList("intList") + var intList []int + for _, v := range rawIntList { + if n, ok := v.(int); ok { + intList = append(intList, n) + } + } + + rawMap := store.GetMap("map") + myMap := make(map[string]int) + for k, v := range rawMap { + switch n := v.(type) { + case int: + myMap[k] = n + case float64: + myMap[k] = int(n) + } + } + + fmt.Printf("%T\n", strList) // []string + fmt.Printf("%T\n", intList) // []int + fmt.Printf("%T\n", myMap) // map[string]int + + fmt.Println(strList) // [a b c] + fmt.Println(intList) // [1 2 3] + fmt.Println(myMap) // map[a:1 b:2] + + boolVal := store.GetBool("bool") + fmt.Println(*boolVal) // true + intVal := store.GetInt("int") + fmt.Println(*intVal) // 55 + floatVal := store.GetFloat("double") + fmt.Println(*floatVal) // 99.4 +} + +//*************** 3 *************************** +/* +func main() { + store := jsonstore.NewJSONStore("store.json") + + store.ResetValue("map") + store.ResetValue("str") + + fmt.Println(store.GetValue("map")) // + fmt.Println(store.GetValue("str")) // +} +*/ + +//*************** 2 *************************** +/* +func main() { + store := jsonstore.NewJSONStore("store.json") + + store.SetValue("strList", "-_-") + store.SetValue("double", 99) + + fmt.Println(store.GetValue("strList")) // -_- + fmt.Println(store.GetValue("double")) // 99 +} +*/ + +//*************** 1 *************************** +/* +func main() { + store := jsonstore.NewJSONStore("store.json") + store.SetValue("strList", []string{"a", "b", "c"}) + store.SetValue("int", 55) + store.SetValue("bool", true) + store.SetValue("double", 3.14) + store.SetValue("map", map[string]int{"a": 1, "b": 2}) + store.SetValue("str", "(づ˶•༝•˶)づ♡") + + fmt.Println(store.Values()) + // [[a b c] 55 true 3.14 map[a:1 b:2] (づ˶•༝•˶)づ♡] + + fmt.Println(store.Keys()) + // [bool double map str strList int] + + fmt.Println(store.Contains("strList")) // true + fmt.Println(store.GetValue("strList")) // [a b c] + fmt.Println(store.GetValue("int")) // 55 + fmt.Println(store.GetValue("bool")) // true + fmt.Println(store.GetValue("double")) // 3.14 + fmt.Println(store.GetValue("map")) // map[a:1 b:2] + fmt.Println(store.GetValue("str")) // (づ˶•༝•˶)づ♡ +} */ + +/*func main() { + fmt.Println("Starting JSON Store Demo") + store := jsonstore.NewJSONStore("store.json") + + // Set some values + mapValue := map[string]any{"a": 1, "b": 2} + strList := []any{"a", "b", "c"} + intList := []any{1, 2, 3} + + store.SetValue("map", mapValue) + store.SetValue("strList", strList) + store.SetValue("intList", intList) + + // Get values + retrievedStrList := store.GetList("strList") + retrievedIntList := store.GetList("intList") + retrievedMap := store.GetMap("map") + + // Print results + fmt.Printf("strList type: %T\n", retrievedStrList) + fmt.Printf("intList type: %T\n", retrievedIntList) + fmt.Printf("map type: %T\n", retrievedMap) + + fmt.Printf("strList: %v\n", retrievedStrList) + fmt.Printf("intList: %v\n", retrievedIntList) + fmt.Printf("map: %v\n", retrievedMap) + + // Let's demonstrate more features similar to the commented section in the Dart code + store.SetValue("int", 55) + store.SetValue("bool", true) + store.SetValue("double", 3.14) + store.SetValue("str", "(づ˶•༝•˶)づ♡") + + fmt.Println("\nAll values:", store.Values()) + fmt.Println("All keys:", store.Keys()) + + fmt.Printf("Contains 'strList': %v\n", store.Contains("strList")) + fmt.Printf("Value of 'strList': %v\n", store.GetValue("strList")) + fmt.Printf("Value of 'int': %v\n", store.GetValue("int")) + fmt.Printf("Value of 'bool': %v\n", store.GetValue("bool")) + fmt.Printf("Value of 'double': %v\n", store.GetValue("double")) + fmt.Printf("Value of 'map': %v\n", store.GetValue("map")) + fmt.Printf("Value of 'str': %v\n", store.GetValue("str")) + + // Update values + store.SetValue("strList", "-_-") + store.SetValue("double", 99) + fmt.Printf("\nUpdated 'strList': %v\n", store.GetValue("strList")) + fmt.Printf("Updated 'double': %v\n", store.GetValue("double")) + + // Reset values + store.ResetValue("map") + store.ResetValue("str") + fmt.Printf("After reset, 'map': %v\n", store.GetValue("map")) + fmt.Printf("After reset, 'str': %v\n", store.GetValue("str")) +} +*/ diff --git a/part_5/go_json_store/store.json b/part_5/go_json_store/store.json new file mode 100644 index 0000000..837c154 --- /dev/null +++ b/part_5/go_json_store/store.json @@ -0,0 +1,19 @@ +{ + "bool": true, + "double": 99.4, + "int": 55, + "intList": [ + 1, + 2, + 3 + ], + "map": { + "a": 1, + "b": 2 + }, + "strList": [ + "a", + "b", + "c" + ] +} \ No newline at end of file diff --git a/part_8/8.1/golang/todo/.vscode/launch.json b/part_6/6.1/golang/todo/.vscode/launch.json similarity index 100% rename from part_8/8.1/golang/todo/.vscode/launch.json rename to part_6/6.1/golang/todo/.vscode/launch.json diff --git a/part_8/8.1/golang/todo/db/db.go b/part_6/6.1/golang/todo/db/db.go similarity index 97% rename from part_8/8.1/golang/todo/db/db.go rename to part_6/6.1/golang/todo/db/db.go index 87176c4..74d0e46 100644 --- a/part_8/8.1/golang/todo/db/db.go +++ b/part_6/6.1/golang/todo/db/db.go @@ -12,7 +12,7 @@ type SQLiteRepository struct { } func createDB(pathToDB string) *sql.DB { - db, err := sql.Open("sqlite3", dbName) + db, err := sql.Open("sqlite3", pathToDB) if err != nil { log.Fatal(err) } diff --git a/part_8/8.1/golang/todo/db/db_definition.go b/part_6/6.1/golang/todo/db/db_definition.go similarity index 100% rename from part_8/8.1/golang/todo/db/db_definition.go rename to part_6/6.1/golang/todo/db/db_definition.go diff --git a/part_8/8.1/golang/todo/db/models.go b/part_6/6.1/golang/todo/db/models.go similarity index 100% rename from part_8/8.1/golang/todo/db/models.go rename to part_6/6.1/golang/todo/db/models.go diff --git a/part_6/6.1/golang/todo/db/projects_crud.go b/part_6/6.1/golang/todo/db/projects_crud.go new file mode 100644 index 0000000..64110ad --- /dev/null +++ b/part_6/6.1/golang/todo/db/projects_crud.go @@ -0,0 +1,92 @@ +package db + +import ( + "errors" + + "github.com/mattn/go-sqlite3" +) + +// Метод для добавления проекта в базу данных +func (s *SQLiteRepository) AddProject(project Project) (*Project, error) { + res, err := s.db.Exec( // Запрос на добавление проекта + // Используем экранирование данных для предотвращения SQL-инъекции + // данные из переменных project.Name и project.Description + // будут вставлены в запрос в место знаков вопроса + // в пордке их перечисления + "INSERT INTO projects(name, description) values(?,?)", + project.Name, project.Description, + ) + if err != nil { // Если произошла ошибка + var sqliteErr sqlite3.Error + + // Если такой проект уже существует + if errors.As(err, &sqliteErr) { + if errors.Is( + sqliteErr.ExtendedCode, + sqlite3.ErrConstraintUnique) { + return nil, ErrDuplicate // Возвращаем ErrDuplicate + } + } + return nil, err + } + + id, err := res.LastInsertId() // Получаем ID + if err != nil { + return nil, err + } + project.ID = int(id) // Устанавливаем ID проекту + + return &project, nil +} + +// Метод для удаления проекта из базы данных +func (s *SQLiteRepository) DeleteProject(projectID int) error { + // Запрос на удаление проекта из таблицы projects + s.db.Exec("DELETE FROM projects WHERE id = ?", projectID) + // Запрос на удаление всех задач, связанных с проектом + res, err := s.db.Exec( + "DELETE FROM tasks WHERE project_id = ?", + projectID, + ) + if err != nil { + return err + } + + // Проверяем, были ли удалены задачи + rowsAffected, err := res.RowsAffected() + if err != nil { + return err + } + + // Если не было удалено ни одной задачи + if rowsAffected == 0 { + return ErrDeleteFailed + } + + return err +} + +// Метод для получения всех проектов +func (s *SQLiteRepository) GetAllProjects() ([]Project, error) { + // Запрос на получение всех проектов + rows, err := s.db.Query("SELECT * FROM projects") + if err != nil { + return nil, err + } + defer rows.Close() // Закрываем соединение + + // Перебираем результаты запроса и добавляем в []Project + var projects []Project + for rows.Next() { + var project Project + // считываем данные из каждой строки, в соответствующие + // поля структуры Project + if err := rows.Scan(&project.ID, &project.Name, + &project.Description); err != nil { + return nil, err + } + // Добавляем проект в срез + projects = append(projects, project) + } + return projects, nil +} diff --git a/part_6/6.1/golang/todo/db/tasks_crud.go b/part_6/6.1/golang/todo/db/tasks_crud.go new file mode 100644 index 0000000..a9171ca --- /dev/null +++ b/part_6/6.1/golang/todo/db/tasks_crud.go @@ -0,0 +1,129 @@ +package db + +import "errors" + +// Метод для добавления задачи в базу данных +func (s *SQLiteRepository) AddTask(task Task, projectID int) (*Task, error) { + // Запрос на добавление задачи проекту с id == projectID + res, err := s.db.Exec( + "INSERT INTO tasks(name, description, priority,"+ + " is_done, project_id) values(?,?,?,?,?)", + task.Name, task.Description, task.Priority, + task.IsDone, projectID, + ) + if err != nil { + return nil, err + } + + id, err := res.LastInsertId() // Получаем ID + if err != nil { + return nil, err + } + task.ID = int(id) // Устанавливаем ID задаче + + return &task, nil +} + +// Метод для удаления задачи из базы данных +func (s *SQLiteRepository) DeleteTask(taskID int) error { + // Запрос на удаление задачи из таблицы tasks + res, err := s.db.Exec( + "DELETE FROM tasks WHERE id = ?", + taskID, + ) + if err != nil { + return err + } + + // Проверяем, была ли удалена задача + rowsAffected, err := res.RowsAffected() + if err != nil { + return err + } + + // Если не была удалена ни одна задача + if rowsAffected == 0 { + return ErrDeleteFailed + } + + return err +} + +// Метод для получения всех задач +func (s *SQLiteRepository) GetAllTasks() (tasks []ProjectTask, err error) { + // Запрос на получение всех задач + rows, err := s.db.Query("SELECT * FROM tasks") + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var task ProjectTask + // считываем данные из каждой строки, в соответствующие + // поля структуры ProjectTask + if err := rows.Scan(&task.ID, &task.Name, + &task.Description, &task.Priority, + &task.IsDone, &task.ProjectID); err != nil { + return nil, err + } + // Добавляем задачу в срез + tasks = append(tasks, task) + } + return +} + +// Метод для получения всех задач конкретного проекта +func (s *SQLiteRepository) GetProjectTasks(projectID int) (tasks []Task, err error) { + // Запрос на получение всех задач у проекта с заданным id + rows, err := s.db.Query( + "SELECT * FROM tasks WHERE project_id = ?", + projectID, + ) + if err != nil { + return nil, err + } + defer rows.Close() // Закрываем соединение + + for rows.Next() { + var task Task + var progID int + // считываем данные из каждой строки, в соответствующие + // поля структуры Task + if err := rows.Scan(&task.ID, &task.Name, &task.Description, + &task.Priority, &task.IsDone, &progID); err != nil { + return nil, err + } + tasks = append(tasks, task) + } + return +} + +// Метод для обновления задачи +func (s *SQLiteRepository) TaskDone(taskId int) error { + if taskId == 0 { // Проверка на валидность + return errors.New("invalid updated ID") + } + // Запрос на перевод задачи с указанным id + // в состояние "выполнена" + res, err := s.db.Exec( + "UPDATE tasks SET is_done = ? WHERE id = ?", 1, + taskId, + ) + if err != nil { + return err + } + + // Проверяем, была ли обновлена задача + rowsAffected, err := res.RowsAffected() + if err != nil { + return err + } + + // Если не была обновлена ни одна задача + if rowsAffected == 0 { + return ErrUpdateFailed + } + + return nil +} diff --git a/part_8/8.1/golang/todo/go.mod b/part_6/6.1/golang/todo/go.mod similarity index 100% rename from part_8/8.1/golang/todo/go.mod rename to part_6/6.1/golang/todo/go.mod diff --git a/part_8/8.1/golang/todo/go.sum b/part_6/6.1/golang/todo/go.sum similarity index 100% rename from part_8/8.1/golang/todo/go.sum rename to part_6/6.1/golang/todo/go.sum diff --git a/part_8/8.2/golang/todo_gorm/main.go b/part_6/6.1/golang/todo/main.go similarity index 55% rename from part_8/8.2/golang/todo_gorm/main.go rename to part_6/6.1/golang/todo/main.go index 5b2c4a6..6194dec 100644 --- a/part_8/8.2/golang/todo_gorm/main.go +++ b/part_6/6.1/golang/todo/main.go @@ -7,8 +7,11 @@ import ( ) func main() { + // Создаем репозиторий rep := db.NewSQLiteRepository() + // Создаем отложенное закрытие соединения defer rep.Close() + // Бесконечный цикл for { menu.CreateMenu(rep) time.Sleep(2 * time.Second) diff --git a/part_8/8.2/golang/todo_gorm/menu/menu.go b/part_6/6.1/golang/todo/menu/menu.go similarity index 71% rename from part_8/8.2/golang/todo_gorm/menu/menu.go rename to part_6/6.1/golang/todo/menu/menu.go index d74d0b6..bf4872d 100644 --- a/part_8/8.2/golang/todo_gorm/menu/menu.go +++ b/part_6/6.1/golang/todo/menu/menu.go @@ -12,16 +12,23 @@ import ( "github.com/dixonwille/wmenu" ) +// Функция для создания меню func CreateMenu(rep *db.SQLiteRepository) { menu := wmenu.NewMenu("What would you like to do?") - menu.Action(func(opts []wmenu.Opt) error { handleFunc(rep, opts); return nil }) + menu.Action(func(opts []wmenu.Opt) error { + handleFunc(rep, opts) + return nil + }) menu.Option("Add a new Project", 0, false, nil) menu.Option("Delete a Project by ID", 1, false, nil) menu.Option("Get all Projects", 2, false, nil) menu.Option("Add a Task", 3, false, nil) - menu.Option("Get all Tasks", 4, true, nil) // выбор по умолчанию + // Выбор по умолчанию. Если пользователь жмякнет Enter, + // не выбирая никакого пункта меню, + // то будет выполнен этот пункт + menu.Option("Get all Tasks", 4, true, nil) menu.Option("Get all Project tasks", 5, false, nil) menu.Option("Done a Task by ID", 6, false, nil) menu.Option("Delete a Task by ID", 7, false, nil) @@ -34,6 +41,7 @@ func CreateMenu(rep *db.SQLiteRepository) { } } +// Функция для обработки ввода выбранного пункта меню func handleFunc(rep *db.SQLiteRepository, opts []wmenu.Opt) { switch opts[0].Value { case 0: @@ -66,10 +74,12 @@ func handleFunc(rep *db.SQLiteRepository, opts []wmenu.Opt) { } } +// Функция для вывода сообщения о невалидных данных func printNotValidData() { fmt.Println("Data is not valid!!!") } +// Функция для получения числового значения из потока ввода func getIntValueFromStd(reader *bufio.Reader) (int, error) { tempID, _, _ := reader.ReadLine() idStr := strings.TrimSuffix(string(tempID), "\n") @@ -80,6 +90,7 @@ func getIntValueFromStd(reader *bufio.Reader) (int, error) { return idProj, nil } +// Функция для получения строки из потока ввода func getStringValueFromStd(reader *bufio.Reader) (string, error) { data, err := reader.ReadString('\n') data = strings.TrimSuffix(data, "\r\n") diff --git a/part_8/8.2/golang/todo_gorm/menu/project_handlers.go b/part_6/6.1/golang/todo/menu/project_handlers.go similarity index 65% rename from part_8/8.2/golang/todo_gorm/menu/project_handlers.go rename to part_6/6.1/golang/todo/menu/project_handlers.go index 71d116a..85dbd20 100644 --- a/part_8/8.2/golang/todo_gorm/menu/project_handlers.go +++ b/part_6/6.1/golang/todo/menu/project_handlers.go @@ -7,9 +7,10 @@ import ( "os" ) +// Функция для добавления нового проекта func addProject(rep *db.SQLiteRepository) { - project := db.Project{} - reader := bufio.NewReader(os.Stdin) + project := db.Project{} // Создаем новый проект + reader := bufio.NewReader(os.Stdin) // Создаем поток ввода fmt.Print("Input project name: ") name, _ := getStringValueFromStd(reader) @@ -19,18 +20,22 @@ func addProject(rep *db.SQLiteRepository) { project.Name = name project.Description = desc + // Если название и описание проекта не пустые if project.Name != "" && project.Description != "" { - project, err := rep.AddProject(project) + project, err := rep.AddProject(project) // Добавляем проект if err != nil { fmt.Println(err) } else { + // Выводим информацию о добавленном проекте fmt.Printf("\nAdded project: %+v\n", *project) } } else { + // Выводим сообщение об ошибке printNotValidData() } } +// Функция для удаления проекта func deleteProjectByID(rep *db.SQLiteRepository) { fmt.Print("Input ID for deleting project: ") id, err := getIntValueFromStd(bufio.NewReader(os.Stdin)) @@ -47,6 +52,7 @@ func deleteProjectByID(rep *db.SQLiteRepository) { fmt.Println("Project deleted") } +// Функция для получения всех проектов func getAllProjects(rep *db.SQLiteRepository) { progects, err := rep.GetAllProjects() if err != nil { diff --git a/part_8/8.2/golang/todo_gorm/menu/task_handlers.go b/part_6/6.1/golang/todo/menu/task_handlers.go similarity index 73% rename from part_8/8.2/golang/todo_gorm/menu/task_handlers.go rename to part_6/6.1/golang/todo/menu/task_handlers.go index b2d1673..5fc2747 100644 --- a/part_8/8.2/golang/todo_gorm/menu/task_handlers.go +++ b/part_6/6.1/golang/todo/menu/task_handlers.go @@ -7,6 +7,7 @@ import ( "os" ) +// Функция для добавления новой задачи func addTask(rep *db.SQLiteRepository) { task := db.Task{} reader := bufio.NewReader(os.Stdin) @@ -45,6 +46,7 @@ func addTask(rep *db.SQLiteRepository) { } } +// Функция для удаления задачи func deleteTaskByID(rep *db.SQLiteRepository) { fmt.Print("Input ID for deleting task: ") id, err := getIntValueFromStd(bufio.NewReader(os.Stdin)) @@ -61,6 +63,7 @@ func deleteTaskByID(rep *db.SQLiteRepository) { fmt.Println("Task deleted") } +// Функция для получения всех задач func getAllTasks(rep *db.SQLiteRepository) { tasks, err := rep.GetAllTasks() if err != nil { @@ -72,12 +75,16 @@ func getAllTasks(rep *db.SQLiteRepository) { } else { fmt.Println("You current tasks: ") for _, it := range tasks { - fmt.Printf("TaskID: %v || Name: %v || Desc: %v || Priority: %v || IsDone: %v || ProjID: %v\n", - it.ID, it.Name, it.Description, it.Priority, it.IsDone, it.ProjectID) + fmt.Printf("TaskID: %v || Name: %v || Desc: %v ||"+ + " Priority: %v || IsDone: %v || ProjID: %v\n", + it.ID, it.Name, it.Description, it.Priority, + it.IsDone, it.ProjectID, + ) } } } +// Функция для получения всех задач проекта func getAllProjectTasks(rep *db.SQLiteRepository) { fmt.Print("Input ID for project: ") @@ -96,14 +103,21 @@ func getAllProjectTasks(rep *db.SQLiteRepository) { if len(tasks) == 0 { fmt.Println("You don't have any task") } else { - fmt.Printf("Project with ID = %d have next tasks:\n", id) + fmt.Printf( + "Project with ID = %d have next tasks:\n", + id, + ) for _, it := range tasks { - fmt.Printf("TaskID: %v || Name: %v || Desc: %v || Priority: %v || IsDone: %v\n", - it.ID, it.Name, it.Description, it.Priority, it.IsDone) + fmt.Printf("TaskID: %v || Name: %v || Desc: %v ||"+ + " Priority: %v || IsDone: %v\n", + it.ID, it.Name, it.Description, + it.Priority, it.IsDone, + ) } } } +// Функция для перевода задачи в состояние "Выполнено" func doneTask(rep *db.SQLiteRepository) { fmt.Print("Input task ID: ") diff --git a/part_8/8.1/golang/todo/todo.db b/part_6/6.1/golang/todo/todo.db similarity index 100% rename from part_8/8.1/golang/todo/todo.db rename to part_6/6.1/golang/todo/todo.db diff --git a/part_6/6.2/golang/todo_gorm/db/db.go b/part_6/6.2/golang/todo_gorm/db/db.go new file mode 100644 index 0000000..d44e0e8 --- /dev/null +++ b/part_6/6.2/golang/todo_gorm/db/db.go @@ -0,0 +1,94 @@ +package db + +import ( + _ "database/sql" + "fmt" + "log" + "os" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +type SQLiteRepository struct { + db *gorm.DB // заменили на *gorm.DB +} + +func NewSQLiteRepository() *SQLiteRepository { + var db *gorm.DB + rep := &SQLiteRepository{} + // Если база данных не существует, то создаем ее + if _, err := os.Stat(dbName); os.IsNotExist(err) { + // Отквываем соединение с базой данных + db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{}) + if err != nil { + log.Fatal(err) + } + fmt.Println("DB isn't exist") + // Создаем таблицы + db.AutoMigrate(&Project{}, &ProjectTask{}) + // Заполняем БД значениями по умолчанию + rep.db = db + putDefaultValuesToDB(rep) + } else { + // Отквываем соединение с базой данных + db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{}) + if err != nil { + log.Fatal(err) + } + rep.db = db + fmt.Println("DB already exists") + } + + return rep +} + +func putDefaultValuesToDB(rep *SQLiteRepository) { + firstProject, _ := rep.AddProject(Project{ + Name: "Go", + Description: "Roadmap for learning Go", + }) + secondProject, _ := rep.AddProject(Project{ + Name: "One Year", + Description: "Tasks for the year", + }) + rep.AddTask(Task{ + Name: "Variable", + Description: "Learning Go build-in variables", + Priority: 1, + }, firstProject.ID) + rep.AddTask(Task{ + Name: "Struct", + Description: "Learning use struct in OOP code", + Priority: 3, + }, firstProject.ID) + rep.AddTask(Task{ + Name: "Goroutine", + Description: "Learning concurrent programming", + Priority: 5, + }, firstProject.ID) + rep.AddTask(Task{ + Name: "DataBase", + Description: "How write app with db", + Priority: 1, + }, firstProject.ID) + rep.AddTask(Task{ + Name: "PhD", + Description: "Ph.D. in Technical Sciences", + Priority: 5, + }, secondProject.ID) + rep.AddTask(Task{ + Name: "Losing weight", + Description: "Exercise and eat less chocolate", + Priority: 2, + }, secondProject.ID) + rep.AddTask(Task{ + Name: "Пафос и превозмогание", + Description: "10к подписчиков на канале", + Priority: 2, + }, secondProject.ID) +} + +func (r *SQLiteRepository) Close() { + +} diff --git a/part_10/10.4/golang/todo-service/db/db_definition.go b/part_6/6.2/golang/todo_gorm/db/db_definition.go similarity index 100% rename from part_10/10.4/golang/todo-service/db/db_definition.go rename to part_6/6.2/golang/todo_gorm/db/db_definition.go diff --git a/part_8/8.2/golang/todo_gorm/db/models.go b/part_6/6.2/golang/todo_gorm/db/models.go similarity index 100% rename from part_8/8.2/golang/todo_gorm/db/models.go rename to part_6/6.2/golang/todo_gorm/db/models.go diff --git a/part_8/8.2/golang/todo_gorm/db/projects_crud.go b/part_6/6.2/golang/todo_gorm/db/projects_crud.go similarity index 73% rename from part_8/8.2/golang/todo_gorm/db/projects_crud.go rename to part_6/6.2/golang/todo_gorm/db/projects_crud.go index 5546660..761be79 100644 --- a/part_8/8.2/golang/todo_gorm/db/projects_crud.go +++ b/part_6/6.2/golang/todo_gorm/db/projects_crud.go @@ -6,12 +6,14 @@ import ( "github.com/mattn/go-sqlite3" ) +// Метод для добавления проекта в базу данных func (r *SQLiteRepository) AddProject(project Project) (*Project, error) { tx := r.db.Create(&project) if tx.Error != nil { var sqliteErr sqlite3.Error if errors.As(tx.Error, &sqliteErr) { - if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) { + if errors.Is(sqliteErr.ExtendedCode, + sqlite3.ErrConstraintUnique) { return nil, ErrDuplicate } } @@ -21,6 +23,7 @@ func (r *SQLiteRepository) AddProject(project Project) (*Project, error) { return &project, nil } +// Метод для удаления проекта из базы данных func (r *SQLiteRepository) DeleteProject(projectID int) error { tx := r.db.Delete(&Project{ID: projectID}) if tx.Error != nil { @@ -35,6 +38,7 @@ func (r *SQLiteRepository) DeleteProject(projectID int) error { return nil } +// Метод для получения всех проектов func (r *SQLiteRepository) GetAllProjects() ([]Project, error) { var projects []Project tx := r.db.Find(&projects) diff --git a/part_8/8.2/golang/todo_gorm/db/tasks_crud.go b/part_6/6.2/golang/todo_gorm/db/tasks_crud.go similarity index 50% rename from part_8/8.2/golang/todo_gorm/db/tasks_crud.go rename to part_6/6.2/golang/todo_gorm/db/tasks_crud.go index 61fd340..1acb024 100644 --- a/part_8/8.2/golang/todo_gorm/db/tasks_crud.go +++ b/part_6/6.2/golang/todo_gorm/db/tasks_crud.go @@ -2,12 +2,13 @@ package db import "errors" +// Метод для добавления задачи в базу данных func (r *SQLiteRepository) AddTask(task Task, projectID int) (*Task, error) { - pjTask := &ProjectTask{ + pjTask := &ProjectTask{ // создаем связь между задачей и проектом Task: task, ProjectID: projectID, } - tx := r.db.Create(pjTask) + tx := r.db.Create(pjTask) // создаем задачу if tx.Error != nil { return nil, tx.Error } @@ -15,7 +16,9 @@ func (r *SQLiteRepository) AddTask(task Task, projectID int) (*Task, error) { return &pjTask.Task, nil } +// Метод для удаления задачи из базы данных func (r *SQLiteRepository) DeleteTask(taskID int) error { + // удаляем задачу по ее ID tx := r.db.Delete(&ProjectTask{Task: Task{ID: taskID}}) if tx.Error != nil { return tx.Error @@ -29,8 +32,9 @@ func (r *SQLiteRepository) DeleteTask(taskID int) error { return nil } +// Метод для получения всех задач func (r *SQLiteRepository) GetAllTasks() (tasks []ProjectTask, err error) { - tx := r.db.Find(&tasks) + tx := r.db.Find(&tasks) // получаем все задачи if tx.Error != nil { return nil, tx.Error } @@ -41,12 +45,15 @@ func (r *SQLiteRepository) GetAllTasks() (tasks []ProjectTask, err error) { return } +// Метод для получения всех задач конкретного проекта func (r *SQLiteRepository) GetProjectTasks(projectID int) (tasks []Task, err error) { if projectID == 0 { return nil, errors.New("invalid updated ID") } var pjTasks []ProjectTask + // получаем все задачи конкретного проекта + // и добавляем их в срез pjTasks []ProjectTask tx := r.db.Where("project_id", projectID).Find(&pjTasks) if tx.Error != nil { return nil, tx.Error @@ -56,22 +63,29 @@ func (r *SQLiteRepository) GetProjectTasks(projectID int) (tasks []Task, err err } for _, it := range pjTasks { + // Отделяем задачу от проекта + // и добавляем в срез tasks tasks = append(tasks, it.Task) } return } +// Метод для обновления задачи func (r *SQLiteRepository) TaskDone(taskId int) error { - if taskId == 0 { + if taskId == 0 { // Проверка на валидность return errors.New("invalid updated ID") } + // Поиск задачи по ее ID. Сначала создаем экземпляр ProjectTask + // передаем в него Task{ID: taskId} pjTask := &ProjectTask{Task: Task{ID: taskId}} - tx := r.db.Find(&pjTask) + tx := r.db.Find(&pjTask) // ищем задачу if tx.Error != nil { return tx.Error } - pjTask.IsDone = true - r.db.Save(&pjTask) + pjTask.IsDone = true // обновляем поле IsDone + r.db.Save(&pjTask) // сохраняем обновленную задачу + + // проверяем обновилась ли задача rowsAffected := tx.RowsAffected if rowsAffected == 0 { return ErrUpdateFailed diff --git a/part_8/8.2/golang/todo_gorm/go.mod b/part_6/6.2/golang/todo_gorm/go.mod similarity index 100% rename from part_8/8.2/golang/todo_gorm/go.mod rename to part_6/6.2/golang/todo_gorm/go.mod diff --git a/part_8/8.2/golang/todo_gorm/go.sum b/part_6/6.2/golang/todo_gorm/go.sum similarity index 100% rename from part_8/8.2/golang/todo_gorm/go.sum rename to part_6/6.2/golang/todo_gorm/go.sum diff --git a/part_8/8.1/golang/todo/main.go b/part_6/6.2/golang/todo_gorm/main.go similarity index 100% rename from part_8/8.1/golang/todo/main.go rename to part_6/6.2/golang/todo_gorm/main.go diff --git a/part_8/8.1/golang/todo/menu/menu.go b/part_6/6.2/golang/todo_gorm/menu/menu.go similarity index 100% rename from part_8/8.1/golang/todo/menu/menu.go rename to part_6/6.2/golang/todo_gorm/menu/menu.go diff --git a/part_8/8.1/golang/todo/menu/project_handlers.go b/part_6/6.2/golang/todo_gorm/menu/project_handlers.go similarity index 100% rename from part_8/8.1/golang/todo/menu/project_handlers.go rename to part_6/6.2/golang/todo_gorm/menu/project_handlers.go diff --git a/part_8/8.1/golang/todo/menu/task_handlers.go b/part_6/6.2/golang/todo_gorm/menu/task_handlers.go similarity index 100% rename from part_8/8.1/golang/todo/menu/task_handlers.go rename to part_6/6.2/golang/todo_gorm/menu/task_handlers.go diff --git a/part_8/8.2/golang/todo_gorm/todo.db b/part_6/6.2/golang/todo_gorm/todo.db similarity index 75% rename from part_8/8.2/golang/todo_gorm/todo.db rename to part_6/6.2/golang/todo_gorm/todo.db index a9842cde2ecc6b9f2c38859dc8e016414f84bf8a..23b8f03ad939332b5b22d26f5469c54bccb4e1d9 100644 GIT binary patch delta 412 zcmZo@U~E{xI6<0~n}LCWb)tg3C^v&%RUt3`4+a+ACHu|WHrg_>i_6L~Hu+9=;I|>@3}IazXMexokRV4-zYv9l(!9+0f};Ga)Z~)lc#xS1 z3ZZ_UfuXJn8VMlo<|F(L3LH%Q_Zj#<@!#JpsBoFzT#$)boe`=jz9g|YyO^Daky#cd zRLsN+3_^CkE(ZRK{EPSt_`UcQ`CjpLZ59+L;p2#7XJ?2_XXKbX$<9=1|AieF8!xtB i*l}Ukg?$$`DO}ilVS@sYy#d6yu=~PRrp+(y#2En>O^0Cs delta 258 zcmZozz}V2hI6<0~kAZ=KWuk(;Fdu_nv?(wD4+du5M-2RC{Kt78Z59+L;MHmhWM&sv zS7&TVEJ;ktNi8VK&q_@$i7!bk&MrpbuuN{@)t-Ekw_hkA$kW#`C{n@OHBvz%Au}aG zb8