Результати пошуку за запитом: обучение c*
Формат даних та підрахунок віку у JavaScript
Автор: Редакция ITVDN
Введение
Как веб-разработчик, Вы можете знать, что форматирование данных на серверном языке – не очень сложная задача. Достаточно базового понимания языка и того, что Вам нужно для реализации, и вот – у Вас есть хорошо отформатированный объект даты и времени. Например, следующий код С# является хорошо отформатированным и может предоставить нужный Вам объект даты и времени.
var dateOfBirth = new DateTime(1995, 08, 29); // My date of birth
var formatted = dateOfBirth.ToString("MMMM dd, yyyy");
// Would hold: August 29, 1995
В выше написанном коде мы предусмотрели формат данных, который нам нужен, и код, что обеспечит ожидаемый результат. Впрочем, делать это в JavaScript весьма трудно, потому как в JavaScript нет переопределенного метода ToString, который может преобразовать объект даты и времени в должным образом форматированное значение.
Тем не менее, объекты Date в JavaScript используют методы, с помощью которых можно извлечь значения месяца, дня или года. Мы будем их использовать, чтобы сгенерировать форматированный string для объекта date. Также заметим, что в JavaScript объект даты и времени является числом, которое отображается как количество миллисекунд от 1-го января 1970 г. Поэтому, чтобы не писать свой собственный код для подсчета месяцев и дат, можете использовать встроенные функции getMonth, getDate и др. чтобы получить нужные значения. В нашей статье мы покажем Вам, как написать код и как правильно форматировать запись string в объект даты и времени.
Объект даты и времени в Javascript
Объект даты и времени (Date) в JavaScript намного компактнее, чем в других языках программирования. Он не обеспечивает множество функций и особенностей. Это просто конструктор, который принимает число миллисекунд или значение строки, что представляет объект даты и времени в пределах от 1 января 1970 года до сегодняшнего дня (каким бы он ни был). Вы легко можете создать его экземпляр, используя следующий код
var date = Date.now(); // current date time
// OR
var date = new Date(); // new instance; default
// OR
var date = new Date('string-notation-of-datetime');
// Any date time upto 1 January 1970 from Now.
Теперь давайте поработаем с данным исходным кодом и посмотрим, что JavaScript может нам предложить.
Написание веб-приложения
В Вашем HTML Вы можете определить поля ввода от пользователя и установить диапазон их типов, что позволило бы пользователю вводить значение любого из этих типов. В нашей статье мы будем использовать тип date. Используем следующую HTML-разметку
Примечание: мы использовали Bootstrap в качестве стиля.
<input type="date" class="form-control"/>
Контроль после рендеринга
Это то, что у нас есть для макета, а теперь давайте обратимся ко входным данным пользователей. Мы должны найти указанную пользователем строку даты и времени, а также рассчитать по ней возраст.
var dateValue = new Date($('input').val()); // Get the value
// Now comes the stringification... Following code does that.
var date = getMonth(dateValue.getMonth()) + " " + dateValue.getDate() + ", " + dateValue.getFullYear();
В JavaScript методы getDate, getMonth возвращают номер объекта. Вместо использования номера в качестве даты создадим другую функцию, которая возвращает месяц из нашего целого значения.
Примечание: date.getMonth() при возврате значения начинает отсчет от 0.
function getMonth(index) { // Pass the index as parameter
switch (index) { // Switch on index
case 0:
return "January";
break;
case 1:
return "February";
break;
case 2:
return "March";
break;
case 3:
return "April";
break;
case 4:
return "May";
break;
case 5:
return "June";
break;
case 6:
return "July";
break;
case 7:
return "August";
break;
case 8:
return "September";
break;
case 9:
return "October";
break;
case 10:
return "November";
break;
case 11:
return "December";
break;
default: // Wouldn't get called usually because range is 0-11
"Invalid number: " + index;
break;
}
}
Описанная выше функция возвращает строку для месяца. Поэтому, вышеуказанный код сможет вернуть данные в строковом представлении.Что касается функции расчета возраста, то реализовать ее не так просто, как в С# или других языках. Вам надо вручную отбросить значения объекта даты и времени в миллисекундах с 1970 года, учитывая вычисление результата от даты рождения до текущего времени. Запутались? Давайте проверим наш код и упростим формулировку.
var age = Math.abs(
new Date(
Date.now() - dateValue // 1. Get the difference as new Date object
).getUTCFullYear() - 1970 // 2. Calculate the years
); // 3. Get the value
Мы разделили процесс на три этапа:
Прежде всего получим значение после отрицания даты рождения от текущей даты. Это будет основой для нашего алгоритма возраста.
Дальше найдем UTC-значение года от значения, что мы получили через отрицание, и вычтем от него 1970.
Теперь получим абсолютное значение от шага 2.
Теперь функция будет вмещать значение возраста для введенных пользователем данных. Запустим вышеуказанную функцию и получим HTML, для примера
HTML-разметка с указанием даты в отформатированной строке и возраста пользователя.
Заключение
Теперь Вы знаете как можно выбрать введенные пользователем данные и рассчитать возраст пользователя с помощью JavaScript, а также как показать его в строковом представлении для удобства чтения.
Источник: http://www.c-sharpcorner.com/UploadFile/201fc1/calculating-and-formatting-date-in-javascript/
10 порад для написання JavaScript без JQuery
Автор: Редакция ITVDN
Введение
JQuery - огромная библиотека. Она пришла приблизительно в то время, когда IE6 был браузером номер один. Тогда было много специфических моментов и разногласий, что делало процесс разработки утомительным и JQuery был идеальным инструментом для написания кроссбраузерного кода.
С тех пор, однако, веб-браузеры намного усовершенствовались. Вы можете с удобством использовать все возможности, предоставляемые ES5, и имеете в полном распоряжении огромную API-библиотеку HTML5, которая делает работу с DOM-элементами намного приятнее. Разработчики теперь могут выбирать, что же можно оставлять из JQuery для некоторых проектов, продолжая сохранять свою производительность.
Не поймите неправильно – JQuery по-прежнему отличная библиотека и чем чаще вы будете использовать ее, тем лучше. Тем не менее, для небольших проектов, например, для простых страниц с ограниченным JS взаимодействием, расширениями браузеров и мобильных сайтов, вы можете использовать vanlla JS.
Вот 10 советов, которые помогут в вашей деятельности.
1. Прослушивание на готовность документа (Document Ready)
Первое, что вы делаете, когда пишете JQuery, это упаковывание своего кода в вызов $(document).ready() для того, чтобы определить готовность DOM к манипуляциям. Без JQuery у вас есть событие DOMContentLoaded. Вот как оно используется.
2. Выбор элементов
Давным-давно Вы могли только выбирать элементы по ID, классу и имени тега, а JQuery с ее умными CSS-селекторами выступала своеобразным спасателем. Браузеры исправили это и представили две важные API - querySelector и querySelectorAll.
3. Установка и удаление слушателей событий
Прослушивание событий - фундаментальная часть построения веб-приложения. Принято было использовать две основные стороны, которые отличались тем, каким способом все было сделано - IE и остальное. Но сегодня мы просто используем addEventListener.
4. Манипулирование классами и свойствами
Манипулирование именами классов элементов без JQuery было очень неудобно использовать. Но проблема была решена благодаря свойству ClassList. И если нужно управление атрибутами, Вам нужен SetAttribute.
5. Получение и установка содержимого элементов
JQuery имеет удобный текст и html ( )методы. Вместо их можно использовать свойства textContent и innerHTML, которые были у нас в течение очень долгого времени.
6. Установка и удаление элементов
Хотя JQuery и делает все намного проще, добавление и удаление DOM-элементов невозможно без простого JavaScript. Здесь показано, как добавлять, удалять и заменять любые элементы, какие Вы только захотите.
7. Прохождение по DOM дереву
Любой настоящий JS-ниндзя знает, что есть много возможностей, скрытых в DOM. По сравнению с JQuery простые интерфейсы DOM предлагают ограниченную функциональность для выбора нескольких уровней. И, тем не менее, есть множество вещей, которые Вы можете делать, путешествуя по DOM - дереву.
8. Обработка массивов
Некоторые из утилитных методов, которые предоставляет JQuery, доступны со стандартом ES5. При переборе массивов можно использовать forEach и map вместо их JQuery аналогов - each() и map(). Просто будьте осторожны при различиях в аргументах и значениях по умолчанию в обратных вызовах.
9. Animations
Методы анимации JQuery самым лучшим образом подходят ко всему, что Вы бы хотели «оживить» и, если нужны сложные анимации из скриптов в приложении, Вы должны по-прежнему иметь дело с ней. Но благодаря всем чудесам CSS3, некоторые простые случаи можно обработать с помощью легкой библиотеки Animate.css, которая позволяет запускать анимацию, добавляя или удаляя имена классов элементов.
10. AJAX
Ajax – это еще одна технология, которая используется при кросс-браузерном беспорядке. Хорошая новость - теперь можно использовать один и тот же код везде. Плохая новость - по-прежнему громоздко создавать экземпляры и отправлять AJAX-запросы с XMLHttpRequest, так что лучше предоставить это библиотеке. Но Вы не должны подключать всю JQuery только для этого. Вы можете использовать одну из самых многочисленных и легких библиотек, которые доступны. Вот пример построения запроса AJAX напрямую, и с помощью небольшой библиотеки запросов.
Выводы
Стремление к минимальному, нулевому количеству наворотов на веб-странице - достойная цель, что окупит себя быстрой загрузкой и лучшим пользовательским опытом. Но будьте осторожны - никто не выиграет, если Вы будете изобретать велосипед, который уже используется в JQuery. Не жертвуйте хорошей практикой разработки только для того, чтобы сократить количество кода. Но есть множество мест, где на сегодня советы вполне применимы. Попробуйте следовать ванили в следующий раз, это может быть все, что вам нужно!
Источник: http://tutorialzine.com/2014/06/10-tips-for-writing-javascript-without-jquery/
Оператор nameof: Нова функція С# 6.0
Автор: Редакция ITVDN
Введение
12 ноября 2014 в рамках конференции Connect () Microsoft презентовала Visual Studio 2015, которая имеет много новых и интересных возможностей тестирования для разработчиков. Microsoft анонсировала новую версию C# - C# 6.0, улучшенную и обновленную. Одно из нововведений функций C# 6.0 –оператор nameof.
Что такое оператор nameof
С введением оператора nameof теперь возможно избегать сложно закодированых строчек в коде. Оператор nameof принимает имя элементов кода и возвращает строчный литерал этого элемента. Параметры, которые принимает оператор nameof, включают имя класса и всех его членов, таких как: методы, переменные и константы.
Довольно удобно использовать строчные литералы, чтобы бросить ArgumentNullException (назвать аргумент винованым) и вызвать события PropertyChanged (чтоб назвать измененное свойство), но велика вероятность появления ошибки, потому что можно неправильно их записать или не восстановить после рефакторинга. Выражения оператора nameof являются особым видом строчного литерала, где компилятор проверяет, есть ли у Вас что-то с заданным именем и Visual Studio знает, куда он ссылается, поэтому навигация и рефакторинг будут работать легко.
Оператор nameof может быть полезным для разных сценариев, таких как INotifyPropertyChanged, ArgumentNullException и отображения.
Пример 1
string person;
Console.WriteLine(nameof(person)); // prints person
int x = 2;
Console.WriteLine(nameof(x)); //prints x
Пример 2
class Operatornameof
{
public Operatornameof(string name) //constructor
{
if (name == null)
throw new ArgumentNullException(nameof(name)); // use of nameof Operator
else
Console.WriteLine("Name: " + name);
}
}
Пример 3
class Operatornameof
{
private int _price;
public int price
{
get
{
return this._price;
}
set
{
this._price = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.price))); //// INotifyPropertyChanged
}
}
private void PropertyChanged(Operatornameof operatornameof1, PropertyChangedEventArgs propertyChangedEventArgs)
{
throw new NotImplementedException();
}
}
Программа 1 с использованием Visual Studio 2013
using System;
using System.Text;
namespace CSharpFeatures
{
public class operatornameof
{
public operatornameof(string name, string location, string age)
{
if (name == null)
throw new ArgumentNullException("name");
else
Console.WriteLine("\n Name: " + name);
if (location == null)
throw new ArgumentNullException("location");
else
Console.WriteLine(" Location: " + location);
if (age == null)
throw new ArgumentNullException("age");
else
Console.WriteLine(" Age: " + age);
}
static void Main(String[] args)
{
operatornameof p = new operatornameof("Abhishek", "Ghaziabad", "23");
Console.ReadKey();
}
}
}
Программа 1 с использованием Visual Studio 2015 Preview
using System;
using System.Text;
namespace CSharpFeatures
{
public class Operatornameof
{
public Operatornameof(string name, string location, string age)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
else
Console.WriteLine("Name: " + name);
if (location == null)
throw new ArgumentNullException(nameof(location));
else
Console.WriteLine("Location: " + location);
if (age == null)
throw new ArgumentNullException(nameof(age));
else
Console.WriteLine("Age: " + age);
}
static void Main(String[] args)
{
Operatornameof p = new Operatornameof("Abhishek", "Ghaziabad", "23");
Console.Read();
}
}
}
Программа 2 с использованием Visual Studio 2013
using System;
namespace CSharpFeatures
{
class Operatornameof1
{
static void Main(string[] args)
{
details d = new details();
d.Age = 23;
d.Name = "Abhishek";
Console.WriteLine("\n Name: {0} ", d.Name);
Console.WriteLine(" Age: {0} ", d.Age);
Console.ReadKey();
}
}
class details
{
private string _Name;
public int _Age;
public string Name
{
get { return this._Name; }
set { this._Name = value; }
}
public int Age
{
get { return this._Age; }
set { this._Age = value; }
}
}
}
Программа 3 с использованием Visual Studio 2015 Preview
using System;
namespace CSharpFeatures
{
class Operatornameof2
{
static void Main(string[] args)
{
details d = new details();
Console.WriteLine("{0} : {1}", nameof(details.Name), d.Name);
Console.WriteLine("{0} : {1}", nameof(details.Age), d.Age);
Console.ReadKey();
}
}
class details
{
public string Name { get; set; } = "Abhishek";
public int Age { get; set; } = 23;
}
}
Из данной статьи Вы узнали, как использовать оператор nameof, чтобы избежать использования сложно закодированых строчек в коде. Надеемся, что Вам понравилась новая функция C# 6.0, введенная Microsoft.
Источник: http://www.c-sharpcorner.com/UploadFile/16101a/nameof-operator-a-new-feature-of-C-Sharp-6-0/
Приховування методу С#
Автор: Редакция ITVDN
Введение
В данной статье Вы узнаете, как скрывать метод и как вызывать скрытые элементы базового класса. Рассмотрим это на конкретных примерах.
Создадим в Visual Studio консольное дополнение с классом Student. У класса Student два поля: FirstName и LastName, и метод, который выводит FirstName и LastName на экране консоли.
using System;
namespace methodHidingInCSharp {
class Student {
public string FirstName;
public string LastName;
public void PrintName() {
Console.WriteLine(FirstName + " " + LastName);
}
}
class Program {
static void Main(string[] args) {
}
}
}
Создадим класс DiplomaStudent и GraduateStudent, которые унаследуют класс Student.
using System;
namespace methodHidingInCSharp {
class Student {
public string FirstName;
public string LastName;
public void PrintName() {
Console.WriteLine(FirstName + " " + LastName);
}
}
class DiplomaStudent : Student {
}
class GraduateStudent : Student {
}
class Program {
static void Main(string[] args) {
}
}
}
Если нужно создать объект класса DiplomaStudent и GraduateStudent, это можно сделать главным методом, например:
class Program {
static void Main(string[] args) {
DiplomaStudent ds = new DiplomaStudent();
ds.FirstName = "Sam";
ds.LastName = "Fisher";
ds.PrintName();
GraduateStudent gs = new GraduateStudent();
gs.FirstName = "Aiden";
gs.LastName = "Pearce";
gs.PrintName();
}
}
Так как классы DiplomaStudent и GraduateStudent наследуют класс Student, можно вызывать всех участников, кроме частных (приватных).
При запуске проекта получим следующий результат:
Результат вышел таким, как и предполагалось. Но есть небольшая проблема. Невозможно установить, какой из этих двух результатов DiplomaStudent, а какой – GraduateStudent. Для этого создадим дополнение к имени (studentType) с указанием Diploma или Graduate. Таким образом, просто смотря на имена, можно определить, какой из них DiplomaStudent, а какой – GraduateStudent.
Вернемся к проекту. Теперь стоит создать метод PrintName, который будет одинаковым для обоих производных классов, и добавить DiplomaStudent и GraduateStudent, чтоб сделать их более читабельными и понятными.
class DiplomaStudent : Student {
public void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Diploma Student");
}
}
class GraduateStudent : Student {
public void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Graduate Student");
}
}
Как известно, тот же метод используется в базовом классе.
class Student {
public string FirstName;
public string LastName;
public void PrintName() {
Console.WriteLine(FirstName + " " + LastName);
}
}
В результате дочерний класс скрывает реализацию базового класса.
При построении кода появляется зеленая волнистая линия. Если навести курсор мыши на линию, можно увидеть объяснение: если нужно специально скрыть унаследованный член, используйте новое ключевое слово.
Чтобы скрыть унаследованный от производного класса член, используйте новое ключевое слово, например:
class DiplomaStudent : Student {
public new void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Diploma Student");
}
}
class GraduateStudent : Student {
public new void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Graduate Student");
}
}
Запустите программу:
Результат оправдал ожидания. Рассмотрим, как вызвать метод назад после скрытия. Существует несколько способов.
Первый – использование основных ключевых слов.
class DiplomaStudent : Student {
public new void PrintName() {
base.PrintName();
}
}
class GraduateStudent : Student {
public new void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Graduate Student");
}
Базовый класс реализуется, когда мы выполним программу.
Второй способ – превратить тип переменной дочернего класса в базовый класс.
using System;
namespace methodHidingInCSharp {
class DiplomaStudent : Student {
public new void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Diploma Student");
}
}
class GraduateStudent : Student {
public new void PrintName() {
Console.WriteLine(FirstName + " " + LastName + " - Graduate Student");
}
}
В двух предыдущих случаях реализовывается метод дочернего класса и используется новое ключевое слово, чтобы скрыть реализацию базового метода. То есть, когда Вы запускаете приложение, оно печатает реализацию дочернего класса.
class Program {
static void Main(string[] args) {
DiplomaStudent ds = new DiplomaStudent();
ds.FirstName = "Sam";
ds.LastName = "Fisher";
re I have type - casted the child class reference variable into a base class
((Student)ds).PrintName();
GraduateStudent gs = new GraduateStudent();
gs.FirstName = "Aiden";
gs.LastName = "Pearce";
((Student)gs).PrintName();
}
}
Запустите программу.
В предыдущем результате Вы получили базовую реализацию.
Третий способ состоит в создании переменной базового класса, которая указывает на дочерний класс.
class Program {
static void Main(string[] args) {
DiplomaStudent ds = new DiplomaStudent();
ds.FirstName = "Sam";
ds.LastName = "Fisher";
re I have type - casted the child class reference variable into a base class
((Student)ds).PrintName();
GraduateStudent gs = new GraduateStudent();
gs.FirstName = "Aiden";
gs.LastName = "Pearce";
((Student)gs).PrintName();
}
}
Результат тот же.
Источник: http://www.c-sharpcorner.com/UploadFile/219d4d/method-hiding-in-C-Sharp/
Узагальнені класи С#
Автор: Редакция ITVDN
Введение
Обобщенные классы в С# представляют параметры типа. Они имеют 5 параметров. Обощенный класс становится частью обусловленного класса сам по себе. Класс типа Т приведен в примере ниже. Буква Т определяет тип, который в основном базируется на зоне абонента.
Запустите программу Visual Studio. Выберите тип проекта и строчку console application.
Шаг 1
Нажмите на ярлык файла -> Новое -> Программа.
Шаг 2
Выберите строчку Visual C# в левой части окна. Кликните Console Application в правом окне. Назовите программу «GenericClass». Задайте, где Вы хотите сохранить программу. Нажмите Ok.
Шаг 3
Введите следующий код в дополнение:
public class Myclass
{
public void Compareme(T v1, T v2)
{
if (v1.Equals(v2))
{
Console.Write("The value is matching");
}
else
{
Console.Write("The value is not matching");
}
}
}
class Program
{
static void Main(string[] args)
{
Myclass objmyint = new Myclass();
objmyint.Compareme("Amit", "Amit");
Console.ReadLine();
}
}
После введения кода, Вы получите такие исходные данные.
Измените строчку на что-либо другое, проверьте исходные данные. В примере создан второй строчный параметр «amit».
public class Myclass
{
public void Compareme(T v1, T v2)
{
if (v1.Equals(v2))
{
Console.Write("The value is matching");
}
else
{
Console.Write("The value is not matching");
}
}
}
class Program
{
static void Main(string[] args)
{
Myclass objmyint = new Myclass();
objmyint.Compareme("Amit", "amit");
Console.ReadLine();
}
}
Посмотрите на результат.
Источник: http://www.c-sharpcorner.com/UploadFile/d1028b/generic-class-in-C-Sharp/
Обробка файлів С#. NET
Автор: Редакция ITVDN
Введение
Статья объяснит Вам, как выполнять задачи по считыванию и введению файловой информации из разных областей, используя С#. .NET программирование API. Оно включает анализ структуры каталогов, определяет существующие папки и файлы, а также выполняет операции, связанные с файлами: перемещение, копирование и удаление объектов с диска. Цель статьи – определить типы, которые содержатся в области имен System.IO и объяснить, как разными способами можно считывать и вводить информацию в символьно-ориентированый, бинарный и строчный архив данных.
Структура файловой системы
Область имен System.IO состоит из 4 классов, которые помогут Вам оперировать конкретными файлами, работать с машинной структурой каталогов. Каталог адресов и файлов непосредственно наследует System.Object и поэтому выполняет задачи создания, копирования, перемещения и удаления файлов, используя при этом разные статические способы. Они содержат только статические методы, а главное то, что на их основе никогда не создаются экземпляры. Типы FileInfo и DirectotryInfo возникли от базового класса типа FileSystemInfo и обычно их используют, чтобы получить детальную информацию про файл или каталог, поскольку их элементы обычно настроены на возвращение типизованых объектов. Они используют те же общедоступные методы, что и каталог адресов и файлов, но могут сохранять данные, а элементы этих классов не статичные.
В шаблоне .NET область имен System.IO выполняет роль библиотеки базовых классов, которая предназначена для производственных и исходящих услуг на базе файлов. Как и любая область имен, System.IO содержит большое количество классов, интерфейсов, нумераций, структур данных и их передачи. В таблице ниже представлены основные классовые типы данных:
Классовые типы
Характеристика
Хранилище/содержание каталогов
Классовые типы данных помогают управлять системой структуры каталогов.
Информация про накопитель
Этот класс данных предоставляет детальную информацию про накопители, которые содержатся в компьютере.
Файловий поток
Класс данных предоставляет Вам файл прямого доступа с информацией в виде потока байтов.
Файл/сведения про файл
Классовые типы данных руководят файлами, которые содержатся в компьютере.
Путь
Этот класс выполняет операции в System.String, в котором содержится информация про файл и каталог независимо от платформы.
Устройство двойного считывания/устройство двойного введения информации
Классовые типы позволяют Вам сохранять и находить простые типы данных в виде двойных значений.
Поток считывания/поток введения
Этот класс используется для сохранения текстовой информации в файле.
Строчная последовательность считывания/строчная последовательность введения информации
Эти классовые типы данных также работают с текстовой информацией. Однако, базовая система хранилища – скорее, строчный буфер, чем физический файл.
Поток буферизации
В этом типе можно лишь временно хранить поток байтов. Вы можете разместить данные в хранилище позже.
В System.IO содержится класс DriveInfo, чтобы руководить системой диска во время произведения разных операций. Класс DriveInfo предоставляет детальную и полную информацию про количество дисков, общее пространство на жёстком диске, свободное пространство, название диска, состояние готовности и другое. Обратите внимание на следующую программу, которая показывает основные дисководы:
DriveInfo[] di = DriveInfo.GetDrives();
Console.WriteLine("Total Partitions");
foreach(DriveInfo items in di)
{
Console.WriteLine(items.Name);
}
Следующие фрагменты кода отдельно выполняют все другие операции класса DriveInfo.
using System;
using System.IO;
namespace DiskPartition
{
class Program
{
static void Main(string[] args)
{
DriveInfo[] di = DriveInfo.GetDrives();
Console.WriteLine("Total Partitions");
Console.WriteLine("---------------------");
foreach(DriveInfo items in di)
{
Console.WriteLine(items.Name);
}
Console.Write("\nEnter the Partition::");
string ch = Console.ReadLine();
DriveInfo dInfo = new DriveInfo(ch);
Console.WriteLine("\n");
Console.WriteLine("Drive Name::{0}", dInfo.Name);
Console.WriteLine("Total Space::{0}", dInfo.TotalSize);
Console.WriteLine("Free Space::{0}", dInfo.TotalFreeSpace);
Console.WriteLine("Drive Format::{0}", dInfo.DriveFormat);
Console.WriteLine("Volume Label::{0}", dInfo.VolumeLabel);
Console.WriteLine("Drive Type::{0}", dInfo.DriveType);
Console.WriteLine("Root dir::{0}", dInfo.RootDirectory);
Console.WriteLine("Ready::{0}", dInfo.IsReady);
Console.ReadKey();
}
}
}
После разработки этой программы, она отображает каждую деталь дисковода и конкретные дисководы, как показано ниже:
Работа с каталогами
Чтобы производить операции с каталогами, то есть создавать и удалять данные, шаблон .NET содержит два элементарных класса: DirectoryInfo и Directory.
Классовый тип DirectoryInfо
Класс DirectoryInfo содержит серию методов создания, удаления, перемещения и перечень каталогов и подкаталогов. В следующем кодовом примере отображена информация относительно временного каталога.
DirectoryInfo di = new DirectoryInfo(@"D:\temp");
Console.WriteLine("*******Direcotry Informations*******\n\n");
Console.WriteLine("Full Name={0}", di.FullName);
Console.WriteLine("Root={0}", di.Root);
Console.WriteLine("Attributes={0}", di.Attributes);
Console.WriteLine("Creation Time={0}", di.CreationTime);
Console.WriteLine("Name={0}", di.Name);
Console.WriteLine("Parent={0}", di.Parent);
Кодовый пример производит информацию относительно временного каталога, который содержится на диске D:
Допускается, что путь, пройденный конструктором времени класса DirectoryInfo существует. Но если Вы попробуете работать с несуществующим каталогом, то общая среда выполнения языков CLR исключит это действие. Чтобы создать каталог, сначала проверьте, нет ли таких исключений.
DirectoryInfo di = new DirectoryInfo(@"D:\temp\xyz");
di.Create();
При помощи программ и при использовании метода CreateSubdirectory можно также увеличить структуру каталога. В следующем кодовом примере показано, как создается каталог на диске D, а потом в D:\ajay\:
DirectoryInfo di = new DirectoryInfo(@"D:\");
di.CreateSubdirectory("ajay");
di.CreateSubdirectory(@"ajay\ajay11");
Класс каталога
Класс каталога выполняет почти те же функции, что и класс DirectoryInfo. Класс каталога, как правило, возвращает строчные данные, а не типизированые объекты класса DirectoryInfo. В следующем примере показано, как удалять каталог и подкаталог на диске D.
static void Main(string[] args)
{
DirectoryInfo di = new DirectoryInfo(@"d:\abc");
Console.WriteLine("Name:{0}", di.FullName);
Console.Write("Are you sure to Delete:");
string str = Console.ReadLine();
if (str == "y")
{
Directory.Delete(@"d:\abc", true);
}
Console.Write("Deleted.....");
}
Считывание и введение информации в файл
Операции считывания и введения информации происходят при использовании файлового объекта. Следующий фрагмент кода считывает текстовый файл, размещенный в компьютере.
private void button1_Click(object sender, EventArgs e)
{
try
{
textBox2.Text = File.ReadAllText(txtPath.Text);
}
catch (FileNotFoundException)
{
MessageBox.Show("File not Found....");
}
}
Сначала пользователя спрашивают, правда ли он желает действовать в выбранном им направлении. Позже, когда настанет очередь файла, метод ReadAllText считывает всю текстовую информацию с файла и отображает ее за текстовым полем.
Кроме того, используя класс File, к файлу, с которого считывается информация, можно добавить что-то свое, кроме самого текста, как показано ниже.
File.WriteAllText(@"d:\test.txt", textBox2.Text);
Этот класс выбирает такой путь, что сохранит файл и способ введения данных как, например, текстовое поле или другой способ.
На следующих изображениях показан процесс считывания текстового файла после того, как был выбран соответствующий шаг:
Поток
Благодаря .NET такие классы, как FileStream, StreamReader/Writer, BinaryReader/Writer могут считывать данные и вводить их в файл. В основном, такой поток информации демонстрирует фрагмент данных, который переходит от начального места до указаного. Таким образом, он способствует взаимодействию последовательности байтов, несмотря на вид устройства, на котором хранятся байты.
Методы
Характеристика
Считывание/считывание байтов
Считывает информацию про количество байтов с исходящей точки.
Введение/введение байтов
Вводит информацию про количество байтов в исходящую точку.
Поиск
Определяет позицию в исходящей точке.
Расположение
Определяет текущую позицию в текущем потоке информации.
Размер
Меняет размер потока информации на байты.
Заполнитель
Обновляет основное хранилище данных вместе с текущим буфером, а потом устанавливает новый.
Выход
Закрывает текущий поток информации и предоставляет информацию, связанную с этим потоком.
Файловый поток
Обновление файлового потока используют, чтобы считывать и вводить информацию в файл. Для того, чтобы создать файловый поток, сначала нужно иметь доступ к необходимому файлу. Затем открыть файл и определить путь получения доступа к файлу. Наконец, выбрать общий каталог, в котором Вы хотите ограничить доступ к файлу.
Перечисления
Значения
Режим доступа к файлу
Создает, добавляет, открывает, приостанавливает - OpenOrCreate
Доступ к файлу
Считывает, вводит - ReadWrite
Общий каталог
Передает, считывает, вводит - ReadWrite
Класс файлового потока может считывать или вводить только один байт или же массив байта. Вам нужно будет раскодировать классовый тип System.String соответствующим массивом байта. Область System.Text определяет закодированый тип, чтобы потом выбрать метод закодирования или раскодирования текстового фрагмента в массив байта. Но закодированый массив байта сохраняется в файле способом FileStream.Write. Чтобы возвратить байт назад на накопитель, нужно вернуться на начальное место и использовать метод ReadByte. Затем Вам следует отобразить строчный массив байта и закодированый текстовый фрагмент на компьютере.
using(FileStream fs = new FileStream(@"d:\ajay123.doc", FileMode.Create))
{
string msg = "first program";
byte[] byteArray = Encoding.Default.GetBytes(msg);
fs.Write(byteArray, 0, byteArray.Length);
fs.Position = 0;
byte[] rFile = new byte[byteArray.Length];
for (int i = 0; i < byteArray.Length; i++)
{
rFile[i] = (byte)fs.ReadByte();
Console.WriteLine(rFile[i]);
}
Console.WriteLine(Encoding.Default.GetString(rFile));
}
Двойное считывание и двойное введение информации
Классовый тип BinaryReader и Writer позволит Вам считывать и вводить дискретную информацию в указанный поток в компактном двойном формате. Классовый тип BinaryWriter определяет нужный способ введения информации, чтобы разместить ее в указанный поток.
Элементы
Характеристика
Классовый тип
Ввод
Считывает элемент к текущему потоку
Двойное введение
Поисковик
Определяет позицию в текущем потоке
Двойное введение
Закрытие
Не допускает двойное считывание
Двойное введение
Заполнитель
Заполняет двойной поток
Двойное введение
Символьный считыватель
Возвращает доступные элементы, не направляет их в поток
Двойное считывание
Считыватель
Считывает указаный ряд байтов или других элементов и сохраняет их во входящем массиве данных
Двойное считывание
В следующих примерах показано, как вводится определенная информация к новому файлу champu.dat, используя BinaryWriter. Далее информация считывается в то время, как классовый тип BinaryReader применяет целый ряд способов.
class Program
{
static void Main(string[] args)
{
// writing
FileInfo fi = new FileInfo("champu.dat");
using (BinaryWriter bw = new BinaryWriter(fi.OpenWrite()))
{
int x = 007;
string str = "hello champu ,one day you will become doomkatu";
bw.Write(x);
bw.Write(str);
}
//Reading
FileInfo f = new FileInfo("champu.dat");
using (BinaryReader br = new BinaryReader(fi.OpenRead()))
{
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadString());
}
Console.ReadLine();
}
}
Строчное считывание и введение данных
Можно использовать StringWriter и StringReader, чтобы поставлять текстовую информацию на поток запоминающего устройства. Вы в этом убедитесь, когда добавите информацию в виде символов к указаному буферу. На следующих кодовых примерах изображено, что лучше вводить блок строчных данных в StringWriter, чем в файл, размещенный на жестком диске.
static void Main(string[] args)
{
// writing
using (StringWriter sw = new StringWriter())
{
sw.WriteLine("helloooooooooooooooooooo");
// Reading
using (StringReader sr = new StringReader(sw.ToString()))
{
string input = null;
while ((input = sr.ReadLine()) != null)
{
Console.WriteLine(input);
}
}
}
}
Вывод
Данная статья начинается со вступительной части про файловую систему .NET и содержит детальное описание ее иерархических классов. Благодаря статье Вы выучили, как управлять физическим файлом и каталогом на жестком диске, используя классовые типы File и Directory. Было детально рассмотрено классовый тип Stream. Область System.IO содержит ряд устройств введения и считывания информации, как, например, FilStream, BinaryStream, StringStream и другие. Статья рассказывает про доступ к информации и ее ввод.
Використання календаря в Microsoft Outlook
Автор: Олександр Марченко
Введение
В современной компании Вам придется работать в команде, а это означает, что впредь Вы обязаны планировать совместные активности, уведомлять своих коллег о вашем отсутствии на рабочем месте и доступности к рабочим встречам.
В решении Microsoft Outlook присутствует множество возможностей для упрощения и автоматизации данного процесса. Так, одним из самых часто востребованных является планировщик задач и событий. Раздел «Календарь» позволяет пользователю совмещать на одном экране несколько календарей, принадлежащих как разным учетным записям, так и разным сотрудникам, автоматически отбирать все встречи одного сотрудника по определенному проекту или департаменту, просматривать календари коллег и планировать совместные мероприятия.
Так выглядит незапланированная неделя в вашем календаре. К тому же вы можете настроить ее отображение под себя. Для этого достаточно перейти в меню File//Options//Calendar
А вот так может выглядеть неделя, на которой назначено несколько рабочих задач, пара встреч, уведомление о недоступности на весь день и внесена личная встреча.
Так, зеленым цветом помечены события из рабочей категории, их отличительная особенность – возможность смещаться по времени, бордовым отмечены корпоративные собрания, которые не могут смещаться по времени, красным отмечено событие, которое попадает в категорию «Личное» и не подлежит разглашению. Кроме того, 16 июля мы видим событие, которое будет распространятся на весь день, а его подпись гласит, что мы будем недоступны для наших коллег.
В следующей статье мы детально рассмотрим процесс создания и редактирования событий и задач в разделе «Календарь» из Microsft Outlook 2013.
Заміщення методу С#
Автор: Редакция ITVDN
Введение
В данной статье Вы узнаете, для чего и как использовать замещение метода в C#.
Для того, чтобы на примере показать замещение метода в С#, создадим класс «Student» с двумя полями: FirstName и LastNamе. В примере используется также метод печати, который выводит FirstName и LastName в консоль.
class Student {
public string FirstName;
public string LastName;
public virtual void Print() {
Console.WriteLine(FirstName + " " + LastName);
}
}
Класс Student выступает как базовый/родительский класс для классов DiplomaStudent и GraduateStudent.
class DiplomaStudent : Student {
}
class GraduateStudent : Student {
}
ПРИМЕЧАНИЕ: Если производный класс наследует базовый класс, то все учасники, кроме частных членов, доступны в производном классе. То есть, оба поля и метод печати можно вызвать/инициировать в производном классе.
Если нужно распечатать детали студентов на экране консоли, можно создать пример двух производных классов от «Student», используя основной метод.
class Program {
static void Main(string[] args) {
DiplomaStudent ds = new DiplomaStudent();
ds.FirstName = "Max";
ds.LastName = "Payne";
ds.Print();
GraduateStudent gs = new GraduateStudent();
gs.FirstName = "Lara";
gs.LastName = "Croft";
gs.Print();
}
}
Запустите программу.
На данном этапе невозможно определить, к какому типу из категорий студентов принадлежит каждый студент. Например, добавим (-studentType) и прикрепим его после имени студента, чтобы сделать его более удобным для чтения.
Для этого можно создать метод печати для обоих производных классов.
class DiplomaStudent : Student {
public void Print() {
Console.WriteLine(FirstName + " " + LastName + " - diploma student");
}
}
class GraduateStudent : Student {
public void Print() {
Console.WriteLine(FirstName + " " + LastName + " - graduate student");
}
}
Но если Вы хотите не скрыть реализацию базового метода, а заместить ее, то можно использовать виртуальное ключевое слово.
class Student {
public string FirstName;
public string LastName;
public virtual void Print() {
Console.WriteLine(FirstName + " " + LastName);
}
}
Теперь базовый метод печати стал виртуальным. То есть, его можно заменить в производном классе и добавить его реализацию.
Но сначала надо удалить метод печати с обоих производных классов, как показано ниже:
class DiplomaStudent : Student {
}
class GraduateStudent : Student {
}
Напишите override, потом поставьте пробел. Вы увидите метод печати в Intellisense.
Выберите и нажмите Enter. Он унаследует метод сигнатур.
class DiplomaStudent : Student {
public override void Print() {
base.Print();
}
}
class GraduateStudent : Student {
public override void Print() {
base.Print();
}
}
Удалите его и добавьте свою собственную реализацию, как показано ниже:
class DiplomaStudent : Student {
public override void Print() {
Console.WriteLine(FirstName + " " + LastName + " - diploma student");
}
}
class GraduateStudent : Student {
public override void Print() {
Console.WriteLine(FirstName + " " + LastName + " -graduate student");
}
}
Запустите программу.
Предположим, что по какой-то причине Вам необходимо отменить реализацию вызова и печати базового класса. Это можно сделать при помощи такой комбинации: основное ключевое слово, затем точка (.), потом метод.
class DiplomaStudent : Student {
public override void Print() {
base.Print();
}
}
Источник: http://www.c-sharpcorner.com/UploadFile/219d4d/method-overriding-in-C-Sharp/
Створення Super Meat Boy на Unity
Автор: Антон Даніелян
Введение
Данная статья ориентирована на тех, у кого уже есть небольшой опыт работы с Unity. В первую очередь мы рассмотрим воссоздание механики управления главного героя игры Super Meat Boy. Также узнаем, как построить сцену, имея скриншот уровня оригинальной игры. Все материалы, использованные в данном примере, принадлежат разработчикам оригинальной игры.
Для начала стоит сказать пару слов о фоновых картинках для уровней. Чтоб не создавать весь уровень из отдельных элементов, редактируем найденные на просторах интернета скриншоты, на которых вырезаем главного героя, таймер с левой части экрана и следы крови. Теперь у нас есть подготовленный фон.
Элементы Уровня
Поверхности, по которым можно двигаться, задаем с помощью компонента Polygon Collider 2D. Места, где игрок может умереть (выпасть из поля зрения камеры или попасть на режущую пилу) обозначаем тегом killzone. К ним крепим данный скрипт:
void OnTriggerEnter2D(Collider2D other)
{
if (coll.tag =="killzone")
{
Application.LoadLevel(Application.loadedLevelName);
}
}
При прикосновении коллайдер игрока вызывает срабатывание скрипта и подгружает этот же уровень, то есть происходит рестарт. Аналогично работает и загрузка следующего уровня, единственным отличием является передаваемое методу Application.LoadLevel() текстовое значение с названием уровня. Этот скрипт прикрепляем к объекту endTarget.
Следы крови размещаем на все потенциально доступные игроку поверхности (кроме уровня песочницы, где они находятся на каждой из 4 сторон блока). Они состоят из отключенного по умолчанию компонента Sprite Renderer, компонента Box Collider 2D с активированным значением IsTrigger и скрипта, который собственно и включает Sprite Renderer при коллизии с игроком.
SpriteRenderer sR;
void Start()
{
sR = transform.GetComponent<SpriteRenderer>();
}
void OnTriggerEnter2D(Collider2D coll)
{
if (coll.tag =="Player")
{
sR.enabled = true;
}
}
Получаем компонент Sprite Renderer во время выполнения при помощи метода GetComponent(), вызываемого на данном объекте. Если тег прикасающегося коллайдера равен "Player", то включаем Sprite Renderer, который отображает картинку крови на уровне.
Создание персонажа
Внешний вид персонажа
В оригинальной игре мит-бой тщательно анимирован и имеет большое количество визуальных эффектов, большинство из которых мы воссоздавать не будем по причине нецелесообразности. Вместо анимации будем использовать простую подмену спрайтов при смене состояния игрока. Для главного персонажа нам понадобятся компоненты Rigid Body 2D, Sprite Renderer, Box Collier 2D, Circle Collider 2D и скрипт управления, который мы рассмотрим чуть ниже.
В инспекторе на компоненте Rigid Body 2D ставим галочку на Fixed Angle, в Circle Collider 2D на IsTrigger. Этим мы зафиксировали персонажа в одном положении и указали, что Circle Collider 2D выполняет функцию триггера. Радиус окружности коллайдера должен быть таким, что немного выходит за рамки квадратного коллайдера. Он является триггером появления следов крови на уровне.
Объявление переменных
Для корректной имитации поведения нам понадобятся переменные для скорости ходьбы, бега, прыжка, а также ускорения в воздухе и на земле.
public float jumpForce = 50f;
public float speed = 10;
public float speedMultiplier = 4f;
public float acceleration = 5f;
public float airAcceleration = 2f;
Для данных переменных экспериментальным путем были подобраны значения, которые больше всего напоминают поведение оригинала.
Также нам понадобятся переменные для контроля вида персонажа и собственно его физика. Они позже будут инициализированы уже знакомым нам способом во время выполнения.
SpriteRenderer spriteRender;
Rigidbody2D rBody;
Для правильного отображения разных состояний мит-боя будем использовать несколько картинок, поэтому берем переменные типа Sprite.
//спрайты разных состояний
public Sprite jumpSprite;
public Sprite RunSprite;
public Sprite IdleSprite;
public Sprite SlidingOnAWallSprite;
Данные спрайты будем инициализировать не в рантайме, а в редакторе, где проводим им ссылку на картинку для каждого состояния.
И напоследок еще понадобятся данные о высоте, толщине персонажа и состояние прыжка.
float playerWidth;
float playerHeight;
//флаг состояния прыжка
bool ableToJump = true;
Управление главным героем
После объявления всех нужных нам переменных, переходим к реализации. Зарезервированный метод Awake() отработает сразу поле загрузки уровня, поэтому в нем и инициализируем переменные толщины, высоты и другие.
void Awake()
{
//инициализация этих переменных произойдет сразу после запуска сцены
playerWidth = GetComponent<BoxCollider2D>().bounds.extents.x + 0.05f;
playerHeight = GetComponent<BoxCollider2D>().bounds.extents.y + 0.05f;
rBody = transform.GetComponent<Rigidbody2D>();
spriteRender = transform.GetComponent<SpriteRenderer>();
}
Переменные playerHeigth и palyerWidth будут полезны при определении, находится ли игрок на земле. К ним прибавляем небольшой зазор, который не даст лучу от персонажа заметить его же коллайдер.
Метод IsOnGround() возвращает true в случае, если хотя бы один из созданных лучей касается коллайдера. Для удобства создаем два луча – с левой нижней части коллайдера персонажа и правой соответственно. При создании отнимаем высоту, учитывая вертикальный и горизонтальный зазоры. Этот способ позволит уйти от многих проблем при прыжках возле стен.
public bool IsOnGround()
{
//создаем луч длинной 0.01 справа с направлением вниз
bool rightBottom = Physics2D.Raycast(
new Vector2(transform.position.x + playerWidth - 0.055f,
transform.position.y -playerHeight), -Vector2.up, 0.01f);
//аналогичный луч слева
bool leftBottom = Physics2D.Raycast(
new Vector2(transform.position.x - playerWidth + 0.055f,
transform.position.y - playerHeight),-Vector2.up, 0.01f);
return (rightBottom || leftBottom) ? true : false;
}
Метод Run() отвечает за движение игрока по горизонтали. Параметр int directionX отвечает за направление, если число позитивное, то двигаемся вправо, негативное – влево соответственно. Если нажат LShift, то учитывается умножитель ускорения. Если игрок находится в воздухе, то множим на переменную ускорения в воздухе.
private void Run(bool onGround, int directionX)
{
rBody.AddForce(new Vector2((directionX * speed - rBody.velocity.x) *
(Input.GetKey(KeyCode.LeftShift) ? speedMultiplier : 1f) *
(onGround ? acceleration : airAcceleration), 0));
}
Метод JumpNearWall() отвечает за прыжок персонажа возле стены. Аналогично методу Run(), он принимает параметр int directionX.
private void JumpNearWall(int directionX)
{
//убираем инерцию
rBody.velocity = Vector2.zero;
rBody.AddForce(new Vector2(directionX *
jumpForce * airAcceleration * 3,
jumpForce * airAcceleration * 5));
StartCoroutine(JumpCoolDown());
}
В конце тела этого метода вызываем корутин, который будет убирать возможность прыгать суммарно на 0.1 секунд.
IEnumerator JumpCoolDown()
{
yield return new WaitForSeconds(0.05f);
ableToJump = false;
yield return new WaitForSeconds(0.05f);
ableToJump = true;
}
Метод FlipPlayer() меняет направление используемого спрайта игрока.
void FlipPlayer(bool toLeft)
{
//если повернут направо, а нужно налево
if ((transform.localScale.x < 0 && toLeft) ||
//если повернут налево, а нужно направо
(transform.localScale.x > 0 && !toLeft))
{
transform.localScale = new Vector3(transform.localScale.x * -1f,
transform.localScale.y, transform.localScale.z);
}
}
Метод FixedUpdate() является зарезервированным и вызывается независимо от количества отработанных кадров. Для начала получаем значение, касается ли персонаж пола и стен слева и справа.
bool onGround = IsOnGround();
bool nearLwall = Physics2D.Raycast(
new Vector2(transform.position.x - playerWidth, transform.position.y),
-Vector2.right, 0.01f);
bool nearRwall = Physics2D.Raycast(
new Vector2(transform.position.x + playerWidth, transform.position.y),
Vector2.right, 0.01f);
Присваиваем спрайт по умолчанию – спрайт безделья.
spriteRender.sprite = IdleSprite;
Теперь считываем нажатие кнопок управления.
if (Input.GetKey(KeyCode.RightArrow))
{
//двигаем персонажа в позитивном направлении по оси Х
if (!nearRwall) Run(onGround, 1);
//присваиваем новый спрайт и меняем его направление
spriteRender.sprite = RunSprite;
FlipPlayer(false);
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
//двигаем персонажа в негативном направлении по оси Х
if (!nearLwall) Run(onGround, -1);
spriteRender.sprite = RunSprite;
FlipPlayer(true);
}
Если персонаж находится на поверхности и нажат пробел, то выполняем прыжок и активируем таймер до следующего прыжка.
if (Input.GetKeyDown(KeyCode.Space) && onGround && ableToJump)
{
//выполняем "прыжок с земли"
rBody.AddForce(new Vector2(0, jumpForce * acceleration* 1.7f));
spriteRender.sprite = jumpSprite;
//таймер до следующего прыжка
StartCoroutine(JumpCoolDown());
}
В противном случае разделяем поведение для прыжка возле левой и правой стенки.
if (Input.GetKeyDown(KeyCode.Space) && nearLwall && ableToJump)
{
//прыжок от стены вправо
JumpNearWall(1);
}
if (Input.GetKeyDown(KeyCode.Space) && nearRwall && ableToJump)
{
//прыжок от стены влево
JumpNearWall(-1);
}
Если игрок возле стенки, меняем спрайт и уменьшим скорость вертикального движения при прикосновении к стене после прыжка. Поворачиваем спрайт в нужном направлении и скрипт управления готов.
spriteRender.sprite = SlidingOnAWallSprite;
rBody.velocity = new Vector2(rBody.velocity.x,
(rBody.velocity.y > 9.0f) ? rBody.velocity.y * 0.6f : rBody.velocity.y);
if (nearLwall) FlipPlayer(true);
else FlipPlayer(false);
Теперь осталось опробовать все на практике. К данной статье прикреплен проект с уровнем «песочница», который можно изменить, как угодно добавив или убрав элементы.
Процедури та таймінг у відділі SEO
Автор: Андрій Афанасьєв
Введение
Всем привет! У меня давно созрела навязчивая мысль написать о том, какой является структура работы в техническом отделе SEO. “Почему именно такая тематика?” - спросите Вы. Это наболевшее. Иногда клиенты, да и просто люди, которые не занимаются всерьез данным продуктом, смотрят на весь процесс со стороны и думают: “Да это же просто дело. Взял проектик, денек-два оптимизировал сайт, ссылочек подкупил, всего делов. Может мне и самому SEO заняться?” Забавляет и интернет-пространство, например, рекламой с лозунгами наподобие: “Хватит платить сеошникам. Продвинь свой сайт самостоятельно!”. Это не может не веселить, если, конечно, не учитывать, что часть пользователей все-таки ведутся на подобные вещи.
Ну а если всерьез, то я скажу банальную вещь, что любая стоящая работа требует не менее качественного подхода. Любое интернет-агентство маленького, среднего или большого размаха разрабатывает и выстраивает свой процесс отработки клиентских проектов. В данной статье мы рассмотрим только работу технического отдела, потому что существует еще и аккаунтинг, и топ-менеджмент, которые тоже важны во взаимодействии компании и клиента. Но там “своя кухня” и она несколько отличается от технической.
Идем дальше…
Как известно, для того, чтобы построить качественный и надежный дом, нужно начать с фундамента. Так вот, в отделе SEO таковым является регламент процедур и тайминга. Это путеводитель как для руководителя отдела, так и для остальных членов команды. Зачем он нужен?
Отвечаю. У каждой компании в отработке находится много текущих + еженедельный поток новых клиентов, которые требуют в разы больше внимания, чем текущие. Когда я приведу пример технологии Abweb, Вы поймете критическую важность этого регламента. Если одновременно ведется работа по десяткам проектов, просто физически невозможно держать все в голове. Необходимо иметь универсальный план действий, который разбит на множество подзадач и переносить его в проекцию каждого проекта.
Ну, теперь конкретно о процессах
Для того, чтобы всю информацию было проще воспринять, я четко структурирую все процессы в виде двух таблиц. Как правило, процесс продвижения можно условно поделить на 2 глобальных этапа: внутренняя и внешняя оптимизация. Поэтому и процедуры для них разные.
Внутренняя оптимизация (1-й месяц)
Процедура
Старт выполнения
Тайминг
Проверка доступов от клиента (админка, FTP, хостинг)
1-й день работ
5 рабочих дней
Создание папки проекта и файла проекта в CRM с семантикой и основными доступами
1-й день работ
Анализ проекта, составление технического задания по внутренней оптимизации для программиста и техническое задание для копирайтера
2-й день работ
Отправка сформированных технических заданий аккаунт-менеджеру, который ведет проект.
В тот же день, когда составлено ТЗ, но не позднее 5-ого рабочего дня со старта проекта
Внедрение правок на тестовом домене.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на оптимизацию утверждено клиентом.
5 рабочих дней (4 дня реализация + 1 день на исправление багов по программной части)
Написание текстов для целевых страниц.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тексты утверждено клиентом.
Отправка выполненного ТЗ по оптимизации на тестовом домене аккаунт-менеджеру.
В день, когда ТЗ было полностью внедрено и проверено.
1 рабочий день
Отправка написанных текстов аккаунт-менеджеру.
В день, когда тексты были полностью написаны и проверены.
Перенос выполненных правок на основной домен.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тестовом утверждено клиентом.
2 рабочих дня
Размещение текстов.
В день, когда аккаунт-менеджер дал сигнал, что клиент утвердил тексты.
3 рабочих дня
Тестирование основной функциональности сайта после внесенных правок (форм заказа, авторизация, регистрация, добавление контента и его сохранение и т.д.) + исправление багов, если они есть
В день, когда все правки по внутренней оптимизации были перенесены на основной домен.
2 рабочих дня
Отправка сайта и целевых страниц на принудительную переиндексацию поисковыми системами для скорейшего индексирования ПС
В день, когда все правки по внутренней оптимизации были перенесены на основной домен + протестирован основной функционал
1 рабочий день
Добавление сайта в систему мониторинга для отслеживания позиций.
Когда все внедрено, отправлено на переиндексацию.
Итого примерно
19 рабочих дней
Ситуация выглядит таким образом, что за 16 рабочих дней (условно 3 рабочих недели) вся оптимизация должна быть внесена на основной версии сайта. 1 рабочая неделя отводится на тестирование выполненных правок, переиндексацию сайта, мониторинг динамики по позициям и составления отчета по всей проделанной работе.
Обращаю внимание, что тут предлагается такой подход, в котором сначала все внедряется на тестовой копии (которую обязательно нужно закрыть от индексации), демонстрируется и согласовывается с клиентом и, если все OK, переносится на основной домен. Я склонен считать, что это процесс затратный по времени, но зато безопасный!
Переходим ко второму и последующим месяцам.
Второй и дальнейшие месяцы плюс-минус похожи в плане выполняемых процессов.
Внешняя оптимизация (2-й и последующие месяцы)
Процедура
Старт выполнения
Тайминг
Планирование и составление ссылочной стратегии в виде ТЗ со списком закупаемых анкоров.
После получения оплаты
3 рабочих дня
Регистрация аккаунтов для закупки ссылок по проекту
1 этап закупки ссылок
На 4-й рабочий день
2 рабочих дня
Пополнение ссылочного аккаунта для 1 этапа
Плановая проверка сайта на предмет внутренней оптимизации/составление ТЗ по дооптимизации/отправка аккаунт-менеджеру на утверждение
12-й рабочий день
2 рабочих дня
Внедрение правок по дооптимизации на основании предыдущего пункта
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на дооптимизацию утверждено клиентом.
4 рабочих дня
Пополнение ссылочного аккаунта для 2 этапа
14-й рабочий день
2 рабочих дня
2 этап закупки ссылок
Модерация ссылочных бирж
1 раз в 2 рабочих дня
11 рабочих дней
Наполнение ТЗ на ссылки списком доноров, откуда куплены ссылки
За день до составления и отправления отчета аккаунт-менеджером.
1 рабочий день
Итого примерно
22 рабочих дня
Выше приведена таблица со всеми процедурами и ориентировочными дедлайнами по каждому из них.
Хочу сделать акцент на том, что весь этот грандиозный план действий должен быть ориентиром, но всегда бывают исключения. Сроки реализации задач часто зависят от сложности и объема работ по проекту, оперативности клиента по согласованиям технических заданий, текстов и внесенных правок. Могут также вклиниваться и форс-мажорные задачи, которых мы, как правило, не ожидаем. К таким нюансам нужно быть морально готовым и все равно максимально выстроить процессы под нужные дедлайны.
Достаточно ли этого?
Буду честен. Конечно, нет. Недостаточно лишь прописать процедуры. Чтобы все было “в ажуре”, Вам и нам нужны:
Квалифицированные и перспективные ребята, которые будут закрывать все вопросы и задачи, которые расписаны выше (SEO-специалисты, копирайтеры, программисты и т.д.);
Календарные планы по процессам. Например, календарный план по закупке ссылочной массы на каждый месяц, который позволит не запутаться в большом потоке, когда что закупать;
Правильная постановка задач друг другу в худшем случае с помощью блокнота, а в лучшем - CRM-систем или других программ для фиксирования задач и планирования;
Высокая степень самоорганизованности и четко выстроенный тайм-менеджмент у каждого сотрудника;
Регулярное проведение планерок.
Я с удовольствием поделился с Вами прототипом своего видения по выстраиванию процессов в отделе производства SEO. Буду рад услышать замечания и положительные отзывы. На сегодня пока все;)