11 Eylül 2020 Cuma

Python + Selenium Instagram Fotoğraf Beğeni Botu, Instagram Photo Like Automation


Python3 kütüphanelerinden biri olan Selenium ile bir instagram botu veya instagram otomasyonu kodlayacağız. Selenium ve Chrome Webdriver'ını kullanarak programımızı yapacağız. Ek olarak yüklü gelen time kütüphanesinden de yararlanacağız.

,


Import İşlemleri ve Ana Sayfaya Gitmek

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('https://www.instagram.com') #Go to instagram login page.
sleep(2) #Wait for loading page.

İlk satırlarda selenium içerisinden webdriver'ı; time içerisinden ise sleep fonksiyonunu projemize dahil edeceğiz.
3. satırda Chrome Webdriver'ını başlatıyoruz. Ve bir sonraki satırda get() komutunun içine, adres parametresi olarak instagram'ın adresini veriyoruz. Ve sayfa doğru düzgün yüklenene kadar bekleyeceğiz. Ben iki saniye yeter diye düşünüyorum.

Input ve Buttonu Bulmak

Instagram hesabına giriş yapmak için doğru input alanına doğru değerleri yazıp, giriş yap butonuna tıklamamız gerekiyor. Input'ları bulmak için name sıfatlarını kullanacağız. Kullanıcı adı inputunun name sıfatı username, şifre inputunun name sıfatı ise password olarak belirlenmiş. Input'lara yazı yazabilmek, içini doldurmak için send_keys() fonksiyonunu kullanacağız.

Butonu bulabilmek için find_element_by_xpath() fonksiyonunun içine geçerli sayfada var olan ve type sıfatı submit olan bir button elementi bul anlamına gelen bir string vereceğiz. Button'ları kullanmak için ise yani tıklamak için click() fonksiyonunu çalıştaracağız.

Ve en sonda giriş işlemini yine 2 saniye bekleyeceğiz.

username = driver.find_element_by_name('username').send_keys('KULLANICI ADI') 
password = driver.find_element_by_name('password').send_keys('ŞİFRE')
girisbutton = driver.find_element_by_xpath('//button[@type="submit"]').click() #Log-in button
sleep(2) 

Şimdi Değil Butonları

Giriş yapıldıktan sonra iki kere kullanıcıya soru soruyor instagram. Birincisi şifreyi kaydetmek ikincisi ise bildirimlere izin vermek konusunda. İkisini de içinde şimdi değil yazan butonlara tıklayıp atlayacağız. 

Butonların içerisinde yazan yazı farklı dillerde farklı olacaktır. Türkçede 'Şimdi Değil', İngilizcede 'Not Now' gibi değişiklik gösterecektir. 

Bu butonlara erişmek için find_element_by_xpath() fonksiyonuna başvuracağız yine. Bu fonksiyonu, içinde Şimdi Değil yazan butonu bul anlamına gelen bir string ile çalıştaracağız. Ve her ikisinden sonra da sleep() ile biraz bekleyeceğiz.

simdidegil = driver.find_element_by_xpath('//button[contains(text(), "Şimdi Değil")]').click() #Answer to 'save your password?'
sleep(1.5)
simdidegil = driver.find_element_by_xpath('//button[contains(text(), "Şimdi Değil")]').click() #Answer to 'open notification?'
sleep(0.5)

Kullanıcı Aramak ve Hedef Profile Gitmek

Fotoğraflarını beğeneceğimiz kullanıcıyı bulmak için ilk önce instagram'ın arama kutusuna, hedef profilimizin ismini yazacağız. Daha sonra çıkan ilk öneriye tıklayarak profili görünteleyeceğiz.

Arama kutusunu bulmak için find_element_by_xpath() kullanacağız gene ve bu sefer geçerli sayfadaki input'lar içerisinden type sıfatı text olan elementi bul diyeceğiz.

Çıkan ilk öneriye gitmek için ise kolay yolu kullanacağız. Arama kutusuna rastgele bir şeyler yazın ve çıkan ilk önerinin a elementinin xpath yolunu kopyalacağız ve aynı fonksiyonu kullanacağız.


 

aramakutusu = driver.find_element_by_xpath('//input[@type="text"]').send_keys('HEDEF HESAP') #The search bar that we type target username
sleep(2) #Wait for loading suggestions
profile = driver.find_element_by_xpath('//*[@id="react-root"]/section/nav/div[2]/div/div/div[2]/div[3]/div[2]/div/a[1]').click() #Click on the first suggestion
sleep(3) #Wait for loading target profile

Sayfanın En Aşağısına Gitmek ve Tüm Fotoğrafları Yüklemek

Instagram profildeki fotoğrafların ilk önce bir kısmını yüklüyor. Sayfanın en aşağısına gittiğinizde ise bir kısmını daha yüklüyor. Tüm fotoğrafları yüklemek için fotoğraflar bitene kadar sürekli sayfanın aşağına kadar gitmeniz gerek. Bunun için bir fonksiyon yazacağız. Ve while loop kullanacağız. Sayfanın dibi olarak footer elementini referans alacağız. 

Footer elementini bulmak için find_element_by_tag_name() komutuna tag_name parametresini gireceğiz.

Daha sonra sayfanın geçerli yüksekliğini bulmak için bir JavaScript komutu çalıştaracağız. JS komutunu execute_script() adlı fonksiyon aracılığıyla yürüteceğiz. Daha sonra location_once_scrolled_into_view ile sayfayı footer elementini görene kadar indireceğiz. 

Ve birkaç saniye bekledikten sonra geçerli yükseklik ile sayfayı hareket ettirmeden önceki yüksekliği kıyaslayacağız. Eğer yeterli süre bekledikten sonra(bu internet bağlantısına göre değişebilir) yükseklik değişmemişse bu profilde başka fotoğraf olmadığı anlamına geliyor. Eğer değişmişse geçerli yüksekliği kaydedip, sayfayı tekrar en aşağıya kadar çekeceğiz ve yine kontrol edeceğiz.

def scrollAllWayDown():
    #This function scroll down to see the footer element and wait for a couple second. If page scroll length has changed then scroll again because that mean there is other pictures.
    global driver
    footer = driver.find_element_by_tag_name('footer') #The footer element
    last_height = driver.execute_script('return document.body.scrollHeight') #Before scroll down note scroll length
    while True:
        footer.location_once_scrolled_into_view #Scroll down to see footer
        sleep(2) #Wait for internet
        new_height = driver.execute_script('return document.body.scrollHeight') #Run javascript code again to check scroll length.
        if new_height == last_height: #If scroll height hasnt changed then there is no more pictures.
            print('sayfa bitti!!!')
            break
        else: #If it changed set the last height equal new height and repeat function.
            last_height = new_height

scrollAllWayDown()

Fotoğrafları Açmak ve Beğenmek

A) Fotoğrafları açmak için a elementlerini bulmalıyız ve click fonksiyonunu çalıştırmalıyız. Her fotoğrafın a elementi'ni bulmak için onların ayırt edici bir özellikleri olmalıdır. Ancak a elementleri'nde bizim kullanabileceğimiz bir sıfat yok. 

Ama onların parent elementi olan div elementlerinde ayırt edici olarak kullanabileceğimiz class sıfatları var. 

find_elements_by_class_name() kullanarak aynı class sıfatına sahip div elementlerini bulacağız. Sonra onların child elementi ve bizim hedefimiz olan a elementleri'ne erişeceğiz.

tumKutular = driver.find_elements_by_class_name('v1Nh3') #Every photo attribute has a parent div so first find divs
tumLinkler = []
for i in tumKutular:
    tumLinkler.append(i.find_element_by_tag_name('a')) #And find attribute in divs

B) Burada tumLinkler isimli bir dizi oluşturduk. Bu dizinin her üyesi tıklanabilir. Tıklayıp fotoğrafı açacağız ve kalp butonunu bulup, tıklayacağız. Ve yukarıdaki çıkış butonuna tıklayıp o fotoğrafı kapatmış olacağız. 

Kalp ve çıkış butonlarının xpath adreslerini kullanacağız. Bunun için elementi seçip, sağ tıklayıp, Copy Xpath ile xpath adresini temin edeceğiz. Ve find_element_by_xpath() 'in içine yapıştaracağız.



for i in tumLinkler:
    i.click() #Click link and open photo
    sleep(2)
    begenbuton = driver.find_element_by_xpath('/html/body/div[4]/div[2]/div/article/div[3]/section[1]/span[1]/button') 
    begenbuton.click() #Click heart button
    sleep(0.2)
    cikis = driver.find_element_by_xpath('/html/body/div[4]/div[3]/button').click() #Click exit button
    

Kodun Son Hali:

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('https://www.instagram.com') #Go to instagram login page.
sleep(2) #Wait for loading page.

username = driver.find_element_by_name('username').send_keys('YOUR USERNAME') 
password = driver.find_element_by_name('password').send_keys('YOUR PASSWORD')
girisbutton = driver.find_element_by_xpath('//button[@type="submit"]').click() #Log-in button
sleep(2) 

simdidegil = driver.find_element_by_xpath('//button[contains(text(), "Şimdi Değil")]').click() #Answer to 'save your password?'
sleep(1.5)
simdidegil = driver.find_element_by_xpath('//button[contains(text(), "Şimdi Değil")]').click() #Answer to 'open notification?'
sleep(0.5)

aramakutusu = driver.find_element_by_xpath('//input[@type="text"]').send_keys('HEDEF HESAP') #The search bar that we type target username
sleep(2) #Wait for loading suggestions
profile = driver.find_element_by_xpath('//*[@id="react-root"]/section/nav/div[2]/div/div/div[2]/div[3]/div[2]/div/a[1]').click() #Click on the first suggestion
sleep(3) #Wait for loading target profile

def scrollAllWayDown():
    #This function scroll down to see the footer element and wait for a couple second. If page scroll length has changed then scroll again because that mean there is other pictures.
    global driver
    footer = driver.find_element_by_tag_name('footer') #The footer element
    last_height = driver.execute_script('return document.body.scrollHeight') #Before scroll down note scroll length
    while True:
        footer.location_once_scrolled_into_view #Scroll down to see footer
        sleep(2) #Wait for internet
        new_height = driver.execute_script('return document.body.scrollHeight') #Run javascript code again to check scroll length.
        if new_height == last_height: #If scroll height hasnt changed then there is no more pictures.
            print('sayfa bitti!!!')
            break
        else: #If it changed set the last height equal new height and repeat function.
            last_height = new_height

scrollAllWayDown()

tumKutular = driver.find_elements_by_class_name('v1Nh3') #Every photo attribute has a parent div so first find divs
tumLinkler = []
for i in tumKutular:
    tumLinkler.append(i.find_element_by_tag_name('a')) #And find attribute in divs

for i in tumLinkler:
    i.click() #Click link and open photo
    sleep(2)
    begenbuton = driver.find_element_by_xpath('/html/body/div[4]/div[2]/div/article/div[3]/section[1]/span[1]/button') 
    begenbuton.click() #Click heart button
    sleep(0.2)
    cikis = driver.find_element_by_xpath('/html/body/div[4]/div[3]/button').click() #Click exit button
    

2 Temmuz 2020 Perşembe

Unity3D Yükleme Ekranı Oluşturma, Make a Loading Bar Screen



Unity' de sahneler arası geçişte kullanabileceğimiz ve oyuncumuzun programın ne yaptığını bilip, donmadığını teyit etmesi veya beklerken sıkılmaması için örneğin bir seviyeden başka bir seviyeye geçerken gösterdiğimiz bir ekrandır.

Neler Kullanılacak

  • Temel olarak diğer sahneye geçmek için bir koşul veya buton lazım, ben nasıl yapılacağını göstereceğim için bir buton kullanıyorum.
  • Yükleme ekranımızı üstüne tasarlamak için bir adet panel nam-ı diğer 'TheLoadingPanel',
  • Yükleme çubuğu olacak bir slider nam-ı diğer 'LoadingBar',
  • İsteğe bağlı olarak panelin üst kısmında gözükecek bir adet text nam-ı diğer 'LoadingText',
  • Yine isteğe bağlı olarak yükleme çubuğunun yüzde kaç dolduğunu yazdıracağımız bir adet text nam-ı diğer 'LoadingProgress',
  • Kodları devralacak bir gameobject ben ismini '_GameManager' koydum,
  • Ve tabi ki ikinci bir sahne.

Yapılışı

  • Hierarchy penceresinde _GameManager'i oluşturun.
  • Daha sonra button ve paneli oluşturun.
  • Daha sonra panelin içerisine slider ve text bileşenlerini yaratın.
  • Paneli inspector penceresinden deaktif hale getirin.

  • LoadingBar içindeki "Handle Slide Area" bileşenini silin çünkü bu slider kendi başına dolacak.
  • LoadingText yazısının içeriğini 'Yükleniyor...' olarak belirleyin. Ve LoadingBar'ın yukarısında veya aşağında yerleştirin.
  • LoadingProgress'i ise LoadingBar içerisine ortalayabilirsiniz ya da sağa ya da sola dayalı olarak kullanabilirsiniz. Bunun içindeyse '0%' gibi yüklemenin ilerleyeşi gösterilecek.
  • TheLoadingPanel' i aşağıdaki gibi tasarlayabilirsiniz.
theLoadingPanel

Kodlama Kısmı

Kodları devralması için '_GameManager' adlı boş bir GameObject yaratmıştık. 
  • '_GameManager' üstüne tıklayın ve Inspector penceresindeki Add Component butonuna tıklayın.
  • Açılan küçük pencerenin altındaki New Script butonuna tıklayıp, kod parçasına bir isim verin ve onu yaratın. Ben 'GameManager' adını layık gördüm.
  • Oluşturduktan sonra kodu açın ve aşağıdaki kodları içine yapıştırın:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
 public GameObject theLoadingPanel; //Panelimiz
 public Slider loadingBar; //Yükleme çubuğumuz
 public Text loadingProgress; //Yükleme çubuğumuzun ilerleyişi
 AsyncOperation operation; //Sahneyi asenkron olarak yükleyecek zımbırtı

 public void SahneYukle(int sahneIndex)
 {
  operation = SceneManager.LoadSceneAsync(sahneIndex);
  StartCoroutine(YuklemeEkrani(1));
 }
    
 IEnumerator YuklemeEkrani(int index)
 {
  theLoadingPanel.SetActive(true);
  while (!operation.isDone)
  {
   int progress = Mathf.CeilToInt(operation.progress * 100f);
   loadingBar.value = progress / 100f;
   loadingProgress.text = progress+ "%";
   yield return null;
  }
 }
}

  • Daha sonra Button'un üstüne tıklayın ve Inspector penceresinde On Click() içine _GameManager'i sürükleyin ve fonksiyon olarak 'SahneYükle (int)' i seçin ve yazı kutusunun içine 1 yazın.

24 Mayıs 2020 Pazar

Python3 Tkinter, PyperClip, Random, String: Parola Oluşturucu Yapmak, Create a Password Generator


Python 3 ile beraber yüklenen Tkinter modülü ile grafiksel kullanıcı arayüzüne sahip programlar yapabiliriz. Tkinter için Visual Studio gibi arayüzde bulunan araçları sürükleyip bıraktığımız, yerlerini değiştirebildiğimiz bir yapı söz konusu değil. Programdaki araçları kodlarla arayüze getirip istersek kodlarla konumlarını ayarlayabiliriz. Parola oluşturucuda kullanıcıdan parola uzunluğunu alacağımız bir Entry, oluşturulan parolayı yazacağımız başka bir Entry, hangi karakterlerin kullanılacağını seçtirmek için 3 tane CheckBox ve 2 tane de Button kullanacağız.



Penceremizi Yaratmak

Pencereyi yaratmadan önce uygulamamıza dahil etmemiz gereken Tkinter hariç 3 kütüphane var. Ve daha sonra sınıfımızı oluşturacağız.

import random
import string
import pyperclip
from tkinter import *
class Main:
    def __init__(self, master):
        self.master = master
        master.title('Parola Oluşturucu')

        self.parolaUzunluguL = Label(master, text="parola uzunluğu:")
        self.parolaUzunluguL.grid(row=0, column=0, pady=4, padx=12, sticky=EW)
        self.defaultValue = StringVar(master, '8')
        self.parolaUzunluguE = Entry(master, textvariable=self.defaultValue)
        self.parolaUzunluguE.grid(row=0, column=1,columnspan=2, padx=12, sticky=E)

        self.harfBool = IntVar()
        self.harfBool.set(True)
        self.checkHarf = Checkbutton(master, text="harfler", variable = self.harfBool)
        self.checkHarf.grid(row=1, column=0, pady=4, sticky=EW)

        self.rakamBool = IntVar()
        self.rakamBool.set(True)
        self.checkRakam = Checkbutton(master, text="rakamlar", variable=self.rakamBool)
        self.checkRakam.grid(row=1, column=1, pady=4, sticky=EW)

        self.noktalamaBool = IntVar()
        self.noktalamaBool.set(True)
        self.checkNoktalama = Checkbutton(master, text="noktalamalar", variable=self.noktalamaBool)
        self.checkNoktalama.grid(row=1, column=2, pady=4, sticky=EW)

        self.olusturB = Button(master, text='oluştur', command=self.parolaOlustur)
        self.olusturB.grid(pady=4, padx=12, sticky=EW, columnspan=3, row=2, column=0)

        self.olusturulanParola = Entry(master)
        self.olusturulanParola.grid(pady=8, padx=12, row=3, column=0, columnspan=2, sticky= EW)

        self.kopyala = Button(master, text="kopyala", command = self.parolayiKopyala)
        self.kopyala.grid(pady=8, padx=12, row=3, column=2, sticky=EW)

root = Tk()
main = Main(root)
root.mainloop()

Gerekli Methodları Yazmak

1-Parola Oluşturma Methodu:

Parola oluştururken ilk önce kullanıcımızın istediği parola uzunluğunu Entry widget'ından alacağız. Burada Entry'den aldığımız veriyi integer tipine dönüştürmemiz gerekiyor. Daha sonra karakter setlerini Checkbox değerlerine göre belirleyeceğiz. Eğer rakamlar CheckBox'u seçili değilse, rakamlar değişkenimiz boş olacak. Ve diğer ikisini de böyle belirliyoruz. For döngüsü ile rastgele seçtiğimiz karakterleri parola değişkenimize ekleyeceğiz. Ve en sonunda oluşturulan parolayı göstereceğimiz Entry'e bunu yazacağız.

    def parolaOlustur(self):
        parolaUzunlugu = int(self.parolaUzunluguE.get())
        harfler = string.ascii_letters if self.harfBool.get() else ""
        rakamlar = string.digits if self.rakamBool.get() else ""
        noktalama = string.punctuation if self.noktalamaBool.get() else ""
        parola = ""
        for i in range(parolaUzunlugu):
            randChar = random.choice(harfler+rakamlar+noktalama)
            parola += randChar
        self.olusturulanParola.delete(0, END)
        self.olusturulanParola.insert(END, parola)

2-Oluşan Parolayı Clipboard'a Kopyalamak:

Oluşturduğumuz ve Entry widget'ına yazdırdığımız parolayı kullanıcının daha kolay kullanması için 'pyperclip' kütüphanesini kullanarak kopyalama işlemini yapacağız. Tabii bunun için önce pyperclip kütüphanesi yüklememiz gerekiyor. Yükledikten sonra uygulama içinde kullanabiliriz. Böyle işlemleri daha kolay yapmak için PyCharm IDE'sini kullanabilirsiniz ki ben öyle yapıyorum. PyCharm'ın ücretsiz Community Edition'u mevcut.


    def parolayiKopyala(self):
        pyperclip.copy(self.olusturulanParola.get())

Programımızın Son Hali




import random
import string
import pyperclip
from tkinter import *
class Main:
    def __init__(self, master):
        self.master = master
        master.title('Parola Oluşturucu')

        self.parolaUzunluguL = Label(master, text="parola uzunluğu:")
        self.parolaUzunluguL.grid(row=0, column=0, pady=4, padx=12, sticky=EW)
        self.defaultValue = StringVar(master, '8')
        self.parolaUzunluguE = Entry(master, textvariable=self.defaultValue)
        self.parolaUzunluguE.grid(row=0, column=1,columnspan=2, padx=12, sticky=E)

        self.harfBool = IntVar()
        self.harfBool.set(True)
        self.checkHarf = Checkbutton(master, text="harfler", variable = self.harfBool)
        self.checkHarf.grid(row=1, column=0, pady=4, sticky=EW)

        self.rakamBool = IntVar()
        self.rakamBool.set(True)
        self.checkRakam = Checkbutton(master, text="rakamlar", variable=self.rakamBool)
        self.checkRakam.grid(row=1, column=1, pady=4, sticky=EW)

        self.noktalamaBool = IntVar()
        self.noktalamaBool.set(True)
        self.checkNoktalama = Checkbutton(master, text="noktalamalar", variable=self.noktalamaBool)
        self.checkNoktalama.grid(row=1, column=2, pady=4, sticky=EW)

        self.olusturB = Button(master, text='oluştur', command=self.parolaOlustur)
        self.olusturB.grid(pady=4, padx=12, sticky=EW, columnspan=3, row=2, column=0)

        self.olusturulanParola = Entry(master)
        self.olusturulanParola.grid(pady=8, padx=12, row=3, column=0, columnspan=2, sticky= EW)

        self.kopyala = Button(master, text="kopyala", command = self.parolayiKopyala)
        self.kopyala.grid(pady=8, padx=12, row=3, column=2, sticky=EW)
    def parolaOlustur(self):
        parolaUzunlugu = int(self.parolaUzunluguE.get())
        harfler = string.ascii_letters if self.harfBool.get() else ""
        rakamlar = string.digits if self.rakamBool.get() else ""
        noktalama = string.punctuation if self.noktalamaBool.get() else ""
        parola = ""
        for i in range(parolaUzunlugu):
            randChar = random.choice(harfler+rakamlar+noktalama)
            parola += randChar
        self.olusturulanParola.delete(0, END)
        self.olusturulanParola.insert(END, parola)

    def parolayiKopyala(self):
        pyperclip.copy(self.olusturulanParola.get())

root = Tk()
main = Main(root)
root.mainloop()

25 Nisan 2020 Cumartesi

PHP Laravel: Forms & HTML Açılır Liste, Select Elemanını Kullanmak, Dropdown List Using Select Element



Laravel framework'ü ile proje geliştirirken sayfadaki formları ve form içindeki bileşenleri tek satırda oluşturabiliriz.


Form Açmak

{{ Form::open(array('url'=>'/dizin/dizin', 'method' =>'post'))}}
//buraya select öğesini koyabiliriz.
{{Form::close()}}

Select Elemanı

{{Form::select('name', array('value' => 'key', 'v2' => 'k2'), 'selectedvalue', array('id' => 'dropdownlist', 'class' => 'form_element_class', 'onchange' => 'changedSelect(this.value)'))}}
Böyle bir kod ile select elemanının formda kullanılacak olan `name` özelliğini, `id`, `class` ve bir değişiklik olduğunda `onchange listener` özelliğini kontrol edebiliyoruz. Ayrıca HTML olarak yazsaydık seçili değeri değiştirmek için her option'a PHP'de kontrol yaptıracak ve veritabanında kayıtlı olan hangisiyse onun seçili olmasıyla uğraşacaktık. Ama Laravel Form ile seçili olanı çok kolay bir şekilde belirleyebiliyorsunuz. HTML'de aşağıdaki kodu yazdığımızda ortaya çıkan select elemanını oluşturacaktır.
<select class="form_element_class" id="dropdownlist" onchange="changedSelect(this.value)">
<option value="value">key</option>
<option value="v2">k2</option>
</select>

Ve bunun sonucunda aşağıdaki select öğesi gözükecektir. Geliştirici seçeneklerinden kontrol edebilirsiniz.

30 Mart 2020 Pazartesi

Python3 Tkinter Zamanlayıcı, Geri Sayım Uygulaması Yapmak, Countdown App, Timer: time, threading, tkinter


Python 3'te girdiğimiz saniye kadar geri sayan ve saydığı sırada bunu her bir saniyede bir defa ekrana yazan bir program yazacağız. Ve nesne yönelimli programlama stilini kullanacağız.


Gerekli Kütüphaneleri Projeye Dahil etmek

Time, Threading ve Tkinter

from tkinter import *
import time
import threading

Sınıfımızı Oluşturalım

import time
import threading
from tkinter import *
class Main:
    def __init__(self, master):
        self.master = master
        master.title('Zamanlayıcı')

        self.secondL = Label(master, text='saniye:')
        self.secondL.grid(row = 0, column= 0, pady=10, padx=10)
        self.secondE = Entry(master)
        self.secondE.grid(row = 0, column=1, padx=10)

        self.startButton = Button(master, text='başlat', command=self.threadStartTimer)
        self.startButton.grid(row=1, column=1, sticky = EW, padx=10)

        self.stopButton = Button(master, text='durdur', command=self.threadStopTimer)
        self.stopButton.grid(row=2, column=1, sticky = EW, padx=10)
        self.stopButton['state'] = 'disabled'

Burada uygulamamıza Tkinter kullanarak arayüz ekledik. Bir labelimiz, bir entrymiz, iki tane de butonumuz var. Butonlarımızdan bir tanesi geri sayımı başlatmak, bir tanesi de geri sayımı durdurmak için var oldular. Yalnız durdur butonumuzu başlangıçta kullanışsız hale getiriyoruz. Onu sadece geri sayım sırasında aktifleştireceğiz.

Method: Başlama

    def threadStartTimer(self):
        self.startedThread = threading.Thread(target=self.startTimer)
        self.startedThread.start()

    def startTimer(self):
        self.deadCounting = False
        second = int(self.secondE.get())
        now = time.time()
        future = now + second
        while time.time() <= future and not self.deadCounting:
            self.startButton['state'] = 'disabled'
            self.stopButton['state'] = 'active'
            self.secondE.delete(0, END)
            self.secondE.insert(0, int(future - time.time()))
            if int(future - time.time()) == 0:
                self.startButton['state'] = 'active'
                self.stopButton['state'] = 'disabled'
            time.sleep(.1)

Thread kullanmamızın asıl amacı ikinci methodda yazdığımız while döngüsü çalışırken bir yandan da Tkinter penceremizin güncellenmesi. Eğer Thread kullanmazsak Tkinter penceremez while döngüsü bitene kadar yenilenmeyecek çünkü sırasıyla yaptırıyor olacaktık. İkinci metodda self.deadCounting boolean'ı, geri sayımı durdurmak için orada.

Method: Durdurma

    def threadStopTimer(self):
        self.deadCounting = True
        self.stopButton['state'] = 'disabled'
        self.startButton['state'] = 'active'

self.deadCounting'i True yaparak Thread'da çalışan while döngüsünü kırdık. Geri sayımı bitirdiğimizden dolayı durdurma butonumuzu deaktif, başlat butonunu da aktif hale getiriyoruz. 

Kodun Son Hali

import time
import threading
from tkinter import *
class Main:
    def __init__(self, master):
        self.master = master
        master.title('Zamanlayıcı')

        self.secondL = Label(master, text='saniye:')
        self.secondL.grid(row = 0, column= 0, pady=10, padx=10)
        self.secondE = Entry(master)
        self.secondE.grid(row = 0, column=1, padx=10)

        self.startButton = Button(master, text='başlat', command=self.threadStartTimer)
        self.startButton.grid(row=1, column=1, sticky = EW, padx=10)

        self.stopButton = Button(master, text='durdur', command=self.threadStopTimer)
        self.stopButton.grid(row=2, column=1, sticky = EW, padx=10)
        self.stopButton['state'] = 'disabled'

        self.adButton = Button(master, text='kodlardan bir blog')
        self.adButton.grid(row=3, column=1, sticky= EW, padx=10,pady=10)

    def threadStartTimer(self):
        self.startedThread = threading.Thread(target=self.startTimer)
        self.startedThread.start()

    def startTimer(self):
        self.deadCounting = False
        second = int(self.secondE.get())
        now = time.time()
        future = now + second
        while time.time() <= future and not self.deadCounting:
            self.startButton['state'] = 'disabled'
            self.stopButton['state'] = 'active'
            self.secondE.delete(0, END)
            self.secondE.insert(0, int(future - time.time()))
            if int(future - time.time()) == 0:
                self.startButton['state'] = 'active'
                self.stopButton['state'] = 'disabled'
            time.sleep(.1)

    def threadStopTimer(self):
        self.deadCounting = True
        self.stopButton['state'] = 'disabled'
        self.startButton['state'] = 'active'

root = Tk()
main = Main(root)
root.mainloop()


17 Şubat 2020 Pazartesi

Python3 PyGame: Yazı ve Buton Oluşturmak, Create Text and Interactive Button


Oyun yapmak için kullanılan Python kütüphanelerinden biri olan PyGame' de yazı yazacak ve çalışır bir buton yapacağız.

Projenin Sonunda Elde Edeceğimiz Görüntü


Pencere Oluşturmak

import pygame
SIZE = WIDTH, HEIGHT = 640, 480
BLACK = 0, 0, 0
BGCOLOR = 65, 157, 120
WHITE = 255, 255, 255
FONTDIR = 'gravity.otf'

pygame.init()
pencere = pygame.display.set_mode(SIZE)
pygame.display.set_caption('Yazı Yazmak ve Buton Oluşturmak')

Burada pygame kütüphanesini import ettik ve penceremizin boyutlarını SIZE constant veri tipinde sakladık. 

Ayrıca daha sonra işimize yarayacak bazı renk kodlarını da en başta yazdık.
BGCOLOR yukarıdaki resimde de gördüğünüz pencerenin arka planının kodu. Siz isterseniz değiştirebilirsiniz.

Yazı yazacağımız için bir font'a ihtiyacımız olacak. İlla ki bu fontu kullanmak zorunda değilsiniz. İnternetten bedava font dosyaları bulabilirsiniz. Ve kodun içinde bu dosyanın yerini belirtmeniz gerekiyor. Eğer font dosyası, python dosyanızla aynı klasörde bulunursa FONTDIR verisine sadece font dosyasının ismini yazsanız yeterli.

pygame.init() fonksiyonuyla pygame'i başlatıyoruz.
Yukarıda belirlediğimiz pencere boyutlarını pygame.display.set_mode() içine yerleştiriyoruz ve en son satırda da penceremizin başlığı yer alıyor.

Arka Plan Rengi

calisiyor = True
while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False
 pencere.fill(BGCOLOR)
 pygame.display.flip()

pencere.fill(BGCOLOR) ile arka plan rengimizi belirledik.
üstte tanımladığımız calisiyor boolean verisiyle oyunumuzun ne zaman kapanacağını kontrol altına aldık.

pygame.event ile eğer pencerenin sağ üstündeki çarpıya tıklandıysa calisiyor verisini false'a çevirerek programı sonlandırmış oluruz.

pygame.display.flip() fonksiyonu penceremizi yenilemeye yarıyor. bunun yerine pygame.display.update() fonksiyonu da kullanılabilir.


Yazıyı Oluşturmak

font = pygame.font.Font(FONTDIR, 32)

textContent = 'KODLARDAN1BLOG'
calisiyor = True
while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False
 
 pencere.fill(BGCOLOR)

 text = font.render(textContent, True, WHITE)
 textRect = text.get_rect()
 textRect.center = (WIDTH / 2, HEIGHT / 2 - 60)
 pencere.blit(text, textRect)

 pygame.display.flip()

pygame.font.Font(fontAddress, fontSize)
font.render(text, antialiase, color, backgroundcolor)
pencere.blit(surface, points)


Butonu Oluşturmak

buttonIdleColor = 225, 199, 141
buttonHoverColor = 224, 164, 88
buttonPressedColor = 45, 48, 71
buttonWidth, buttonHeight = 200, 60
buttonX = WIDTH / 2 - buttonWidth / 2
buttonY = HEIGHT / 2 
buttonRect = pygame.Rect(buttonX, buttonY, buttonWidth, buttonHeight)

buttonColor = buttonIdleColor
textContent = 'KODLARDAN1BLOG'
calisiyor = True
while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False

 pencere.fill(BGCOLOR)

 text = font.render(textContent, True, WHITE)
 textRect = text.get_rect()
 textRect.center = (WIDTH / 2, HEIGHT / 2 - 60)
 pencere.blit(text, textRect)

 pygame.draw.rect(pencere, buttonColor, buttonRect)

 pygame.display.flip()

Burada butonumuzun pozisyonu belirlerken, yazıdaki gibi orta noktasını değil, butonun sol üst köşesini belirliyoruz. 
Bu sefer pygame.draw.rect(surface, color, rect) fonksiyonunu kullandık. Bununla aslında buton değil bir dikdörtgen oluşturduk.
buttonIdleColor : fare butonun üstünde değilken.
buttonHoverColor : fare butonun üstündeyken.
buttonPressedColor : fare butonun üstünde ve basılı iken.


Butona Ruhunu Üflemek

while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False

 mouseX, mouseY = pygame.mouse.get_pos()
 click = pygame.mouse.get_pressed()
 if buttonX + buttonWidth > mouseX > buttonX and buttonY + buttonHeight > mouseY > buttonY:
  buttonColor = buttonHoverColor
  buttonTextColor = BLACK
  if click[0] == 1:
   buttonColor = buttonPressedColor
   buttonTextColor = WHITE
   textContent = 'KODLARDAN1BLOG.com'
 else:
  buttonColor = buttonIdleColor
  buttonTextColor = BLACK

 pencere.fill(BGCOLOR)

 text = font.render(textContent, True, WHITE)
 textRect = text.get_rect()
 textRect.center = (WIDTH / 2, HEIGHT / 2 - 60)
 pencere.blit(text, textRect)

 pygame.draw.rect(pencere, buttonColor, buttonRect)

 pygame.display.flip()

mouse.get_pos() ile mouse imlecinin bulunduğu x ve y koordinatlarını alıyoruz ve onları mouseX ve mouseY değişkenlerine atadık.
mouse.get_pressed() ile hangi butonların basılı olup olmadığını anlayabiliyoruz. [sol tuş, kaydırma tuşu, sağ tuş] formatında bir veri veriyor. Ve sol tuşun basılı olup olmadığını anlamak için mouse.get_pressed()[0] kodunu kullanıyoruz.


Butonun Üstüne Yazı Yazmak

Burada önemli olan pozisyonu ayarlayabilmek yoksa normal yazı yazmaktan hiçbir farkı yok. Ve tabii yazıyı butonun üstüne yazdıracağımız için ekrana ilk önce butonu basıp daha sonra yazıyı yazmalıyız.

while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False

 mouseX, mouseY = pygame.mouse.get_pos()
 click = pygame.mouse.get_pressed()
 if buttonX + buttonWidth > mouseX > buttonX and buttonY + buttonHeight > mouseY > buttonY:
  buttonColor = buttonHoverColor
  buttonTextColor = BLACK
  if click[0] == 1:
   buttonColor = buttonPressedColor
   buttonTextColor = WHITE
   textContent = 'KODLARDAN1BLOG.com'
 else:
  buttonColor = buttonIdleColor
  buttonTextColor = BLACK

 pencere.fill(BGCOLOR)
 
 text = font.render(textContent, True, WHITE)
 textRect = text.get_rect()
 textRect.center = (WIDTH / 2, HEIGHT / 2 - 60)
 pencere.blit(text, textRect)
 
 pygame.draw.rect(pencere, buttonColor, buttonRect)

 buttonText = font.render('I LOVE', True, buttonTextColor)
 buttonTextRect = buttonText.get_rect()
 buttonTextRect.center = buttonRect.center
 pencere.blit(buttonText, buttonTextRect)
 
 pygame.display.flip()

Buton oluştururken pygame.Rect(x, y, width, height) kullanmanın avantajı bu dörtlünün tam ortasını pygame.Rect().center ile alabiliyor olmamız. Bu yüzden butonun ağırlık merkezini bulmak zor olmadı.


Projenin Son Hali ve Kodlar


import pygame
SIZE = WIDTH, HEIGHT = 640, 480
BLACK = 0, 0, 0
BGCOLOR = 65, 157, 120
WHITE = 255, 255, 255
FONTDIR = 'gravity.otf'

pygame.init()
pencere = pygame.display.set_mode(SIZE)
pygame.display.set_caption('Yazı Yazmak ve Buton Oluşturmak')

font = pygame.font.Font(FONTDIR, 32)

buttonIdleColor = 225, 199, 141
buttonHoverColor = 224, 164, 88
buttonPressedColor = 45, 48, 71
buttonWidth, buttonHeight = 200, 60
buttonX = WIDTH / 2 - buttonWidth / 2
buttonY = HEIGHT / 2 
buttonRect = pygame.Rect(buttonX, buttonY, buttonWidth, buttonHeight)

buttonColor = buttonIdleColor
textContent = 'KODLARDAN1BLOG'
calisiyor = True
while  calisiyor:
 for e in pygame.event.get():
  if e.type == pygame.QUIT: 
   calisiyor = False

 mouseX, mouseY = pygame.mouse.get_pos()
 click = pygame.mouse.get_pressed()
 if buttonX + buttonWidth > mouseX > buttonX and buttonY + buttonHeight > mouseY > buttonY:
  buttonColor = buttonHoverColor
  buttonTextColor = BLACK
  if click[0] == 1:
   buttonColor = buttonPressedColor
   buttonTextColor = WHITE
   textContent = 'KODLARDAN1BLOG.com'
 else:
  buttonColor = buttonIdleColor
  buttonTextColor = BLACK

 pencere.fill(BGCOLOR)
 
 text = font.render(textContent, True, WHITE)
 textRect = text.get_rect()
 textRect.center = (WIDTH / 2, HEIGHT / 2 - 60)
 pencere.blit(text, textRect)
 
 pygame.draw.rect(pencere, buttonColor, buttonRect)

 buttonText = font.render('I LOVE', True, buttonTextColor)
 buttonTextRect = buttonText.get_rect()
 buttonTextRect.center = buttonRect.center
 pencere.blit(buttonText, buttonTextRect)
 
 pygame.display.flip()

24 Ocak 2020 Cuma

Unity: 2D Karakter Animasyonunu Oluşturmak, Create 2D Animation in Unity


Proje Oluşturma

Unity3D'de, 2D projemizi oluşturuyoruz.

Başlangıç

Bir sprite animation oluşturmak için elimizde birkaç tane sprite dosyası olmalı. Bunlardan birisini şu siteden bulabilirsiniz. Ben bu sprite paketini indireceğim ve bunun üzerinden çalışacağız. Linke tıklayın ve Download butonuna basarak 'Skeleton Sprite Pack.rar' arşivini indirin. İçindeki Skeleton klasörünü 'Animasyon' projemizin Assets klasörünün içine çıkartın. 

Bunu yaptıktan sonra Unity'de ufak bir 'Importing Small Assets' penceresi çıkabilir.

Sprite Mode -> Multiple

Unity'de Project sekmesinde Assets klasörümüzün içerisinde Skeleton klasörümüz görünüyor olmalı. Skeleton klasörünün de içerisinde Sprite Sheets klasörü bulunuyor. Orada karşımıza 6 tane resim dosyası bulunuyor. Bunlardan 'Skeleton Idle.png' dosyasına tıklayalım ve Inspector panelinde Texture Type'ı "Sprite (2D and UI)", Sprite Mode'u ise "Multiple" olarak seçelim. Bu iki seçimi yaptıktan sonra panelin alt kısmında Apply butonuna basalım. Daha sonra ise Sprite Editor butonuyla dosyamızı kendi keyfimize göre düzenleyelim.

Sprite Editor

Sprite Editor butonuna tıkladıktan sonra açılan pencerenin üst kısmındaki Slice butonuna tıklayın ve açılan minik pencere;
Type = Automatic
Pivot = Center
Method = Delete Existing
durumunduyken Slice butonuna tıklayın ve ardından sağ üst köşedeki Apply butonuna tıklayıp Sprite Editor penceresini kapatın.

Karakterimizi Oluşturmak

Hierarchy penceresindeki Create butonuna tıklayın. Açılan menüde imleci 2D Object yazısının üstüne getirin ve Sprite'a tıklayın. Daha sonra Inspector panelinde Sprite Renderer bölümündeki None (Sprite)'a tıklayın ve açılan Select Sprite penceresindeki arama kutusuna 'idle 0' yazın ve Skeleton Idle_0'ı seçin. Böylece varsayılan sprite'ı seçtik.

Yeni Animasyon Oluşturmak

Animasyon oluşturmak için Unity'nin Animation penceresini kullanmamız gerekiyor. Bu pencere açık değilse Ctrl ve 6 tuşlarına basın. Daha sonra karakterimizin üstüne tıkladığınızda Animation penceresinin sağ kısmında Create butonu gözükecektir. Bu butona tıklayın. Açılan diyalog penceresinde animasyonun ismini ve nereye kaydedileceğini seçebileceğiz. Ben ismini 'idleAnim' koydum. Şimdi Animation penceresinin sol kısmında Add Property butonuna tıklayın ve açılan menüde Sprite Renderer'ın altındaki Sprite'a tıklayın. Şimdi şöyle görünecek:
Daha sonra Animation penceresinin sol kısmında 1.00'ın altında olan dörtgeni silin. 
Daha sonra Animation penceresinde kırmızı kaydet butonuna tıklayın, Sprite Editor ile düzenlediğimiz Skeleton Idle_0.png dosyasının içindeki 11 dosyanın tamamını seçin, sürükleyin ve Animation penceresinin sol kısmına bırakın. Samples 60 yazan yeri 10 veya 20 olarak değiştirin. Bu yaklaşık 11 sprite'ın ne kadar hızlı veya yavaş gösterileceğini ayarlayacaktır. Samples anahtarını 10'a ayarladığımızda bir saniyede 10 sprite gösterilecektir. En sonunda kırmızı kaydet butonuna tıklayın ve animasyonumuz kaydolmuş olacaktır. Animation penceresini kapatabiliriz. Oyunumuzu başlattığımızda animasyonumuzun çalıştığını görebiliriz.