Перегрузка операторов и преобразования типов (C#)

Примеры перегрузки операторов

В данной рассматриваем примеры перегрузки операторов + и — в языке C#. Таким же образом можно перегрузить другие операторы, которые принимают два параметра.

Так же показываю как задать инструкцию явного преобразования типов из одного созданного класса в другой.

В коде ниже создано 2 класса: Vector и Coord. В классе Vector перегружены два бинарных оператора + и -.

В классе Coord объявлены только конструктор и два свойства X, Y, обозначающие координату.

С помощью инструкции public static explicit operator Coord(Vector v)  мы можем задать правило преобразования объекта класса Vector в объект класса Coord:

using System.IO;
using System;
using System.Text;

class Coord
{
  public int X {get;set;}
  public int Y {get;set;}
  
  public Coord(int x, int y)
  {
      this.X = x;
      this.Y = y;
  }
  
  public override string ToString()
  {
      return String.Format("Coord: X = {0}, Y = {1}", this.X, this.Y);
  }
}

class Vector
{
    //Объвляем автосвойства, чтобы не использовать public поля
  public int X {get;set;}
  public int Y {get;set;}

  public Vector(int x, int y)
  {
    this.X = x;
    this.Y = y;
  }

    //Оператор + принимает на вход 2 параметра
  public static Vector operator+(Vector v1, Vector v2)
  {
    return new Vector(v1.X + v2.X, v1.Y + v2.Y);
  }

    //Оператор - принимает на вход 2 параметра
  public static Vector operator-(Vector v1, Vector v2)
  {
    return new Vector(v1.X - v2.X, v1.Y - v2.Y);
  }

    //Переопределение метода ToString()
    public override string ToString()
    {
        return String.Format("Vector: X = {0}, Y = {1}", this.X, this.Y);
    }
    
    //Инструкция по явному преобразованию класса Vector в класс Coord
    //Вместо explicit можно написать implicit, тогда преобразование можно
    //будет делать неявным
    public static explicit operator Coord(Vector v)
    {
        return new Coord(v.X, v.Y);
    }
  
}

class Program
{
  static void Main()
  {
    Console.WriteLine("Start program.");
    Vector v1 = new Vector(10,20);
    Vector v2 = new Vector(15,50);
    Console.WriteLine(v1+v2);
    Console.WriteLine(v1-v2);
    //----------------------
    Coord c1 = new Coord(100,200);
    Console.WriteLine(c1); //Явное преобразование Vector в Coord
    Coord c2 = (Coord)(v1+v2);
    Console.WriteLine(c2);
  }
}

Результат работы программы:

Подключаемся к серверу MySQL через SSH для выполнения запросов (C#)

В данной записи показываю, как подключаться в MySQL через SSH с помощью C# и библиотеки Renci.SshNet
В среде Visual Studio (старше 2008) через систему управления пакетами Nuget добавляем библиотеку SshNet.
Добавляем библиотеку mysql.dll (Можно скачать connector на www.mysql.com).
Переходим к написанию кода. Объявляем SshClient:

private static SshClient client = new SshClient("120.20.20.20", "login_ssh", "password_ssh");

Настраиваем строку подключения к MySQL

Объявим строку подключения connBuilderIMSoverSSH и настроим ее:

private static MySqlConnectionStringBuilder connBuilderIMSoverSSH = new MySqlConnectionStringBuilder();

connBuilderIMSoverSSH.Server = "127.0.0.1";     //Текуший ПК
connBuilderIMSoverSSH.Port = 12140;               //Порт, который пробрасываем (Не обязательно такой. Можно пробросить любой свободный)
connBuilderIMSoverSSH.UserID = "login_mysql";
connBuilderIMSoverSSH.Password = "pass_mysql ";
connBuilderIMSoverSSH.Database = "Database_Name";

Пробрасываем порт для SSH

Проверяем, открыто ли подключение к SSH. Если не открыто, открываем:

if (!client.IsConnected)
{
  client.Connect();
  //Объявляем и инициализируем пробрасываемый порт
  ForwardedPortLocal port = new ForwardedPortLocal("127.0.0.1", 12140, "10.247.250.100", 3306);	//3306 - порт MySQL
  client.AddForwardedPort(port);
  //Открываем порт
  port.Start();
}

Выполняем запрос к MySQL через SSH

/// <summary>
/// Выбирает данные из новой системы через SSH
/// </summary>
/// <param name="query">Запрос</param>
/// <returns></returns>
public DataTable ExecuteSqlOverSSH(string query)
{
  DataTable table = new DataTable();
  //Открываем соединение с MySQL
  using (var sql = new MySqlConnection(connBuilderIMSoverSSH.ConnectionString))
  {
    sql.Open();
    var cmd = sql.CreateCommand();
    cmd.CommandTimeout = 600;
    cmd.CommandText = query;
    var rdr = cmd.ExecuteReader();
    table.Load(rdr);
  }

  return table;
}

В итоге мы получили функцию, которая возвращает результат запроса в БД MySQL через SSH в виде DataTable.

Заполнение квадратной матрицы по спирали (Python)

Как заполнить матрицу по спирали

В этой записи я продемонстрирую заполнение квадратной матрицы по спирали на языке Python. Использован Python версии 3.6

#n - размерность матрицы n x n
#mat - результирующая матрица
#st - текущее значение-счетчик для записи в матрицу
#m - коеффициент, используемый для заполнения верхней
#матрицы последующих витков, т.к. одномерные матрицы
#следующих витков имеют меньше значений
n = int(input())
mat = [[0]*n for i in range(n)]
st, m = 1, 0

# Заранее присваиваю значение центральному элементу
# матрицы
mat[n//2][n//2]=n*n

for v in range(n//2):
    #Заполнение верхней горизонтальной матрицы
    for i in range(n-m):
        mat[v][i+v] = st
        st+=1
        #i+=1
    #Заполнение правой вертикальной матрицы    
    for i in range(v+1, n-v):
        mat[i][-v-1] = st
        st+=1
        #i+=1
    #Заполнение нижней горизонтальной матрицы
    for i in range(v+1, n-v):
        mat[-v-1][-i-1] =st
        st+=1
        #i+=1
    #Заполнение левой вертикальной матрицы
    for i in range(v+1, n-(v+1)):
        mat[-i-1][v]=st
        st+=1
        #i+=1
    #v+=1
    m+=2

#Вывод результата на экран
for i in mat:
    print(*i)

Коротко объясню, для чего нужна переменная m. Обратите внимание на результирующую матрицу при n = 5:

matrix

Начиная со значения 17 мы заполняем новый виток до значения 19. То есть, имеем всего 3 значения: 17, 18, 19.
Для этого и используется коэффициент m, чтобы заново не штудировать все 5 значений.

Работа с анимацией в Android (Java, XML)

В данном посте рассматривается работа с анимацией в Android.

Для начала необходимо в папке Res создать папку anim и выбрать Resource type anim. Затем добавлять файлы Animation Resourse File в эту папку.

Далее рассмотрим примеры анимаций.

Анимация прозрачности

<?xml version="1.0" encoding="utf-8"?>
<alpha
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromAlpha="0.0"
  android:toAlpha="1.0"
  android:duration="3000">
</alpha>

Анимация перемещения

<?xml version="1.0" encoding="utf-8"?>
<translate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXDelta="-150"
  android:toXDelta="0"
  android:fromYDelta="-200"
  android:toYDelta="0"
  android:duration = "3000">
</translate>

Анимация поворота

<?xml version="1.0" encoding="utf-8"?>
<rotate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromDegrees="0"
  android:toDegrees="360"
  android:duration = "3000">
</rotate>

Анимация масштабирования

<?xml version="1.0" encoding="utf-8"?>
<scale
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXScale="0.1"
  android:toXScale="1.0"
  android:fromYScale="0.1"
  android:toYScale="1.0"
  android:pivotX="50%"
  android:pivotY="50%"
  android:duration="3000">

Использование сразу нескольких эффектов анимаций

Объединяем анимации разворота и масштабирования:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <rotate
    android:fromDegrees="0"
    android:toDegrees="360"
    android:duration="3000"
    android:pivotY="50%"
    android:pivotX="50%">
  </rotate>
  <scale
    android:fromXScale="0.1"
    android:toXScale="1.0"
    android:fromYScale="0.1"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="3000">
  </scale>
</set>

Запуск анимации через контекстное меню

В приведенном ниже коде описанные анимации запускаются через контекстное меню:

package razilov.ru;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

  private TextView textView;

  private final int MENU_ALPHA_ID = 1;
  private final int MENU_SCALE_ID = 2;
  private final int MENU_TRANSLATE_ID = 3;
  private final int MENU_ROTATE_ID = 4;
  private final int MENU_COMBO_ID = 5;

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    switch (v.getId()){
      case R.id.textView:
      menu.add(0, MENU_ALPHA_ID, 0, "Alpha");
      menu.add(0, MENU_SCALE_ID, 0, "Scale");
      menu.add(0, MENU_TRANSLATE_ID, 0, "Translate");
      menu.add(0, MENU_ROTATE_ID, 0, "Rotate");
      menu.add(0, MENU_COMBO_ID, 0, "Combo");
    }
    super.onCreateContextMenu(menu, v, menuInfo);
  }

//Работа с анимацией
  @Override
  public boolean onContextItemSelected(MenuItem item) {
    Animation anim = null;

    switch (item.getItemId()){
      case MENU_ALPHA_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myalpha);
      break;
      case MENU_SCALE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myscale);
      break;
      case MENU_TRANSLATE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.mytrans);
      break;
      case MENU_ROTATE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myrotate);
      break;
      case MENU_COMBO_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.mycombo);
      break;
    }

    textView.startAnimation(anim);
    return super.onContextItemSelected(item);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView)findViewById(R.id.textView);
    registerForContextMenu(textView);
  }
}

Код очень простой. Если есть вопросы, задавайте.

Результат приведенного кода привожу по ссылке.

Программное добавление элементов в Android (Java)

В этой статье разбираемся как осуществить программное добавление элементов в Android. В следующем фрагменте кода показано объявление элементов, настройка их параметров и отображение их в LinearLayout.

Добавляем элементы в активити из кода

Привожу пример программного добавления элементов:

package razilov.ru;

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        ViewGroup.LayoutParams linLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        setContentView(linearLayout, linLayoutParams);


        ViewGroup.LayoutParams lpView = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        TextView tv = new TextView(this);
        tv.setText("TextView");
        tv.setLayoutParams(lpView);
        linearLayout.addView(tv);

        Button btn = new Button(this);
        btn.setText("Button");
        linearLayout.addView(btn, lpView);

        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.leftMargin = 50;

        Button btn1 = new Button(this);
        btn1.setText("Btn1");
        linearLayout.addView(btn1, layoutParams);

        LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams1.gravity = Gravity.RIGHT;

        Button btn2 = new Button(this);
        btn2.setText("btn2");
        linearLayout.addView(btn2, layoutParams1);

    }
}

Функция addView добавляет элемент в контрол.

Отображение переменных из конфигурационного файла (Smarty)

В папке configs создаем конфигурационный файл.
Например myconf.conf .

В нем пишем:

#Это просто комментарий
sitename = ‘My new WebSite’
author = ‘Nickolay Razilov’

В *.tpl файле в самом начале прописываем:

{config_load file=’myconf.conf’}

Отображаем переменные из myconf.conf в файле *.tpl:

Site name is {#sitename#} and author is {#author#}.

Установка Smarty

В папке с сайтом создаем 4 папки:

  1. cache
  2. configs
  3. templates
  4. templates_c

Скачиваем Smarty и копируем папку libs из архива со Smarty
в папку с сайтом. Для удобства можно переименовать libs в lib.

В php файле прописываем:

include_once «lib/smarty.class.php»;     //подключаем файл с классом Smarty
$smarty = new Smarty();                       //создаем объект smarty

Установка завершена. Проверяем.

$smarty->assign(‘name_var’, $name_var);    //передача параметров (Название переменной в  первом параметре и значение этой переменной во втором параметре).

$smarty->display(‘index.tpl’);                         //отображение шаблона  index.tpl (должен лежать в папке templates)

В шаблоне index.tpl пишем:

{$name_var}   —  нам отобразится переменная, заданная в файле index.php


/openmp (включение поддержки OpenMP 2.0)

Установка данного параметра компилятора в среде разработки Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Дополнительные сведения см. в разделе Открытие свойств страниц проекта.
  2. Разверните узел Свойства конфигурации.
  3. Разверните узел C/C++.
  4. Выберите страницу свойств Язык.
  5. Измените значение свойства Поддержка OpenMP.