# Типы данных, переменные и операции

Любая наша программа состоит из каких-то данных и каких-то операций над ними. Это могут быть простые данные (примитивные) такие как строки, числа и тд, так и сложные, такие как дата, время и тд. В сегодняшнем уроке мы подробно поговорим о том как выглядят эти самые базовые типы данных и что мы можем делать с ними.

## Базовые типы данных

В Ruby у нас есть 4 базовых (примитивных) типа данных:

```ruby
'ruby is live' # строка (String). Записывается либо через одинарные кавычки (''), либо через двойные ("")
321321 # целое число (Integer). Позволяет нам также записать его с разделителем 321_321 для более удобного чтения
421.431 # Число с плавающей запятой (Float)
true # Логический тип данных (Boolean). Либо true, либо false
false # Логический тип данных (Boolean). Либо true, либо false
```

> `#` - служит для написания комментариев в коде. Эти комментарии служат подсказкой для разработчика, но в самой программе ничего, что есть в комментарии, выполняться не будет

## Переменные

Наши значения по ходу работы программы мы может записывать в специальные контейнеры, которые будут хранить в себе это значение. Такие контейнеры называют _переменные_ (Variable). Посмотрим на пример:

```ruby
string_var = 'string example' # строка (String)
another_string_var = 'string example v2' # строка (String)
integer_var = 125 # целое число (Integer)
negative_int_var = -13132 # целое отрицательное число (Integer)
float_var = 0.345 # Число с плавающей запятой (Float)
negative_float_var = -0.345 # отрицательное число с плавающей запятой (Float)
true_var = true # Логический тип данных (Boolean)
false_var = true # Логический тип данных (Boolean)
```

Как можно заметить переменные имеют имена, которые ты как разработчик можешь придумать самостоятельно. Единственное что нельзя делать - называть переменные словами, которые зарезервированы системой. Список слов [тут](https://www.geeksforgeeks.org/ruby-keywords/).

Сразу запоминаем правила:

* переменные всегда пишем на английском
* всегда маленькими буквами
* если переменная состоит из 2 слов, то соединяем из нижним подчеркиванием `_` (это называется _snake case_)

Но что можно делать с этим ? Давайте разберем

## Операции

Начнем с базовых математических операций. Что можно делать с числами ? Все тоже самое. что и в математике: умножать, складывать, вычитать и тд.

```ruby
sum = 20 + 50 # = 70. Обычная операция сложения. Также есть операция вычитания (-), умножения (*), деления (/) и тд.
first = 100
second = 13
result = first - second # = 87. Все что мы можем делать напрямую с числами, мы можем делать и с переменными. Переменные просто скрывают значение за каким-то названием
difficult_math = (35 + 10) / 5 # = 9. Все как в математике. Сначала в скобках происходит вычисление, потом уже с результатом этого вычесления. Соответсвенно если скобки убрать, то сначала будет выполнено деление
```

В данном примере мы складывали простые числа. А теперь попробуем сложить целые числа и дробные.

```ruby
some_float = 0.4566
some_int = 100
int_and_float = some_int + some_float
puts int_and_float # = 100.4566
```

Как можем заметить, при сложении дробного и целого числа мы получаем новое **дробное** число. Важно запомнить, что при математических операциях где хоть одно из чисел является дробным мы получим новое **дробное** число. Возможно возникнет вопрос: а что тут важного ? Давайте посмотрим на деление одного целого числа на другое.

```ruby
int_devision = 5 / 2 
puts int_devision # = 2
```

Первое, что мы заметим, результат нашей операции не является дробное число. Если мы совершаем математическую операцию между двумя **целыми** числами, то и получаем **целое** число.

Второе, что мы заметим, здесь не работает правило округления как в математике. Если мы вспомним математическое правило, то при остатке от деления больше, чем `0.4` число должно округлиться до ближайшего числа в большую сторону. Ruby вместо этого просто напросто отбрасывает дробную часть как будто ее и нет вовсе. Как же тогда нам получить верное значение ? Для этого воспользуется правилом выше. Нам необходимо, чтобы хотя бы одно из чисел было дробным.

```ruby
int_devision = 5 / 2.0 
puts int_devision # = 2.5
```

или тоже самое, но уже через переменные

```ruby
divisible = 5
divider = 2
int_devision = divisible / divider.to_f
puts int_devision # = 2.5
```

В примере выше мы воспользовались функцией `.to_f`, которая превратит наше натуральное число в дробное, что позволит нам получить верное значение. Если вам по какой то причине нужна возможность округлять числа в ту или иную сторону, то можно воспользоваться следующими функциями:

* `.round` - округление по правилам математики
* `.ceil` - округление числа в большую сторону
* `.floor` - коругление числа в меньшую сторону

```ruby
some_float = 2.5
puts some_float.round # = 3
puts some_float.floor # = 2
puts (some_float - 0.4).ceil # = (2.5 - 0.4) = 2.1 => ceil => 3
```

Помимо числовых операций мы также можем манипулировать и строками. Если при сложении чисел мы получаем их сумму, то при сложении строк мы получаем объединенную новую строку.

```ruby
hello_str = 'Hello'
world_str = 'world'
hello_world_str = hello_str + ' ' + world_str # = Hello world. В случае со строками сложение работает уже по другому. Сложение для строк это объединение строк
```

В некоторых языках программирования существует невидимое преобразование числа в строку при попытке сложить его с другой строкой, но в Ruby это не работает

```ruby
concat_str = "It is a " + 100 # Появится ошибка о невозможности конвертировать Integer в String.
```

Для того, чтобы решить эту проблему нам необходимо явно превращать наше число в строку с помощью функции `.to_s`

```ruby
concat_str = "It is a " + 100.to_s
puts concat_str # = It is a 100
```

Но вызывать каждый раз функцию `.to_s` банально неудобно, да и не принято в сообществе. Самым простым способом для сложение строк - использование _интерполяции_ строк. Она позволяет нам вставлять любое значение внутрь строки используя синтаксис `#{}`, в котором мы можем размещать любые значения, будь то числа или даже какое то вычисление, при этом сам Ruby вызовет у конечного результата метод `.to_s`. Главное правило для интерполяции - использование двойных кавычек, а не одинарных.

```ruby
some_int = 1000
concat_str = "It is a #{some_int}" # при использовании интерполяции Ruby невидимо для нас вызывает .to_s фкнкцию
puts concat_str # = It is a 100
```

Помимо этого мы можем изменять значение в одной и той же переменной

```ruby
change_word = 'Hi'
puts change_word # = Hi
change_word = 'Bye'
puts change_word # = Bye
```

Или даже можем менять значения разных типов данных (что делать не рекомендуется во избежание запутанности кода)

```ruby
some_value = 150
puts some_value # = 150
some_value = 'Hello'
puts some_value # = Hello
```

### Задание greeting

* попросите пользователя ввести свое имя в консоль и запишите его в переменную с помощью [gets](https://www.rubyguides.com/2019/10/ruby-chomp-gets/)
* Распечатайте в консоль сообщение `Hi, имя_пользователя`

#### Дополнительный материал

* [gets](https://www.rubyguides.com/2019/10/ruby-chomp-gets/)
* [арифметика в ruby](https://www.freecodecamp.org/news/ruby-number-methods-integer-and-float-methods-with-examples/)
* [интерполяция строк](https://www.rubyguides.com/2019/07/ruby-string-concatenation/)
