29 Eylül 2015 Salı

bash if koşulu

Çift Köşeli Parantez
if koşulları çift köşeli parantez ile yazılabilir. Köşeli parantezden sonra noktalı virgül konulur.
if [[ $ans1_1 = y ]]; then
    fedoraDeps
elif [[ $ans1_1 = n ]]; then
    :
else
    echo "Answer 'y' or 'n'"
fi
Tek Köşeli Parantez - test komutuna denk gelir
Tek köşeli parantez ile de yazılabilir. Bu durumda "[" test komutuna denk gelir.
if [ -f "log/server.log" ] ; then echo "log started" ; fi
Bu kullanım şeklinde "[" karakterinden sonra ve "]" karakterinden önce en az bir boşluk olmalıdır. Yani şöyle olmalı if boşluk [ boşluk ... boşluk ]. Sebebi ise şu
A bit of history: this is because '[' was historically not a shell-built-in but a separate executable that received the expresson as arguments and returned a result. If you didn't surround the '[' with space, the shell would be searching $PATH for a different filename (and not find it) . 
Şu örnek yanlıştır. Boşluk olmadığı için [test: command not found hatası alırız.
#!/bin/bash

result="test"
if [$result = "test"];
then printf "ok"
fi
Doğrusu şöyle olmalı.
#!/bin/bash

result="test"
if [ "$result" = "test" ]; then
  printf "ok"
fi
Not: test komutunda karşılaştırılan tipler aynı olmalı yani string ile string karşılaştırılabilir. Bir değişkeni string haline getirmek için çift tırnak içine alabiliriz.
if [ "$result" != "job completed" ] ...

Köşeli Parantez Olmadan
Köşeli parantez olmadan da yazılabilir.
if is_log_started; then
    echo "log started"
fi

If İçinde Metod Çağırma
Metodlar sadece 0-255 arasında bir rakam dönebilir.
function is_log_started()
{
  if test -f "log/server.log"; then
    return 0
  fi
    return 1
}
Çoğu zaman metod içindeki en son çalıştırılan komutu dönmek yeterli oluyor.
function is_log_started
{
  test -f "log/server.log"
}
Bu metod şöyle kullanılır
if is_log_started; then
    echo "log started"
fi






21 Eylül 2015 Pazartesi

Reflection ile Nesne Yaratmak

Not : Konuyla ilgili olarak Reflection ile Arayüzleri Bulmak başlıklı yazıya göz atabilirsiniz.

Giriş
Reflection geniş bir konu olduğu için okunabilirlik adına konuları belli başlıkla altında toplamayı uygun buldum.

Java
Reflection ile Nesne Yaratmak yazısına taşıdım.

C#
Assembly'ye Erişmek
Doğru Assembly'yi bulmak için yükleme denenebilir.
Assembly myassembly = Assembly.LoadFile(myassemblypath);
veya zaten yüklü ise
AppDomain.CurrentDomain.GetAssemblies()
ile doğru Assembly bulunabilir. AppDomain çalışma esnasında yüklenebilir veya kaldırılabilir.

Activator Sınıfı
CreateInstance metodu

Bir type ile nesne yaratmak
Bu metod hep type ile hem de generics ile çalışıyor.
Type ile çalışanı şöyle
Activator.CreateInstance(typeof(MyClass));
Generics ile çalışanı şöyle
Activator.CreateInstance<MyClass>()
Generics ile çalışanı daha hızlı ama pek kullanıldığını görmedim. Ben type ile çalışanı hakkında yazacağım.
Örnek:
var testVar = 123;
var genType = typeof(MyClass<>).MakeGenericType(testVar.GetType());
var genInstance = Activator.CreateInstance(genType);
Console.WriteLine(genInstance.GetType().FullName);

Assembly içindeki IMyType arayüzden türeyen tüm sınıfların nesneleri yaratılıyor.
List<IStringType> types = new List<IStringType>();
            types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies()
                           from t in assembly.GetTypes()
                           where t.IsClass && t.GetInterfaces().Contains(typeof(IMyType))
                           select Activator.CreateInstance(t) as IMyType);
Assembly içindeki MyType sınıfından türeyen tipler bulunuyor.
Assembly myassembly = Assembly.LoadFile(myassemblypath);
List<Type> types = myassembly.GetTypes().Where(x => x.BaseType == typeof(MyType));

İsim ile nesne yaratmak (1)
Not : .Net ile çalışırken typeName denilince sınıfın namespace artı ismi akla gelmeli. Bazen assembly içinde <>c.... şeklinde başlayan sınıflar görülebilir. Bu sınıfle derleyici tarafından üretilen anonim sınıflardır.

Bu yöntemi hiç kullanmadım. Bence pek tercih edilmemeli.
Belirtilen assembly içindeki sınıfın default constructor'ını kullanarak nesne yaratır. Metodun imzası şöyle
public static ObjectHandle CreateInstance(
  string assemblyName,
  string typeName
)
Ben assembly name'inin çok karışık olmasından şikayetçiyim
var assemblyName =
    "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

var typeName = "System.Net.WebClient";

var instance = Activator.CreateInstance(assemblyName, typeName).Unwrap();

İsim ile nesne yaratmak (2)
Bu yöntem daha kolay. Type.GetType ile bir başka assembly içindeki nesnenin type'ı alınır.
Activator.CreateInstance(Type.GetType("mynamespace."+ classname + ". myDLL",true)); 
Automation ile nesne yaratmak 
Örnek:
dynamic ie = Activator.CreateInstance(Type.
GetTypeFromProgID("InternetExplorer.Application"));

ie.AddressBar = false;
ie.MenuBar = false;
ie.ToolBar = false;

ie.Visible = true;
ie.Navigate("www.google.com");
Automation ile nesne yaratmak (2)
Örnek
Guid CLSID = new Guid("A5B020FD-E04B-4e67-B65A-E7DEED25B2CF");
var manager = (IExample)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID));

Assembly Sınıfı
Bu sınıf ta Activator gibi nesne yaratabiliyor.
CreateInstance metodu
string className = "myfullyqualifiedclassname";
System.Reflection.Assembly.GetExecutingAsembly().CreateInstance (className); 



nohup

Giriş
Linux ve Unix'te terminalden çalıştırılan programlar, terminal kapatılınca işletim sistemi tarafından öldürülürler. İş "&" karakteri ile arka plana atılsa bile bu durum değişmez. Kullanıcı terminali kapatsa veya logoff olsa bile bazı işlerin çalışmasını isteyebilir. Bu durumda Linux ve Unix'te nohup kullanılır.

Windows'ta nohup'a direkt karşılık gelen bir şey yok. Kullanıcı terminali kapatırsa uygulamanın çalışmaya devam etmesi start komutu ile sağlanabiliyor ancak logoff olması durumunda uygulamanın çalışmaya devam edebilmesinin tek yolu uygulamayı Scheduled Task veya Servis olarak çalıştırmak.

nohup ve diğer seçenekler
Yazıya başlamadan önce şunu belirtmekte fayda var, nohup tek seçenek değil. Aynı işlevi yerine getirebilen screen, tmux, byobu gibi başka uygulamalar da var.

Zaten Çalışmakta Olan Uygulamalar İçin
disown yapılabilir. Önce Ctrl+Z ile uygulama duraklatılır. bg ile arka plana gönderilir. disown ile mevcut kabuk ile bağlantısı koparılır. Sonra kabuktan çıkılır.

nohup nedir
Açıklaması şöyle
NAME
       nohup - run a command immune to hangups, with output to a non-tty

SYNOPSIS
       nohup COMMAND [ARG]...
       nohup OPTION
Linux ve Unix'te nohup nasıl kullanılır?
nohup komutunu şöyle kullanılır.
nohup COMMAND [ARGS] &
nohup arkaplanda çalıştırılır. Böylece shell'de çalışmaya devam edebiliriz. Nohup uygulamamızın çıktısını nohup.out dosyasına yönlendirir. Bazen bu dosya çok büyük boyutlara ulaşabildiği için dikkatli olmak gerekir.

stdout akımını yönlendirmek
Eğer istersek çıktıyı dev/null'a yönlendirebiliriz.
nohup COMMAND > /dev/null &
stdout, stderror ve stdin akımlarını yönlendirmek
Eğer nohup ile çalıştırılan komut stdin, stdout, stderr gibi akımlara ihtiyaç duyuyorsa, shell'den çıkınca bu akımlar da kapatılacağı için uygulamamız donabilir. Bu durumda nohup şöyle kullanılır.
nohup myprogram > foo.out 2> foo.err < /dev/null &

stdout ve sterr akımlarını yönlendirmeyi anlamak kolay. Peki niçin stdin'i de dev/null'a yönlendiriyoruz. Uygulamamız terminalden bir şey okuyorsa artık terminali olmayacağı için donar. < dev/null ile uygulama terminalden okumaya çalışır ve EOF okur.

nohup altta ne yapar?
Normalde parent uygulama kapatılırsa veya ölürse, başlattığı child uygulamalar etkilenmezler! Ancak bir terminal kapatılırsa, terminali kontrol eden uygulama yani shell SIGHUP sinyali alır. Shell kendi session'ı içindeki her uygulamaya da SIGHUP (Hang up) sinyali gönderir. Böylece uygulamalar da ölürler.

nohup HUP sinyalini dikkate almaz. Böylece kendi başlattığı komut ta HUP sinyalinden etkilenmez.

nohup ve execvp ilişkisi
Aslında kod çok basit.
Önce nohup sinyali kaale almamasını sağlayan sistem çağrısını yapar.
signal(SIGHUP, SIG_IGN);
Daha sonra execvp çağrısı ile verilen komutu çalıştırır.
execvp(*argv, argc);

Windows'ta Start
Başka bir programı çalıştırmaya yarar.
start java -jar spider.jar
Eğer istenirse yeni pencere küçültülmüş olarak başlatılabilir. Örnek:
start /min java -jar spider.jar
Normalde program bitince pencere de kapanır. cmd /k ile yeni komut satırı açık kalır.
start cmd /k java -jar spider.jar



RS232

RS232'den Önce Ne Vardı
Açıklaması şöyle. RS232 voltaja göre çalışırken, daha önceki teknoloji akıma göre çalışıyordu. Yani telgraf teli gibiydi. 
Like other early DEC terminals, the VT50 series were equipped with both an RS-232 port as well as a 20mA current loop, an older serial standard used with teletype machines that was more suitable for transmission over long runs of twisted-pair wiring.

RS232
Seri port denilince en çok akla gelen standart RS232. Bu standart teorik olarak en az 3 kablodan oluşmaktadır. Tx (Transmit), Rx (Receive) ve Ground.

Eskiden 25 pin'li RS232 portları vardı. Daha sonra IBM 9 pinli RS232 portları çıkarttı.

Aşağıdaki şekilde 9 pinli kablo mevcut. Basit bir iletişim için sadece 2,3,5 numaralı pinleri karşı tarafa bağlamak yeterli.



RS232 bir bitin yani 1 ve 0'ı temsil etmek için kullanılması gereken voltaj seviyelerini tanımlar. Aslında bütün elektrik, optik ve Wifi sinyalleri analogtur. Analog sinyali dijital hale getirmek için bir encoding kullanılır. Manchester Code örnek verilebilir.

Basit bir kodek şöyle çalışır. Eğer sinyal %20'den küçükse 0, %80'den büyükse 1 kabul edilir.

Voltaj seviyeleri artı voltaj ve eksi voltaj olduğu için bi-polar olarak ta adlandırılıyor. Ground voltaj 0 olmak zorunda değildir. Örneğin bu voltajı 5 V seviyesine ayarlayarak, ve kabloya 3 V vererek, eksi voltaj yaratmak mümkün.

POSIX ile RS232 programlamak için termios yapısı yazısına bakabilirsiniz.

RS485
RS485 RS232 ile aynı fakat daha uzun mesafelerde kullanılabiliyor.

RS422
RS422 burada.

20 Eylül 2015 Pazar

Java 8 Stream Sınıfları


Functional Paketi
Java 8 Functional Kavramları yazısına taşıdım.

Arayüzler
Tüm arayüzler BaseStream<T>'den kalıtıyor.
Stream<T> gibi generic veya IntStream, LongStream gibi generic olmayan bir sürü arayüz geliyor.
Bu arayüzler arasında allMatch(), anyMatch(), collect(), concat(), count() gibi ortak metodlar var.

Stream Arayüzü
Stream arayüzünü metodlardan dönmek yerine collect metodu ile elde edilen listeyi dönmek çok daha iyi. Örnekte Stream dönen bir metod var
Stream<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfthing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey);
        // No collect
}
Bence Stream yerine Collection dönen bir metod daha iyi anlaşılır.
ImmutableSet<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfThing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey)
        .collect(MyCustomCollectors.toImmutableSet());
}
anyMatch
Bu metod C#'taki Enumerable.Any ile aynı işlevi yerine getiriyor.
if (Stream.of(">", "<", "&", "l", "p").anyMatch(string::contains)) {
  ...
}

collect metodu
collect() metodu içine bir collector alır. Collector stream içindeki elemanlara bir işlem uygular. Stream sınıfları ile bir çok collector geliyor.

List'e şöyle çevrilir.
theIntStream.collect(Collectors.toList())
Map'e şöyle çevrilir.
Map<String, String> map =
    orders.stream ()
          .collect (Collectors.toMap (SomeOrder::getID,SomeOrder::getSummary));

Örnek'te string'leri birleştiren Collectors.joining() görülebilir.
Arrays.stream(s.split(Pattern.quote("||")))
   .distinct()
   .filter(st -> !st.isEmpty()) 
   .collect(Collectors.joining("||"));

Örnek'te nesneleri gruplayan Collectors.groupingBy() görülebilir.
Map<String, Long> result = 
 Stream.of(text1, text2, text3 .... text10)
 .flatMap(list -> list.stream())
 .collect(Collectors.groupingBy(x -> x, Collectors.counting()));
distinct metodu
SQL'deki distinct ile aynı işlemi yapar. Birden fazla olan elemanlardan sadece bir tanesini seçer. Örnek
Arrays.stream(s.split(Pattern.quote("||")))
   .distinct();
flatMap
Java 8 Stream flatMap yazısına taşıdım.

filter metodu
Örnek:
LinkedList<User> users = new LinkedList<>();
users.add(new User(1, "User1"));
users.add(new User(2, "User2"));
users.add(new User(3, "User3"));
List<User> resultUserList = users.stream()
        .filter(user -> user.getId() == 1)
        .collect(Collectors.toList());
findFirst
Akımdaki ilk elemanı verir. Genellikle get() ile beraber kullanılır.
System.out.println(
            "Result: " +
            Stream.of(1, 2, 3)
                    .filter(i -> {
                        System.out.println(i);
                        return true;
                    })
                    .findFirst()
                    .get()
    );

foreach
Her bir eleman için bir metodu çağırır.

mapToInt Metodu
Linq'teki select gibi nesnenin dönüşmesini sağlar. Aslında IntStream nesnesi döner. Bu nesne ile normal Stream<T> sınıfında olmayan average(), sum() gibi metodları kullanabiliriz.
double average = roster
.stream()
.filter(new Predicate<Person>(){
          public boolean test(Person p){
              return p.getGender() == Person.Sex.MALE;
           }
      })
.mapToInt(Person::getAge)
.average()
.getAsDouble();

max metodu
Listedeki en büyük elemanı bulur. Örnek:
System.out.println(list.stream().max(Integer::compare).get());
System.out.println(list.stream().min(Integer::compare).get());
of metodu
Verilen diziyi stream'e çevirir. Örnek:
public static void main(final String[] args) throws Exception {   
    Stream.of(args).forEach(System.out::println);
}
Bir başka örnek
System.out.println(Stream
        .of("a", "b", "c", "d", "e", "f")
        .reduce("", (s1, s2) -> s1 + "/" + s2)
    );
peek
Sadece debug amaçlı kullanılması gerekiyormuş.

reduce
reduce identity, accumulator ve combiner isimli üç metod alır. Örnek
BinaryOperator<String> accumulator = (s1, s2) -> {
    System.out.println("joining \"" + s1 + "\" and \"" + s2 + "\"");
    return s1 + "/" + s2;
};
System.out.println(Stream
                .of("a", "b", "c", "d", "e", "f")
                .parallel()
                .reduce("", accumulator)
);
toArray
Sonucu array olarak alabilmemizi sağlar. Örnekte bir input dizisi P tipinden bir başka diziye çevriliyor.
Arrays.stream(inputArray).map(e -> e.transformToP()).toArray(P[]::new);

IntStream arayüzü
IntStream yazısına taşıdım.