1
0
mirror of https://github.com/MADTeacher/go_basics.git synced 2025-11-23 21:34:47 +02:00
This commit is contained in:
Stanislav Chernyshev
2025-03-25 21:11:56 +03:00
parent e04e890078
commit ae0f585f49
298 changed files with 9160 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
package client
import (
"fmt"
"log"
"net"
)
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func RunClient(port int) {
s, _ := net.ResolveUDPAddr("udp4", fmt.Sprintf("localhost:%d", port))
connection, err := net.DialUDP("udp4", nil, s)
checkErr(err)
fmt.Printf("The UDP server is %s\n", connection.RemoteAddr().String())
defer connection.Close()
count := 0
for {
data := []byte(fmt.Sprintf("%d)Hello!\n", count))
fmt.Print("->", string(data))
_, err = connection.Write(data)
checkErr(err)
buffer := make([]byte, 1024)
n, _, err := connection.ReadFromUDP(buffer)
checkErr(err)
fmt.Printf("<-: %s", string(buffer[0:n]))
count++
if count >= 5 {
data := []byte("STOP")
fmt.Println("->", string(data))
_, err = connection.Write(data)
checkErr(err)
fmt.Println("Finished!")
return
}
}
}

3
part_10/10.1/udp/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module udp
go 1.24

38
part_10/10.1/udp/main.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"udp/client"
"udp/server"
)
const PORT = 8081
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("You didn't select a launch option!!!")
return
}
numGR, err := strconv.Atoi(os.Args[1])
checkErr(err)
switch numGR {
case 1:
fmt.Println("Server is running")
server.RunServer(PORT)
case 2:
fmt.Println("Client is running")
client.RunClient(PORT)
default:
log.Fatal("What pokemon is this?")
}
}

View File

@@ -0,0 +1,44 @@
package server
import (
"fmt"
"log"
"net"
"strings"
"time"
)
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func RunServer(port int) {
s, err := net.ResolveUDPAddr("udp4", fmt.Sprintf(":%d", port))
checkErr(err)
connection, err := net.ListenUDP("udp4", s)
checkErr(err)
defer connection.Close()
buffer := make([]byte, 1024)
fmt.Println("Oo")
for {
n, addr, err := connection.ReadFromUDP(buffer) // ждем подсоединение клиента
checkErr(err)
fmt.Printf("<- %s", string(buffer[0:n]))
if strings.TrimSpace(string(buffer[0:n])) == "STOP" {
fmt.Println()
fmt.Println("Exiting UDP server!")
return
}
time.Sleep(5 * time.Second)
fmt.Printf("->: %s", string(buffer))
_, err = connection.WriteToUDP(buffer, addr)
checkErr(err)
}
}

View File

@@ -0,0 +1,53 @@
package client
import (
"bufio"
"fmt"
"log"
"net"
)
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func RunClient(port int) {
// запускает реализацию клиента TCP и соединяет вас с нужным TCP-сервером
connection, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
checkErr(err)
fmt.Printf("The TCP server is %s\n", connection.RemoteAddr().String())
defer connection.Close()
count := 0
for {
// отправка сообщения на сервер
data := []byte(fmt.Sprintf("%d)Hello!\n", count))
fmt.Print("->", string(data))
fmt.Fprint(connection, fmt.Sprintf("%d)Hello!\n", count))
// или
//_, err = connection.Write(data)
// checkErr(err)
// считываем ответ TCP-сервера
message, err := bufio.NewReader(connection).ReadString('\n')
// или
// buffer := make([]byte, 1024)
// _, err := connection.Read(buffer)
// message := string(buffer)
checkErr(err)
fmt.Printf("<-: %s", message)
count++
if count >= 5 {
data := []byte("STOP")
fmt.Println("->", string(data))
_, err = connection.Write(data)
checkErr(err)
fmt.Println("Finished!")
return
}
}
}

3
part_10/10.2/tcp/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module udp/server
go 1.24

38
part_10/10.2/tcp/main.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"udp/server/client"
"udp/server/server"
)
const PORT = 8081
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("You didn't select a launch option!!!")
return
}
numGR, err := strconv.Atoi(os.Args[1])
checkErr(err)
switch numGR {
case 1:
fmt.Println("Server is running")
server.RunServer(PORT)
case 2:
fmt.Println("Client is running")
client.RunClient(PORT)
default:
log.Fatal("What pokemon is this?")
}
}

View File

@@ -0,0 +1,62 @@
package server
import (
"fmt"
"log"
"net"
"strings"
"time"
)
func checkErr(err error) {
if err != nil {
log.Print(err)
}
}
func handleConnection(connection net.Conn) {
defer connection.Close()
buffer := make([]byte, 1024)
for {
n, err := connection.Read(buffer) // считывание данных
checkErr(err)
fmt.Printf("Receive: %s from %s\n",
string(buffer[0:n-1]), connection.RemoteAddr().String())
if strings.TrimSpace(string(buffer[0:n])) == "STOP" {
// завершение работы сервера
fmt.Println()
fmt.Printf("Close connection with client: %s\n",
connection.RemoteAddr().String())
break
}
time.Sleep(2 * time.Second)
fmt.Printf("Send : %s to %s\n",
string(buffer[0:n-1]), connection.RemoteAddr().String())
_, err = connection.Write(buffer) // отправка сообщения клиенту
checkErr(err)
}
}
func RunServer(port int) {
// net.Listen возвращает Listener переменную,
// которая является общим сетевым прослушивателем для потоковых протоколов
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
checkErr(err)
defer listener.Close()
for {
connection, err := listener.Accept() // ожидание подключения клиента к серверу
// Только после успешного вызова Accept()TCP-сервер может начать
// взаимодействовать с TCP-клиентами
if err != nil {
log.Print(err)
return
}
go handleConnection(connection)
}
}

View File

@@ -0,0 +1,77 @@
package client
import (
"bufio"
"fmt"
"io"
"log"
"net"
"os"
"strings"
"sync"
)
var waitingGr sync.WaitGroup
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func sendMessage(connection net.Conn, waitingGr *sync.WaitGroup) {
defer waitingGr.Done()
for {
reader := bufio.NewReader(os.Stdin) // считываем введенное сообщение
text, _ := reader.ReadString('\n')
if strings.TrimSuffix(strings.TrimSpace(text), "\r\n") == "/stop" {
// завершение работы клиента
break
} else {
_, err := connection.Write([]byte(text))
checkErr(err)
}
}
}
func receiveMessage(connection net.Conn, waitingGr *sync.WaitGroup) {
defer waitingGr.Done()
for {
// ждем сообщение от сервера и считываем его
message, err := bufio.NewReader(connection).ReadString('\n')
if err == io.EOF {
fmt.Println("Connection close!")
break
} else if err != nil {
fmt.Println(err.Error())
break
}
message = message[:len(message)-1] // обрезаем символ перевода на следующую строку
fmt.Println(string(message))
}
}
func RunClient(port int) {
// запускает реализацию клиента TCP и соединяет вас с нужным TCP-сервером
connection, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
checkErr(err)
fmt.Printf("The TCP server is %s\n", connection.RemoteAddr().String())
defer connection.Close()
waitingGr.Add(1)
fmt.Println("Enter name: ")
temp := bufio.NewReader(os.Stdin)
userName, _ := temp.ReadString('\n')
_, err = connection.Write([]byte(userName))
checkErr(err)
go sendMessage(connection, &waitingGr)
go receiveMessage(connection, &waitingGr)
waitingGr.Wait()
}

View File

@@ -0,0 +1,3 @@
module tcp/server
go 1.24

View File

@@ -0,0 +1,38 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"tcp/server/client"
"tcp/server/server"
)
const PORT = 8081
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("You didn't select a launch option!!!")
return
}
numGR, err := strconv.Atoi(os.Args[1])
checkErr(err)
switch numGR {
case 1:
fmt.Println("Server is running")
server.RunServer(PORT)
case 2:
fmt.Println("Client is running")
client.RunClient(PORT)
default:
log.Fatal("What pokemon is this?")
}
}

View File

@@ -0,0 +1,85 @@
package server
import (
"bufio"
"fmt"
"log"
"net"
)
var connections []net.Conn
func checkErr(err error) {
if err != nil {
log.Print(err)
}
}
func handleConnection(connection net.Conn) {
connections = append(connections, connection)
userName, _ := bufio.NewReader(connection).ReadString('\n')
userName = userName[:len(userName)-2]
_, err := connection.Write([]byte("Hi " + userName + "\n"))
checkErr(err)
for {
text, err := bufio.NewReader(connection).ReadString('\n')
if err != nil {
connection.Close()
removeConnection(connection)
broadCastMessage(userName+" is offline\n", connection)
break
}
broadCastMessage(userName+":"+text, connection)
}
}
func removeConnection(connection net.Conn) {
var i int
for i = range connections {
if connections[i] == connection {
break
}
}
if len(connections) > 1 {
connections = append(connections[:i], connections[i+1:]...)
} else {
connections = nil
}
}
func broadCastMessage(msg string, connection net.Conn) {
// отправка сообщения всем клиентам
for _, c := range connections {
if connection != c {
_, err := c.Write([]byte(msg))
checkErr(err)
}
}
msg = msg[:len(msg)-1]
fmt.Println(msg)
}
func RunServer(port int) {
// net.Listen возвращает Listener переменную,
// которая является общим сетевым прослушивателем для потоковых протоколов
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
checkErr(err)
defer listener.Close()
for {
connection, err := listener.Accept() // ожидание подключения клиента к серверу
// Только после успешного вызова Accept()TCP-сервер может начать
// взаимодействовать с TCP-клиентами
if err != nil {
log.Print(err)
return
}
go handleConnection(connection)
}
}

View File

@@ -0,0 +1,5 @@
{
"yaml.schemas": {
"swaggerviewer:openapi": "file:///e%3A/code/golang/todo-service/todo-service-api.yml"
}
}

View File

@@ -0,0 +1,98 @@
package db
import (
_ "database/sql"
"fmt"
"log"
"os"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type SQLiteRepository struct {
db *gorm.DB
}
func NewSQLiteRepository() *SQLiteRepository {
var db *gorm.DB
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{}, &Task{})
putDefaultValuesToDB(db)
} else {
db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
fmt.Println("DB already exists")
}
return &SQLiteRepository{
db: db,
}
}
func putDefaultValuesToDB(db *gorm.DB) {
firstProject := Project{
Name: "Go",
Description: "Roadmap for learning Go",
}
secondProject := Project{
Name: "One Year",
Description: "Tasks for the year",
}
db.Create(&firstProject)
db.Create(&secondProject)
db.Create(&Task{
Name: "Variable",
Description: "Learning Go build-in variables",
Priority: 1,
Project: &firstProject,
})
db.Create(&Task{
Name: "Struct",
Description: "Learning use struct in OOP code",
Priority: 3,
Project: &firstProject,
})
db.Create(&Task{
Name: "Goroutine",
Description: "Learning concurrent programming",
Priority: 5,
Project: &firstProject,
})
db.Create(&Task{
Name: "DataBase",
Description: "How write app with db",
Priority: 1,
Project: &firstProject,
})
db.Create(&Task{
Name: "PhD",
Description: "Ph.D. in Technical Sciences",
Priority: 5,
Project: &secondProject,
})
db.Create(&Task{
Name: "Losing weight",
Description: "Exercise and eat less chocolate",
Priority: 2,
Project: &secondProject,
})
db.Create(&Task{
Name: "Пафос и превозмогание",
Description: "10к подписчиков на канале",
Priority: 2,
Project: &secondProject,
})
}
func (r *SQLiteRepository) Close() {
}

View File

@@ -0,0 +1,12 @@
package db
import "errors"
const dbName = "todo.db"
var (
ErrDuplicate = errors.New("record already exists")
ErrNotExists = errors.New("row not exists")
ErrUpdateFailed = errors.New("update failed")
ErrDeleteFailed = errors.New("delete failed")
)

View File

@@ -0,0 +1,17 @@
package db
type Project struct {
ID int `json:"id" gorm:"primary_key;autoIncrement:true;not null"`
Name string `json:"name" gorm:"unique;not null"`
Description string `json:"description"`
}
type Task struct {
ID int `json:"id" gorm:"primary_key;autoIncrement;not null"`
Name string `json:"name" gorm:"not null"`
Description string `json:"description" gorm:"not null"`
Priority uint8 `json:"priority" gorm:"not null"`
IsDone bool `json:"isDone" gorm:"not null"`
ProjectID int `json:"projectID" gorm:"not null"`
Project *Project `gorm:"foreignKey:ProjectID;references:ID"`
}

View File

@@ -0,0 +1,49 @@
package db
import (
"errors"
"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) {
return nil, ErrDuplicate
}
}
return nil, tx.Error
}
return &project, nil
}
func (r *SQLiteRepository) DeleteProject(projectID int) error {
tx := r.db.Delete(&Project{ID: projectID})
if tx.Error != nil {
return tx.Error
}
rowsAffected := tx.RowsAffected
if rowsAffected == 0 {
return ErrDeleteFailed
}
return nil
}
func (r *SQLiteRepository) GetAllProjects() ([]Project, error) {
var projects []Project
tx := r.db.Find(&projects)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return projects, nil
}

View File

@@ -0,0 +1,73 @@
package db
import "errors"
func (r *SQLiteRepository) AddTask(task Task) (*Task, error) {
tx := r.db.Create(&task)
if tx.Error != nil {
return nil, tx.Error
}
return &task, nil
}
func (r *SQLiteRepository) DeleteTask(taskID int) error {
tx := r.db.Delete(&Task{ID: taskID})
if tx.Error != nil {
return tx.Error
}
rowsAffected := tx.RowsAffected
if rowsAffected == 0 {
return ErrDeleteFailed
}
return nil
}
func (r *SQLiteRepository) GetAllTasks() (tasks []Task, err error) {
tx := r.db.Find(&tasks)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return
}
func (r *SQLiteRepository) GetProjectTasks(projectID int) (tasks []Task, err error) {
if projectID == 0 {
return nil, errors.New("invalid updated ID")
}
tx := r.db.Where("project_id", projectID).Find(&tasks)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return
}
func (r *SQLiteRepository) TaskDone(taskId int) error {
if taskId == 0 {
return errors.New("invalid updated ID")
}
pjTask := &Task{ID: taskId}
tx := r.db.Find(&pjTask)
if tx.Error != nil {
return tx.Error
}
pjTask.IsDone = true
r.db.Save(&pjTask)
rowsAffected := tx.RowsAffected
if rowsAffected == 0 {
return ErrUpdateFailed
}
return nil
}

View File

@@ -0,0 +1,16 @@
module golang/todo-service
go 1.24
require (
github.com/gorilla/mux v1.8.1
github.com/mattn/go-sqlite3 v1.14.24
gorm.io/driver/sqlite v1.5.7
)
require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
golang.org/x/text v0.14.0 // indirect
gorm.io/gorm v1.25.12 // indirect
)

View File

@@ -0,0 +1,16 @@
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

View File

@@ -0,0 +1,20 @@
package main
import (
"golang/todo-service/db"
"golang/todo-service/service"
"log"
"net/http"
)
const PORT = "8080"
func main() {
rep := db.NewSQLiteRepository()
defer rep.Close()
router := service.NewRouter(rep)
log.Printf("Server started")
log.Fatal(http.ListenAndServe(":"+PORT, router))
}

View File

@@ -0,0 +1,22 @@
package service
import "golang/todo-service/db"
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
type GoodResponse struct {
Code int `json:"code"`
Message string `json:"message"`
ID int `json:"id"`
}
type ProjectsList struct {
Items []db.Project `json:"items,omitempty"`
}
type TasksList struct {
Items []db.Task `json:"items,omitempty"`
}

View File

@@ -0,0 +1,87 @@
package service
import (
"encoding/json"
"golang/todo-service/db"
"io"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
func deleteProject(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
params := mux.Vars(r)
idStr, ok := params["id"]
if !ok {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
id, err := strconv.Atoi(idStr)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
err = repository.DeleteProject(id)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Project not found"})
return
}
w.WriteHeader(http.StatusOK)
}
func addProject(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var project db.Project
reqBody, err := io.ReadAll(r.Body)
if err == nil {
json.Unmarshal(reqBody, &project)
if project.Name == "" {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
project.ID = 0
project, err := repository.AddProject(project)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Project with that name already exists"})
return
}
goodResponse := GoodResponse{
Code: 201,
Message: "Проект создан",
ID: project.ID,
}
jsonGoodResponse, _ := json.Marshal(goodResponse)
w.WriteHeader(http.StatusCreated)
w.Write(jsonGoodResponse)
return
}
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
}
func getProjects(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
progects, err := repository.GetAllProjects()
if err != nil || len(progects) == 0 {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Projects not found"})
return
}
projectsList := ProjectsList{progects}
jsonGoodResponse, _ := json.Marshal(projectsList)
w.WriteHeader(http.StatusOK)
w.Write(jsonGoodResponse)
}

View File

@@ -0,0 +1,153 @@
package service
import (
"encoding/json"
"golang/todo-service/db"
"io"
"net/http"
"strconv"
)
func deleteTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
queryStr := r.URL.Query()
idStr, ok := queryStr["id"]
if !ok {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
if len(idStr) == 0 {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
id, err := strconv.Atoi(idStr[0])
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
err = repository.DeleteTask(id)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Task not found"})
return
}
w.WriteHeader(http.StatusOK)
}
func getTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
queryStr := r.URL.Query()
idStr, ok := queryStr["projectID"]
if !ok {
tasks, err := repository.GetAllTasks()
if err != nil || len(tasks) == 0 {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Tasks not found"})
return
}
// возвращаем все имеющиеся задачи
projectsList := TasksList{tasks}
jsonGoodResponse, _ := json.Marshal(projectsList)
w.WriteHeader(http.StatusOK)
w.Write(jsonGoodResponse)
return
}
if len(idStr) == 0 {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
id, err := strconv.Atoi(idStr[0])
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
tasks, err := repository.GetProjectTasks(id)
if err != nil || len(tasks) == 0 {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Tasks not found"})
return
}
// возвращаем все задачи конкретного проекта
projectsList := TasksList{tasks}
jsonGoodResponse, _ := json.Marshal(projectsList)
w.WriteHeader(http.StatusOK)
w.Write(jsonGoodResponse)
}
func addTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var task db.Task
reqBody, err := io.ReadAll(r.Body)
if err == nil {
json.Unmarshal(reqBody, &task)
if task.Name == "" || task.ProjectID == 0 {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
task.ID = 0
task, err := repository.AddTask(task)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
goodResponse := GoodResponse{
Code: 201,
Message: "Задача создана",
ID: task.ID,
}
jsonGoodResponse, _ := json.Marshal(goodResponse)
w.WriteHeader(http.StatusCreated)
w.Write(jsonGoodResponse)
return
}
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
}
func doneTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
queryStr := r.URL.Query()
idStr, ok := queryStr["id"]
if !ok {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
if len(idStr) == 0 {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
id, err := strconv.Atoi(idStr[0])
if err != nil {
errorResponse(w, ErrorResponse{http.StatusBadRequest,
"Validation Failed"})
return
}
err = repository.TaskDone(id)
if err != nil {
errorResponse(w, ErrorResponse{http.StatusNotFound,
"Tasks not found"})
return
}
w.WriteHeader(http.StatusOK)
}

View File

@@ -0,0 +1,23 @@
package service
import (
"log"
"net/http"
"time"
)
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s %s %s %s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}

View File

@@ -0,0 +1,102 @@
package service
import (
"encoding/json"
"fmt"
"golang/todo-service/db"
"net/http"
"github.com/gorilla/mux"
)
type Route struct {
Name string // имя функции обработчика
Method string // тип HTTP-сообщения
Pattern string // шаблон пути
HandlerFunc http.HandlerFunc // ссылка на функцию обработчик
// сигнатура функции должна быть func(ResponseWriter, *Request)
}
var repository *db.SQLiteRepository
func NewRouter(rep *db.SQLiteRepository) *mux.Router {
repository = rep
router := mux.NewRouter().StrictSlash(true)
for _, route := range routes {
var handler http.Handler
handler = route.HandlerFunc
//оборачиваем функцию-обработчик в логгер
handler = Logger(route.HandlerFunc, route.Name)
// handler := route.HandlerFunc
// // // добавляем новый обработчик
router. //HandleFunc(route.Pattern, handler).Methods(route.Method)
Methods(route.Method). // тип HTTP-сообщения
Path(route.Pattern). // шаблон пути
Name(route.Name). // имя функции обработчика
Handler(handler) // ссылка на функцию обработчик
}
router.Use(mux.CORSMethodMiddleware(router))
return router
}
func home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Wold in REST API style!!!")
}
var routes = []Route{
{ // домашняя страница
"home",
http.MethodGet,
"/api/v1/todo",
home,
},
{ // удаление проекта по id
"deleteProject",
http.MethodDelete,
"/api/v1/todo/project/del/{id}",
deleteProject,
},
{ // добавление проекта
"addProject",
http.MethodPost,
"/api/v1/todo/project",
addProject,
},
{ // получить все проекты
"getProjects",
http.MethodGet,
"/api/v1/todo/projects",
getProjects,
},
{ // удаление задачи
"deleteTask",
http.MethodDelete,
"/api/v1/todo/task",
deleteTask,
},
{ // получение всех задач или конкретного проекта
"getTask",
http.MethodGet,
"/api/v1/todo/task",
getTask,
},
{ // добавить задачу
"addTask",
http.MethodPost,
"/api/v1/todo/task",
addTask,
},
{ // изменение статуса задачи на «Выполнено»
"doneTask",
http.MethodPut,
"/api/v1/todo/task",
doneTask,
},
}
func errorResponse(w http.ResponseWriter, err ErrorResponse) {
jsonResponse, _ := json.Marshal(err)
w.WriteHeader(err.Code)
w.Write(jsonResponse)
}

View File

@@ -0,0 +1,429 @@
openapi: 3.0.2
info:
title: ToDo client-server api
description: |
Документация по описанию конечных точек сервера, посредством которых
происходит доступ к ресурсам
version: 1.0.0
servers:
- url: http://127.0.0.1:8080/api/v1/todo
tags:
- name: task
- name: project
paths:
/project:
post:
tags:
- project
description: |
Добавление проекта
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
responses:
"201":
description: Добавление прошло успешно.
content:
application/json:
schema:
$ref: '#/components/schemas/GoodResponse'
examples:
response:
value: |-
{
"code": 201,
"message": "Project created",
"id": 1
}
"400":
description: Невалидная схема проекта или входные данные не верны.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
/project/del/{id}:
delete:
tags:
- project
description: |
Удалить проект
parameters:
- description: Идентификатор
in: path
name: id
required: true
schema:
type: integer
example: 1
responses:
"200":
description: Удаление прошло успешно.
"400":
description: Невалидная схема проекта или входные данные не верны.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
"404":
description: Проект не найден.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 404,
"message": "Project not found"
}
/projects:
get:
tags:
- project
description: |
Получить список проектов
responses:
"200":
description: Запрос прошел успешно
content:
application/json:
schema:
$ref: "#/components/schemas/ProgectsList"
"404":
description: Проект не найден.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 404,
"message": "Projects not found"
}
/task:
put:
tags:
- task
description: |
Изменение статуса задачи
parameters:
- in: query
required: true
name: id
schema:
type: integer
example: 1
responses:
"201":
description: Запрос прошел успешно
"400":
description: Невалидная схема задачи или входные данные не верны.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
"404":
description: Проект не найден.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 404,
"message": "Tasks not found"
}
post:
tags:
- task
description: |
Добавление задачи
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
responses:
"201":
description: Добавление прошло успешно.
content:
application/json:
schema:
$ref: "#/components/schemas/GoodResponse"
examples:
response:
value: |-
{
"code": 201,
"message": "Task created",
"id": 1
}
"400":
description: Невалидная схема задачи или входные данные не верны.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
get:
tags:
- task
description: |
Получение списка всех задач или конкретного проекта
parameters:
- in: query
name: projectID
schema:
type: integer
example: 1
responses:
"200":
description: Запрос прошел успешно
content:
application/json:
schema:
$ref: "#/components/schemas/TasksList"
"400":
description: Невалидная схема задачи или входные данные не верны.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
"404":
description: Проект не найден.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 404,
"message": "Tasks not found"
}
delete:
tags:
- task
description: |
Удаление задачи с заданным ID
parameters:
- in: query
required: true
name: id
schema:
type: integer
example: 1
responses:
"200":
description: Запрос прошел успешно
"400":
description: Невалидная схема задачи или входные данные не верны.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 400,
"message": "Validation Failed"
}
"404":
description: Задача не найдена.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
response:
value: |-
{
"code": 404,
"message": "Task not found"
}
components:
schemas:
Error:
required:
- code
- message
properties:
code:
type: integer
nullable: false
message:
type: string
nullable: false
GoodResponse:
required:
- code
- id
- message
properties:
code:
type: integer
nullable: false
message:
type: string
nullable: false
id:
type: integer
nullable: false
example:
code: 0
id: 6
message: message
Project:
required:
- description
- id
- name
type: object
properties:
id:
type: integer
description: id project
name:
type: string
description: Имя проекта
nullable: false
description:
type: string
description: Описание проекта
nullable: false
example:
id: 1
name: Пафос и Превозмогание
description: Прожать батоны и вперед!!!
ProgectsList:
type: object
properties:
items:
type: array
description: Список существующих проектов
nullable: false
items:
$ref: '#/components/schemas/Project'
example:
items:
- id: 1
name: Пафос и Превозмогание
description: Прожать батоны и вперед!!!
- id: 1
name: Пафос и Превозмогание
description: Прожать батоны и вперед!!!
Task:
required:
- description
- id
- isDone
- name
- projectID
- priority
type: object
properties:
id:
type: integer
description: id task
name:
type: string
description: Имя задачи
nullable: false
description:
type: string
description: Описание задачи
nullable: false
priority:
type: integer
description: приоритет задачи
nullable: false
isDone:
type: boolean
description: Флаг о выполнении задачи
nullable: false
projectID:
type: integer
description: id task
nullable: false
example:
id: 1
name: 10к подписчиков
description: Прожать батоны и вперед!!!
isDone: false
projectID: 1
priority: 3
TasksList:
type: object
properties:
items:
type: array
description: Список существующих проектов
nullable: false
items:
$ref: '#/components/schemas/Task'
example:
items:
- id: 1
name: 10к подписчиков
description: Прожать батоны и вперед!!!
isDone: false
projectID: 1
- id: 1
name: 10к подписчиков
description: Прожать батоны и вперед!!!
isDone: false
projectID: 1

Binary file not shown.

View File

@@ -0,0 +1,19 @@
package calculator
import "math"
func Add(a, b int) int {
return a + b
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Pow2(a int) int {
return int(math.Pow(float64(a), 2))
}

View File

@@ -0,0 +1,3 @@
module golang/testing
go 1.19

View File

@@ -0,0 +1,13 @@
package main
import (
"fmt"
calc "golang/testing/calculator"
)
func main() {
fmt.Println(calc.Add(4, 2)) // 6
fmt.Println(calc.Sub(23, 12)) // 11
fmt.Println(calc.Mul(5, 6)) // 30
fmt.Println(calc.Pow2(5)) // 25
}

View File

@@ -0,0 +1,38 @@
package test_test
import (
calc "golang/testing/calculator"
"testing"
)
func TestAdd(t *testing.T) {
result := calc.Add(2, 5)
expected := 7
if result != expected {
t.Errorf("result %d, expected %d", result, expected)
}
}
func TestSub(t *testing.T) {
result := calc.Sub(15, 5)
expected := 10
if result != expected {
t.Errorf("result %d, expected %d", result, expected)
}
}
func TestMul(t *testing.T) {
result := calc.Mul(3, 6)
expected := 18
if result != expected {
t.Errorf("result %d, expected %d", result, expected)
}
}
func TestPow2(t *testing.T) {
result := calc.Pow2(3)
expected := 9
if result != expected {
t.Errorf("result %d, expected %d", result, expected)
}
}

View File

@@ -0,0 +1,19 @@
package calculator
import "math"
func Add(a, b int) int {
return a + b
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Pow2(a int) int {
return int(math.Pow(float64(a), 2))
}

View File

@@ -0,0 +1,3 @@
module golang/testing
go 1.19

View File

@@ -0,0 +1,13 @@
package main
import (
"fmt"
calc "golang/testing/calculator"
)
func main() {
fmt.Println(calc.Add(4, 2)) // 6
fmt.Println(calc.Sub(23, 12)) // 11
fmt.Println(calc.Mul(5, 6)) // 30
fmt.Println(calc.Pow2(5)) // 25
}

View File

@@ -0,0 +1,70 @@
package test_test
import (
calc "golang/testing/calculator"
"testing"
)
type testData struct {
arg1, arg2, expected int
}
type testPowData struct {
arg, expected int
}
func TestAdd(t *testing.T) {
cases := []testData{
{2, 3, 5},
{10, 5, 15},
{-8, -3, -11},
}
for _, it := range cases {
result := calc.Add(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestSub(t *testing.T) {
cases := []testData{
{2, 3, -1},
{10, 5, 5},
{-8, -3, -5},
}
for _, it := range cases {
result := calc.Sub(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestMul(t *testing.T) {
cases := []testData{
{2, 3, 6},
{10, 5, 50},
{-8, -3, 24},
}
for _, it := range cases {
result := calc.Mul(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestPow2(t *testing.T) {
cases := []testPowData{
{2, 4},
{-2, 4},
{3, 9},
}
for _, it := range cases {
result := calc.Pow2(it.arg)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}

View File

@@ -0,0 +1,19 @@
package calculator
import "math"
func Add(a, b int) int {
return a + b + 1
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Pow2(a int) int {
return int(math.Pow(float64(a), 2))
}

View File

@@ -0,0 +1,3 @@
module golang/testing
go 1.19

View File

@@ -0,0 +1,13 @@
package main
import (
"fmt"
calc "golang/testing/calculator"
)
func main() {
fmt.Println(calc.Add(4, 2)) // 6
fmt.Println(calc.Sub(23, 12)) // 11
fmt.Println(calc.Mul(5, 6)) // 30
fmt.Println(calc.Pow2(5)) // 25
}

View File

@@ -0,0 +1,76 @@
package test_test
import (
"fmt"
calc "golang/testing/calculator"
"testing"
)
type testData struct {
arg1, arg2, expected int
}
type testPowData struct {
arg, expected int
}
func TestAdd(t *testing.T) {
cases := []testData{
{2, 3, 5},
{10, 5, 15},
{-8, -3, -11},
}
for _, it := range cases {
t.Run(
fmt.Sprintf("%d+%d=%d", it.arg1, it.arg2, it.expected), // имя подтеста
func(t *testing.T) { // подтест
result := calc.Add(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
},
)
}
}
func TestSub(t *testing.T) {
cases := []testData{
{2, 3, -1},
{10, 5, 5},
{-8, -3, -5},
}
for _, it := range cases {
result := calc.Sub(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestMul(t *testing.T) {
cases := []testData{
{2, 3, 6},
{10, 5, 50},
{-8, -3, 24},
}
for _, it := range cases {
result := calc.Mul(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestPow2(t *testing.T) {
cases := []testPowData{
{2, 4},
{-2, 4},
{3, 9},
}
for _, it := range cases {
result := calc.Pow2(it.arg)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}

View File

@@ -0,0 +1,19 @@
package calculator
import "math"
func Add(a, b int) int {
return a + b + 1
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Pow2(a int) int {
return int(math.Pow(float64(a), 2))
}

View File

@@ -0,0 +1,15 @@
package calculator
import "testing"
func BenchmarkMul(b *testing.B) {
for i := 0; i < b.N; i++ {
Mul(5, 10)
}
}
func BenchmarkPow2(b *testing.B) {
for i := 0; i < b.N; i++ {
Pow2(5)
}
}

View File

@@ -0,0 +1,41 @@
package calculator
import (
"testing"
)
type testData struct {
arg1, arg2, expected int
}
type testPowData struct {
arg, expected int
}
func TestSub(t *testing.T) {
cases := []testData{
{2, 3, -1},
{10, 5, 5},
{-8, -3, -5},
}
for _, it := range cases {
result := Sub(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestPow2(t *testing.T) {
cases := []testPowData{
{2, 4},
{-2, 4},
{3, 9},
}
for _, it := range cases {
result := Pow2(it.arg)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}

View File

@@ -0,0 +1,3 @@
module golang/testing
go 1.19

View File

@@ -0,0 +1,13 @@
package main
import (
"fmt"
calc "golang/testing/calculator"
)
func main() {
fmt.Println(calc.Add(4, 2)) // 6
fmt.Println(calc.Sub(23, 12)) // 11
fmt.Println(calc.Mul(5, 6)) // 30
fmt.Println(calc.Pow2(5)) // 25
}

View File

@@ -0,0 +1,19 @@
package calculator
import "math"
func Add(a, b int) int {
return a + b + 1
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Pow2(a int) int {
return int(math.Pow(float64(a), 2))
}

View File

@@ -0,0 +1,41 @@
package calculator
import (
"testing"
)
type testData struct {
arg1, arg2, expected int
}
type testPowData struct {
arg, expected int
}
func TestSub(t *testing.T) {
cases := []testData{
{2, 3, -1},
{10, 5, 5},
{-8, -3, -5},
}
for _, it := range cases {
result := Sub(it.arg1, it.arg2)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}
func TestPow2(t *testing.T) {
cases := []testPowData{
{2, 4},
{-2, 4},
{3, 9},
}
for _, it := range cases {
result := Pow2(it.arg)
if result != it.expected {
t.Errorf("result %d, expected %d", result, it.expected)
}
}
}

View File

@@ -0,0 +1,3 @@
module golang/testing
go 1.19

View File

@@ -0,0 +1,13 @@
package main
import (
"fmt"
calc "golang/testing/calculator"
)
func main() {
fmt.Println(calc.Add(4, 2)) // 6
fmt.Println(calc.Sub(23, 12)) // 11
fmt.Println(calc.Mul(5, 6)) // 30
fmt.Println(calc.Pow2(5)) // 25
}

36
part_11/11.6/1.go Normal file
View File

@@ -0,0 +1,36 @@
package main
import (
"fmt"
"github.com/jaswdr/faker"
)
func main() {
faker := faker.New()
fmt.Println("----------Names----------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Person().Name())
}
fmt.Println("----------Beer----------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Beer().Name())
}
fmt.Println("----------Address----------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Address().Address())
}
fmt.Println("----------Country----------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Address().Country())
}
fmt.Println("----------Email----------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Internet().Email())
}
fmt.Println("-----Phone Number--------")
for i := 0; i < 3; i++ {
fmt.Println(faker.Phone().Number())
}
}

14
part_2/2.5.1/1.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "fmt"
func main() {
t := 20
if t >= 30 {
fmt.Println("Надеть шорты")
} else {
fmt.Println("Надеть брюки")
}
}
// Надеть брюки

13
part_2/2.5.1/2.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
func main() {
sun := true // поменяйте на false и снова запустите приложение
if !sun {
fmt.Println("Взять зонт")
}
fmt.Println("Выйти на улицу")
}
// Выйти на улицу

18
part_2/2.5.1/3.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import "fmt"
func main() {
var value int = 15
if value > 0 && value < 10 {
fmt.Println("Число входит в диапазон от 0 до 10")
} else if value > 10 && value < 20 {
fmt.Println("Число входит в диапазон от 10 до 20")
} else if value > 20 && value < 30 {
fmt.Println("Число входит в диапазон от 20 до 30")
} else {
fmt.Println("Значение > 30")
}
}
// Число входит в диапазон от 10 до 20

22
part_2/2.5.1/4.go Normal file
View File

@@ -0,0 +1,22 @@
package main
import "fmt"
func main() {
var value int = 15
if value > 30 {
if value < 50 {
fmt.Println("30 < value < 50")
} else {
fmt.Println("30 < value >= 50")
}
} else {
if value > 10 {
fmt.Println("30 >= value >= 10")
} else {
fmt.Println("30 >= value < 10")
}
}
}
// 30 >= value >= 10

13
part_2/2.5.1/5.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
func main() {
if value := 15; value > 30 {
fmt.Println("30 < value")
} else {
fmt.Println("30 >= value")
}
}
// 30 >= value

19
part_2/2.5.2/1.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import "fmt"
func main() {
value := 2
switch value {
case 2:
fmt.Println("2")
fmt.Printf("%d + 2 = %d", value, value+2)
case 4:
fmt.Println("4")
default:
fmt.Println("8")
}
}
// 2
// 2 + 2 = 4

20
part_2/2.5.2/2.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import "fmt"
func main() {
value := 2
switch value := 4; value {
case 2:
fmt.Println("2")
fmt.Printf("%d + 2 = %d", value, value+2)
case 4:
fmt.Println("4")
default:
fmt.Println("8")
}
fmt.Printf("value = %d", value)
}
// 4
// value = 2

15
part_2/2.5.2/3.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
name := "Alex"
switch name {
case "Stanislav":
fmt.Println("Admin")
case "Maxim", "Alex", "Bill":
fmt.Println("Employee")
}
}
// Employee

17
part_2/2.5.2/4.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "fmt"
func main() {
name := "Stanislav"
switch name {
case "Stanislav":
fmt.Println("Admin")
fallthrough
case "Maxim", "Alex", "Bill":
fmt.Println("Employee")
}
}
// Admin
// Employee

17
part_2/2.5.2/5.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "fmt"
func main() {
name := "Stanislav"
switch name {
case "Stanislav":
fmt.Println("Admin")
break
fallthrough
case "Maxim", "Alex", "Bill":
fmt.Println("Employee")
}
}
// Admin

25
part_2/2.5.2/6.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import "fmt"
func main() {
var value int = 5
switch {
case value > 30:
switch {
case value < 50:
fmt.Println("30 < value < 50")
default:
fmt.Println("30 < value >= 50")
}
case value < 30:
switch {
case value > 10:
fmt.Println("30 >= value >= 10")
default:
fmt.Println("30 >= value < 10")
}
}
}
// 30 >= value < 10

10
part_2/2.6/1.go Normal file
View File

@@ -0,0 +1,10 @@
package main
import "fmt"
func main() {
value := 2
for i := 0; i < 10; i++ {
fmt.Printf("%d * %d = %d\n", value, i, value*i)
}
}

19
part_2/2.6/2.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"strconv"
)
func main() {
str := ""
i := 0
for {
str += strconv.Itoa(i)
if i >= 5 {
break
}
i++
}
fmt.Println(str) // 012345
}

16
part_2/2.6/3.go Normal file
View File

@@ -0,0 +1,16 @@
package main
import (
"fmt"
"strconv"
)
func main() {
str := ""
i := 0
for i <= 5 {
str += strconv.Itoa(i)
i++
}
fmt.Println(str) // 012345
}

14
part_2/2.6/4.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "fmt"
func main() {
i := 13
for i > 0 {
i--
if i%2 == 0 {
continue
}
fmt.Printf("%d ", i)
}
}

27
part_2/2.6/5.go Normal file
View File

@@ -0,0 +1,27 @@
package main
import "fmt"
func main() {
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
if i == j {
continue
}
fmt.Printf("%d %d || ", i, j)
}
}
// 0 1 || 0 2 || 1 0 || 1 2 ||
fmt.Println()
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
if i == j {
break
}
fmt.Printf("%d %d || ", i, j)
}
}
fmt.Println("Oo")
// 1 0 || Oo
}

11
part_2/2.6/6.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
array := [4]int{2, 5, 6, 0}
for i := 0; i < len(array); i++ {
array[i] += 3
fmt.Printf("%d ", array[i])
}
}

14
part_2/2.6/7.go Normal file
View File

@@ -0,0 +1,14 @@
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]
}

11
part_2/2.6/8.go Normal file
View File

@@ -0,0 +1,11 @@
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]
}

15
part_2/2.6/9.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
myMap := map[int]string{
1: "Alex",
2: "Maxim",
200: "Jon",
}
for i, v := range myMap {
fmt.Printf("key = %d, value = %s\n", i, v)
}
}

11
part_2/2.7/1.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
fmt.Println(1) // 1
goto myLable
fmt.Println(2)
myLable: // метка для безусловного перехода
fmt.Println(3) // 3
}

16
part_2/2.7/2.go Normal file
View File

@@ -0,0 +1,16 @@
package main
import "fmt"
func main() {
test()
fmt.Println(1)
goto myLable
fmt.Println(2)
myLable:
fmt.Println(3)
}
func test() {
goto myLable // error: label myLable not defined
}

10
part_2/2.7/3.go Normal file
View File

@@ -0,0 +1,10 @@
package main
import "fmt"
func main() {
myLable: // бесконечный цикл
fmt.Println(1)
goto myLable
fmt.Println(2)
}

15
part_3/3.1/1.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
hello() // вызов функции hello
fmt.Println("exit")
}
func hello() {
fmt.Println("Hello World!")
}
// Hello World!
// exit

15
part_3/3.1/2.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
add(3, 5)
}
func add(a int, b int) {
fmt.Println(a + b) // 8
}
// func add(a, b int) {
// fmt.Println(a + b)
// }

13
part_3/3.1/3.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
func main() {
userInfo(3, 5, "Alex")
}
func userInfo(age, exp int, name string) {
fmt.Printf("User name: %s, age: %d, exp years: %d", name, age, exp)
}
// User name: Alex, age: 3, exp years: 5

11
part_3/3.1/4.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
fmt.Println(userInfo(3, 5, "Alex")) // User name: Alex, age: 3, exp years: 5
}
func userInfo(age, exp int, name string) string {
return fmt.Sprintf("User name: %s, age: %d, exp year: %d", name, age, exp)
}

24
part_3/3.1/5.go Normal file
View File

@@ -0,0 +1,24 @@
package main
import "fmt"
func main() {
rez, check := add(10, 8)
fmt.Printf("a + b = %d, a > b = %t", rez, check)
}
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
// }

17
part_3/3.1/6.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "fmt"
func main() {
rez, check := add(10, 8)
fmt.Printf("a + b = %d, a > b = %t", rez, check)
}
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

17
part_3/3.1/7.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "fmt"
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
}
return
}
// Sum = 32

14
part_3/3.1/8.go Normal file
View File

@@ -0,0 +1,14 @@
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
}

34
part_3/3.1/9.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"fmt"
"math/rand"
"time"
)
// генератор случайных чисел
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
}
func sliceCreator2(size int16) *[]int16 {
slice := make([]int16, size, size+10)
for i := range slice {
slice[i] += int16(generator.Int())
}
return &slice
}
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]
}

20
part_3/3.10/1.go Normal file
View File

@@ -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)
}
}

25
part_3/3.10/2.go Normal file
View File

@@ -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
}
}
}

12
part_3/3.11/1.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
defer fmt.Printf("%d ", i)
}
}
// Finish!
// 2 1 0

13
part_3/3.11/2.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
func main() {
defer fmt.Printf("%d ", 0)
defer fmt.Printf("%d ", 1)
defer fmt.Printf("%d ", 2)
fmt.Println("Finish!")
}
// Finish!
// 2 1 0

19
part_3/3.2/1.go Normal file
View File

@@ -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]

19
part_3/3.2/2.go Normal file
View File

@@ -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]

19
part_3/3.2/3.go Normal file
View File

@@ -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]

15
part_3/3.2/4.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
a, b, rez := 10, 13, 0
add(a, b, &rez)
fmt.Printf("%d + %d = %d\n", a, b, rez)
}
func add(a, b int, rez *int) {
*rez = a + b
}
// 10 + 13 = 23

35
part_3/3.2/5.go Normal file
View File

@@ -0,0 +1,35 @@
package main
import "fmt"
func find1(slice *[]int, value int, check *bool) {
*check = false
for i := range *slice {
if (*slice)[i] == value {
*check = true
break
}
}
}
func find2(slice *[]int, value int) bool {
for i := range *slice {
if (*slice)[i] == value {
return true
}
}
return false
}
func main() {
slice := []int{2, 4, 5, 7, 103, 55}
var check bool
value := 2
find1(&slice, value, &check)
fmt.Printf("%d contains in slice? %t\n", value, check)
value = 22
fmt.Printf("%d contains in slice? %t\n", value, find2(&slice, value))
}
// 2 contains in slice? true
// 22 contains in slice? false

18
part_3/3.3/1.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import "fmt"
func myFunc(value map[string]map[string][]int) {
fmt.Println(value)
}
func main() {
myMap := map[string]map[string][]int{
"a": {"a2": []int{2, 5, 3}},
"b": {"bbc": []int{0, 10, 3}},
"c": {"alex": []int{}},
}
myFunc(myMap)
}
// map[a:map[a2:[2 5 3]] b:map[bbc:[0 10 3]] c:map[alex:[]]]

20
part_3/3.3/2.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import "fmt"
type MyType map[string]map[string][]int
func myFunc(value MyType) {
fmt.Println(value)
}
func main() {
myMap := MyType{
"a": {"a2": []int{2, 5, 3}},
"b": {"bbc": []int{0, 10, 3}},
"c": {"alex": []int{}},
}
myFunc(myMap)
}
// map[a:map[a2:[2 5 3]] b:map[bbc:[0 10 3]] c:map[alex:[]]]

19
part_3/3.4/1.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import "fmt"
var global string = "Global value"
// global := "Global value" // так объявлять нельзя, будет ошибка
func myFunc() {
fmt.Println(global)
}
func main() {
fmt.Println(global)
myFunc()
}
// Global value
// Global value

18
part_3/3.4/2.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import "fmt"
var global string = "Global value"
func myFunc() {
global := 10
fmt.Println(global)
}
func main() {
fmt.Println(global)
myFunc()
}
// Global value
// 10

20
part_3/3.4/3.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import "fmt"
var global string = "Global value"
func myFunc() {
global := 10
fmt.Println(global)
}
func main() {
fmt.Println(global)
myFunc()
if true {
local := 20
fmt.Println(local)
}
local = 5 // undefined: local
}

23
part_3/3.4/4.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import "fmt"
var global string = "Global value"
func myFunc() {
global := 10
fmt.Println(global)
}
func main() {
fmt.Println(global) // Global value
local := 20
{
fmt.Println(local) // 20
{
local := 10
fmt.Println(local) // 10
}
fmt.Println(local) // 20
}
}

13
part_3/3.5/1.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
myFunc := add // var myFunc func(a int, b int) int = add
fmt.Println(add(3, 5)) // 8
fmt.Println(myFunc(3, 5)) // 8
}

17
part_3/3.6/1.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func sub(c, a, b int, addFunc func(a int, b int) int) int {
return c - addFunc(a, b)
}
func main() {
myFunc := add // var myFunc func(a int, b int) int = add
fmt.Println(sub(4, 3, 10, add)) // -9
fmt.Println(sub(4, 3, 10, myFunc)) // -9
}

19
part_3/3.6/2.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import "fmt"
type MyFunctionAdd func(a int, b int) int
func add(a, b int) int {
return a + b
}
func sub(c, a, b int, addFunc MyFunctionAdd) int {
return c - addFunc(a, b)
}
func main() {
myFunc := add // var myFunc func(a int, b int) int = add
fmt.Println(sub(4, 3, 10, add)) // -9
fmt.Println(sub(4, 3, 10, myFunc)) // -9
}

Some files were not shown because too many files have changed in this diff Show More