Langsung ke konten utama

Service Tagging di Symfony

 Ketika kita bekerja dengan Service di Symfony, aplikasi kita akan mempunyai banyak Service / Object yang saling berkaitan. Kadang kita ingin mengelompokkan beberapa Service dengan behaviour / kegunaan tertentu menjadi satu kelompok. Untuk mengelompokkan Service, kita bisa menggunakan Tags. Ada banyak tags bawaan dari symfony yang bisa anda baca langsung di https://symfony.com/doc/current/reference/dic_tags.html

Membuat Tags

Anggap saya akan membuat perbandingan jarak antar titik. Saya akan menggunakan 2 metode yang berbeda, yaitu menggunakan rumus haversine (lihat di sini) dan satu lagi menggunakan crawling ke google map. Untuk itu saya membuat 2 buah Class yang masing-masing digunakan untuk membuat formula perhitungan jarak yang akan implements ke Interface DistanceCalculatorInterface seperti potongan kode berikut:
<?php // src/DistanceCalculator/DistanceCalculatorInterface.php

namespace App\DistanceCalculator;

/**
 *
 * @author programmer
 */
interface DistanceCalculatorInterface 
{
    public function getDistance(string $latLongA, string $latLongB):float;
}
kemudian berikut potongan kode untuk masing-masing Class perhitungan
<?php // src/DistanceCalculator/HaversineCalculator.php

namespace App\DistanceCalculator;

/**
 * Description of HaversineCalculator
 *
 * @author programmer
 */
class HaversineCalculator implements DistanceCalculatorInterface 
{
    /**
     * 
     * @var float
     */
    private $pi;
    
    /**
     * 
     * @var float
     */
    const EARTH_RADIUS = 6371;
    
    public function __construct() 
    {
        $this->pi = pi();
    }
    
    public function getDistance(string $latLongA, string $latLongB): float 
    {
        $latLongA = $this->split($latLongA);
        $latLongB = $this->split($latLongB);
        
        $radianLatA = $this->getRadians(
            $latLongA[0]
        );
        $radianLatB = $this->getRadians(
            $latLongB[0]
        );
        $radianLat = $this->getRadians(
            $latLongB[0] - $latLongA[0]
        );
        $radianLong = $this->getRadians(
            $latLongB[1] - $latLongA[1]
        );
        
        $a = (sin($radianLat/2) * sin($radianLat/2)) 
                + (cos($radianLatA) * cos($radianLatB)) 
                * (sin($radianLong/2) * sin($radianLong/2));
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        
        return round(self::EARTH_RADIUS * $c, 2);
    }
    
    protected function split(string $latLong):array
    {
        return array_map(function (string $point) {
            return (float) $point;
        }, explode(",", $latLong));
    }
    
    protected function getRadians(float $x):float
    {
        return $x * ($this->pi / 180);
    }

}
kemudian perhitungan dari google map
<?php // src/DistanceCalculator/GMapDistanceCalculator.php


namespace App\DistanceCalculator;

/**
 * Description of GMapDistanceCalculator
 *
 * @author programmer
 */
class GMapDistanceCalculator implements DistanceCalculatorInterface 
{
    public function getDistance(string $latLongA, string $latLongB): float 
    {
        // contoh script untuk scraping ke google map
        
        return 8;
    }

}

kemudian saya buat Class DistanceCalculatorCollection yang akan dipakai untuk memuat semua Service yang implement dari  DistanceCalculatorInterface tersebut:
<?php // src/DistanceCalculator/DistanceCalculatorCollection.php

namespace App\DistanceCalculator;

/**
 * Description of DistanceCalculatorCollection
 *
 * @author programmer
 */
class DistanceCalculatorCollection 
{
    
    private iterable $calculators;
    
    public function __construct(iterable $calculators) 
    {
        $this->calculators = $calculators;
    }
    
    public function getCalculators():array
    {
        return iterator_to_array($this->calculators);
    }
}
kemudian Class Collectionnya saya panggil dari Controller:
<?php // src/Controller/DistanceController.php


namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use App\DistanceCalculator\DistanceCalculatorCollection;

/**
 * Description of DistanceController
 * @Route("/distance", name="distance_")
 * @author programmer
 */
class DistanceController 
{
    
    /**
     * @Route("/", name="index")
     */
    public function index(DistanceCalculatorCollection $collection)
    {
        dump($collection->getCalculators());
        exit;
    }
}
sekarang saya sudah punya 2 Class untuk menghitung dengan 2 rumus yang berbeda beserta 1 Class untuk menampung Object dari kedua Class tersebut

Mendaftarkan Service Tags

Untuk mendaftarkan kedua Class yang digunakan untuk menghitung tersebut, tambahkan di file konfigurasi services.yaml yang berada di folder config/services.yaml.  Kemudian tambahkan seperti kode berikut:
services:
    # .....
    App\DistanceCalculator\HaversineCalculator:
        tags:
            - { name: distance.calculator }
            
    App\DistanceCalculator\GMapDistanceCalculator:
        tags:
            - { name: distance.calculator }
kode di atas berarti kita mendaftarkan 2 Service dengan nama tag distance.calculator. Kemudian daftarkan juga Class Collection yang berguna untuk tempat berkumpulnya Service tersebut.
services:
    # ...
    App\DistanceCalculator\DistanceCalculatorCollection:
        arguments:
            $calculators: !tagged distance.calculator
kemudian paggil controller melalui browser maka akan muncul sepeti berikut:


kemudian jika digunakan untuk menghitung seperti potongan kode berikut:
<?php // src/Controller/DistanceController.php


namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use App\DistanceCalculator\DistanceCalculatorCollection;

/**
 * Description of DistanceController
 * @Route("/distance", name="distance_")
 * @author programmer
 */
class DistanceController 
{
    
    /**
     * @Route("/", name="index")
     */
    public function index(DistanceCalculatorCollection $collection)
    {
        $from = '-7.325447718127029, 112.75154637208772';
        $to = '-7.365628717636805, 112.75223597318133';
        foreach ($collection->getCalculators() as $calc) {
            $result = $calc->getDistance($from, $to);
            dump($result);
        }
        exit;
    }
}
akan keluar hasil seperti berikut:


Mendaftarkan Berdasarkan Interface

Untuk otomatis semua Class yang merupakan turunan dari interface  DistanceCalculatorInterface dengan tag distance.calculator bisa menggunakan keyword _instanceof di file services.yaml:
services:
    # ...

    _instanceof:
        App\DistanceCalculator\DistanceCalculatorInterface:
            tags:
                - { name: distance.calculator }

Komentar

Postingan populer dari blog ini

Contoh Perhitungan Algoritma Perceptron

      Melanjutkan tulisan saya sebelumnya tentang algoritma perceptron,kali ini saya akan menulis tentang conto perhitungan manual algoritma perceptron. Untuk contoh kasusnya saya menggunakan data logika AND. Cekidot.... Algoritma      Data yang kita gunakan sebagai contoh adalah data logika AND sebagai berikut: x1 x2 target 0 0 0 0 1 0 1 0 0 1 1 1       tentukan bobot awal secara acak, saya pakai contoh w1 = 0,w2 =0, learning rate = 1, bias = 0,maksimal epoh = 10. Disini saya memakai fungsi aktivasi undak biner. Epoh ke 1 Data ke satu x = {0,0}, bobot w = {0,0},b=0,target = 0 y_in = (x1*w1)+(x2*w2)+b = (0*0)+(0*0)+0 = 0 y = sign(0) = 1 karena y != target maka hitung error dan update bobot  error = target - y = 0 - 1 = -1 w1_baru = w1_lama +(learning_rate*error*x1)                = 0 ...

Contoh Perhitungan Algoritma Learning Vector Quantization

Melanjutkan tulisan saya tentang algoritma Learning Vector Quantization yang lalu, kali ini saya akan melanjutkan dengan contoh perhitungan manual. Berikut ini contoh data yang akan kita hitung. No X1 X2 X3 X4 target 1 0 1 1 0 0 2 0 0 1 1 1 3 1 1 1 1 0 4 1 0 0 1 1 pada contoh di atas, saya menggunakan 4 data sebagai data training beserta target yang bertujuan untuk mendapatkan bobot yang akan digunakan pada proses klasifikasi. Bobot awal adalah { 1, 1, 1, 0} dan { 1, 0, 1, 1} dengan learning rate 0,05 dengan fungsi pembelajaran = 0,1. Pelatihan Iterasi ke 1 1. Data ke 1 { 0, 1, 1, 0} dengan target 0, bobot = {{ 1, 1, 1, 0},{ 1, 0, 1, 1}}      - menghitung bobot untuk masing masing output :          kelas 0 = sqrt(((0-1)^2)+((1-1)^2)+((1-1)^2)+((0-...

Part 7 : Normalisasi Histogram

Menyambung tulisan saya yang sebelumnya tentang pengolahan citra khususnya histogram,kali ini saya lanjutkan tentang Normalisasi histogram.Sebelumnya saya harap agan sudah mengerti tentang histogram.Jika belum bisa di baca dulu di tulisan saya sebelumnya di sini . Normalisasi Histogram adalah menskalakan nilai piksel secara linear untuk menggunakan secara penuh jangkauan yang tersedia. Rumus :  Keterangan : n k= nilai grayscale dari piksel ke k(k = 0,1,2,3....) min = nilai grayscale terkecil yang diperoleh dari histogram max = nilai grayscale terbesar L = range nilai grayscale citra Contoh perhitungan : dari tabel di atas,nilai min adalah 2 yaitu nilai grayscale terkecil dari citra dan max adalah 5 s = 0 - 2 /5 - 2 =0 (untuk n = 0)  hasil = 0 x 7(nilai maksimal grayscale) = 0 sk = 3 - 2 /5 - 2 = 0.333  (untuk n = 3) hasil = 0.333 x 7 = 2 keterangan : 7 adalah range grayscale dari citra,dan untuk banyak kasus biasanya memakai 255. Tujuan Normalisasi...