Пишем класс, описывающий рациональные дроби (C#)

Рациональные дроби

Рациональные дроби — это числа, представляемые обыкновенной дробью с числителем и знаменателем.

Рациональные дроби

В данной статье выкладываю код, который я написал для реализации класса рациональных дробей. Это было одно из заданий для получения сертификата курса проектирования на C#.

В представленном листинге ниже реализован данный класс:

Показать текст ->

В классе описаны методы выполнения арифметический операций с рациональными дробями:

  • Сложение и вычитание дробей через НОЗ (наименьший общий знаменатель);
  • Умножение и деление дробей;
  • Умножение дроби на число;
  • Преобразование числа к рациональной дроби (любое число это рациональная дробь, где взятое число делится на 1);
  • Преобразование рациональной дроби к десятичной;
  • Описаны функции нахождения НОЗ и сокращения рациональной дроби.

Настройка майнинга XMR на Linux Fedora (Пул minergate.com)

Майнинг XMR на Fedora.

В данной заметке запускаем майнинг XMR на Fedora, используя сервис Minergate.com через CPU майнер minerd.

Майнер будет браться с GitHub и компилироваться. Git должен быть уже установлен, если у вас нету Git, установить можно так:

yum install git

Далее устанавливаем необходимые пакеты:

yum install -y cpp make automake gcc libcurl-devel openssl-devel

Клонируем репозиторий с GitHub:

git clone https://github.com/wolf9466/cpuminer-multi

Выполняем команды в терминале:

cd cpuminer-multi
./autogen.sh
CFLAGS="-march=native"
./configure
make
make install

Запускаем майнинг

Лично мне пригодилась следующая команда для запуска:

minerd -a cryptonight -o stratum+tcp://xmr.pool.minergate.com:45560 -u MY_EMAIL -p 4

Пример выполнения команды:

Майнинг XMR на Fedora

Список команд для запуска можно взять здесь.

На данном сайте есть статья о запуске майнинга на Linux Ubuntu.

Выгрузка больших объемов данных из Oracle БД и заливка в MySQL (Python)

Недавно понадобилось перелить большие объемы данных из БД Oracle в MySQL для последующего анализа. Задача решалась с помощью Python.

Строился sql запрос к таблицам Oracle для выгрузки данных в курсор, и затем, построчно пробегая по курсору, данные заливались в MySQL.

Подготовка модулей pymysql, sshtunnel и cx_Oracle

Для работы с MySQL понадобилось установить модуль pymysql, и модуль sshtunnel, так как подключение находилось за SSH. Для работы с Oracle был установлен модуль cx_Oracle и скачан Oracle Instant Client с сайта Oracle (может понадобиться указать путь к распакованному архиву в переменной среды PATH и перезагрузить компьютер). Так же необходимо иметь актуальные версии Microsoft Visual C++ Redistributable (в моем случае версии 2013).

Устанавливаем модули (через cmd от имени администратора):

pip3 install pymysql

pip3 install sshtunnel

pip3 install cx_Oracle

Переливаем данные из Oracle в MySQL

Работаем со следующим кодом:

import cx_Oracle
import pymysql
import datetime
import os
import sshtunnel

#Если работаем с ОС Windows, то задаем переменную NLS_LANG = .AL32UTF8
#чтобы избежать проблем с кириллицей
if(os.name == 'nt'):
    os.environ['NLS_LANG'] = '.AL32UTF8'

#Объявляем переменные типа даты для последующего цикла (строка 51)
startdate = datetime.datetime.now().date() - datetime.timedelta(days=2)
enddate = datetime.datetime.now().date() - datetime.timedelta(days=1)

insert_query = ("replace into resultTable "
             "(name, date, mainData, count, sumvalues) "
             "values (%s, %s, %s, %s, %s)")

#Создаем подключение к MySQL и инициализируем объект курсора             
db = pymysql.connect(passwd="pass11",db="data",host="serv3", user="root")
cur = db.cursor()

#Создаем подключение к Oracle и инициализируем объект курсора
oracleDb = cx_Oracle.connect("username/password@10.250.100.100/servicename")
oraclesCursor = oracleDb.cursor()

ora_query='''
select * from oracleData
where date between to_date('{0} 00:00:00','dd.mm.yyyy hh24:mi:ss') and to_date('{0} 23:59:59','dd.mm.yyyy hh24:mi:ss')
'''

#Строим SSH туннель
#Здесь пробрасываем порт 12140
#Можно пробросить любой свободный
with sshtunnel.SSHTunnelForwarder(
        ('ssh_address', 22),
        ssh_username='ssh_username',
        ssh_password='ssh_password',
        remote_bind_address=('mysql_address', 3306),
        local_bind_address=('127.0.0.1', 12140)
) as tunnel:
    conn = MySQLdb.connect(
        user='root',
        password='password123',
        host='127.0.0.1',
        database='Db_Name',
        port=12140)
    curss = conn.cursor()
    
    startdate_oracle_temp = startdate

    #Формируем цикл по дате. Один оборот цикла обрабатывает один день
    while startdate_oracle_temp <= enddate:
        ora_query = all_oracle.format(startdate_oracle_temp.strftime('%d.%m.%Y'))
        oraclesCursor.execute(ora_query)
        for raw in oraclesCursor:
            #В качестве параметров %s, %s, %s, %s, %s переменной insert_query передаем raw
            cur.execute(insert_query, raw)
        db.commit()
        startdate_oracle_temp = startdate_oracle_temp + datetime.timedelta(days=1)
        
cur.close()
db.close()

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

Можно в запросе к Oracle указать сразу весь диапазон дат, но в случае сбоя этот запрос надо выполнять заново. Если нужна хотя бы часть данных, с которыми необходимо работать, используйте цикл. Преимущества цикла в том, что если Вы выполняете запрос данных за, например, 10-30 дней или более, уже после первого оборота цикла данные за один день будут обработаны и с ними можно работать.

Если Вы зададите весь диапазон дат в сам запрос, придется ждать обработки всех заданных дат и только потом начинать с ними работать.

Классические примеры перегрузки операторов и преобразования типов (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