Skip navigation

Category Archives: Easy


I imported a CSV in pandas like below

>>> import pandas
>>> df = pandas.read_csv('file.csv',names=['count', 'province', 'city', 'district', 'region', 'area'])
>>> df.head()
   count province         city           district region area
0   7923     Aceh   Aceh Barat   Arongan Lambalek            
1    628     Aceh   Aceh Barat     Johan Pahlawan            
2    235     Aceh   Aceh Barat        Woyla Timur            
4   3900     Aceh   Banda Aceh                         

using SQL, I can do something like this

    SELECT SUM(count) AS sum, district 
        FROM table WHERE city = 'Aceh Barat' 
        GROUP BY district 
        ORDER BY sum DESC

but using pandas python library, I can achieve the same using.

>>> import pandas, numpy
>>> df = pandas.read_csv('file.csv',names=['count', 'province', 'city', 'district', 'region', 'area'])
>>> df[df['city'] == 'Aceh Barat'].groupby('district').aggregate(numpy.sum).sort(['count'], ascending=False)
                  count
district               
Arongan Lambalek   7923
Johan Pahlawan      628
Woyla Timur         235

>>> df[df['city'] == 'Aceh Barat'].groupby('district').aggregate(numpy.sum).sort(['count'], ascending=False)
                  count
district               
Arongan Lambalek   7923
Johan Pahlawan      628
Woyla Timur         235

>>> df[df['city'] == 'Medan']
        count        province   city            district region area
10340  108769  Sumatera Utara  Medan                 NaN    NaN  NaN
10341     759  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10342     579  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10343    1272  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10344     769  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10345     379  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10346     988  Sumatera Utara  Medan        Medan Amplas    NaN  NaN
10347    4395  Sumatera Utara  Medan          Medan Area    NaN  NaN
10348    5598  Sumatera Utara  Medan         Medan Barat    NaN  NaN

>>> df[df['city'] == 'Medan'].groupby('district').aggregate(numpy.sum).sort(['count'], ascending=False)
                    count
district                 
Medan Tuntungan      7425
Medan Tembung        6349
Medan Barat          5598
Medan Timur          5378
Medan Amplas         4746
Iklan

Kemarin saya sedang iseng membuka-buka StackOverflow dan menemukan pertanyaan ini Displaying CSV file content in Yii Framework’s CGridView.

Inti pertanyaannya adalah bagaimana menampilkan isi file CSV menggunakan GridView.

Cara mudahnya adalah dengan menggunakan CArrayDataProvider.

$file = fopen('test.csv', 'r');
$data = array();
while (($line = fgetcsv($file)) !== FALSE) {
    //$line is an array of the csv elements
    $data[] = $line;
}
fclose($file);
$columns = array();
foreach ($data[0] as $key => $value) {
    $columns[] = array(
        'name' => $key,
        'header' => $value,
    );
}
$data = array_slice($data, 1);
$dataProvider = new CArrayDataProvider($data, array(
    'keyField' => 0,
));
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'columns' => $columns
));

Jika ingin menggunakan secara generik, kita bisa membuat kelas baru bernama CsvDataProvider.

class CsvDataProvider extends CArrayDataProvider {

    private $_columns = array();

    public function __construct($file, $config = array()) {
        $handler = fopen($file, 'r');
        $data = array();
        while (($line = fgetcsv($handler)) !== FALSE) {
            $data[] = $line;
        }
        fclose($handler);
        $this->_columns = array();
        foreach ($data[0] as $key => $value) {
            $this->_columns[] = array(
                'name' => $key,
                'header' => $value,
            );
        }
        $data = array_slice($data, 1);
        parent::__construct($data, array_merge($config, array(
            'keyField' => 0,
        )));
    }

    public function getColumns() {
        return $this->_columns;
    }
}

cara menggunakannya mudah

$dataProvider = new CsvDataProvider('file.csv');
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'columns' => $dataProvider->getColumns(),
));

Tapi kode di atas belum bisa memfasilitasi sorting dan pagination. Kerugiannya juga adalah kinerja yang buruk jika digunakan pada berkas CSV berukuran sangat besar. Dan ada ide menarik untuk menggunakan library pemrosesan CSV yang hemat memori dan dengan fungsi lengkap. Nanti mungkin kalau sempat saya tuliskan penuhnya.


I was just looking a good way to mount /tmp directory on AWS EC2 ephemeral storage automatically. Then I stumbled on this post. Nice method if you are using Ubuntu (or other distribution that uses Upstart).

# File /etc/init/mounted-mnt.conf

# mounted-mnt - Binds /tmp to /mnt/tmp

description     "Binds /tmp to /mnt/tmp"

start on mounted MOUNTPOINT=/mnt

task

script
    test -d /mnt/tmp || mkdir -m 1777 /mnt/tmp
    mount --bind /mnt/tmp /tmp
end script

And the good idea behind this, as told in the post, is

Some servers, like Apache/Passenger, might create important temporary files on /tmp. Once rc.local – the last in the boot sequence – ran they would get hidden and confuse the servers.


Di grup Olimpiade Informatika, salah satu pertanyaan yang sering muncul oleh siswa yang baru mulai belajar C++ adalah

Apa itu `using namespace std`

Sebelum menjawab ini, mungkin perlu dijelaskan sedikit tentang konsep namespace di C++. Pada pelatihan pemrograman untuk Olimpiade Informatika, hal ini memang tidak terlalu dibutuhkan, jadi dalam banyak sesi pelatihan penggunaan statement using namespace std; sering dianggap hafalan. Untuk itu saya coba sedikit jelaskan tentang namespace.

Deklarasi sebuah fungsi sederhana di C++ adalah sebagai berikut

int function(){
    return 1;
}

int main(){
    function();
}

Kadang-kadang untuk beberapa fungsi yang penggunaannya mirip, kita suka menggunaan nama yang sama. Dan untuk membedakan antara fungsi-fungsi tersebut kita menambahkan nama tertentu (umumnya) di depan fungsi.

int ns1_function(){
    return 1;
}

int ns2_function(){
    return 2;
}

int main(){
    ns1_function();
    ns2_function();
}

Untuk jumlah fungsi yang tidak banyak, penambahan nama seperti ns1_ dan ns2_ tidak terlalu masalah. Akan tetapi untuk program yang kodenya berukuran sangat besar dan memiliki fungsi yang sangat banyak, pengaturan demikian akan menyebabkan maintenance menjadi lebih sulit. Oleh karena itu untuk memudahkan, C++ memiliki fitur yang disebut namespace

namespace ns1 {
    int function(){
        return 1;
    }
}

namespace ns2 {
    int function(){
        return 2;
    }
}

int main(){
    ns1::function();
    ns2::function();
}

Kodenya sekarang jadi terlihat sedikit lebih rapi.

Dan kadang-kadang dalam sebuah kode mungkin kita hanya membutuhkan sebuah namespace saja. Dari situ lah datangnya statement using namespace. Ini akan membuat semua elemen di dalam sebuah namespace dapat langsung diakses tanpa perlu menspesifikasikan namespace elemen tersebut.

namespace ns1 {
    int function1(){
        return 1;
    }
    int function2(){
        return 2;
    }
    int function3(){
        return 3;
    }
    int function4(){
        return 4;
    }
}

using namespace ns1;

int main(){
    function1();
}

Karena di atas kita hanya membutuhkan namespace ns1 saja, dan menuliskan ns1:: berulang-ulang akan sangat merepotkan, maka kita bisa tinggal menggunakan statement using namespace ns1. Saat memanggil fungsi function1 kita tidak perlu lagi menambahkan ns1:: di depannya.

Lalu, untuk memberikan hasil ke sistem grading, biasanya kita membutuhkan perintah untuk menampilkan hasil ke layar/terminal atau lebih tepatnya disebut stdout. Di C++ untuk melakukan hal ini kita membutuhkan perintah cout. Sebenarnya perintah ini berada pada namespace yang bernama std.

Penggunaan sebenarnya adalah sebagai berikut

#include <iostream>

int main(){
    std::cout << "Hello World!";
}

Di depan cout sebenarnya masih perlu dituliskan std::. Dan akan sangat merepotkan jika kita membutuhkannya berulang kali

#include <iostream>

int main(){
    std::cout << "Hello World1" << std::endl;
    std::cout << "Hello World2" << std::endl;
    std::cout << "Hello World3" << std::endl;
    std::cout << "Hello World4" << std::endl;
    std::cout << "Hello World5" << std::endl;
    std::cout << "Hello World6" << std::endl;
}

Kita bisa mengurangi jumlah penulisan std:: dengan menggunakan statement using namespace std; yang membuat semua elemen di dalam namespace std (seperti cout dan endl) dapat langsung diakses.

#include <iostream>

using namespace std;

int main(){
    cout << "Hello World1" << endl;
    cout << "Hello World2" << endl;
    cout << "Hello World3" << endl;
    cout << "Hello World4" << endl;
    cout << "Hello World5" << endl;
    cout << "Hello World6" << endl;
}

Jika nanti sudah berkutat di kode-kode yang berukuran besar dan kompleks, maka akan terasa penggunaan namespace ini.


Pada postingan kali ini saya akan menuliskan bagaimana menggunakan AWS SDK for PHP version 2 pada Yii. Sebelum menggunakan yang versi 2, saya sudah menggunakan versi 1 dan versi kedua ini lebih mudah digunakan karena dia sudah mendukung pengaturan kode PHP yang sudah terstruktur sesuai dengan rekomendasi standar yang sedang tren yakni PSR. Oleh karena itu penggunaan SDK v2 ini dapat dilakukan dengan menggunakan Composer.

Cara instalasi program Composer untuk melakukan instalasi library AWS SDK, dapat dilihat di sini.

Seperti instalasi paket library ala Composer, pertama-tama kita membuat spesifikasi paket pada berkas “composer.json”. Untuk menambahkan AWS SDK, isi “composer.json” adalah sebagai berikut.

{
  "config": {
    "vendor-dir": "protected/composer/vendors"
  },
  "require": {
    "aws/aws-sdk-php": "2.3.*@dev"
  }
}

Sebenarnya konfigurasi Composer untuk instalasi SDK sudah cukup pada baris 5 sampai 7, tetapi saya pribadi lebih suka menambahkan konfigurasi untuk menyimpan library dari Composer pada direktori “protected/composer/vendors” agar tidak mengotori direktori lain seperti “protected/extensions” dan “protected/vendors“.

Setelah menambahkan konfigurasi tersebut, kita harus menjalankan perintah instalasinya.

petra@pc$composer install
Loading composer repositories with package information
Installing dependencies
  - Installing symfony/event-dispatcher (v2.2.1)
    Loading from cache

  - Installing guzzle/guzzle (v3.5.0)
    Loading from cache

  - Installing aws/aws-sdk-php (dev-master a299b46)
    Cloning a299b46693878b5a7ffaa30e236fbefe9113b6e0

symfony/event-dispatcher suggests installing symfony/dependency-injection (2.2.*)
symfony/event-dispatcher suggests installing symfony/http-kernel (2.2.*)
aws/aws-sdk-php suggests installing ext-apc (Allows service description opcode caching, request and response caching, and credentials caching)
aws/aws-sdk-php suggests installing doctrine/cache (Adds support for caching of credentials and responses)
aws/aws-sdk-php suggests installing monolog/monolog (Adds support for logging HTTP requests and responses)
aws/aws-sdk-php suggests installing symfony/yaml (Eases the ability to write manifests for creating jobs in AWS Import/Export)
Writing lock file
Generating autoload files

Sebelum bisa menggunakan composer, kita harus melakukan include untuk autoloading Composer.

require_once(dirname(__FILE__).'/protected/composer/vendors/autoload.php');
// change the following paths if necessary
$yii=dirname(__FILE__).'/yii/framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';

// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

require_once($yii);
Yii::createWebApplication($config)->run();

Lalu kode di bagian controllernya seperti demikian

class SiteController extends Controller
{

    public function actionIndex()
    {
        if (Yii::app()->request->getIsPostRequest()) {
            $file = CUploadedFile::getInstanceByName('file');
            /* @var $file CUploadedFile */
            if (isset($file)) {
                $s3 = \Aws\S3\S3Client::factory(array(
                        'key' => 'YourAWSKEY',
                        'secret' => 'YourAWSSecret',
                        'region' => \Aws\Common\Enum\Region::SINGAPORE,
                    ));
                /* @var $s3 Aws\S3\S3Client */
                try {
                    $result = $s3->putObject(array(
                        'Bucket' => 'bucketname',
                        'Key' => $file->name,
                        'SourceFile' => $file->tempName,
                        ));
                    /* @var $result \Guzzle\Service\Resource\Model */
                    $url = $result->get("ObjectURL");
                    Yii::app()->user->setFlash('Success', "Upload Success: " . CHtml::link($url, $url));
                } catch (\Aws\S3\Exception\S3Exception $exc) {
                    /* @var $exc \Aws\S3\Exception\S3Exception */
                    $message = $exc->getMessage();
                    Yii::app()->user->setFlash('Failed', "Upload Failed: {$message}");
                }
            }
        }
        $this->render('index');
    }

}

Bagian controller akan menangani request dari upload form kemudian melakukan pengunggahan ke S3. Untuk pengunggahan kita memerlukan kelas S3Client dari AWS SDK. Pada instansiasinya kita perlu mengeset key dan secret dari akun AWS yang dimiliki, serta region tempat penyimpanan.

Lalu proses pengunggahan sendiri akan dilakukan dengan menginvokasi method putObjectObyek yang dikembalikan oleh method ini hanya berupa model yang berisi return value dari invokasi HTTP request yang dilakukan oleh Guzzle. Untuk mengambil URL dari file yang telah diunggah, kita ambil saja atribut ObjectURL pada model tersebut.

Bagian viewnya sangat sederhana.

<h1>Upload file</h1>

<?php if (Yii::app()->user->hasFlash('Success')): ?>
    <div class="flash-success">
        <?php echo Yii::app()->user->getFlash('Success'); ?>
    </div>
<?php endif; ?>
<?php if (Yii::app()->user->hasFlash('Failed')): ?>
    <div class="flash-error">
        <?php echo Yii::app()->user->getFlash('Success'); ?>
    </div>
<?php endif; ?>

<?php echo CHtml::beginForm('', 'post', array('enctype' => 'multipart/form-data')); ?>
<?php echo CHtml::fileField('file'); ?>
<?php echo CHtml::submitButton(); ?>
<?php echo CHtml::endForm(); ?>

Nanti hasilnya akan seperti demikian.

Tampilan Sebelum Pengunggahan

Tampilan Sebelum Pengunggahan

Setelah melakukan pengunggahan, dia akan menampilkan URL yang telah disimpan oleh setFlash.

Tampilan Setelah Pengunggahan

Tampilan Setelah Pengunggahan

Dan di AWS S3 console, sudah bisa dilihat di dalam bucketnya kalau filenya sudah diunggah.

Isi Bucket Setelah Pengunggahan

Isi Bucket Setelah Pengunggahan

AWS SDK for PHP version 2 ini jauh lebih enak digunakan daripada versi sebelumnya karena sudah memenuhi standar PSR sehingga bisa digunakan dengan Composer serta dengan mudah diintegrasikan pada aplikasi Yii. Selain S3, SDK ini juga menyediakan banyak library untuk layanan AWS lainnya seperti EC2, DynamoDB, dll.

Kodenya dapat dilihat di link ini.

Failed

Belakangan ini saya harus mengolah beberapa data yang jumlahnya cukup besar, tidak terlalu besar tetapi juga tidak cukup kecil untuk dijalankan di laptop sendiri. Cara yang saya gunakan adalah MapReduce menggunakan Apache Hadoop. Berhubung data yang besar itu sudah terlanjur saya simpan di Amazon S3 maka secara intuitif pengolahan datanya baiknya dilakukan menggunakan Amazon Elastic MapReduce (yang merupakan salah satu alasan saya belajar kilat menggunakan Hadoop).

Dan menjalankan skrip MapReduce di AWS EMR ini sebenarnya tidak terlalu sulit. Kalau sudah bisa berhasil menjalankan contoh aplikasi WordCount bawaannya Hadoop, menjalankannya di EMR hanya sekedar melakukan konfigurasi saja. Tutorial instalasi Hadoop untuk local machine dan cara menjalankan program contoh WordCount dapat dilihat di halaman ini.

Read More »


Setelah di postingan sebelumnya menjelaskan tentang cara penggunaan CJuiAutoComplete secara sederhana, postingan ini akan mencoba menyambungkan autocomplete tersebut dengan database.

Read More »


Untuk memenuhi permintaan dari Jupri yang atas permintaan di bagian Request yang meminta tutorial bagaimana cara membuatautocomplete”seperti facebook”.

Autocomplete textfield adalah sebuah textfield yang ketika diberikan input sebuah string maka textfield itu akan menampilkan beberapa hasil rekomendasi. Contoh yang sering terlihat adalah autocomplete di Facebook search ataupunsearch suggestiondi Google Search.

Contoh penggunaan autocomplete untuk Facebook search.

Di Yii sendiri sudah ada komponen bawaan yang mendukung pembuatan fitur autocomplete seperti ini. Komponen ini adalah CJuiAutoComplete (sebelumnya sudah ada CAutoComplete yang kemudian dihentikan pengembangannya). Komponen CJuiAutoComplete tidak lain merupakan pembungkus dari widget jQuery UI – Autocomplete. Kematangan widget ini membuat pengembang Yii menghentikan komponen CAutoComplete dan beralih menggunakan jQuery UI.

Read More »


Kemaren, seperti beberapa tahun sebelumnya, saya kembali mengisi sesi pengantar Linux untuk Pelatihan Nasional bagi Tim Olimpiade Komputer Indonesia yang akan mengikuti International Olympiads of Informatics tahun 2012 di Milan.

Pengantar Linux ini memiliki tujuan agar siswa bisa terbiasa untuk memrograman dalam lingkungan sistem operasi Linux. Ini tidak lain karena di IOI nanti lingkungan pemrograman yang disediakan adalah Linux. Dalam pengantar ini, selain memperkenalkan tentang Linux serta program-program apa saja yang ada di sana (Nautilus, GCC, GEdit, Geany, dsb), saya juga memperkenalkan bagaimana menggunakan terminal untuk membantu dalam pemrograman.

Materinya dapat dilihat di bawah. Semoga bermanfaat.

NB: Materi ini merupakan versi terbaru dari yang sudah saya tulis tahun lalu. Ada beberapa tambahan seperti time dan batch processing.


Di dalam menangani aksi login dan logout untuk pengguna suatu aplikasi, Yii telah dilengkapi dengan komponen CWebUser. Komponen ini diinisiasi dan dikonfigurasi pada berkas “/protected/config/main.php”

'components' => array(
        'user' => array(
            'class' => 'CWebUser',
            // enable cookie-based authentication
            'allowAutoLogin' => true,
            'loginUrl' => array('/login'),
        ),

properti loginUrl menentukan URL mana yang akan dituju aplikasi ketika pengguna gagal terautentikasi. Untuk kasus ini URLnya adalah “/login”. Yang menjadi permasalahan di sini adalah kadang-kadang saya membutuhkan tampilan login yang berbeda, misalnya untuk user biasa dan administrator.

Sebagai contoh, ketika user yang belum terautentikasi mengakses URL “/account” maka tampilan loginnya akan berupa

dan ketika user yang belum terautentikasi mengakses URL “/admin” maka tampilan loginnya diharapkan sedikit lebih keren seperti berikut

Read More »

%d blogger menyukai ini: