Архив за месяц: Март 2015

TestCase в NUnit и Gallio

В NUnitTestCase - это атрибут, однако в Gallio это не так. Т.о. в каждой из обозначенных платформ своя реализация поведения обозначенного элемента. В этой заметке показан пример исходного кода, который успешно компилируется и работает как в случае использования Gallio, так и в случае использования NUnit.

Хорошую книгу о том, как грамотно создавать автономные и интеграционные тесты, в т.ч. и под такие закрытые системы как AutoCAD, я указывал здесь, в п.21. Кроме того, Gallio имеет неплохую offline документацию, доступную в меню Пуск -> Все программы -> Gallio -> Offline Documentation, а документация по NUnit присутствует online.

Gallio может выдавать отчёты о результатах теста как в формате XML, так и в формате HTML. В то же время NUnit может генерировать только XML. Для получения HTML на основе XML отчётов NUnit я рекомендую пользоваться утилитой NUnitOrange.

Полагаю, что лучше всего различие продемонстрирует исходный код:

/* © Andrey Bushman, 2015
 * Tests.cs
 * Recommended format of naming of tests: 
 * UnitOfWorkName_Scenario_ExpectedBehavior
 */
#if !ENTRY_POINT
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Converters;
using System.Windows.Forms;
using System.Windows;

#if NUNIT
using Fw = NUnit.Framework;

#elif GALLIO
using Gallio.Framework;
using Gallio.Model;
using Fw = MbUnit.Framework;
#endif

#if TEIGHA_CLASSIC
using Db = Teigha.DatabaseServices;
using Rt = Teigha.Runtime;
using Gm = Teigha.Geometry;
#endif

#if NANOCAD
using cad = HostMgd.ApplicationServices.Application;
using Ap = HostMgd.ApplicationServices;
using Ed = HostMgd.EditorInput;
 
#elif BRICSCAD
using cad = Bricscad.ApplicationServices.Application;
using Ap = Bricscad.ApplicationServices;
using Ed = Bricscad.EditorInput;
 
#elif AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Rt = Autodesk.AutoCAD.Runtime;
using Gm = Autodesk.AutoCAD.Geometry;
using Br = Autodesk.AutoCAD.BoundaryRepresentation;
using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
using Us = Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices;
#endif

#if AUTOCAD_NEWER_THAN_2012
using corecad = Autodesk.AutoCAD.ApplicationServices.Core.Application;
#endif

#if AUTOCAD && (PLATFORM_x64 || PLATFORM_x86)
using In = Autodesk.AutoCAD.Interop;
using Ic = Autodesk.AutoCAD.Interop.Common;
#endif

using Ex = Bushman.CAD.Extensions.ExtensionSample.UnitTests;

namespace Bushman.CAD.Extensions.ExtensionSample.UnitTests {
  [Fw.TestFixture,
#if NUNIT
 Fw.Apartment(ApartmentState.STA)
#endif
]
  public class Tests {

    const String blockName = "TEMP_BLOCK";

    // ***********************************************************************

    [Fw.Ignore("Sample of ignored test.")]
    [Fw.Test]
    [Fw.Category("Autodesk API")]
    [Fw.Description("Some description")]
    public void HasAttributeDefinitions_WhenAttribsExist_IsTrue() {
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.ObjectId id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForRead) as
              Db.BlockTableRecord;

            Fw.Assert.IsTrue(btr.HasAttributeDefinitions);
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    [Fw.Test]
    [Fw.Category("Autodesk API")]
    [Fw.Description("This test shows AutoCAD .NET API bug. It exists in " +
      "AutoCAD 2009-2016.")]
    public void HasAttributeDefinitions_WhenAttribsInNotExist_IsFalse() {
      Db.ObjectId id = Db.ObjectId.Null;
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            // create new block definition with an attribute definition
            id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;
            // remove all attribute definitions
            String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition))
              .Name;
            foreach (Db.ObjectId itemId in btr) {
              if (itemId.ObjectClass.Name == name) {
                Db.DBObject obj = tr.GetObject(itemId, Db.OpenMode.ForWrite);
                obj.Erase(true);
              }
            }
            tr.Commit();
          }
        }
        // Check attribute definition count
        using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
          Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
            Db.BlockTableRecord;

          Fw.Assert.IsFalse(btr.HasAttributeDefinitions);
          tr.Commit();
        }
      } // close and discard changes
    }

    // ***********************************************************************

    [Fw.Test]
    [Fw.Category("Bushman API")]
    [Fw.Description("I am some description 1 :)")]
    public void HasAttDefs_WhenAttribsExist_IsTrue() {
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.ObjectId id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForRead) as
              Db.BlockTableRecord;

            Fw.Assert.IsTrue(btr.HasAttDefs());
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    [Fw.Test]
    [Fw.Category("Bushman API")]
    [Fw.Description("I am some description 2 :)")]
    public void HasAttDefs_WhenAttribsIsNotExist_IsFalse() {
      Db.ObjectId id = Db.ObjectId.Null;
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;
            // remove all attribute definitions
            String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition))
              .Name;
            foreach (Db.ObjectId itemId in btr) {
              if (itemId.ObjectClass.Name == name) {
                Db.DBObject obj = tr.GetObject(itemId, Db.OpenMode.ForWrite);
                obj.Erase(true);
              }
            }
            tr.Commit();
          }

          // Check attribute definition count
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;

            Fw.Assert.IsFalse(btr.HasAttDefs());
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    // **********************************************************************

    // Creating of the temp block with an instance of AttributeDefinition
    internal static Db.ObjectId CreateBlockDefinition(Db.Database db) {
      if (null == db || db.IsDisposed) {
        throw new ArgumentException("null == db || db.IsDisposed");
      }

      Db.ObjectId id = Db.ObjectId.Null;

      // Create a temp block definition with an AttributeDefinition instance
      using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
        Db.BlockTable bt = tr.GetObject(db.BlockTableId, Db.OpenMode.ForWrite
          ) as Db.BlockTable;
        Db.BlockTableRecord btr = new Db.BlockTableRecord();
        btr.Name = blockName;

        // its content: the circle and attribite definition
        Db.Circle circle = new Db.Circle();
        circle.SetDatabaseDefaults();
        circle.Radius = 20.0;
        circle.Center = Gm.Point3d.Origin;
        circle.ColorIndex = 50;

        btr.AppendEntity(circle);

        Db.AttributeDefinition atDef = new Db.AttributeDefinition(
          circle.Center, "Hello!""ATTRIB""New value",
          Us.GetTextStyleStandardId(db));
        atDef.SetDatabaseDefaults();

        btr.AppendEntity(atDef);

        id = bt.Add(btr);
        tr.AddNewlyCreatedDBObject(btr, true);

        tr.Commit();
      }
      return id;
    }
    // **********************************************************************

    // This test template reads the Database from the DWG file for own work.
    [Fw.Test]
    [Fw.Category("TestCase using samples")]
    public void CircleIsExists() {
      const String dwgFileName = @"..\NUnit\data-for-testing\data_01.dwg";
      Boolean result = false;
      // Read Database from the DWG file
      using (Db.Database db = new Db.Database(truetrue)) {
        db.ReadDwgFile(dwgFileName, Db.FileOpenMode.OpenForReadAndWriteNoShare,
          false"");
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction())
          {
            Db.ObjectId msId = Us.GetBlockModelSpaceId(db);
            Db.BlockTableRecord ms = tr.GetObject(msId, Db.OpenMode.ForRead) 
              as Db.BlockTableRecord;
            Rt.RXClass rxc = Rt.RXClass.GetClass(typeof (Db.Circle));
            Db.ObjectId id = ms.Cast<Db.ObjectId>().FirstOrDefault();
            result = Db.ObjectId.Null != id;

            tr.Commit();
          }
          Fw.Assert.IsTrue(result);
        }
      } // close and discard changes
    }

    // **********************************************************************

#if GALLIO
    [Fw.StaticTestFactory]
    public static IEnumerable<Fw.Test> TestSuite_RenameMe() {
      yield return new Fw.TestSuite("Gallio tests some suite") {
        Description = "An example test suite.",
        Metadata =
        {
            { MetadataKeys.Category, "TestCase using samples" },
            { MetadataKeys.Description, "I am some description 3 :)" }
        },
        Timeout = TimeSpan.FromMinutes(2),
        Children =
        {
            new Fw.TestCase("CircleMustToBeExisting", () => {
              __CheckingOfCircleExisting(@"..\NUnit\data-for-testing\data_01.dwg", true);
            }),
            new Fw.TestCase("CircleMustNotToBeExisting", () => {
              __CheckingOfCircleExisting(@"..\NUnit\data-for-testing\data_02.dwg", false);
            })
        }
      };
    }
#elif NUNIT
    [Fw.Test]
    [Fw.Category("TestCase using samples")]
    [Fw.TestCase(@"..\NUnit\data-for-testing\data_01.dwg"true)]
    [Fw.TestCase(@"..\NUnit\data-for-testing\data_02.dwg"false)]
#endif
    public void CheckingOfCircleExisting(String dwgFileName, 
      Boolean expectedResult) {
      __CheckingOfCircleExisting(dwgFileName, expectedResult);
    }

    static void __CheckingOfCircleExisting(String dwgFileName, 
      Boolean expectedResult) {
      // Read Database from the DWG file
      using (Db.Database db = new Db.Database(truetrue)) {
        db.ReadDwgFile(dwgFileName, Db.FileOpenMode.OpenForReadAndWriteNoShare,
          false"");
        Boolean result = false;
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.ObjectId msId = Us.GetBlockModelSpaceId(db);
            Db.BlockTableRecord ms = tr.GetObject(msId, Db.OpenMode.ForRead)
              as Db.BlockTableRecord;
            Rt.RXClass rxc = Rt.RXClass.GetClass(typeof(Db.Circle));
            
            result = ms.Cast<Db.ObjectId>().Any(n=>n.ObjectClass.IsDerivedFrom(rxc));
            tr.Commit();
          }
          Fw.Assert.AreEqual(expectedResult, result);
        }
      } // close and discard changes
    }

    // **********************************************************************
  }
}
#endif

Результаты тестов, в пакетном режиме автоматически произведённых в AutoCAD 2009-2015 и представленных в формате HTML можно скачать и посмотреть отсюда. Пакетное тестирование происходило с использованием acad.exe для AutoCAD 2009-2012 и accoreconsole.exe для AutoCAD 2013-2015. Тесты для AutoCAD 2009 и 2010 скомпилированы с использованием платформы Gallio. Тесты для AutoCAD 2011-2015 собраны с использованием NUnit. Внешнее представление отчётов в HTML-формате у этих платформ несколько отличается, но оба варианта достаточно удобны для использования.

В коде тестов я активно использую один из своих вспомогательных классов: WorkingDatabaseSwitcher. Вот его исходный код:

/* © Andrey Bushman, 2015
 * WorkingDatabaseSwitcher.cs
 */
#if !ENTRY_POINT
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Converters;
using System.Windows.Forms;
using System.Windows;

#if NUNIT
using Fw = NUnit.Framework;

#elif GALLIO
using Gallio.Framework;
using Fw = MbUnit.Framework;
#endif

#if TEIGHA_CLASSIC
using Db = Teigha.DatabaseServices;
using Rt = Teigha.Runtime;
using Gm = Teigha.Geometry;
#endif

#if NANOCAD
using cad = HostMgd.ApplicationServices.Application;
using Ap = HostMgd.ApplicationServices;
using Ed = HostMgd.EditorInput;
 
#elif BRICSCAD
using cad = Bricscad.ApplicationServices.Application;
using Ap = Bricscad.ApplicationServices;
using Ed = Bricscad.EditorInput;
 
#elif AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Rt = Autodesk.AutoCAD.Runtime;
using Gm = Autodesk.AutoCAD.Geometry;
using Br = Autodesk.AutoCAD.BoundaryRepresentation;
using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
using Us = Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices;
#endif

#if AUTOCAD_NEWER_THAN_2012
using corecad = Autodesk.AutoCAD.ApplicationServices.Core.Application;
#endif

#if AUTOCAD && (PLATFORM_x64 || PLATFORM_x86)
using In = Autodesk.AutoCAD.Interop;
using Ic = Autodesk.AutoCAD.Interop.Common;
#endif

using Ex = Bushman.CAD.Extensions.ExtensionSample.UnitTests;

namespace Bushman.CAD.Extensions.ExtensionSample.UnitTests {

  /// <summary>
  /// This class switches the WorkingDatabase. It was created for using in the 
  /// tests.
  /// </summary>
  internal sealed class WorkingDatabaseSwitcher : IDisposable {

    Db.Database oldDb = null;
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="db">Target database.</param>
    public WorkingDatabaseSwitcher(Db.Database db) {
      oldDb = Hs.WorkingDatabase;
      Hs.WorkingDatabase = db;
    }

    public void Dispose() {
      Hs.WorkingDatabase = oldDb;
    }
  }
}
#endif

В обозначенных выше тестах я тестирую в том числе и некоторый метод HasAttDefs(), вот его исходный код:

/* © Andrey Bushman, 2015
 * ExtensionMethods.cs
 */
#if !ENTRY_POINT
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using System.Windows.Controls;
using System.Windows.Converters;
using System.Windows.Forms;
using System.Windows;

#if TEIGHA_CLASSIC
using Db = Teigha.DatabaseServices;
using Rt = Teigha.Runtime;
using Gm = Teigha.Geometry;
#endif

#if NANOCAD
using cad = HostMgd.ApplicationServices.Application;
using Ap = HostMgd.ApplicationServices;
using Ed = HostMgd.EditorInput;
 
#elif BRICSCAD
using cad = Bricscad.ApplicationServices.Application;
using Ap = Bricscad.ApplicationServices;
using Ed = Bricscad.EditorInput;
 
#elif AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Rt = Autodesk.AutoCAD.Runtime;
using Gm = Autodesk.AutoCAD.Geometry;
using Br = Autodesk.AutoCAD.BoundaryRepresentation;
using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
using Us = Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices;
#endif

#if AUTOCAD_NEWER_THAN_2009
using In = Autodesk.AutoCAD.Internal;
#endif

#if AUTOCAD_NEWER_THAN_2012
using corecad = Autodesk.AutoCAD.ApplicationServices.Core.Application;
#endif

#if AUTOCAD && (PLATFORM_x64 || PLATFORM_x86)
using In = Autodesk.AutoCAD.Interop;
using Ic = Autodesk.AutoCAD.Interop.Common;
#endif

using Ex = Bushman.CAD.Extensions.ExtensionSample;

namespace Bushman.CAD.Extensions.ExtensionSample {
  public static class ExtensionMethods {
    /// <summary>
    /// This method is a replace for the 
    /// <c>BlockTableRecord.HasAttributeDefinitions</c> method. Implementation 
    /// by Autodesk works wrong: it returns <c>True</c> after the 
    /// <c>AttributeDefinition</c> instance was deleted from the 
    /// <c>BlockTableRecord</c>. Info source: 
    /// http://bushman-andrey.blogspot.ru/2014/03/blocktablerecordhasattributedefinitions.html
    /// </summary>
    /// <param name="btr">Target instance of the <c>BlockTableRecord</c> class.
    /// </param>
    /// <returns>returns true or false.</returns>
    public static Boolean HasAttDefs(this Db.BlockTableRecord btr) {
      String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition)).Name;
      return btr.Cast<Db.ObjectId>().Any(n => !n.IsNull && n.IsValid
          && !n.IsErased && !n.IsEffectivelyErased && String.Equals(
          n.ObjectClass.Name, name, StringComparison.InvariantCulture));
    }
  }
}
#endif

Шаблон проекта VS для написания модульных тестов для .Net-расширений AutoCAD

Ранее я уже приводил пример создания общего шаблона для .NET плагина под любую версию AutoCAD не старше чем 2009-я. Аналогичный шаблон можно создать и для модульных тестов под эти плагины. 

В качестве платформы тестирования для управляемых расширений [плагинов] AutoCAD можно использовать Gallio или NUnit

Gallio благополучно работает с любой версией AutoCAD новее чем 2008 (я не проверял для версий старее чем AutoCAD 2009-й). Однако разработка Gallio на сегодняшний день приостановлена. Тем не менее его можно успешно продолжать использовать. Исходники Gallio опубликованы на GitHub и доступны для изучения\изменения. Однако Gallio работает только с acad.exe - использовать accoreconsole.exe не удастся.

NUnit успешно работает начиная с AutoCAD 2011 и во всех более новых версиях. Версии AutoCAD 2011 - 2014 требуют предварительной установки переменной NEXTFIBERWORLD в значение 0 с последующим перезапуском AutoCAD. По завершению работы тестов, не забудьте переменной NEXTFIBERWORLD снова назначить в качестве значения 1.

Начиная с AutoCAD 2015 компания Autodesk уходит от использования фиберов, поэтому версии AutoCAD, новее чем 2014-я не требуют предварительного изменения обозначенной переменной для успешной работы тестов. Поскольку версии AutoCAD 2010 и все более старые не имеют переменной NEXTFIBERWORLD, то использовать в них тесты NUnit не представляется возможным.

В отличие от Gallio, NUnit может работать как с acad.exe, так и с accoreconsole.exe.

Т.о. в AutoCAD 2009 и 2010 следует использовать тестовую платформу Gallio, в то время как начиная с AutoCAD 2011 можно использовать либо Gallio, либо NUnit по вашему желанию (я предпочитаю NUnit).

Один и тот же исходный код модульных тестов может компилироваться под разные платформы тестирования. По аналогии с шаблоном плагинов AutoCAD, который я демонстрировал в видео ранее, можно создать шаблон для модульных тестов управляемых расширений AutoCAD. Такой шаблон позволяет пакетно компилировать один и тот же исходный код модульных тестов под разные версии AutoCAD с использованием как платформы Gallio, так и платформы NUnit. В приведённом ниже примере для AutoCAD 2009 и 2010 я генерирую тесты с использованием Gallio, а для AutoCAD 2011-2015 - с использованием NUnit. Оба проекта построены на основе соответствующих шаблонов: первый - на основе шаблона для .NET расширений AutoCAD, а второй - на основе шаблона для создания модульных тестов для .NET расширений AutoCAD.

Дополнительно генерируется набор BAT-файлов, каждый из которых предназначен для запуска тестов в конкретной версии AutoCAD. Результаты тестирования оформляются в виде отчёта в формате HTML. На мой взгляд всё получается достаточно удобно.

Когда-то я писал о баге, присутствующем в AutoCAD .NET API и давал свой вариант обходного решения. Обозначенное ниже видео построено на основе этого кода: тесты выявляют баг в API от Autodesk, а так же проверяют работоспособность моего варианта решения.


UPD:
Добавил генерацию BAT-файла, который последовательно выполняет тесты во всех нужных версиях AutoCAD (в данном случае AutoCAD 2009-2015). Вот видео на эту тему:



Далее привожу код тестов данного видео:

/* © Andrey Bushman, 2015
 * Tests.cs
 */
#if !ENTRY_POINT
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Converters;
using System.Windows.Forms;
using System.Windows;

#if NUNIT
using Fw = NUnit.Framework;

#elif GALLIO
using Gallio.Framework;
using Fw = MbUnit.Framework;
#endif

#if TEIGHA_CLASSIC
using Db = Teigha.DatabaseServices;
using Rt = Teigha.Runtime;
using Gm = Teigha.Geometry;
#endif

#if NANOCAD
using cad = HostMgd.ApplicationServices.Application;
using Ap = HostMgd.ApplicationServices;
using Ed = HostMgd.EditorInput;
 
#elif BRICSCAD
using cad = Bricscad.ApplicationServices.Application;
using Ap = Bricscad.ApplicationServices;
using Ed = Bricscad.EditorInput;
 
#elif AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Rt = Autodesk.AutoCAD.Runtime;
using Gm = Autodesk.AutoCAD.Geometry;
using Br = Autodesk.AutoCAD.BoundaryRepresentation;
using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
using Us = Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices;
#endif

#if AUTOCAD_NEWER_THAN_2012
using corecad = Autodesk.AutoCAD.ApplicationServices.Core.Application;
#endif

#if AUTOCAD && (PLATFORM_x64 || PLATFORM_x86)
using In = Autodesk.AutoCAD.Interop;
using Ic = Autodesk.AutoCAD.Interop.Common;
#endif

using Ex = Bushman.CAD.Extensions.CAD.ExtensionMethods.UnitTests;

namespace Bushman.CAD.Extensions.CAD.ExtensionMethods.UnitTests {
  [Fw.TestFixture,
#if NUNIT
 Fw.Apartment(ApartmentState.STA)
#endif
]
  public class Tests {

    const String blockName = "TEMP_BLOCK";

    // ***********************************************************************
    
    [Fw.Test]
    [Fw.Category("Autodesk API")]
    public void HasAttributeDefinitions_WhenAttribsExist_IsTrue() {
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.ObjectId id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForRead) as
              Db.BlockTableRecord;

            Fw.Assert.IsTrue(btr.HasAttributeDefinitions);
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    // [Fw.Ignore("We can't fix this bug, because it is by Autodesk.")]
    [Fw.Test]
    [Fw.Category("Autodesk API")]
    public void HasAttributeDefinitions_WhenAttribsInNotExist_IsFalse() {
      Db.ObjectId id = Db.ObjectId.Null;
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            // create new block definition with an attribute definition
            id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;
            // remove all attribute definitions
            String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition))
              .Name;
            foreach (Db.ObjectId itemId in btr) {
              if (itemId.ObjectClass.Name == name) {
                Db.DBObject obj = tr.GetObject(itemId, Db.OpenMode.ForWrite);
                obj.Erase(true);
              }
            }
            tr.Commit();
          }
        }
        // Check attribute definition count
        using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
          Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
            Db.BlockTableRecord;

          Fw.Assert.IsFalse(btr.HasAttributeDefinitions);
          tr.Commit();
        }
      } // close and discard changes
    }

    // ***********************************************************************

    [Fw.Test]
    [Fw.Category("Bushman API")]
    public void HasAttDefs_WhenAttribsExist_IsTrue() {
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.ObjectId id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForRead) as
              Db.BlockTableRecord;

            Fw.Assert.IsTrue(btr.HasAttDefs());
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    [Fw.Test]
    [Fw.Category("Bushman API")]
    public void HasAttDefs_WhenAttribsIsNotExist_IsFalse() {
      Db.ObjectId id = Db.ObjectId.Null;
      // Create new temp database
      using (Db.Database db = new Db.Database(truetrue)) {
        using (new WorkingDatabaseSwitcher(db)) {
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            id = CreateBlockDefinition(db);
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;
            // remove all attribute definitions
            String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition))
              .Name;
            foreach (Db.ObjectId itemId in btr) {
              if (itemId.ObjectClass.Name == name) {
                Db.DBObject obj = tr.GetObject(itemId, Db.OpenMode.ForWrite);
                obj.Erase(true);
              }
            }
            tr.Commit();
          }

          // Check attribute definition count
          using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForWrite) as
              Db.BlockTableRecord;

            Fw.Assert.IsFalse(btr.HasAttDefs());
            tr.Commit();
          }
        }
      } // close and discard changes
    }

    // **********************************************************************

    // Creating of the temp block with an instance of AttributeDefinition
    internal static Db.ObjectId CreateBlockDefinition(Db.Database db) {
      if (null == db || db.IsDisposed) {
        throw new ArgumentException("null == db || db.IsDisposed");
      }

      Db.ObjectId id = Db.ObjectId.Null;

      // Create a temp block definition with an AttributeDefinition instance
      using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
        Db.BlockTable bt = tr.GetObject(db.BlockTableId, Db.OpenMode.ForWrite
          ) as Db.BlockTable;
        Db.BlockTableRecord btr = new Db.BlockTableRecord();
        btr.Name = blockName;

        // its content: the circle and attribite definition
        Db.Circle circle = new Db.Circle();
        circle.SetDatabaseDefaults();
        circle.Radius = 20.0;
        circle.Center = Gm.Point3d.Origin;
        circle.ColorIndex = 50;

        btr.AppendEntity(circle);

        Db.AttributeDefinition atDef = new Db.AttributeDefinition(
          circle.Center, "Hello!""ATTRIB""New value",
          Us.GetTextStyleStandardId(db));
        atDef.SetDatabaseDefaults();

        btr.AppendEntity(atDef);

        id = bt.Add(btr);
        tr.AddNewlyCreatedDBObject(btr, true);

        tr.Commit();
      }
      return id;
    }
  }
}
#endif

Вставка HTML в буфер обмена

При работе с буфером обмена из C# выяснилось, что вставить туда HTML так, чтобы программы типа Word распознавали его не как текст, а именно как HTML не совсем просто, под катом пример.


Собственно, для вставки HTML в буфер, его нужно специальным образом подготовить. Вот таким методом:
public static string PrepareHtmlToClippboard(stringhtml)
{
    Encoding enc = Encoding.UTF8;

    string begin = "Version:0.9rnStartHTML:{0:000000}rnEndHTML:{1:000000}"
        + "rnStartFragment:{2:000000}rnEndFragment:{3:000000}rn";

    string html_begin = "rnrn"
        + "
        + " content="text/html; charset=" + enc.WebName + "">rn"
        + "HTML clipboardrn
rnrn"
        + "";

    string html_end = "rn
rnrn";

    string begin_sample = String.Format(begin, 0, 0, 0, 0);

    intcount_begin = enc.GetByteCount(begin_sample);
    intcount_html_begin = enc.GetByteCount(html_begin);
    intcount_html = enc.GetByteCount(html);
    intcount_html_end = enc.GetByteCount(html_end);

    string html_total = String.Format(
        begin
        , count_begin
        , count_begin + count_html_begin + count_html + count_html_end
        , count_begin + count_html_begin
        , count_begin + count_html_begin + count_html
        ) + html_begin + html + html_end;

    return html_total;

}
Ну и вот так это можно использовать:
DataObject dataObj = new DataObject();
dataObj.SetData(DataFormats.Html, PrepareHtmlToClippboard("здесь HTML"));
dataObj.SetData(DataFormats.Text, "здесь текст, если приемник не понимает html");

Clipboard.SetDataObject(dataObj, true);
Собственно все.

Касова термолента, термочеки, чекова стрічка

Касова стрічка (термолента) — це стрічка, на якій друкують чеки в магазинах, вона виготовлена ​​на основі термобумаги. Необхідне зображення на стрічці проявляється після того як на неї впливали високими температурами спеціальної друкуючої головки. Основним плюсом цього виду стрічки вважається те, що для друку не потрібен картридж.

Чекова стрічка — спеціальний папір, згорнута в невеликі рулони і володіє деякими особливими властивостями:

Колір — білий,
добре вбирати фарбу і точно відповідати розмірам касових апаратів, для того щоб прискорити процес заміни чекової стрічки.

Чекова стрічка також розрізняється по кількості шарів (одно- або двошаровий)

Сучасна касова стрічка, так само як і сучасні етикетки, виготовлена ​​у відповідності зі все зростаючими вимогами до її якості. Вона зовсім не нагадує той сірий і непоказний касовий ролик, який можна було зустріти в магазинах навіть у другій половині 20 століття.

Сьогодні касові видаткові матеріали роблять з щільної, ідеально білого паперу, яка виключно добре вбирає фарбу, не допускаючи її розсіювання або розмазування при виході з касової машини.

Існують кілька варіантів чекової стрічки, найпоширеніші з яких:
звичайна касова стрічка
касова стрічка двошаровий
чекова стрічка активна
чекова стрічка активна двухактівная
касовий ролик з термодруком

Робот-пилосос YCR-M02: перший робот з інтелектом!

Не втомлююся дивуватися, як швидко почала розвиватися робототехніка, ось уже на прилавках магазинів і в Інтернеті з’явилися роботи-пилососи п’ятого покоління, а здавалося, зовсім недавно ми з подивом дивилися на перші чудо-моделі домашніх помічників. Чим же вирішив здивувати нас виробник на цей раз? Пальма першості в розробці роботів-пилососів п’ятого покоління належить, звичайно iRobot. Лідеру високих технологій США. Що ж нового в Roomba 530?

1. Просунута система навігації.

Робот орієнтується в просторі так, ніби у нього є очі. Дійсно, безліч датчиків дозволяють йому не натикатися на меблі або предмети. Корпус робота оброблений спеціальним м’яким матеріалом, так що коли робот-пилосос «впирається» в шафу або стіну, він змінює свою траєкторію і очищає поверхню уздовж предмета. До того ж, виробникові вдалося досягти практично 100% охоплення поверхні підлоги, завдяки розробці унікальних механізмів руху робота.

stat_06_2
Робот легко об’їжджає предмети

2. Потужні щітки.

Потужні турбо-щітки нового покоління здатні впоратися не тільки з пилом, брудом, але і шерстю тварин. Щітки обертаються дуже швидко назустріч один одному, завдяки цьому видаляються навіть найсерйозніші і в’їдаються забруднення.

3. Очищення повітря.

Просунута система фільтрації дозволяє очистити повітря не тільки від пилу, але навіть від найдрібніших алергенів, тому дана модель робота-пилососа буде особливо актуальна для сімей, де є алергіки і маленькі діти.

stat_06_3
На зарядку робот стає автоматично

4. Алгоритм антізапутиванія.

Робот-пилосос Roomba 530 може впоратися не тільки з ковроліном, лінолеумом, паркетом або керамічної плитки, але і спокійно заїхати і з’їхати з килима, навіть володіє довгим ворсом і бахромою. Унікальний алгоритм антізапутиванія відключає щітки робота при зустрічі з подібним перешкодою, внаслідок чого зупинки процесу збирання не відбувається.

stat_06_1
Робот не заплутається в пензликах килима

Смотрите также:купить пылесос irobot

5. Система голосових повідомлень.

Всі сервісні повідомлення робот повідомить Вам особисто завдяки сучасній системі звукового оповіщення. Ви завжди точно знатимете, чи потрібно очистити контейнер для сміття або ввести нову програму збирання. Хоч це поки і не інтелект, але роботи-пилососи вже почали розмовляти!

Жіночий бізнес — як я відкривала Інтернет-магазин сама або історія одного інтернет-магазину …

Бажання зайнятися власним бізнесом було в мене давно. Ніяк не могла знайти відповіді на основні питання: чим займатися, що пропонувати на ринку (товар або послуги), в якій сфері і т.д. Плюс для старту потрібен початковий капітал (мінімум 400 000 руб.), Якого на той момент не було.

Життя саме поступово розставляла все на свої місця.

Восени 2010 року нас з подругою привернула сфера весільного бізнесу.

Ідея пропонувати нареченим красиві, якісні весільні сукні здалася нам дуже привабливою.

Для цього необхідно було 200 000 руб. початкового капіталу, Show-room, постачальники. Здавалося, все реально, всі пункти здійсненні, але звістка про те, що скоро я стану мамою різко внесло свої корективи в наші плани спільного бізнесу.

Ми вирішили призупинити хід дій до кращих часів, за реальними розрахунками — це року на 3.

У процесі підготовки до материнства я подумала, що мені необхідна додаткова робота, без якої я просто не можу.

Найоптимальніший варіант суміщення — інтернет-магазин. Відкрити інтернет-магазин — це ідеальний спосіб самореалізації жінки в роботі, не обмежуючи при цьому виконання материнських обов’язків. Так би мовити «… і вовки ситі, і вівці цілі».

Далі треба було вирішити, що продавати. З досвіду підготовки до весілля мені згадалася проблема з весільною біжутерією: вибір малий, ціни великі. Так, було вирішено зупинитися на продажу весільної біжутерії через інтернет-магазин.

Де взяти движок рішення є скрипта интернет-магазина.

Apple: «Ми отримали тільки дев’ять скарг на вигнуті айфони»


a502apple-bend-9-54245da6a9445[1]
Компанія Apple заявила, що лише дев’ять покупців iPhone 6 звернулися до неї з проблемою вигнутого корпусу, і додала, що при нормальному використанні таких дефектів у її смартфонів виникнути не може. Про це повідомляє блог 9to5mac з посиланням на закритий матеріал Financial Times.

Через кілька днів бурхливого обговорення проблеми, що отримала назву Bendgate, Apple вперше офіційно відреагувала на скарги. Вона зазначила, що деформація корпусу торкнулася лише 9 покупців iPhone з більш ніж 10 мільйонів.

При цьому iPhone 6 і iPhone 6 Plus пройшли безліч тестів на міцність і надійність, включаючи вигин за трьома точкам, циклічну зміну тиску і обертання, щоб бути готовими до щоденного використання в умовах реального життя.

«Наші айфони спроектовані, розроблені і зібрані, щоб бути одночасно красивими і міцними. IPhone 6 і iPhone 6 Plus використовують ретельно вивірену цілісну конструкцію з обробленого анодованого алюмінію 6000 серії, який загартований для додаткової міцності. Вони також оснащені сталевими і титановими вставками, щоб посилити найуразливіші ділянки, і використовують саме тверде скло в індустрії смартфонів. Ми дуже ретельно підбирали ці високоякісні матеріали, керуючись їх міцністю і долговечностью.Apple «

Смотрите также:объектив на айфон

Раніше представник служби підтримки Apple повідомив, що компанія безкоштовно замінить смартфон з деформацією у випадку, якщо експертиза покаже, що користувач не заподіяв шкоду пристрою навмисно.

Численні повідомлення про те, що тонкий корпус iPhone 6 і особливо iPhone 6 Plus гнеться почали надходити через кілька днів після рекордного старту продажів смартфонів у першій хвилі країн, включаючи США, Францію і Великобританію.

Масові скарги на вигини корпусів надходили і в 2012 році, після запуску iPhone 5, який на момент написання замітки є найпопулярнішим смартфоном Apple. Тоді ситуацію погіршував ще й так званий scuffgate: з чорної версії iPhone 5 легко облазить фарба. Цей недолік був виправлений в iPhone 5s, у якого ця модель була замінена на версію Space Gray.

нандролон деканоат

Опис
Нандролон був вперше синтезований в 1950 році, але широке застосування в спортивній практиці він знайшов лише через роки. У бодібілдингу нандролон залишився досі — разом з тестостероном і метандростенолоном він царює тут практично неподільно (хоча на заході — в тих же США його позиції дуже сильно останнім часом ослабли), а от з інших видів спорту, особливо олімпійських, стероїд практично повністю пішов. Пов’язано це з появою чутливих хромато-мас-спектрометрів, що дозволяють визначати довгоживучі метаболіти цього стероїду протягом більше двох років після закінчення його прийому. Але це зовсім не означає, що допінгові скандали, пов’язані з нандролоном, назавжди зникли з перших шпальт газет.

Смотрите также:нандролон купить

Навпаки.
Ті з вас, хто цікавиться футболом, навряд чи забули хвилю позитивних проб на нандролон в італійській, іспанській і французькій чемпіонатах. Крістоф Дюгаррі, Фернанду Коуту, Йап Стам, Едгар Давідс, Хосеп Гвардьола — ось далеко не повний список жертв «нандролоновой війни». Не забута і прикра доля російського футболіста Ігоря Шалімова, дискваліфікованого в Італії якраз за застосування нандролона. Не відстає від короля спорту і королева — легка атлетика. У 1999 році світ був приголомшений: у двох видатних спринтерів сучасності — британця Лінфорда Крісті та жительки Ямайки, а нині спортсменки зі Словенії Мерилін Отті — в крові був виявлений заборонений препарат, ним виявився, як ви вже, мабуть, здогадалися, нандролон. Роком раніше постраждав менш відомий спринтер, але все, же чемпіон Європи з бігу на 200 метрів дуг Уокер, двохтисячний став останнім роком у кар’єрі американського штовхача ядра Сі Джей Хантера. Але ж можна ще згадати чеського тенісиста Петера корду, британського плавця Марка Річардсона — і це тільки найгучніші імена.
Ласкаво б всі скандали ставилися до 70-80-м рокам, але вони почали виникати якраз тоді, коли, здавалося б, уже не залишилося в світі спортсмена, що не обізнаного про неможливість приховати вживання нандролона від пильного ока допінг-контролю. Крім усього іншого, існує маса стероїдів, доступних топ-атлетам і не визначаються за допомогою допінг-тестів. У чому ж справа? Розгадка, як завжди, лежала на поверхні. Виявилося, що 19-нортестостерон теоретично може синтезуватися і сам по собі в людському організмі, тому є кілька шляхів. Але саме теоретично, практично доказів цього факту поки немає. Останні, дослідження, однак, доводять, що можливі прекурсори (попередники) нандролона — 19-норандростерона і 19-ноетіохоланолон — все-таки синтезуються організмом людини, причому у 10% живуть на Землі в кількості, в 4 рази перевершує норму. І саме вони можуть бути одним з винуватців хибнопозитивних допінг-тестів на нандролон. Після визнання цього факту, звинувачення з Мерілін Отті і Дуга Уокера були зняті.
Другий винуватець — нандролон, що входить до складу ветеринарних препаратів, без яких тепер вже не мислиться тваринництво. Споживане в їжу, м’ясо може містити достатньо велика кількість метаболітів нандролона. І, нарешті, третій винуватцем могли бути цілком легальні донедавна прогормони, В поєднанні з важким тренінгом, стресом і зневодненням організму вони були здатні призвести до підвищення рівня ендогенних прекурсорів нандролона в організмі в 5 разів. Вважається, що саме прогормони спровокували позитивні проби на нандролон у Річардсона і Хантера. Є, правда, і ще одне пояснення цих скандалів, про який воліють не згадувати «всує». Справа в тому, що до останнього часу хорошим і вельми дешевим «екраном», яке ховало метаболіти нандролона від пильного ока допінг-лабораторій, був аспірин. Тепер цей «екран» вміють «просвічувати» наскрізь.
Але залишимо допінг-контроль осторонь і перейдемо безпосередньо до нандролон. За своєю структурою молекула цього стероїду практично ідентична молекулі тестостерону. За винятком однієї «маленької» деталі — у неї відсутній метильная група 19. Звідси й інша, також вельми поширене, назва нандролона — 19-Нортес-тостерон.
Завдяки елімінації однієї метильної групи, нандролон знайшов здатність куди як краще стабілізувати андрогенні рецептори, тобто час існування комплексу «нандролон + АР» більше часу існування аналогічного комплексу за участю тестостерону, і не просто більше, а рази так в 2-3. А ви самі розумієте: більше часу андрогенний рецептор знаходиться в активованому стані — більше білка може синтезувати клітка.
Не всі, однак, так добре. Значна частина вільного нандролона перетворюється на дігідронандролон (ДГН), який вже набагато (приблизно в ті ж 2-3 рази) слабкіше власне нандролона. ДГН, крім усього іншого, пригнічує прохідність сигналу по нервових волокнах, на практиці це означає ослаблення лібідо і зменшення нейром’язової стимуляції. Однак перетворення нандролона в ДГН все ж має і позитивну сторону — нандролон проявляє знижену активність в простаті, шкірі і шкірному покриві голови. Простіше кажучи, приймають цей препарат атлети в набагато меншому ступені піддаються таким побічним ефектам тестостерону, як гіпертрофія простати, акнє або випадання волосся.
Нандролон не схильний до дії ароматази. Незважаючи на це, він все ж перетворюється в естроген, але в дуже незначних кількостях: раз на п’ять менших, ніж тестостерон. У той же час відомо, що нандролон володіє вираженою прогестагенной активністю, що може привести, при дозуваннях препарату понад 600 мг на тиждень, до гінекомастії.
Застосування
Тут саме той випадок, коли вирішальну роль відіграють генетичні відмінності. Для одних атлетів нандролон — просто чудовий препарат, іншим же його застосування (особливо це стосується «довгих» ефірів нандролона) нічого, крім проблем, не принесе. Ці «інші» — спортсмени з підвищеним вмістом в м’язових волокнах ферменту 5 -? — Редуктаза або з підвищеною чутливістю до прогестерону. Перші з «інших», втім, можуть спробувати замінити нандролон деканоат фінілпропіонатом, про який буде сказано трохи нижче. Другим же варто обмежитися тижневими дозировками препарату, що не перевищують 300-400 мг або використовувати спільно з нандролоном станозолол. Решті ж нандролон може дати досить вражаючі результати в наборі маси, хоча в цьому питанні він все ж поступається визнаному лідеру — тестостерону. Так само, як і тестостерон, нандролон сприяє активації клітин-супутників і підвищенню рівня ІФР-1 в крові, наслідком чого є гіперплазія м’язів. Правда, дозування для цього повинні бути вищими, ніж у випадку тестостерону — понад 600 мг на тиждень. До речі, при дозуваннях близько 800-1000 мг на тиждень нандролон сприяє затримці води організмом не, тільки, не гірше, але навіть в ряді випадків і краще, ніж всі той, же тестостерон. У період «сушки» і підготовки до змагань нандролон деканоат використовувати абсолютно недоцільно.
Застосування нандролона надає благотворний вплив на суглоби. Цей факт раніше приписувався «скупченню води в суглобових сумках в результаті застосування нандролона», і, як наслідок, полегшенню функціонування суглобів. Насправді це не зовсім так. Точніше, це ще далеко не все.
Строго кажучи, ніяка додаткова вода в суглобових сумках під впливом нандролона не скупчується. Нандролон, який є досить-таки сильним прогестином (20% від потужності прогестерону) і має здатність, щоправда досить слабо вираженою, до перетворення в естрадіол, затримує воду в організмі. З суглобових сумок вода просто не йде, як це має місце у випадку використання препаратів, що мають антиестрогенної (дростанолон) або антіпрогестагенной (станозолол) активністю. «Цикл», в якому використовуються, наприклад тільки тренболон, станозолол і дростанолон, має всі шанси на тлі важких тренувань нанести досить сильний удар по вашим суглобам. Крім цього, варто відзначити, що як прогестини, так і естрогени (при перевищенні певної концентрації в плазмі крові) мають антизапальними властивостями. А оскільки нандролон, як уже було сказано, має прогестагенной активністю, а також здатний перетворюватися в естрадіол, він повинен робити благотворний вплив на суглоби. І справляється з цим завданням стероїд краще своїх «побратимів», начебто тестостерону, метандростенолона або оксиметолона, яким притаманне що-небудь одне — або прогестагенная активність, або схильність до ароматизації.
А ось що стосується зростання сили м’язів, то тут не все так добре. Нандролон ніяк не допомагає відновленню центральної нервової системи після навантаження. Тут потрібно враховувати, що нандролон виключно сильно пригнічує виробництво ендогенного тестостерону, а значить, провідність нервових волокон під час його застосування падає, що робить його практично марним для зростання сили м’язів, а також може викликати таке неприємне явище, як порушення еректильної функції (в народі іменоване «дека дик»). То пак, застосування нандролона є виправданим лише в тому випадку, якщо разом з ним застосовується який-небудь сильний андроген, хоча б той же тестостерон.
Побічні ефекти
Нандролон виключно сильно пригнічує виробництво організмом тестостерону, в цьому питанні він практично лідер. Пов’язано це з тим, що довгоживучі метаболіти нандролона також володіють прогестагенной активністю, та й сам нандролон знаходиться в організмі виключно довго. Як результат — масу, знайдену «на нандролоне», дуже важко втримати. В той же час, проблеми, пов’язані з ароматизацией, цьому стероїду практично не властиві, ризик гінекомастії і надмірного скупчення води супроводжує тільки прийом високих (понад 600 мг на тиждень) доз препарату.
Дозування
Ефективні дозування нандролона починаються з 200 мг на тиждень і … йдуть практично в «нескінченність». Відомі випадки застосування нандролона деканоата атлетами професійного рівня в дозуваннях порядку 800 мг на день! (Треба, однак, сказати, що останнім часом професійні атлети відмовляються від застосування нандролона, вважаючи цей препарат, так би мовити, «вчорашнім днем»). Не варто, втім, забивати собі голову такими дозами — більшість з вас професійного рівня навряд чи коли досягнуть — верхня межа споживання нандролона встановимо в 1 грам на тиждень.
Виходячи з досить довгого періоду напіврозпаду нандролона деканоата, можна рекомендувати його ін’єкції один раз в 7-8 днів, хоча особисто я є прихильником більш частих ін’єкцій навіть довгоживучих препаратів — так можна забезпечити більш стабільний рівень стероїду в крові.
Комбінування з іншими препаратами
Нандролон вкрай рідко застосовується поодинці — бути єдиним стероидом в циклі це, все ж, доля тестостерону, та ще тренболона. «Класичною» вважається комбінація нандролона з метандростенолоном — дійсно, ці два стероїди є синергистами. Але по ефективності її перевершує комбінація нандролона з тестостероном (зазвичай використовують одну «частина» нандролона на дві «частини» тестостерону, тобто, тестостерону треба приймати вдвічі більше). Така комбінація має особливий сенс з причин, які були викладені вище. Комбінація ж усіх трьох перерахованих препаратів є практично найкращою для набору маси. У той же час масу, «придбану» за допомогою цього стероїду, дуже важко утримати, тому нандролон ні в якому разі не повинен бути останнім стероидом в циклі, у другій половині циклу його доцільно замінити болденоном або Метенолон.
Застосування жінками
Треба сказати, що нандролон в 50-60 роки минулого сторіччя досить широко застосовувався для лікування жінок у рамках традиційної медицини. До початку 90-х років того ж століття він активно застосовувався жінками й у спортивній практиці. Похитнули позиції нандролона експерименти Гусенс і Хейнонена. У першому випадку жінки брали нандролон деканоат в дозуванні 50 мг кожні 3-4 дні і 50% з них випробували явища вірилізації. У другому випадку явища вірилізації були виявлені у всіх випробовуваних, але про дозуваннях нічого не було сказано. Втім, дозування в 100 мг на тиждень (50 мг раз на 3-4 дні) для жінок дійсно можна вважати явно завищеною. В експерименті, проведеному в 1996 році, доза нандролона, знову ж деканоата, була вкрай низькою — 30 мг раз на два тижні. Тут уже явищ вірилізації не зазнав ніхто. Наведені дозування треба вважати крайностями, і тим, хто неодмінно хоче поекспериментувати з нандролоном, можна порадити «балансувати» між ними, вибравши для початку дозу в 50 мг раз на десять днів, і поступово її, збільшуючи до рівня 75-100 мг раз на ті ж десять днів. Природно, при появі перших ознак вірилізації прийом препарату слід негайно припинити.

Які килими в тренді

Дизайнер Катерина Чистякова, буваючи на головних європейських меблевих виставках, помітила кілька чітких напрямків у дизайні килимів:

Ф’южн. Килими з футуристичними малюнками, неприродно яскравих кольорів і нестандартних форм.

Анімалістичні принт. Особливою увагою користуються килими з тваринами принтами: леопард, зебра, жираф, павич, оперення красивих птахів.

Графіка сьогодні представлена ​​дуже багате: пікселі, рисочки, смужки, моноцвет, зигзаг, складні геометричні орнаменти.

Антіграфіка — одне з найкрасивіших сучасних напрямків: розмиті акварельні плями, перехід кольорів, градієнт, ефект де граді. Антіграфічний килим легко використовувати як у сучасному інтер’єрі, так і в будинку, виконаному в стилістиці нової класики. Чуттєво і стильно!

Серед модних килимів декоратор Наталія Райлян виділяє також: вантажні килими (шик потертій класики), ажурні (виглядають легко і романтично), килими-послання (з написами, буквами і цифрами). Серед трендових кольорів — відтінки синього і зеленого (середземноморський синій — холодний і заспокійливий; складний і обволікаючий оливковий), цитрусові відтінки, курна м’ята, винні кольору і колір іржі.

Землі сільськогосподарського призначення

Земельний кодекс дає однозначне визначення того, що слід вважати землями сільськогосподарського призначення. Такими, згідно зі ст. 77 документа, є землі за межею сільських і міських поселень, надані для потреб сільського господарства, а також призначені для цих цілей.

Смотрите также:земельные участки все коммуникации

Категорії земель сільськогосподарського призначення

Землі сільськогосподарського призначення ділять на дві групи:

1. Поклад, рілля, сіножаті, виноградник та інші багаторічні насадження — це сільськогосподарські угіддя.

2. Землі під будівлями, спорудами, призначеними для виробництва, зберігання та первинної переробки сільськогосподарської продукції, внутрішньогосподарські дороги, полезахисні лісосмуги, ліси, які не входять до землі лісового фонду, деревно-чагарникова рослинність, несільськогосподарські угіддя, а також неудобья у вигляді ярів, солончаків і іншого — це несільськогосподарські угіддя.

У минулі часи якщо й існувало таке ділення земель на категорії, то досить умовне. Все тому, що право постійного (безстрокового) користування на землю перебувало у держави, а самі землі закріплювалися за сільськогосподарськими організаціями.

До чого привела реформа

Земельна реформа дев’яностих років призвела до того, що всі невживані колгоспами і радгоспами землі (і навіть до десяти відсотків сільськогосподарських угідь) були вилучені. Все, що залишилося у колгоспника, поділили на умовні земельні частки і передали у власність громадян. У підсумку колгоспи і радгоспи залишилися лише з несільськогосподарськими угіддями, які до всього ще й приватизувати не можна було.

Так на базі віджили свій вік колгоспів і радгоспів утворилися зовсім нові товариства, товариства і кооперативи. Розпорядитися своєю часткою власнику з найрізноманітніших причин виявилося важко. В результаті новостворені сільськогосподарські товариства, товариства і кооперативи використовували сільськогосподарські угіддя, які не оформивши свої права володіння юридично.

І ситуація була така, що у громадян, які мають земельні частки, завжди могли зажадати землі, які вони зайняли самовільно. Причому без відшкодування будь-яких витрат. Становище погіршилося і тим, що приблизно дві третини власників земельних ділянок, особливо з числа працівників торгівлі, зв’язку, побуту, культури, охорони здоров’я, вже не підтримували жодного зв’язку з господарствами. А, отже, отримати їхню згоду на те, як розпоряджатися землею, було практично неможливо.

Новий механізм роботи на землі

Звичайно, мало у кого на селі знайшлися коштів, щоб викупити земельні частки у власність. А якщо внести ці самі частки в статутний капітал або передати в оренду, то потім частину прибутку, причому солідна, повинна була піти на те, щоб виплатити дивіденди або орендну плату непрацюючим власникам. А їх не так уже й мало. Як не крути, а вихід був тільки в тому, щоб робити вливання з боку. Однак інвестори при цьому, природно, хотіли і хочуть отримати гарантії за кожен вкладений рубль. Як бути?

Подальші події показали, що без зміни правового статусу землі сільськогосподарського призначення ніяк не обійтися. Федеральний закон «Про обіг земель сільськогосподарського призначення» зняв заборону на приватизацію несільськогосподарських угідь. А Федеральний закон «Про введення в дію Земельного кодексу РФ» надав можливість сільськогосподарським організаціям переоформити своє право постійного (безстрокового) користування несільськогосподарськими угіддями на право оренди або придбати ці угіддя у власність.

Приватизація землі

Приватизація землі стала здійснюватися за цінами, які встановлює суб’єкт Російської Федерації. Що стосується сільськогосподарських угідь, то для них був розроблений порядок продажу земельної частки, в якому були і позитивні, і негативні моменти.

Зрозуміло, що купівля-продаж, як і оренда земельних ділянок, має свої особливості. Будь-які операції з земельними ділянками необхідно робити, керуючись цивільним законодавством. За умови, що інше не передбачено земельним, лісовим, водним кодексами та іншим законодавством. Продажу підлягає тільки ділянку, що пройшов кадастровий облік. А купити його може тільки третя особа, коли орган влади суб’єкта РФ відмовиться придбати ділянку за заявленою ціною.

Як використовувати землі сільськогосподарського призначення

Купуючи землі сільськогосподарського призначення, необхідно пам’ятати, хто і для яких цілей може їх використовувати. Законом визначено, що використовувати їх можна для того, щоб вести сільськогосподарське виробництво, створювати захисні насадження, а також для науково-дослідних, навчальних та інших пов’язаних з сільськогосподарськими виробництвом цілей.

Причому перелік тих, хто може використовувати землі сільськогосподарського призначення, досить великий: починаючи від громадян, господарських товариств і товариств, некомерційних організацій і закінчуючи козацькими товариствами та громадами корінних нечисленних народів Півночі, Сибіру і Далекого Сходу нашої країни.

Необхідно підкреслити, що землі сільськогосподарського призначення цілком придатні для того, щоб створити не тільки свій родовий маєток, поселення, дачне селище, садівниче і городнє товариство, а й особисте підсобне господарство. Необхідно тільки змінити вид дозволеного використання на землі поселень.