Visul Studio Kod Metrikleri (Code Metrics)

Kod metrikleri, Visual Studio içinde yer alan kaynak kodları incelemek ve çeşitli ölçülere göre yazılımı derecelendirmek için kullanılan matematiksel ve istatistiksel yöntemlerdir. Kod metrikleri, bir projenin sınıflarını, modüllerini ve namespacelerini, çeşitli ölçülerle değerlendirerek potansiyel sorun kaynaklarını vurgular.

  • Lines of Code
  • Class Coupling
  • Depth of Inheritance,
  • Cyclomatic Complexity
  • Maintainability Index

Kod Metrikleri, Solution Explorer’da bir projeye veya solution üzerine sağ tıklayıp “Calculate Code Metrics” diyerek veya Analyze menüsünden “Calculate Code Metrics For Solution / Project” ile hesaplanabilir.

Codemetrics

Lines of Code

Lines of Code, bir metoddaki işletilebilir kod satır sayısını gösterir. Alfabe dışı karakterler, commentler, tip ve namespace tanımları bu hesaplamanın dışında kalır. Çok yüksek bir değer, bir tipin veya metodun çok fazla iş yaptığı, bu yüzden de bölünmesi gerektiği anlamına gelir.

Lines of code

Class Coupling

Bu metrik; sınıf seviyesinde, parametreler, yerel değişkenler, dönüş tipleri, method çağırımları, generic ilklemeler, base sınıflar, arayüz implementasyonları vb. aracılığıyla diğer sınıflarla olan bağlantı sayısını ölçer. Kısaca bu metrik bir sınıfın bağlı olduğu sınıf sayısını gösterir. Bu sayının mümkün olduğunca az olması beklenir. Çünkü yüksek coupling değerleri, bir tasarımın diğer sınıflara bağımlılıkları yüzünden, yeniden kullanılmasının ve bakımının güç olduğu anlamına gelir.

classcoupling

Depth of Inheritance

Kalıtım derinliği, bir sınıfın, kalıtım ağacında o sınıfın üst düğümünden köke kadar olan sınıfların sayısını gösterir. Hiyerarşi ne kadar derinleşirse, hangi metodların veya alanların nerelerde tanımlandığını veya yeniden tanımlandığını takip etmek de zorlaşır. Çok derin kalıtım ağaçları, uygulamanın testinin ve bakımının karmaşıklığını arttırır.

Depth of Inheritance

Cyclomatic Complexity

Cyclomatic Complexity programdaki birbirinden farklı kod akışlarının sayısıdır. Daha basitçe açıklamak gerekirse, programdaki karar noktaları olan if bloklarının, do, while, foreach ve for döngülerinin ve switch case bloklarının sayısıdır. Yüksek cyclomatic completixy değerine sahip olan kodların test ve bakımı zor olmaktır. Çünkü bu kodlarda test edilebilecek çok sayıda farklı akış vardır.

Cyclomatic Complexity

Cyclomatic Complexity(CC) değerini hesaplamak için aşağıdaki gibi basit bir yol izlenebilir.

  1. Metodun akışına CC= 1 değeri ile başla.
  2. Her bir if,while,repeat, for, and , or anahtar kelimeleri veya eşdeğerleri için CC’ye 1 ekle
  3. Switch’teki her bir case için CC’ye 1 ekle

Metodlar için cyclomatic complexity değerleri ve riskleri belirtilmiştir. Cyclomatic complexity değeri ne kadar yüksekse metodun karmaşıklığı da o kadar fazladır.

cyclomatic complexity tablo

Maintainability Index

Sınıf üyeleri veya tipler seviyesinde kod bakımının kolaylığına gösteren bu değişken 0-100 arasında bir değer alır. Bu değerin yüksek olması programın sürdürebilirlik seviyesinin yüksek olduğu anlamına gelir. Namespace veya assembly seviyesindeki maintainability index, o namespace veya assembly içerisindeki bütün tiplerin maintainability indexlerinin ortalamasıdır. Bu metrik, Halstead Volume, Cyclomatic Complexity ve Lines of Code metrikleri bir araya getirilerek oluşturulmuştur. Halstead Volume, kullanılan işlenen (operand) ve işlemcilerin (operator) sayısıyla ilgili bir metriktir. Maintainability index için kullanılan denklem aşağıda verilmiştir.

—MI = 171 – 5.2 * log2 (HV) – 0.23 * (CC) – 16.2 * log2 (LOC)

—HV: Halstead Volume
—CC: Cyclomatic Complexity
LOC: Lines of Code

Maintainability index, kolay bir gösterimi olması için ikonlarla ifade edilmiştir. İkonlar için, değer aralıkları ve sürdürebilirlik seviyeleri aşağıdaki gibidir.

maintainability index

Alıntıdır.

https://sametbulu.wordpress.com/tag/metrik/

WSL ile linux sunucusuna uzak masaüstü bağlantısı sağlama


WSL'in açılımı Windows Subsystem for Linux'tur. Basit olarak konuşursak sanal makine olmadan Linux terminalini Windows üzerinde kullanmanızı sağlamaktadır. Git Bash gibi bir kaç UNIX komutu eklenmiş toollara göre farklılık göstermektedir. WSL üzerinde direkt olarak Linux uygulamalarını çalıştırabilirsiniz

Windows Subsystem for Linux(wsl) 
wsl -l -v //versiyonları ile OS'leri gösteririr.

Ubuntu içerindeki kodlar;
lsb_release -a //OS versiyon detayını gösteririr.
cd //anadizine geçişi sağlar.
pwd //gerçerli working directory gösterilir.
sudo apt update && sodu apt -y upgrade //paketlerin güncellenmesi ve yükseltilmesi sağlanır.
sudo apt install xrdp //uzak masa üstü erişimi kurulur.
sudo apt install -y xfce4 //lightweight grafik arayüzü yüklenir.
sudo apt install -y xfce4-goodies
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak //xrdp configurasyonu sağlanıyor.
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini
sudo sed -i 's/max_bpp=32/#max_bpp=32\nmax_bpp=128/g' /etc/xrdp/xrdp.ini
sudo sed -i 's/xserverbpp=24/#xserverbpp=24\nxserverbpp=128/g' /etc/xrdp/xrdp.ini
echo xfce4-session > ~/.xsession
sudo nano /etc/xrdp/startwm.sh
	son iki satıraın başına # konulur.
	# xfce
	startxfce4
sudo /etc/init.d/xrdp start


Dağıtımımızın GUI halini kullanmak için xfce4 yazılımını kurmak gereklidir. Bunun için WSL terminalinde “sudo apt install xfce4” komutunu çalıştırmalıyız.
Kurulum sürerken karşınıza klavye dili ayarı gelecektir, bu işlemi isteğinize göre ayarlayabilirsiniz.
Daha sonra Kali Linux sistemine RDP (uzak masaüstü) bağlantılarını sağlamak için “sudo apt install xrdp” komutunu yazmalıyız.
Xrdp yüklemesi tamamlanınca servisini başlatmak için “sudo /etc/init.d/xrdp start” komutunu çalıştırmamız gerekiyor.
Bu işlemin hemen ardından terminalden “ip add” komutuyla eth0 altındaki IP adresinizi kopyalayıp Windows’unuz üzerinden Uzak Masaüstü Bağlantısı uygulamasına yapıştırarak artık uzak masaüstü bağlantısı gerçekleştirebilirsiniz.

Winrar ile logları rarlayıp yedek almak

Dosya olarak tutulan log kayıtları belirli zaman aralığında(task schedule) temizlenerek hem dosya fazlalığından hemde disk alanınızdan tasararruf edebilirsiniz.

//Yedekle
cd C:\Program Files\WinRAR 
rar a  -r "D:\Test_Backup\Yedek_Log_%DATE:~7,2%-%DATE:~4,2%-%DATE:~-4%_%TIME:~0,2%-%TIME:~3,2%-%TIME:~-5,2% .rar"  "C:\Users\celma\Desktop\test"

//Yedekli dosyaları sil
set folder="C:\Users\celma\Desktop\test"
cd /d %folder%
del /S /Q *.*

//Yedekli klasörleri sil
rd /S /Q “C:\Users\celma\Desktop\test\Tools_klasoru”
rd /S /Q “C:\Users\celma\Desktop\test\Winscp_klasoru”

Git komutları notlar

$ git config --global user.name "John Doe"
$ git config --global user.email "john@doe.org"


git init = Bu klasör artık bir git reposudur. Gizli bir .git klasörü oluşturur.
git status = Bu klasör içerisindeki dosyaların repo’ya aktarılıp aktarılmadığını görebiliriz. Kırmızı ile belirtilen tüm dosyalar eklenmemiştir. Burada dikkat edilmesi gereken nokta .gitignore dosyasıdır eğer sisteminizde .gitignore dosyası var ise burada yer alan dosyalarınız her zaman repoya eklenmez. Bunu bir güvenlik olarak görebiliriz örneğin laravel’de env dosyasında veritabanı vb. şifreler yer aldığı için git reposuna dahil edilmemesi gerektiği .gitignore dosyasında belirtilmiştir. Böyle olunca kullanıcılara .env dosyası paylaşılmaz.
git add dosya.php = Sadece bir klasör veya dosya’yı repoya eklemek istediğimizde.
git add * = Burada * (yıldız) yerine . (nokta) ‘da kullanabiliriz. Tüm dosya ve klasörleri Repo’ya ekler. Bu kod bazı windows sistemlerinde çalışmama durumları olabilmektedir. bu gibi durumlarda git config core.autocrlf true bu kodu çalıştırıp daha sonra git add * çalıştırmalıyız.
git log = Bu repo’da daha önce commit işlemi yapılmış mı bunun kontrolünü sağlıyoruz.
git commit -m “Kurulum Yapıldı” = Bu kısımda git add * ile repomuza eklediğimiz dosya ve klasörlere bir sürüm tarzı bir sistem ekleyerek bir açıklama ile repo’yu ayırıyoruz. Bu ayarlamada ilk işlem sırasında bazı bilgiler isteyebilir bunları git config user.email “mail@adresiniz.com” ve git config user.name “Ad Soyad” girmeniz gerekmektedir. Bu işlem yapıldığında bir hata almaz iseniz git reposu belirlenmiş olacaktır.
git reset –hard * = Bu kod ile ilgili repo’ya geri dönüşümüze imkan sunacaktır, git log ile kontrol ettiğimiz  commit numarasını * yazan kısma yazdığımızda ilgili sürüme tek tıklama ile geri dönüş yapabiliriz.
git reset --hard HEAD: tüm değişiklikler silinir.

git branch v1.1 = Yeni bir branch oluşturduk.
git branch = Mevcut branch’leri kontrol ediyoruz. Yanında * olan branch kullandığınız branch’tir.
git checkout v1.1 = Artık v1.1 branch’imizde geliştirme yapıyoruz ve burada yaptığımız branch’ler v.1′ hiç bir şekilde bozmayacaktır. En temel anlamıyla düşünürsek v1 klasörünü kopyalayıp yapıştırdığımızda adını v1.1 yaparak v1.1 üzerinde düzenleme yapma gibi düşünebiliriz.
git merge v1.1 = Artık v1.1 geliştirmesini tamamlayıp tüm sistemi master branch’inde toplamak istediğimizde bu kodu kullanarak v1.1 branch’ini master branch’ine aktarıyoruz.
git branch -D v1.1 = v1.1 branch’ini siliyoruz.


# Two-step method
git branch NEW-BRANCH-NAME
git checkout NEW-BRANCH-NAME

//Yeni branch yarat ve remote'a gönder
git checkout -b test //test branchi oluşturup ona geçiş yapar.
git push -u origin test //branchi remote'a gönderir.

Bu sayfa ile artık mevcut local sistemimizde ki git’i github’a aktarabiliriz.
git remote add origin https://github.com/yusufkahramaner/repoismi.git = Üst kısımda belirtilen github linkini giriyoruz.
git push origin master = Master kısmı branch adımız. Bu işlem sırasında size kullanıcı adı ve şifre sorarak github senkronizasyonunu yapar.
git clone https://github.com/yusufkahramaner/repoismi.git = Github reposunu local’e çekmek için bu kodu kullanabiliriz.
git remote remove origin = Git veya bitbucket ile bağlantıyı koparır.



git init
git remote add origin https://gitlab.com/cem.elma/NetCoreApp.git
git add .
git commit -m "ilkkayit"
git status
git commit -am "ikinci kayıt" --Burada ek olarak kullandığımız a harfi kayıt işlemini yaparken bütün değişikliğe uğramış dosyaları da kayıta ekleyecektir.
git diff --yapılan değişiklikleri görme
git reset —hard HEAD --Projenizi en son kayıt yapılan haline döndürebilirsiniz.
git fetch origin --master branchini çeker.
git push -u origin master https://gitlab.com/cem.elma/NetCoreApp.git


# Commit tarihçesindeki en son 5 commit kaydının bilgilerini listeleyin
git log -n 5 

# Geri dönmek istediğiniz commit’in hash değerini belirledikten sonra

git revert <commit_hash_ilk_7_karakter> --no-edit

# Yerel deponuzu uzak depo ile senkronize edin
git push


*git --version	//Git versiyonu gösterir.

*git update-git-for-windows	//güncel git versionunun kurulmasını sağlar.

git status //hangi dosyaları değiştirdiğinizi, sildiğinizi veya hangi dosyaları eklediğinizi kolayca görebilirsiniz.

git log //Projeniz için oluşturduğunuz commit'lerin tarihçesini incelemek için kullanılır.

git push //uzaktaki repository’de yayınlama

ls -la //gizli dosylar dahil listeleme yapılır.

//SSH oluşturma
ssh-keygen -t rsa -b 4096 -C "cem.elma@cts.com.tr"
eval "$(ssh-agent -s)" //SSH-Agent in arkada çalışıp çalışmadığı kontrolü yapılır.
ssh-add ~/.ssh/id_rsa //oluşturulan ssh key sisteme eklenir.
cat ~/.ssh/id_rsa.pub // ssh key görüntülenir.

oluşturulan key git üzerinde ssh key olarak eklenir.
ssh -T git@gitlab.com //Remote ile local ssh bağlantısı kontrolü testi yapılır.

git clone //remote proje locale çekilir.

Not: Untracked (Takip Edilmeyen, henüz gite eklenmemiş ve versiyon kontrolü altında olmayan dosyalardır), Tracked (Takip Edilen) dosyalardır.
Değişiklikler working folder(working copy), uzak sunucu ve Staging Area'da tutulur.
Staging Area'yı, proje dosyalarımızdaki bir dizi değişikliği remote repository'ye göndermeden önce kayıt altında tuttuğunuz veri tabanı/alan olarak tanımlayabiliriz.

git add baslik_2.md baslik_2_1.md resimler/*	//baslik_2.md ve baslik_2_1.md dosyaları ile resimler klasörü altındaki tüm dosyaların Staging Area'ya eklenmesini sağlayabiliriz.
git commit -m "1.7 numaralı alt başlık içeriği tamamlandı"

git checkout app/screens/LeaveList/index.js //son staging area bilgisine geri dönülür.
git restore app/screens/Login2/index.js


index.js değişiklik yapılır.
git add app/screens/LeaveList/index.js // Stage'a eklenir
git reset app/screens/LeaveList/index.js // Stage geri alınır.
git checkout app/screens/LeaveList/index.js // Değişiklik geri alınır.

git revert commitnumber

git reset --hard HEAD~1 //bir önceki commite döner ve son commiti siler.
git reset –hard Son gönderiye geri almak. Eğer birleştirme sonucu çakışmalar çıktı ise ve bu çakışmayı geri almak istiyorsanız bu kodu kullanabiliriz.

git reset –hard ORIG_HEAD veya git reset –hard origin/master En son birleştirilmiş stabil duruma geri döndürür. Daha yeni birleştirme işleri için kullanışlıdır. Eğer birleştirme işinizde çakışma varsa “git reset –hard” kullanınız.

git reset –soft HEAD^ Son gönderinizde bazı şeyleri unuttunuz mu? Bu durumdan kurtulmak kolay. Son gönderiyi geri almak istiyorsak ve yapılan değişikliklerinde bir yerlerde saklanmasını istiyorsak bu komutu kullanmalıyız.

git commit –amend Yaptığınız değişiklikleri koruyarak önceki gönderiyi yenilemek istiyorsak bu komutu kullanırız. Ayrıca önceki gönderi mesajını yenilemek içinde kullanılır bu komut.

git checkout – <dosya_adi> Sadece belirtilen dosyayı geri almak için kullanılır.

git restore --staged app/screens/LeaveList/index.js // stagedan dosya geri alınır.
git restore app/screens/LeaveList/index.js //dosya localdende geri alınır.
git reset --hard HEAD~1 //bir önceki commite döner ve son commiti siler.

//istenilen commite dönülür ve ilerisi silinir.
git reset --hard <last_working_commit_id>
git push --force

git reset HEAD^ --hard 

git branch -v: branchleri son commit


Yanlış dosyayı git add ile ekledim ne yapmalıyım?
git reset HEAD readme.md

En son commit’i nasıl geri alırım?
git add .
git commit -m "Ceviz Ekle"
git revert HEAD
Bunu yaptığınız da editörünüz açılacak ve sizden bir commit mesajı girmenizi isteyecektir. Ve en son committe yaptığımız değişikleri geri alan yeni bir commit oluşturacaktır.
Çıktıdan anladığımız kadarıyla revert komutu, aslında gerçek anlamda geri alma işlemi yapmıyor, aksine bir commitin etkilerini geri alan yeni bir commit oluşturuyor

git reset
Şimdi senaryomuza geri dönelim ve lokal branchta çalışırken revert’in oluşturduğu ekstra committen duyduğumuz memnuniyetsizlikle son commit’i geri alalım.
git reset HEAD~1


git stash //devam eden bir işi yarıda bırakıp farklı bir işe geçtiğimizde stashe kaydedebiliriz.
git stash list //ekli olan stashler listelenir.
git stash apply stash{0} //stashe geçiş yapılabilir.
git reset --hard HEAD~1 //stashsiz hale dönülebilir ve tanımlı başka stashe geçilebilir.
git stash pop // yukarıdaki listenin en üstünde yer alan değişiklik geri yüklenecek ve bu değişiklik listeden silinecek.
git stash drop stash@{1} // stash silinir.

git reset -–hard origin/master //masterdan son hali alır.

git add app/screens/LeaveList/index.js // stashe ekleme yapılır.
git reset HEAD app/screens/LeaveList/index.js // stashe eklemesi unstash yapılır.

git revert HEAD // son commite dönülür.
git revert --abort //Dönülen son commit iptal edilir.
git revert --continou revert commiti kabul edilir.
git commit --amend -m "cem commit mesaji düzenlendi." //son commit mesajiını düzenlemek için kullanılır.

//SON YAPILAN COMMITE EK YAPMAK İÇİN;
git add bar.md
git commit --amend --no-edit
git status

Git, bizim için yaptığımız işlemlere referans kaydı tutuyor. Yukarıda revert komutunu geri alırken kullandığımız gibi. git reflog ile HEAD@{n} ‘i takiben yapılan işlemle de ilgili açıklamalar. Tarihten bu kesitlere istediğiniz gibi ışınlanabilirsiniz tek yapmanız gereken git reset HEAD@{n} ile istediğiniz noktaya gidebiliriz.
git reset HEAD@{1} //


git show 6cb87924dc57 // Committe yapılan değişiklikler görüntülenir.
git show 6cb87924dc57 --stat // Committe yapılan değişiklikler sadece dosya adları görünür, içeriksiz.
git log -p 6cb87924dc57 040b42bd78bb3 //iki commit farkları

VİM EDITOR KAPAMA;
"Esc" + ":wq!" YADA "Esc" + ":q!"


git checkout master //komutu ile değişikliklerin aktarılacağı hedef branch'inizi aktif (HEAD) hale getirirsiniz.
git merge loginsorunu //komutu ile kaynak branch'deki commit edilmiş değişiklikler HEAD'e entegre edilir.


git init //git projesi eklenir.
git clone //git projesi çekilir.



git checkout -b Cem developer
git push origin Cem
git push origin --delete Cem //-D silmeye zorlar, -d siler.
git checkout -- . //bütün değişiklikleri siler.
git reset --hard UID : dosyanlarin eski halini de orjinal haline ceviriyor, kalıcı silinir commitler ve dosyalar.
git reset --soft UID : Git bu belirttiğimiz commiti ve sonrasındaki commitleri silecektir, düzenlenmiş dosyalar da Git’e eklenmiş hale gelecektir. Dosyalardaki değişiklikler bozulmayacaktır. Sadece commit silinir dosyalar localde kalır.
git reset --mixed UID : belirttiğimiz commiti ve sonrasındaki commitleri silecektir. Dosyalarımızdaki değişiklikler gitmeyecek ancak dosyalarımız Git’e eklenmemiş olacaktır, yani untracked hale gelecektir.
git commit --amend : reset ettikten sonra dosyalardaki degisikligi yapip yeniden ADD etmek lazim. ADD yaptiktan sonra bir commit gondermek yerine eski commit uzerine yaz diyebiliriz. amacimiz show log diyince yaptigimiz duzeltmenin gereksiz yere log da gorunmemesi idi. bunun icin git commit --amend yazmamiz yeterli.
git branch -v : Detayli olarak branchleri listeler.

git config --global alias.s status <- git komutunu alias yaptik artik git s yazinca git status calisacak ayarlar kullanicinin home directorysinde duruyor, vim ~/.gitconfig yazarak incelenebilir (hic alias yapilmamis ise boyle bi dosya yoktur, ilk basta birseyleri alias yap) bu dosyayi direk olarak editleyerek de alias eklenebilir. veya ilgili satirlari silerek aliaslar silinebilir.
git config --global -unset alias.s <- boyle manuel de silebiliriz.

ep 08 : stash
git stash <- bu komut ile o andaki dosyalari stahse atiyoruz.
git stash list <- tum shash yaptiklarimiz gorebiliriz. dosyalari degil sadece stash yaparak kaydettiklerimizi
git stash pop ve git stash apply <- stashe atilanlari geri cagiriyoruz. pop yazinca stash listden de siliyor.
git stash drop <- bunu yazincada stash lisri siliyor.

eger komutlarin sonuna stash id yazmazsak en son stash icin gecerli islemler. yok yazarsak sadece o yazdigimiz stash id icin islem yapiyor.
stash id degeri list yapinca 2 noktadan onceki string. su sekilde mesela: stash@{0}

stash yaptigimiz branchi silsek bile bir baska branchde git stash appyl falan yaapabiliriz. yyada yeni bir bbracnh acip ona stash edebiliriz.
git stash branch deneme <-- yeni bir branch acar deneme adinda ve orada stashi appy eder.

git pull origin developer //değişikliklerin branche alınmasını sağlar.
git fetch // uzaktaki verileri indirir fakat çalışma alanındaki veriler üzerine yazılmaz, git pullda ise remotedan çekilen veriler otomatik git merge gibi çalışır

ElasticSearch kısa kısa

//create alias
POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "product_search_201910101123", "alias" : "alias_product" } }
    ]
}


GET  product_search_20*


//Remove alias
POST /_aliases
{
    "actions" : [
        { "remove" : { "index" : "product_search_201910101123", "alias" : "alias_product" } }
    ]
}



GET alias_product
GET _cat/aliases?v //tüm alias listesi

GET _cat/indices?v //tüm index listesi

get product_search_201910101501

tüm indexler listelenir;
http://localhost:9200/_cat/indices


DELETE product_search_201910101256


index datalarını görme;
GET product_search_201910101653/_search

GET product_search_201910101653/_search
{
  "query": {
    "term": {
      "name": {
        "value": "iphone"
      }
    }
  }
}
YADA
GET product_search_201910101653/_search?q=name:iphone



ÇOKLU indexe ALİAS ATAMA
POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "i_product", "alias" : "a_product" } },
        { "add" : { "index" : "product_search_201910111157", "alias" : "a_product" } }
    ]
}



GET a_product/_search  //tüm indexlerin bilgileri getirilir
GET product_search_201910111157/_search //sadece belirlenen indexin verisi getirilir.


size: geriye dönecek olan result sayısı (default 10)
from: result içerisindeki offset (default 0)
fields: geriye dönmesini istediğiniz field’lar
sort: neye göre sıralama yapılacağı
facets: data içerisindeki belirli bir field(lar) özelinde özet bilgileri getirmektedir (örneğin bir e-ticaret sitesinde bir ürün aradığınızda, genelde sol menüde o ürün özelinde hangi renkten kaç adet, hangi markadan kaç adet mevcut olduğu bilgileri)
filter: makalenin ilerleyen bölümlerinde detaylı olarak ele alacağız ama özetle filtreler query’leri daha fazla özelleştirebilmek için kullanılır


{
  "from": 0,
  "size": 5,
  "query": {
    "filtered": {
      "query": {
        "term": {
          "name": {
            "value": "iphone"
          }
        }
      },
      "filter": {
        "range": {
          "price": {
            "gte": 3900,
            "lte": 5000
          }
        }
      }
    }
  }
}

INDEX YENİDEN ADLANDIRMA ve eskisini silme
POST /_reindex
{
  "source": {
    "index": "netcoreapp-log-2019.10.14"
  },
  "dest": {
    "index": "netcoreapp-log-2019.10.13"
  }
}

DELETE /netcoreapp-log-2019.10.14



BIRDEN ÇOK INDEXE ALIAS VERME
POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "netcoreapp-log-2019*",
        "alias": "a_netcoreapp-log"
      }
    }
  ]
}

GET netcoreapp-log-2019.10.12/_search?q=message:"mesajı"

Docker kısa kısa

Docker Container kodu ve tüm bağımlılıklarını paketleyen standart bir yazılım birimidir, böylece uygulama bir bilgisayar ortamından diğerine taşındığında hızlı ve güvenilir bir şekilde çalışır.
Docker Image bir uygulamayı çalıştırmak için gereken her şeyi içeren hafif, bağımsız, yürütülebilir bir yazılım paketidir: kod, çalışma zamanı, sistem araçları, sistem kitaplıkları ve ayarları

docker pull redis

-a : Stop durumda olan Container’ın tekrar başlatılırken terminal’in (komut satırı input/output’unun) Container’a tekrar attach edilmesinin (bağlanmasının) istendiğini belirtmektedir.(yani çalıştırılan containerdaki terminal, şuan aktif cmdye attach edilir.)
-i interaktif terminali -t ise terminalin attach olmasını istediğimizi belirtir.
Container’ın Bash’inde iken ps -ef komutunu verin ve Container içinde çalışan bütün process’leri listeleyin. Bende oluşan çıktı aşağıda.

docker build . ile oluşturulan images adı ve tagi boş olur. -t repo:tag ile yaratılırken verilebilir.
docker tag a748835505b2 gsengun/myubuntu:0.1 //repo ve tag değiştirilebilir.


Dockerfile yapısı;
INSTRUCTION argümanlar

RUN
Build işlemi sırasında koşturulması gereken komutları belirtmek için kullanılır. Örneğin baz ubuntu Image’ında bulunmayan bir paketin (örneğin ping) oluşturulacak Image’a eklenmesi isteniyorsa RUN apt-get install -y iputils-ping Instruction’ı Dockerfile’a eklenerek Image oluşturulması sırasında Image’a bu paket eklenmiş olur.
ENTRYPOINT 
Çalıştırılabilir bir dosya (executable) gibi kullanılmak üzere bir Image yaratılmasına olanak tanır.
ADD
Oluşturacağımız Image’e Host dosya sisteminden veya internetten yeni bir dosya/klasör eklemek için kullanılır ADD komutu. Aşağıdaki gibi iki formatta kullanılabilir, src (source - kaynak) ve dest (destination - hedef) path’lerde boşluk bulunması ihtimaline karşın ikinci formatın kullanılması daha uygun görünmektedir.

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
Örnekler:

Host’tan Image’a klasör kopyalanması

ADD [ "./BuildDir/", "/app/bin"]
İnternetten Image’a dosya kopyalanması

ADD [ "https://curl.haxx.se/download/curl-7.50.1.tar.gz", "/tmp/curl.tar.gz" ]
ÖNEMLİ NOT: Host klasörde bulunan ve Image’a kopyalanmak istenmeyen dosyalar .dockerignore dosyasının içinde belirtilebilir. Bu dosya tıplı .gitignore‘a benzemektedir.


COPY
ADD komutu ile aynı şekilde kullanılır fakat İnternetten dosya indiremez sadece Host üzerindeki dosya ve klasörleri kopyalayabilir.


WORKDIR
WORKDIR Instruction’ı kendisinden sonra gelen RUN, CMD, ENTRYPOINT, COPY and ADD Instruction’larını etkiler ve bu Instruction’lar Daemon tarafından koşturulurken relatif olarak kullanılan path’lerin başına bu Instruction’la sağlanan path’i ekler. Bu açıklama komut satırını sıklıkla kullanmamış olan kişilere biraz karmaşık gelmiş olabilir. Bir örnek vererek açıklayalım.

Dockerfile’ımızda aşağıda iki Instruction’ın bulunduğunu düşünelim.

WORKDIR /app/src
ADD [ "./BuildDir/", "binaries/"]
/app/src Container’da WORKDIR olarak belirlendikten sonra ADD Instruction’ı ile Host üzerindeki ./BuildDir/ klasörünün altındaki bütün dosyalar binaries klasörü altına kopyalanmak istenmektedir. WORKDIR olarak /app/src sağlandığı için dosyalar Host’tan /app/src/binaries klasörü altına kopyalanacaklardır.


Docker-Compose
Development (geliştirme), kullanıcı kabul (UAT) ve test ortamlarının kolay bir şekilde yönetilebilmesi için Docker Compose kullanılmaktadır. Docker file bir Container çalıştırma ile ilgiliydi. Günlük olarak kullandığımız veya kullanılmak üzere müşterilerimize sunduğumuz ürünler ve sistemler birden fazla servisin (genellikle web sunucular, uygulama sunucuları, veri tabanı sunucuları, cache sunucuları, message queue sunucuları, vb) bir araya gelmesiyle oluşmaktadırlar. Orta ve büyük ölçekteki sistemleri Docker CLI kullanarak kullanıma sunmak ve bakımını yapmak pek makul değildir. Bu tip sistemlerde Container’ların çalıştırılması, durdurulması, birbirleri ile olan ilişkilerinin belirtilmesi yani basit bir şekilde yönetilebilmesi görevlerini yerine getirecek ayrı bir aracın varlığı gereklidir.
docker-compose.yml dosyasında detayları verilen ve birbirleri ile ilişkileri tanımlanan servisler (Container’lar) tek bir komut ile ayağa kaldırılıp tek bir komut ile durdurulur ve yine tek bir komut ile kaldırılabilirler (silinebilirler).
docker-compose up tüm servisleri ayağa kaldırır.
docker-compose build servicename sadece belli servisi çalıştırır.




FROM hangi docker image'i kullanılacağını belirttiğimiz komut. Bu projemiz build etmek için dotnetcore 2.2 SDK image'ini kullanacağız.
WORKDIR image içerisinde working directory olarak kullanacağımız yeri belirttiğimiz komut. Bu projemizde working directory olarak /app kullanacağız.
COPY proje dosyalarını local file system'dan image'e kopyalamak için kullanılan komuttur. Bizde projemizde ilk olarak csproj dosyasını kopyalayıp restore edeceğiz, sonra bütün bu oluşan dosyaları yeniden kopyalayıp dotnet publish komutu çalıştırarak uygulamamızı oluşturacağız.
ENTRYPOINT container ayağa kaldırılırken ilk olarak çalışacak olan komut ve parametreleri belirttiğimiz komuttur. Container run edilirken dotnet komutuyla HelloDocker.dll'i execute edilecektir.


docker build -t myimg .

docker image ls



Deploying a Container
Image'imizde hazır olduğuna göre son adım olarak bu image'i bir container içerisinde host edip kullanmaya başlayalım. Bunun için kullanmamız gereken en basit şekli aşağıdaki kod satırını çalıştırmak.

Oluşturulan bir imageden birden fazla container oluşturulabilir farklı isimlerde ve aynı anda çalıştırılabilir.

docker start cemtest
docker stop cemtest //containeri durdurur.
docker rm cemtest //containerı siler.
docker stop cemtest2

docker stop cemtest


docker run -p 5123:80 myimg

docker container ls -a


docker container stop stoic_williamson
docker container rm stoic_williamson

docker run --name cemtest --env ASPNETCORE_ENVIRONMENT=Development -p 5250:80 myimg:latest







Bazı Faydalı Docker Komutları
Yüklü olan docker image'lerini listelemeyi sağlayan komut

docker image ls
Image'i silmek için kullanılan komut

docker rmi image_id
Container'ları listelemek için kullanılan komut

docker container ls
Çalışmakta olan bir container'ı stop etmek için kullanılan komut

docker stop container_name
Durmakta olan bir container'ı silmek için kullanılan komut

docker rm container_name


ÖR: redis kurulumu;
docker pull redis
docker run -d -p 6379:6379 --name redis-cemtest redis

docker logs redis-cemtest// log izleme
docker ps //Çalıştığını kontrol edin

docker exec -it redis-cemtest sh //redisi komut satırı üzerinde çalıştırmak için sh geçilir.
redis-cli yazılır ve redis cli çalışır durumda olur.
set name cem
get name
exit



https://hub.docker.com/u/cemelma/

docker login //kullanıcı adı ve şifresi ile login olunur.
docker tag myimg cemelma/test:firsttry
docker push cemelma/test

docker pull cemelma/test:firsttry
docker run -p 5124:80 --name hubtest cemelma/test:firsttry



Tüm containerları silmek
docker container rm $(docker ps -aq)
docker container rm $(docker container ls -aq)


container içerisine girmeden yaratmak.
docker run -i -d ubuntu bash
docker exec -i -t adi


docker commit -a "Cem Elma <cemelma.20@gmail.com>" benim_ubuntum cemelma/benim_ubuntum:latest 
docker push cemelma/benim_ubuntum

huba gönderme:
docker commit -a "CEM ELMA" cemelma/benim_ubuntum:latest cemelma/benim_ubuntum:latest

hubdan çalışır şekilde alma:
docker run -d -i cemelma/benim_ubuntum:latest
docker exec -it containerid bash //bashe geç


docker run --name benim_ubuntum -i -t ubuntu bash

docker start -ia benim_ubuntum //içerisine girer başlatıp








HUB indir;
docker run -d -i cemelma/test:ubuntu
docker ps -a
docker exec -it stoic_liskov bash

apt-get update
apt-get install nano
apt-get install golang
cd /home
mkdir deneme_go_uygulamasi //mv deneme_go_uygulamasi test --isim değiştirme
cd /deneme_go_uygulamasi
touch main.go
nano main.go
//
	package main
	import ("fmt")
	
	func main(){
		fmt.Println("Hello, World")
	}
//

go run main.go
exit
docker ps
docker ps -a
docker stop stoic_liskov
docker start -ai stoic_liskov
docker exec -it stoic_liskov bash
docker stop stoic_liskov
docker commit -a "CEM Elma" stoic_liskov yenirepo:latest
docker images
docker run -d -i yenirepo
docker ps -a //nice_hoover
docker exec -it nice_hoover bash
cd /home/deneme_go_uygulamasi
go run main.go
exit

docker tag yenirepo cemelma/test:ubuntunew
docker push cemelma/test:ubuntunew



docker container rm -f nice_hoover stoic_liskov
docker run -d -i cemelma/test:ubuntunew
docker exec -it objective_dhawan bash

----------------------------------------------------------------------------
docker pull cemelma/test:firsttry
docker run -p 5111:80 --name testweb cemelma/test:firsttry



docker run --name benim_ubuntum -i -d -v C:\Users\celma\Desktop\cwd:/home/test ubuntu
docker exec -it benim_ubuntum bash


docker run -i --rm -v C:\Users\celma\Desktop\cwd:/home/test -w /home/test golang go run main.go

docker inspect golang

//sadece çalışıtrııp kontainer silinir.
docker run -i --rm -v C:\temp\go_app:/home/go_app -w /home/go_app cemelma/test:ubuntunew go run main.go

//çalıştırıp kalır.
docker run --name cem -i -d -v C:\temp\go_app:/home/test cemelma/test:ubuntunew
docker exec -it cem bash
cd /home/test/
go run main.go


docker exec -it -w /home/test/ benim_ubuntum bash  
docker run --name cemubuntu -it -v C:\temp\go_app:/home/go_app -w /home/go_app cemelma/test:ubuntunew bash  



//image kaydetme
docker save -o asd.tar denemecem

//container kaydetme
docker save -o asd.tar denemecem






Docker Machine
//Docker-machine create --driver hyperv --hyperv-virtual-switch HyperVNetwork node1
docker-machine create --driver hyperv --hyperv-virtual-switch HyperVNetwork  --hyperv-memory "4096" --hyperv-cpu-count "1" --hyperv-disk-size "20000" node1
docker-machine ssh node1
Docker-machine env node1
docker-machine regenerate-certs node1
docker-machine restart node1

eval $("C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env node1) //git bash ile çalışır, ve sanal makine içerisinde giriş yapılır.
eval $("C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u) //normal dockera dönmek için  kullanılır.

docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart always -v \\.\pipe\docker_engine:\\.\pipe\docker_engine -v portainer_data:C:\data portainer/portainer
//machine üzerinden;
docker run -d -p 8000:8000 -p 9000:9000 --name portainerCemPc --restart always -v portainer_data:/data  portainer/portainer


cat /etc/os-release //kurulu olan sistem bilgilerini verir.
uname -r // Linux kernel version

Dart dili kısa kısa

Dart tek thread üzerinde çalışır.

*sabit tanımlar;
-final: değer atandıktan sonra, bellekte yer ayrılması sadece değere erişildiğinde olur. (classlar/ogrenci classı)Instance değişkenler sadece final olarak tanımlanır. Const ile tanımlama için static const olmalıdır.
-const: derleme anında atanır, kullanılmasa bile bellekte yer kaplar.


*~/: bölme işleminde int kullanılmak isternirse tilda kullanılabilir.
*{}: method parametrelerinde parametrenin opsiyonel olduğunu belirtir. 
*[]: method parametrelerinde parametrenin sırasız adı ile verilmesini sağlar.

*get/set: classlarda methoda get set atamalarında derğer = ile verilir. Ör;
void set ogrnoAta(int no){
	this.ogrNo = no;
}
Kullanımı;
ogr.ogrnoAta=20; //ogr.ogrnoAta(10) method gibi atamada hata alınır get/set için.


*Constructor içerisinde bir tane tanımlama yapılabilir. Parametre alır veya alamaz kurucu şeklinde, çünkü overloading yok. Birden fazla tanımlama için static olarak yapılabilir.
Eğer birden fazla constructor tanımı yapılmak isteniyorsa isim verilir method gibi tanım yapılır.
class Ogrenci{
	int ogrNo;
	
	Ogrenci(){
	}
	
	Ogrenci(this.ogrNo) //ogrNo değerine otomatik atama yapılır.
	{
		
	}
	
	Ogrenci.NumaraAta(int no) //ogrNo değerine isimlendirilmiş cons ile atama yapılır.
	{
		this.ogrNo;
	}
}


*Extend etme şu şekilde;
class Hayvan{	//class Hayvan extends Object{ aslında default class bu şekilde kalıtılır.
	String renk;
	void YemekYe(){
		print("yemek")
	}
}

class Kedi extends Hayvan{
	int yas;
	
	@override
	void YemekYe(){
		print("yemek yeniyor.");
		super.YemekYe(); // kalıtılmış methoddaki kodlarıda çalıştır.
	}
}


*üst sınıf cons çalıştırma, default ust sınıfı extends edilmesine :super() eklenmiş gibi çalışır.
class Hayvan{
	String renk;
	
	Hayvan(){ //const
		print("Hayvan yaratıldı.");
	}
	
	void YemekYe(){
		print("yemek")
	}
}

class Kedi extends Hayvan{
	int yas;
	
	Kedi(String cins){ //const default olarak Kedi():super(){ //önce üst cons çalıştırılır. Üst cons parametre bekliyor ise Kedi(string renk):super(renk){ ile değer gönderilebilir.
		print("Hayvan yaratıldı.");
	}
	
	@override
	void YemekYe(){
		print("yemek yeniyor.");
		super.YemekYe(); // kalıtılmış methoddaki kodlarıda çalıştır.
	}
}


*abstract classlardan instence üretilemez. kalıtılabilir classlar tanımlanır. İçerisinde methodlar ve değişkenler tanımlanır ve method içleri kalıtılan methodda override ile doldurulmak zorundadır.
*abstractlar interface yerinede implements ile kullanılır.
abstract class Sekil{
	int en;
	int boy;
	
	void AlanHesapla();
	void CevreHesapla();
}

class Dikdortgen extends Sekil{
	
}

*extends ile tek bir method yazılır ve çoklu kalıtım olmaz, implements ile kalıtılan bütün methodları her zaman ezmek gerekir.
Interfaceler ortak özellekileri olan fakat kalıtılımsal olark bir ilişki olmayan yapıları bir arada tutmaya yarar.
class Televizyon implements Kumanda,DigerSinif{
	@override
	void SesAc(){
		print("ses verildi");
	}
}

*static tanımlama, static değişkene direk sınıf üzerinden ulaşılır. Static içerisinden, static olmayan diğer değişken ve methodlara ulaşılamaz.;
main()
{
	var cem = Ogrenci();
	Ogrenci.OgrSayisi++;
}

class Ogrenci{
	String ad;
	static const int okulKod = 1246;
	static int OgrSayisi = 0;
}


*lambda function tanımlama;
main()
{
	f1(1,5);
	f2(5,5);
	f3(2,5);
}

function f1 = (int s1, int s2){ //var f1 ilede tanımlama yapılabilir.
	int toplam = s1+s2;
	Print("toplam ", toplam);
}

var f2 = (int s1, int s2){
	return s1+s2;
}

var f3 = (int s1, int s2) => s1+s2;

*higher order functions: bir fonksiyonu parametre olarak alan veya geriye fonskiyon döndüren fonksiyonlardır.
void main(List<String> args) {
  Function sayilariTopla = (s1,s2) => print(s1+s2);
  birMethod("Cem", sayilariTopla);

  var fonk = birDigerMethod();
  print(fonk(3,3));
}

void birMethod(String isim, Function dynamicFonc)
{
  print("Ad $isim");
  dynamicFonc(2,5);
}

Function birDigerMethod(){
  Function sayilarinKaresiniAl = (s1,s2) => s1*s2;
  return sayilarinKaresiniAl;
}


*Lexical Closure: Closure ile bir üst kapsamdaki değişkenlerin değerleri değiştirilebilir.
void main(List<String> args) {
  var isim = "";
  Function IsimGoster = () => {
	isim = "Cem; //fonk dışında tanımlamış değişkene erişebilip değişiklik yapılabildi.
  }
}


*Liste generate;
import 'dart:math';
void main(List<String> args) {

  //List<int> ogrenciNo = List.filled(30, 0);
  //List<int> ogrenciNo = List.generate(30, (index)>= index); function ile doldurulabilir artan şekilde.
  List<int> ogrenciNumaralari = List.generate(30, (index) => rastgeleOgrenciNoOlutur());
  ogrenciNumaralari.forEach((oankiNumara) => print("Ogrenci No $oankiNumara"));

  // List<Ogrenci> tumOgrenciler = ogrenciNumaralari.map((ogrNo){
  //   return Ogrenci("Ogrenci $ogrNo Adı" , ogrNo);
  // }).toList();

  List<Ogrenci> tumOgrenciler = ogrenciNumaralari.map((ogrNo)=> Ogrenci("Ogrenci $ogrNo Adı" , ogrNo)).toList();

  tumOgrenciler.forEach((ogr) => print("Sadece Öğr Adı: ${ogr.ad}"));
  tumOgrenciler.forEach((ogr) => print("Ogrenci Bilgileri override ile: ${ogr}"));
}

int rastgeleOgrenciNoOlutur()
{
  int olusturSayi = Random().nextInt(60);

  if(olusturSayi != 0)
    return olusturSayi;
    else {
      var yeni = rastgeleOgrenciNoOlutur();
      return yeni;
    }
}

class Ogrenci{
  String ad;
  int no;

  Ogrenci(this.ad, this.no);

  @override
  String toString() {
    return "$ad ve $no";
    //return super.toString();
  }
}


*async kullanımı, dart tek threadte çalıştığı için uzun süren işlemleri arkaplanda devam ettirilmesinde kullanılır.
import 'dart:async';
import 'dart:math';

void main(List<String> args) {
  var random = Random();
  var future = new Future.delayed(new Duration(seconds: 3), (){
    if(random.nextBool()){
      return 100;
    } 
    else{
      throw "boom";
    }
  });

  future.then((value) {
    print("Completed $value");
  }, onError: (error){
    print("Error $error");
  });

  var ffuture = Future.value('a').then((sonuc) => print("Sonuç $sonuc"));
  zincirlemeFuture();

}

void zincirlemeFuture(){
  var ffuture = new Future.value('a').then((v1){ //v1 içeriğinde a var
    return new Future.value('$v1 b').then((v2){ //v2 = a b
      return new Future.value('$v2 c').then((v3){ //v3 = a b c 
        return new Future.value('$v3 d'); // v2 = a b c d
      });
    });
  });

  ffuture.then(print, onError: print); //future.then ilk parametre içerisinde abcd var
  ffuture.then((sondeger) => print("son değer $sondeger"), onError: print); //future.then ilk parametre içerisinde abcd var
}

/* //FUTURE
import 'dart:io';
import 'dart:async';

void main(List<String> args) {
  print("start");
  
  dosyaIceriginiGoster();

  print("end");
}

dosyaIceriginiGoster() async{
    print("içerik geliyor");
    
    String dosyaicerigi = await dosyaIndir();
    print("Dosya İçeriği: $dosyaicerigi");

  Future<String> dosyaicerigithen = dosyaIndir();
  dosyaicerigithen.then((sonuc)=> print("Dosya İçeriği then ile: $sonuc"));

  }
  
Future<String> dosyaIndir() {
  print("Dosya indirme başlandı:");
  
  //sleep(Duration(seconds: 5));
  Future<String> sonuc = Future.delayed(Duration(seconds: 3), (){
    return "İndirilen içerik bu";
  });

  print("Dosya indirilme bitti");
  return sonuc;
}*/



import 'dart:async';
import 'dart:math';
import 'package:http/http.dart' as http;

void main(List<String> args) async{
 
  var func1 = (int v) async => v+1;
  var func2 = (int v) async => v-1;
  var func3 = (int v) async => v*10; 

  var value = 10;
  value = await func1(value);
  value = await func2(value);
  value = await func3(value);
  print(value);

  var response = await http.get('http://google.com');
  print(response.body);

  errorWhenCompleted();

}

void errorWhenCompleted(){
 var random = Random();
  var future = new Future.delayed(new Duration(seconds: 3), (){
    if(random.nextBool()){
      return 100;
    } 
    else{
      throw "boom";
    }
  }).timeout(Duration(seconds: 2));

  future.then(print).catchError(print).whenComplete((){
    print("tamamlandı.");
  });

  var f2 = future.catchError(print);
  var f3 = future.whenComplete(()=>print("Sonuç geldi"));

  //var f4 = future;
}

C# statik method kullanımları

class Program
{
    static void Main(string[] args)
    {

        var list = new List<int>(){0,2};
         
        //1.Yol
        Mex.M2(list);

        //2.Yol
        list.M2();


        list.M3();//this tanımlaması olmadıı için erişim sağlanamaz.
    }
}

public static class Mex
{
    public static void M2(this List<int> list)
    {
        Console.Write("test");
    }


    public static void M3(List<int> list)
    {
        Console.Write("test");
     }


}

static methodlara direk erişim sağlanabilir. Method içerisinde this ile tanımlama program içerisinde . ile belirtilen tip için method çağırımı yapılabilmesini sağlamaktadır. Ör: list.M2();

Visual Studio Kod Metrikleri

Kod metrikleri en genel tanımıyla ; kaynak kodları incelemek ve çeşitli ölçülere göre yazılımı derecelendirmek için kullanılan matematiksel ve istatistiksel yöntemlerdir. Kod metrikleri yazmış olduğumuz sınıflarda , metodlarda, projelerde aksayan ve karmaşıklaşmış noktalar var mı bulmamıza yardımcı olur. Bunu bulurken 5 temel kavramı bilmek gerekiyor.

Class Coupling : Diğer sınıflarla olan bağlantı sayısını ölçer. Bu rakamın yüksek olması yazdığımız metodun dışa bağlı olduğunu gösterir.

Depth of Inheritance : İlgili nesnelerin kalıtım derinliğini ölçer.

Cyclomatic Complexity : Karar ifadelerini ölçer yani if else gibi. Bu rakamında yüksek çıkması kodun karmaşık ve bakımının zor olması demektir.

Lines of Code : Commentler haricinde kalan satır sayısını gösterir. Bu rakamı da küçük tutmak karmaşıklığı azaltır.

Maintainability Index : Sınıf üyeleri veya tipler seviyesinde kod bakımının kolaylığına gösteren bu değişken 0-100 arasında bir değer alır. Bu değerin yüksek olması programın sürdürebilirlik seviyesinin yüksek olduğu anlamına gelir.

Index = MAX(0,(171 – 5.2 * ln(Halstead Volume) – 0.23 * (Cyclomatic Complexity) – 16.2 * ln(Lines of Code))*100 / 171)

Projenizin kod metriklerini görebilmek için önce VS Analyze menüsünden Calculate Code Metrics for Solution’a tıklamanız yeterli.

Nor: https://koraykirdinli.wordpress.com/2010/09/27/visual-studio-kod-metrikleri/ adresinden alıntıdır.

Çok Kullanılan CSS Seçicileri

1. *: Bu #container div öğesinin altındaki her bir çocugu hedefleyecektir.
#container * {
 border: 1px solid black;
}

2. X Y: Descendant(torun)seçicisidir. Seçicilerinizde daha spesifik olmanız gerektiğinde bunları kullanırsınız
li a {
  text-decoration: none;
}

3. X:visited and X:link: Tıklanmamış tüm link etiketlerini :link hedefler ve :visited ise tıklanılmış linkleri hedefler.
a:link { color: red; }
a:visted { color: purple; }

4. X + Y: Komşu seçici denir. Yalnızca önceki öğenin hemen sonrasında bulunan öğeyi seçer. Ör: her ul'den sonraki sadece ilk paragrafı metnini kırmızı yapar.
ul + p {
   color: red;
}

5. X > Y: Standart X Y ile arasındaki fark, direk çocukları seçecektir. Ör: Sadece container içerisindeki ul'ler hedeflenir, li içerisindeki ul'ler hedeflenmez. İçtekileri de hedeflemek için div#container ul kullanılır.
div#container > ul {
  border: 1px solid black;
}
<div id="container">
   <ul>
      <li> List Item
        <ul>
           <li> Child </li>
        </ul>
      </li>
      <li> List Item </li>
      <li> List Item </li>
      <li> List Item </li>
   </ul>
</div>

6. X ~ Y: X + Y yanlnızca ilk seçicinin hemen sonrasındaki seçerken X ~ Y ile seçicin sonrasındaki sıra farketmeksizin tümünü seçer.
ul ~ p {
   color: red;
}

7. X[title]: Nitelik seçicidir. Ör:Yalnızca bir title(başlık) özelliğine sahip olan link etiketleri seçecektir.a[title] {
   color: green;
}

8. X[href="foo"]: href niteliği "foo" olan elementler hedeflenir.
a[href="https://net.tutsplus.com"] {
  color: #1f6053; /* nettuts green */
}

9. X[href*="nettuts"]: Yıldız tırnak içindeki değerin özelliğin içinde bir herhangi bir yerde bulunması gerektiğini belirtir. Dizenin başını ve sonunu işaretlemek için ^ ve $ kullanılır. ^ ile belirttiğimiz kelime ile başlayanları, # ile ise belirttiğimiz kelime ile bitenleri seçtirtebiliriz.
a[href*="tuts"] {
  color: #1f6053; /* nettuts green */
}

10. X[href$=".jpg"]: sonu .jpg ile biten href içeriklerine göre elementleri hedefler.
a[href$=".jpg"] {
   color: red;
}

11. X[foo~="bar"]: Hedeflenen içeriklerde "bar" dizesinin geçmesi seçmek için yeterlidir. Ör: <a href="path/image.jpg" data-info="external image"> Click Me, Fool </a>
a[data-info~="external"] {
   color: red;
}

12. X:checked: Bu takma sınıf, aktif hale gelen bir kullanıcı arabirimi öğesini (bir radyo düğmesi veya onay kutusu gibi) hedefleyecektir. Ör: radio seçildiğinde ilk öğesi olan label mavi olur.
input[type=radio]:checked + label {
          color: blue;
}

13. X:after: Önce(before) ve sonra(after) takma sınıfları superdir. Seçilen öğenin etrafında içerik oluşturmaya olanak sağlarlar.
.clearfix:after {
    content: "";
    display: block;
    clear: both;
    visibility: hidden;
    font-size: 0;
    height: 0;
    }
 
.clearfix { 
   *display: inline-block; 
   _height: 1%;
}

14. X:hover: Bir öğenin üzerine fare ile gelindiğinde çalışır.
div:hover {
  background: #e3e3e3;
}

15. X:not(selector): Ör id'si container olan div'ler dışındaki bütün div'leri seçmek için
div:not(#container) {
   color: blue;
}

16. X::pseudoElement:Pseudo elemanlarını(:: ile belirlenir) kullanarak bir öğenin ilk satırı veya ilk harfi gibi belli bir parçasına stil uygulamanızı sağlar.
p::first-letter { //paragrafın ilk harfi hedeflenir.
   float: left;
   font-size: 2em;
   font-weight: bold;
   font-family: cursive;
   padding-right: 2px;
}

p::first-line { //Paragrafın İlk Satırını Hedefleyin
   font-weight: bold;
   font-size: 1.2em;
}

17. X:nth-child(n): Liste elemanını hedeflemek için kullanılır. Ör: 3.li gibi
li:nth-child(3) {
   color: red;
}

18. X:nth-last-child(n): Liste elemanını sondan hedeflemek için kullanılır. Ör: sondan 3.li gibi
li:nth-last-child(2) {
   color: red;
}

19. 24. X:nth-of-type(n): Elemanın türüne(type) göre seçmede kullanılır. Ör: Sadece içinçi ul hedeflenir.
ul:nth-of-type(3) {
   border: 1px solid black;
}

20. X:nth-last-of-type(n): Elemanın türüne(type) göre sondan başlayarak seçmede kullanılır.
ul:nth-last-of-type(3) {
   border: 1px solid black;
}

21. X:first-child: Yalnızca öğenin ebeveyninin ilk çocuğunu hedeflememizi sağlar.
ul li:first-child {
   border-top: none;
}

22. X:last-child: Yalnızca öğenin ebeveyninin son çocuğunu hedeflememizi sağlar.
ul > li:last-child {
   color: green;
}

23. X:only-child: Ebeveyninin tek çocuğu olan öğeleri hedeflemenize izin verir. Ör: div içerisinde tek p etiketi olanları hedefler.
div p:only-child {
   color: red;
}

24. X:only-of-type: Ana evebeyn konteyneri içinde kardeşi olmayan öğeleri hedefleyecektir. Örnek olarak, tek bir liste öğesine sahip tüm ul'leri hedef alalım.
ul > li:only-of-type {
   font-weight: bold;
}

25. X:first-of-type: first-of-type, türünün ilk kardeşlerini seçmenize izin verir.
<div>
   <p> My paragraph here. </p>
   <ul>
      <li> List Item 1 </li>
      <li> List Item 2 </li>
   </ul>
 
   <ul>
      <li> List Item 3 </li>
      <li> List Item 4 </li>
   </ul>   
</div>

"List Item 2" hedeflemek için;
Çözüm1:Bu kod kısaca, "sayfadaki ilk sırasız listeyi bul, daha sonra yalnızca liste öğeleri olan en yakın olan çocukları bul" diyor. Sonrada, bu bulunan setteki sadece ikinci liste öğesine göre filtreleme yapılıyor.
ul:first-of-type > li:nth-child(2) {
   font-weight: bold;
}
Çözüm2:Başka bir seçenek, bitişik seçiciyi kullanmaktır. Bu senaryoda, p etiketinin hemen sonrarsındaki ul'yi buluruz ve daha sonrada öğenin son çocuğunu buluruz.
p + ul li:last-child {
   font-weight: bold;
}
Çözüm3: Sayfadaki ilk ul'ı kapıyoruz ve alttan başlayarak ilk liste öğesini buluyoruz
ul:first-of-type li:nth-last-child(1) {
   font-weight: bold;   
}