Методы: передача аргумента по ссылке

В C# по умолчанию в методы аргументы передаются по значению (т.е. информация из вне копируется внутрь метода). Если есть необходимость передать аргумент по ссылке, чтобы после применения метода значение передаваемого аргумента менялось не только внутри метода, но и за его пределами, есть специальное слово ref. В коде это выглядит так:

static void Sqr(ref int x) {
  x = x * x;
  }

static void Main() {
  int a = 3;
  Sqr(ref a);

  Console.WriteLine(a);
  }

// будет выведено 9

При использовании ref переменной должно быть присвоено значение до инициализации метода.

Если нужно без присвоения до инициализации, используем out.

Установка модулей через cmd

При команде «pip install chardet» командная строка выдавала ошибку с отказом в доступе. Решение оказалось простым — запускать cmd как администратор.

Находим cmd, кликаем правой кнопкой мыши, выбираем «Запустить от имени администратора».

Динамическая типизация в C#

Если заранее неизвестно к какому типу будет принадлежать переменная, в C# есть выход — ключевое слово var.

var num = 15; // сделает num integer
var num = "dabba"; // сделает num string

var num;
num = 15; // выведет ошибку, при использовании var надо сразу присваивать переменной значение

SQL-инъекции: подстановка кода вместо пароля

Логин: skroob
Пароль: 12345′ OR ‘1’ = 1

Если исходный код SQL-таблицы  такой, то будут проблемы:

$username = $_POST["username"];
$password = $_POST["password"];
query("SELECT * FROM users WHERE username = $username AND password = $password");

// в итоге при подстановке логина и пароля получаем:
// query("SELECT * FROM users WHERE username = 'skroob' AND password = '12345' OR '1' = '1'");
// '1' = '1', поэтому вход будет произведен.

Правильный код:

$username = $_POST["username"];
$password = $_POST["password"];
query("SELECT * FROM users WHERE username = ? AND password = ?", $username, $password);

// в таком случае при подстановке пароля одинарные кавычки будут отделены дробью /'/

Краткий условный оператор

В C# наряду с обычным условным оператором if есть краткий условный оператор. Выглядит так:

int y = 5;
string msg;
msg = (y >= 5) ? "Больше или равно" : "Меньше";
Console.WriteLine(msg);

// Будет выведено "Больше или равно"
// Код "msg = (y >= 5) ? "Больше или равно" : "Меньше";" равнозначен конструкции:

if (y >= 5) {
   msg = "Больше или равно";
   }
else {
   msg = "Меньше";
   }

Запись в список из словарей в цикле

Столкнулся с проблемой при записи новых данных в список из словарей.

При прогоне цикла через обычное копирование получалось что-то такое:

[{Ингредиент: Молоко, Количество: 500, Ед: г}]
[{Ингредиент: Яйца, Количество: 500, Ед: г}, {Ингредиент: Яйца, Количество: 500, Ед: г}]
[{Ингредиент: Творог, Количество: 500, Ед: г}, {Ингредиент: Творог, Количество: 500, Ед: г}, {Ингредиент: Творог, Количество: 500, Ед: г}]
etc

Конструкция ingredient[‘measure’] = ingredient_info[2] оказалось, что меняет по всем списке ingredient_list, содержащем словари, значения по ключу ‘measure’.

Решить проблему удалось через полное копирование списка ingredient в список «а» через a = copy.deepcopy(ingredient). Функция находится в библиотеке copy, которую надо импортировать.

import copy

def cook_book_collector(file_path):
	cook_book = {}
	with open(file_path) as menu: 
		for line in menu: # проходимся по строкам
			dish = line.strip() # 1 строка = название блюда			
			ingredient = {}	# словарь для информации по ингредиенту	
			ingredient_list = [] # список ингредиентов
			for ing_number in range(1, int(menu.readline().strip())+1): # запускаем цикл от 1 до N ингредиентов
				ingredient_info = menu.readline().strip() # читаем строку, затем разбиваем ее на список, затем заполняем словарь ингредиентов
				ingredient_info = ingredient_info.split(' | ')
				
				ingredient['ingridient_name'] = ingredient_info[0]
				ingredient['quantity'] = ingredient_info[1]
				ingredient['measure'] = ingredient_info[2]
				a = copy.deepcopy(ingredient) # копируем словарь в новую переменную, чтобы на строках выше потом не переписались все данные
				ingredient_list.append(a) # добавляем в конец списка инфу по каждому новому ингредиенту
								
			cook_book[dish] = ingredient_list
			menu.readline()
		return cook_book

Как добавить Python в PATH

Решение для Windows 10:

  1. Открываешь месторасположение python
  2. Находишь там python.exe, кликаешь правой кнопкой мыши —> Свойства
  3. Копируешь ПОЛНОСТЬЮ все, что написано в поле «Расположение»
  4. Заходишь в Мой компьютер, правой кнопкой мыши по свободному полю —> Свойства
  5. В левой колонке выбираешь «Дополнительные параметры системы»
  6. Там находишь в самом низу кнопку «Переменные окружения»
  7. В открывшемся окне будет 2 области. В любой находишь переменную Path, кликаешь —> Создать —> вставляешь скопированный путь.
  8. Нажимаешь OK, OK, … пока все не закроется.

Проверяем. Запускаем Консоль, вводим python, запуститься должен Python.

командная строка

Рекурсия

#include <cs50.h>
#include <stdio.h>

int sigma();

int main(void) 
{
    printf("Введите положительное целое число: ");
    int n = GetInt();
    printf("Сумма чисел от 0 до %i = %i\n", n, sigma(n));
}

int sigma(int k) // создаем рекурсивную функцию суммы от 0 до k
{
    if (k==0) return 0;
    
    return (k+sigma(k-1));
}

Бинарный поиск

bool search(int value, int values[], int n)
{
    // смотрим кол-во элементов в массиве, если деление на %2 дает остаток 0, значит, четное кол-во
    // иначе нечетное. Если четное - делим отсортированный массив на 2, смотрим последний элемент в левой части. Сравниваем с искомым.
    // Если нечетное, то вычитаем 1 элемент, делим на 2, смотрим последний элемент в левой части +1.
    // search(needle, haystack, size), где 1 - то, что ищем в массиве; 2 - массив; 3 - размер массива

    int a = 0; //начало массива
    int b = n-1; // конец массива
    int m = b-a; // длина выбранной части массива
    int centr, levo, pravo, i;
    int aa=values[0];
    int bb=values[n-1];
    
   if (aa<=value && bb>=value) 
   {
    do
    {
        float j = m%2; //для определения четного или нечетного
        if (j==0) //если нечетное кол-во элементов в массиве
        {
            centr = (b-a)/2+a;
            if (values[centr]>value)
            {
                b=centr-1;
            }
            else if ((values[centr]<value))
            {
                a=centr+1;
            }
            else return true;
        }
        else // если четное кол-во элементов в массиве
        {
            levo = (b-a+1)/2+a-1;
            pravo = (b-a+1)/2+a;
            if (values[levo]>=value)
            {
                b=levo;
            }
            else
            {
                a=pravo;
            }
        }
        m = b-a;
    
    printf("\na=%i b=%i\n", a, b);
    for (i=a;i<=b;i++)
    {
        printf("%i\n",values[i]);
    }
    
    }
    while (m!=0);
    
// запускаем последний этап проверки, т.к. если остался 1 элемент в конце m может быть равным 0 и цикл закончится

    if (values[a]==value) return true;
    else return false;
       
   }  else return false;
}