Clean Code, or why you should regret not being a clean freak when coding as a team, and what I learned.

Image result for clean freak

What separates two people most profoundly is a different sense and degree of cleanliness. – Friedrich Nietzsche

What is clean code?

You did it. You just wrote some code for an app that you built with your colleagues. You thought to yourself: “I understood what this code does, got the code to function right and tested it so that you can be sure it works perfectly”. Then, a few days later, your friend wants to integrate his code to yours. Your friend opens the file that contains your code and does not understand anything that you wrote, and because of that he called you on a Sunday morning to talk about the code that you wrote over the past working week.

Seeing that it’s from a colleague, you HAD to take the call, even though you just woke up. “But it works!”, you assured your friend. Your friend does not care. He wants to integrate the code quickly so that he can enjoy the rest of his Sunday after not sleeping for two days trying to code the feature that he wants to implement. So on a Sunday, you have to meet your friend and explain each and every line of code that you wrote. If the code that you wrote is tiny, maybe it won’t take long for your friend to understand it. But what if the code is huge in size?

This is usually the point where you regret not being a clean freak when it comes to coding. You only care about implementing a feature that works, and not more than that. You pay no care to your team, even though without them you won’t be able to finish the app and because of that, you need to do extra work that you don’t really have to do if you had wrote cleanly.

Now I’m going to tell you a different story, this time from my own experience. When I finished coding on a certain date late in the week and I expect my friend Aloy to have to read it to implement additional features, I never get contacted (unlike the previous example). Since this worries me, I asked my friend Aloy the next week why he did not contact me and whether or not he understood my code. He said to me that he understood the code perfectly and was quite shocked to see that it is really easy to understand (even though his additional implementation dirties the code somewhat) therefore not needing to contact me to ask about what the code does.

You want your teammates to completely understand the code that you just made, without you having to do extra work. That is (at least, in my case) why you need to write code that is clean.

Clean code meets all of these criteria:

  1. Focused
    • Functions must only do a certain thing and not more than that and there must only be only one abstraction per function (either low such as getDownloadLink(); , mid such as var x = y.function(z) or low abstraction such as .append(x) ). Functions must never have a side effect to it in the sense that it does something else in addition to it’s intended function.
    • Functions must have the fewest parameters that it can possibly have. If able, format the parameters into objects. Keep in mind that the more parameter a function has, the harder it is to understand it. “The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). ” (From the book Clean Code: A Handbook of Agile Software Craftsmanship)
    • Classes must be tiny and only has one reason to change, as per the Single Responsibility Principle. It must have high cohesion and low coupling.
    • Whenever switch statements are absolutely needed to be used, make sure to bury it in an object such as an abstract factory and do not repeat it.
  2. Tested
    • It has to have a test that, if passed, makes developers confident that the code works as intended.
  3. Contains no duplication
    • Remember the principle “Don’t Repeat Yourself”? You wouldn’t want to be writing code that you have written before just because it’s poorly designed, would you? That’s just tedious, even for me. I prefer splitting the code up to a separate function and have my other code execute that function. You may not be used to it at first, but after a while it becomes second nature (trust me, I experienced it myself).
  4. Carefully written
    • It follows standards and is formatted beautifully. The standards vary depending on the language and/or that you choose, but typically your language or framework has a standard in its documentation that if you follow, will yield you code that is able to be more easily understood.
    • Names should be Searchable, Pronounceable, Descriptive and Intention Revealing.
  5. Meaningful Comments
    • The code itself should be written as if it explains to the reader what it does. Comments do not make up for bad code.
    • Good comments however, such as legal comments, TODO comments, warning of consequences, clarification to things that are unalterable, explanations of intent, are needed.

Example Code

I have an example of a code from the app that I am working on, SusunJadwal that meets all of the criteria above. Take a look below at the code for one of the front-end components that it has.

Untitled.png

Look at how simple it is! From this code alone you can know that it is a component that has another component, SplashWrapperComponent inside of it, wrapped around a nice div with an id of bg. You may infer that it is named WelcomeComponent since it appears first on the welcome portion of the app, and you will be correct. That component is then exported so that it may be imported somewhere else.

A front-end developer may notice that it imports a CSS file, and may look at it. What he found was code that was truly pleasing to see.

2.png

Another tiny code! From this, the developer now knows that the div actually is a container for a background image, has a certain width and height and has a hidden overflow.

Now after seeing that code, you may want to know whether or not it works. You now look for a snippet of a test code that tests this component. You open the test code, opened the find tool and search using the name of the component as the only keyword for the search. After that, you notice this code being highlighted as one of the results.

3.png

All the needed test cases for the WelcomeComponent, described and written in few lines each, and since it is a component that does nothing else other than it being displayed nicely on screen, it only needs to be defined and rendered correctly. You notice the names of the test cases, and you smile knowing that both of those criteria are fulfilled if the test results yield green, and it does.

That’s it! The code review process for that component is done. How many minutes did that take to review? It probably did not take more than five minutes. If the code that is written is clean, you can just take a quick look at it, and easily understand what it does and be sure that it works correctly.

Here is a slightly more complicated code. This is a component with some functions. You can see that I have divided the functions into separate methods which are clearly named, and not just combined it into one single method.

slightly more complicated code.png

Here is an even more complicated one…..you get the idea.

import React from 'react';
import RentangTanggalUjianComponent from '../date_range_input/rentangTanggalUjianComponent';
import JumlahSesiPerHariComponent from './JumlahSesiPerHariComponent.jsx';
import PilihTanggalUjianComponent from './PilihTanggalUjianComponent.jsx';
import SendButtonComponent from './SendButtonComponent'
import JumlahTanggalComponent from './JumlahTanggalComponent';

class SettingComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dateRange: [new Date(2020, 6, 2), new Date(2020, 6, 10)],
            isPilihTanggalUjianComponentVisible: false,
            dateCount: 0
        };
        this.dateComponent = React.createRef();
    }

    setDateRange(startDate, endDate) {
        this.setState({
            dateRange: [new Date(startDate.valueOf()), new Date(endDate.valueOf())]
        });
    }

    componentDidMount() {
        this.setDateRange(new Date(2020, 6, 2), new Date(2020, 6, 10))
    }

    setIsPilihTanggalUjianComponentVisible(isVisible) {
        this.setState({ 
            dateCount: 0,
            isPilihTanggalUjianComponentVisible: isVisible });
    }

    submit() {
        const dates = this.dateComponent.current.state.dates_enabled;
        this.props.setState(dates);
    }

    setCount(delta) {
        this.setState({
            dateCount: this.state.dateCount + delta
        })
    }

    render() {
        return <div className="container bg-white min-h-75">
            <RentangTanggalUjianComponent
                setVisibility={this.setIsPilihTanggalUjianComponentVisible.bind(this)}
                setDateRange={this.setDateRange.bind(this)}
            />
            <br/>
            <JumlahSesiPerHariComponent />
            <br/>
            <PilihTanggalUjianComponent
                dateRange={this.state.dateRange}
                visible={this.state.isPilihTanggalUjianComponentVisible}
                setGeneratedDates={this.setGeneratedDates}
                ref={this.dateComponent}
                setCount={this.setCount.bind(this)} />
            <JumlahTanggalComponent
                count={this.state.dateCount}
            />
            <SendButtonComponent
                visible={this.state.isPilihTanggalUjianComponentVisible}
                submit={this.submit.bind(this)} />
        </div>
    }
}

export default SettingComponent;

For all of these cases, I wrote the code myself. Unless I am chasing deadlines, every code that I wrote will be written in this standard of cleanliness.

What I Have Discovered.

Above, I have showed you how I apply the concepts of clean code into my project. However, there are a lot of things other than what I showed you, that I learned when I was either cleaning code, or conversing with my professor. Some of them are specific to Javascript, or even React which you can implement yourself. With that said, here is what I have discovered.

1. For some cases, use React Hooks

React Hooks is a new feature that is added with the release of React 16.8. A feature that could easily be utilized without changing the old code that we have written if we choose not to do that (Facebook even promotes a gradual adoption strategy for React Hooks), this allows us to write react features without the use of a class.

With React Hooks, we can create a different type of Stateful component, one that is created from a functional component, but then added with some Stateful component features. This leads to a cleaner code after transpiling, making it easy to test and debug. React Hooks also allows us to create a global state, which could further shorten the lines of code that I need to write.

Currently, we pass states to components whenever we want elements in other components to modify a component’s state. Let’s say there is an input form on component A, which modifies the state of component B which displays whatever is written on the input form. Let’s also say that these two components are a child component of C. We have to pass what is inputted into the props of component A which passes it to the state of component C, and then component B will have to access component C’s state and pass whatever is in it to its props. Before Hooks, this would be the ideal way to do it. However, with global states, we need only to access the global state, and not have to pass states through multiple component props.

My professor told me about this on the last evaluation day of the project, which led me into discovering how beneficial it is to use hooks instead of pure react.

2. Convert Duplicate Code into Components

Whenever there is a code that is duplicated, we can actually convert them into components. This reduces the line of code that is needed to create a component. This can also lead to fewer code duplication, as we can import the needed components and not have to write them again. We have done this for multiple components, and have added the possibility of creating a component that is imported multiple times in other components into something that we will factor in the planning process of creating the Front End UI.

3. Keep Components Simple

We should have not made components that are unnecessarily complex. We should have remembered that each component must have a single well defined function. We should have kept the logic and presentational counterpart separate. If we had done that, we would not have to rewrite multiple lines of code to change a single component’s function.

4. Use Prettier

Whenever we are planning to create a component, we sometimes argue about how to write it cleanly. If we had used Prettier, a code formatter tool which is compatible with Javascript, JSX and CSS (You can use this with other languages too, if Prettier supports it) and is compatible with various code editors (It supports Atom, Emacs, Espresso, Sublime Text, Vim, Visual Studio, Webstorm and the code editor that we choose to use, VSCode), we would have not worried about formatting as Prettier will clean it automatically according to the Formatting Rules for us. Even though Prettier does not help with Code-Quality Rules (Prettier cannot solve this due to code that fails the Code Quality check may have the correct syntax and formatting, and sometimes removing parts of the code that fails this check may result in broken code), this would have saved us lots of time versus cleaning the code manually.

You can click on this link to find out more information about Prettier. https://prettier.io/

5. Use Small Functions

This may be a general tip, but it is something that I want to mention here. We used to create large functions that does a lot of things before returning a value. However, in the process of refactoring the code, we have learnt that we could separate them into multiple functions and execute them whenever we want to. This allows us to not only make the code easier to understand, we could easily re-use the functions in functions that need them, without us needing to write code that we have written before.

6. Whenever Possible, Destructure.

There are two types of destructuring that we have applied to our project. One of them, is array destructuring. Array destructuring allows us to set multiple variables by way of putting the values in the array, and in the same order as the values that we want our variables to be assigned to, we create an array of variables. Here is a code snippet which demonstrates array destructuring.

const [day, dates] = arrayOfDayDates;

Here, we have set arrayOfDayDates[0] and arrayOfDayDates[1] into day and dates variables respectively. This replaces the conventional way of setting variables like this which unnecessarily elongates the code:

const day = arrayOfDayDates[0];
const dates = arrayOfDayDates[1];

The other type of destructuring that we have implemented is object destructuring. One example that we have used this on is the setting of dates in a component’s state.

Instead of using this….

setDates(dateArray){
    this.setState({ dates: dateArray });
} 

we use this

setDates(dates){
    this.setState({ dates });
} 

Destructuring is a new feature that came out with the release of ES6, and I am glad that unlike last semester, we can use it extensively in our current project to not only shorten the line of code, but also make it more intelligently written.

7. Use Rest/Spread

Rest parameter syntax allows us to represent an infinite number of arguments as an array. This is useful so that we don’t need to create new functions as the number of parameters that we want to pass increases. Here is a code snippet demonstrating the usage of the syntax:

function sumOfAllNumbers(...numberArray) {
  return numberArray.reduce((prev, curr) => {
    return prev + curr;
  });
}

Spread is a syntax that we can use in multiple cases. However the case that we use it is as a more powerful array literal.

Whenever we want to insert the values of an array to another array, we previously did this:

function addDateFromDateArray(dateArray){
    var resultingArray = getArrayFromState("resultingArray");
    for (let i = 0; i < dateArray.length; i++){
        resultingArray.push(dateArray[i]);
    }
    return resultingArray;
}

With the inclusion of Spread in ECMAScript 6, we could now do this instead

function addDateFromDateArray(dateArray){
    var resultingArray = getArrayFromState("dateArray");
    return [...resultingArray, ...dateArray];
}

While this may not reduce complexity, even though by using this we are forfeiting the use of the for loop, this makes the code more concise, which will be more easily readable. This will help in future developments, where code needs to be added on top of existing code.

Conclusion

Whenever you are reviewing code, you want the code that you review to be clean. Therefore, on the basis of respect, you need to also be somebody that churns out clean code every time. You need to be a clean freak when it comes to coding. Set a standard for your team to follow, have your team follow them, and you can be sure that any process of code reviewing will be a lot easier in the future.

Sources

Martin, R. C. (2009). Clean code: A handbook of agile software craftsmanship. Upper Saddle River, NJ: Prentice Hall.

Pengisian form daring

Saya mendapat ide membuat sebuah aplikasi pengisian form dimana kita dapat menginput sebuah file pdf, kemudian kita dapat membuat form-field sebanyak-banyaknya, kemudian kita dapat memprintnya dan/atau menyimpannya ke database setelah selesai mengeditnya. Sebenarnya udah ada yang buat framework berdasarkan ini, tapi saya mau nyoba buat sendiri.

Proyek ini akan saya buat menggunakan:

  1. React
  2. Spring
  3. Firebase (agar nanti mobile versionnya bisa dibuat)

Berikut penjelasan tentang fiturnya:

Pada saat user menginput file, isi file tersebut akan ditampilkan di aplikasi. Jika ada halaman tambahan, akan ada tombol dibawah untuk switch halaman. File PDF ini akan ditampilkan di sebuah kontainer yang terpisah dengan tombolnya agar mudah nanti pas mau dicetak pake react-to-print.

Setelah memasukkan file PDF, pengguna dapat memilih form field yang ingin ditaruh diatas file pdf tersebut, dan tempat dimana form field tersebut ingin ditaruh. Posisi form dan isi form ini akan disimpan dalam database. Form field ini transparan, dapat diselect dengan klik, dan ketika diselect akan: 1) menampilkan close button, dan 2) memperbolehkan user mengedit form tersebut. Akan ada dua tipe form yang akan dapat dipilih: Drawform dan Textinput. Khusus untuk drawform, canvas dapat diresize sesuai keinginan.

Setelah pengguna selesai mengedit form, pengguna dapat menyimpan atau memprint form tersebut. Data disimpan di dalam database.

Database tersebut akan memiliki:

  • Tabel yang akan menyimpan form dan link ke pdf, dipisah dengan id unik yang merupakan nama form tersebut.
  • Tabel form yang akan menyimpan fields. Setiap form dapat memiliki multiple fields. Memiliki id yang sama dengan tabel diatas.
  • Tabel fields yang berisi idfield (sesuai nama container yang digenerate otomatis) dan valuenya. Tabel field ini dapat memiliki dua tipe, yaitu textinput dan drawform. Untuk drawform, ia akan menyimpan link ke image, dan untuk textinput dia akan menyimpan string.

Kalau pengguna memilih print, react-to-print akan dijalankan dan container yang berisi pdf dan form diatasnya akan diprint sesuai dengan tampilannya di web.

 

Sekian dulu, mungkin nanti ditambahkan diagram schemanya dan illustrasi uinya.

 

 

Tujuan fashion saya untuk tahun ini.

[UPDATE 20/03/09] ADDED CAMP COLLAR SHIRT and Target Date.

Setelah melengkapi basic wardrobe saya, yang berarti bahwa ada baju yang decent lah untuk saya pakai setiap harinya, saya membuat tujuan baru, yaitu untuk meng-upgrade wardrobe saya agar berisi outfit yang tidak basic, tetapi cukup timeless dan youthful sebelum akhir tahun (Kamis, 31 December 2020). Ini berarti tidak ada barang-barang yang akan membuat saya terlihat terlalu tua, dan tidak ada barang-barang yang hanya akan saya pakai ketika saya muda, kecuali untuk kasus-kasus khusus.

Untuk membuat basic wardrobe, saya mengacu pada infografis yang ada pada Reddit Male Fashion Advice. Oleh karena itu, saya akan kembali mengacu kepada referensi-referensi fashion untuk membangun wardrobe saya untuk tahun ini. Hal ini saya lakukan karena saya tidak terlalu mengerti bagaimana caranya menyusun outfit yang bagus tanpa referensi.

Untuk referensi, saya menggunakan berbagai sumber, beberapa dari barat, dan beberapa dari timur. Untuk referensi dari barat, saya akan mengacu ke Gentlemen’s Quarters versi UK dan US. Untuk referensi dari timur, saya akan mengacu ke soompi.com dan instagram kdrama_fashion. Saya tidak akan membeli semua baju yang persis sama dengan apa yang direferensikan di semua referensi itu, karena biasanya yang direferensikan di situ adalah barang-barang mahal, tetapi saya akan mencari alternatif yang dapat saya jangkau.

Barang-barang yang kira-kira akan ada di wardrobe saya pada tahun ini

  • Sweatshirt

    • Memiliki material yang tipis, dan didesain untuk menyerap keringat. Saya menginginkannya dengan warna yang terang seperti Beige dan Biru Tosca, atau mungkin dengan pattern garis-garis vertikal.
  • Sweater

6771403707_2_5_1.jpg2632400251_2_1_1.jpg

    • Tidak seperti sweater pada umumnya, saya menginginkan sweater yang materialnya tipis. Hal ini sebenarnya karena yang saya cari dari sweater adalah fakta bahwa rajutannya membuatnya terlihat lebih unik, dan dapat dipakai di musim panas. Saya juga menginginkannya dengan warna yang terang seperti Beige dan Biru Tosca, atau dengan desain yang terdiri dari dua-tiga warna berbeda.
  • Trench Coat

Water-repellent cotton trench - General plane

    • Indonesia adalah negara tropis yang memiliki dua musim, hujan dan kemarau. Pada saat musim hujan, hujannya bisa deras sekali, dan payung saja tidak cukup. Saya ingin Trench Coat karena ia tidak hanya melindungi saya dari hujan, tetapi cukup fashionable sehingga saya tidak terlihat aneh ketika saya tetap memakainya ke mall.
  • Cardigan

3332404401_1_1_1.jpg

    • Untuk menambah layer dan variasi warna ke atasan yang polos. Saya menginginkannya dengan warna yang terang ataupun earth tones.
  • Bag

3281520001_1_1_1.jpgImage result for Faux Leather Hinged Clasp Backpack white

3141520105_1_1_1.jpg

    • Preferably sesuatu yang membuat saya terlihat fashionable dan youthful seperti Canvas Totebags atau backpack yang terlihat seperti kantung. Mungkin satu yang membuat saya terlihat professional. Mungkin briefcase, atau weekender atau backpack professional yang juga fashionable seperti Tumi yang terbuat dari kanvas.
  • More Turtlenecks

Annotation 2020-03-09 015957.png

    • Saya sudah punya yang putih, mungkin saya akan menambah lagi dengan warna hitam, beige dan coklat. Mungkin saya akan bergerak ke fit yang lebih ketat dan rajutan yang bersifat ribbed.
  • Pants

Joggers Slim Fit-Dark blue/Checked-Man

    • Yang penting untuk pants adalah fitnya harus flattering ke tubuh saya dan warnanya harus dapat dikombinasikan dengan seluruh outfit yang ada di wardrobe. Prefer earth tones dan light colours atau dark dengan light checkers dengan bahan kain ringan atau khusus untuk non-biru muda, jeans. Desainnya bisa wide end atau slim fit.
  • Jersey Shirts

Image result for uniqlo jersey shirt navy oxford Image result for uniqlo jersey shirt navy oxford

    • Saya menyukai long sleeve jersey shirt yang saya beli sebelumnya. Mungkin saya akan membelinya lagi dengan warna yang berbeda. Warna yang saya inginkan adalah putih dan biru muda. Saya lebih desain jersey shirt yang memiliki kantung saku, tetapi karena jarang sekali ada shirt yang memiliki material jersey, maka gapapa kalo yang ada cuma yang ada kantung sakunya.
  • Camp Collar Shirt/Cuban Shirt

Annotation 2020-03-09 205002.png

    • Saya ingat saya memiliki hanya satu camp collar shirt yang berwarna oranye. Mungkin untuk tahun ini saya bisa menambah koleksi saya dengan warna polos maupun motif yang dicetak langsung ke kemejanya.
  • Jacket (Trucker, Chore, etc)

Jungle Jacket Slub/Digi Boro Khaki

    • Harus ringan dan memiliki warna earth tones.
  • Payung

    • Payung kuat yang bisa dibuka-tutup secara otomatis dengan memencet satu tombol saja.
  • Alas Kaki
    • Saya memutuskan untuk hanya memiliki maksimum 5 alas kaki saja
      • Sendal

Image result for sendal jepit swallow x the goods dept

      • Sepatu Olahraga yang dapat didobel sebagai athleisure wear
    • Image result for alpha bounce
      • Sepatu Bot atau High top sneakers dengan material kedap air atau dapat dibuat kedap air dengan mudah.

Image result for Chuck Taylor Crafted Boot

      • Sepatu Formal yang unik seperti Double Monk Strap Dress Shoes.Damian Double Monkstrap Tan
      • White/ Off White (The color not the brand) Sneakers.

Sekian blog post saya, mungkin bisa menjadi referensi untuk anda sekalian untuk membangun wardrobe personal anda.

Big O

Apa itu Big O?

Big O adalah konsep yang digunakan untuk mendeskripsikan efisiensi algoritma.

Ada dua hal penting yang kita harus pikirkan ketika mendesain atau menganalisis suatu algoritma, yaitu kompleksitas ruang dan kompleksitas waktu. Kompleksitas waktu mendeskripsikan kira-kira untuk jumlah data yang tertentu, seberapa cepat algoritma akan berjalan, sementara kompleksitas ruang mendeskripsikan kira-kira berapa data yang harus kita simpan untuk menjalankan algoritma tersebut (ada beberapa algoritma yang tidak membutuhkan kita untuk menyimpan data dalam jumlah yang sama dengan data yang diproses).

Dalam academia, biasanya ada tiga tipe notasi yang digunakan untuk mendeskripsikan runtime, yaitu: Big O, Big Omega dan Big Theta. Big O merupakan deskripsi batas atas runtime dari program yang dianalisa, Big Omega merupakan deskripsi batas bawah runtime dari program yang dianalisa, sedangkan Big Theta merupakan deskripsi paling dekat ke runtime yang sebenarnya. Di industri, Big Theta digunakan seakan-akan ia Big O, dan karena itulah kita akan menggunakan deskripsi tersebut.

Tiga kasus yang dapat digunakan untuk mendeskripsikan runtime atau space complexity sebuah algoritma.

Best Case: Ketika diberikan input tertentu yang membuat proses dapat dilakukan secepat mungkin, atau untuk space sekecil mungkin.

Worst Case: Ketika diberikan input tertentu yang membuat proses hanya dapat dilakukan selambat mungkin, atau kalau untuk space sebanyak mungkin data yang harus disimpan.

Average Case: Ekspektasi runtime rata-rata untuk data yang diinput ke dalam algoritma, atau kalau untuk space rata-rata data yang disimpan.

Tips menentukan Runtime Complexity

  • Dropping nilai
    • Ketika menentukan runtime complexity, pastikan semua nilai yang tidak dominan di-drop. Konstan kurang dominan dibandingkan N, maka kalau misalnya ada O(N+1), maka 1 dapat didrop, menghasilkan O(N).
    • Mengapa kita dapat mendropnya begitu saja? Hal ini disebabkan karena notasi Big O untuk runtime menentukan rate of increase dari runtime sebuah algoritma. Konstan 1 tidak akan berubah ketika besar data berubah, sehingga tidak perlu dianggap. Bahkan perkalian dengan konstan pun dapat didrop, misal ada O(5*2^N) maka 5 dapat didrop, yang kemudian akan membuat notasi tersebut menjadi O(2^N).
    • Selain itu, variabel yang non-dominan juga dapat di-drop. Maksud dari variabel yang non-dominan adalah variabel yang tidak memiliki nilai term yang terbesar. Contohnya dalam kasus O(N^2 + N). N^2 memiliki nilai term lebih besar dibandingkan N maka N dapat didrop.
    • Berikut adalah tabel yang diurutkan berdasarkan nilai term, dengan nilai term yang diatas merupakan nilai term yang terkecil.Annotation 2020-03-08 211909.png
    • Sedikit info:
      • Jika N dibagi 2 setiap kali iterasi, maka runtimenya untuk porsi kode tersebut Log N
      • Untuk rekursi, eksponensial dengan C merupakan berapa kali pemanggilan fungsi yang akan menyebabkan rekursi. Biasanya keliatan di return. Untuk kasus tipikal, kalo fungsi f(), terus untuk fungsi tersebut kasus yang bakal rekursi return f() + f(), berarti O(2^n), kalo f() + f() + f() berarti O(3^n).
  • Multipart algorithm: Tambah atau Kali?
    • Misal ada algoritma yang runtimenya A, dan ada algoritma yang runtimenya B
      • Ketika algoritmanya: Loop A, baru setelah itu Loop B, maka tambahkan jadi O(A + B)
      • Ketika algoritmanya: Setiap kali Loop A, Lakukanlah Loop B, maka kalikan jadi O(A * B)
  • Amortized time
    • Khusus untuk ArrayList, yang merupakan dynamic resizing array, ketika arraynya full, dia bakal ngedouble sizenya dengan cara membuat ArrayList baru yang sizenya 2x dari size ArrayList awal dan setelah itu mengkopi semua elemen dari ArrayList yang lama ke ArrayList yang baru. Aksi ini memakan N waktu, tapi jarang terjadi.
    • Kalau arraynya ga penuh kan cuma 1 doang runtimenya. Itulah amortized timenya.
    • Untuk X insertion tapinya, butuh O(2X) time, asumsi array didouble pada power of 2, yaitu 1,2,4,8,16…..X. Hal ini karena X + X/2 + X/4 + X/8……+ 1 mendekati 2. X disini konstan.

Tips menentukan Space Complexity

Satu data merepresentasikan satu konstan. Array yang panjangnya n berarti n data yang harus disimpan. Jika ada array dua dimensi nxn, maka kompleksitasnya n^2. Note bahwa huruf n yang digunakan merupakan huruf kecil, dengan n berarti input size dalam satuan bit yang dibutuhkan untuk merepresentasikan input tersebut.

Alasan mengapa saat saya latihan saya hanya melakukan 6-8 pengulangan untuk setiap gerakan.

Sebelum saya ke pertama kali ke gym pada tahun ini, saya refleksikan ke beberapa tahun belakang alasan mengapa saya tidak menjadi lebih kuat meski saya pergi ke gym setiap minggu. Setelah refleksi itu, saya menyimpulkan bahwa ada beberapa aspek dari olahraga di gym yang saya tidak pikirkan.

Salah satunya adalah olahraga apa yang saya lakukan. Pada saat saya berolahraga, saya tidak memikirkan olahraga yang saya lakukan. Saya hanya melihat alat yang tidak ditempati orang, dan saya latihan menggunakan alat itu.

Saya bahkan tidak menyusun sebuah pola olahraga yang harus saya ikuti setiap kali saya pergi ke gym. Saya hanya olahraga untuk mengangkat beban, dan meningkatkan beban yang saya angkat. Padahal, susunan latihan merupakan suatu hal yang penting sehingga olah raga yang dilakukan dapat menjadi maksimal.

Oleh karena itu, saya mencoba menyusun pola latihan yang akan saya gunakan di gym. Beberapa waktu setelah memikirkan cara menyusun pola latihannya, saya menyadari bahwa saya tidak tahu apa-apa tentang fisiologi manusia. Karena itu, menurut saya sebaiknya saya mengambil pola latihan yang telah dipopulerkan oleh orang lain.

Pada saat saya mencari pola olahraga yang bahkan pemula pun bisa melakukannya, saya menemukan sebuah situs yang dikelola oleh seorang pelatih yang bernama Jeremy Ethier. Dari situsnya saya bisa mendapatkan dua pola olahraga untuk full body training, yaitu pola A dan pola B. Saya hanya menggunakan salah satu dari pola olahraga itu, yaitu pola A.

Di dalam dokumen yang berisi pola A tersebut, saya melihat bahwa rep-range yang direkomendasikan untuk dilakukan adalah 6-8 reps, dengan 6 jika anda pemula dan 8 reps jika anda mahir. Ini konflik dengan reps yang direkomendasikan oleh Celebrity Fitness Trainers untuk kebanyakan dari olahraganya, yaitu 12 reps. Fakta bahwa rekomendasi mereka berbeda membuat saya merasakan konflik di dalam diri saya. Oleh karena itu,saya ingin mencari basis dari keduanya agar saya dapat mengerti mengapa rekomendasi mereka berbeda.

Kemudian saya menemukan website ini. Website tersebut menjelaskan bahwa rep-range yang berbeda menghasilkan hasil yang berbeda dan tergantung tujuan workout kita harus memilih rep-range yang benar. Ketika susunan latihan yang melibatkan gerakan yang dilakukan dalam 12 reps digunakan, maka tujuan dari orang yang membuat susunan latihan tersebut adalah besar dan ketahanan. Ketika susunan latihan hanya menggunakan 6-8 reps dibandingkan 12, maka tujuannya adalah kekuatan dan besar.

Tujuan saya berolahraga adalah untuk meningkatkan kekuatan dan besar. Hal ini karena makin kuat saya makin berat beban yang dapat dipikul dan meningkatnya berat memaksa otot yang digunakan untuk menggunakan gaya yang lebih besar, dan hal ini menyebabkan otot juga menjadi lebih besar dalam waktu yang lebih singkat, sehingga hasilnya akan lebih cepat kelihatan. Karena tujuan saya demikian, maka sudah selayaknya saya melakukan olahraga dengan susunan latihan yang menggunakan 6-8 reps.

 

 

Why Millenials aren’t buying houses.

Research done by Central Statistics Agency has shown that only 55.24 percent of Indonesians own a house in Jakarta. That is not a lot, and there are reasons as to why that is the case, but let’s just talk about one.

I think one of the biggest reasons, is because of the unaffordability of housing. A lot of people, particularly millennials and Gen-Zs, cannot afford to buy a house with their current salary in Indonesia. This is because the prices of houses have risen to the point where they can’t afford it.

If we look at the data from Numbeo, as accessed at 11:36 PM on the 7th of May 2020, the average monthly salary for Indonesians is around 6,806,637.80 Rupiahs. Let’s divide that into three categories which are Needs, Wants and Savings and Investments and set a percentage that is recommended by financial advisors for each of those categories. This would be around 50 percent for needs, 20 percent for wants and 30 percent for savings and investments.

Let’s divide the needs category further. But before we do that, we need to ask ourselves what is it that we truly need to spend money on and sort them out to several concrete categories. Most people will have these categories:

  1. Transportation
  2. Housing (this also include utilities)
  3. Groceries
  4. Taxes

Because we used 6,806,637.80 Rupiahs as our salary per month, our annual salary amounts to 81,679,653.6 Rupiah. To be honest, our annual salary may be actually slightly more than that since Indonesia has a 13 month salary system, where the 13th month salary is given on certain days according to the receiver’s religion, but let’s assume that as a certain bonus that we get annually and we use that to buy essential things that we are not going to buy that often or for some of us, to buy tickets so that we can see our families back where they are. Let’s also assume that that amount is our net salary, and what I meant by net salary is that this amount of money is what you will take home after all the withholding and the deductions have been accounted for.

Then, let’s look at transportation. Financial consultants recommend that we should not spend more than 20 percent of our annual income on automotive expenses. Because of that let’s use 20 percent for transportation, which is around 40 percent of the money that we have set aside for needs. That amounts to 1,361,327.56 Rupiah.

Now we have around 60 percent left of the money that we have set aside for needs, which is around 2,041,991.34 Rupiah. Let’s assume we spend half of that on groceries and half of that for housing. This means we have around  1,020,995.67 Rupiah for each of the two categories.

Let’s assume the amount of money that we should pay each month for our 20 year fixed mortgage ( a payment scheme recommended by financial advisors) is exactly that and  not think about furniture and utilities yet. Do you think that a house that has a 20 year fixed mortgage price of 1,020,995.67 Rupiah per month? Well, it may exist, but it’s extremely rare, especially in an urban city like Jakarta. You certainly cannot have just that amount though, since you’ll need to buy furniture and pay utilities as well. You wouldn’t want to own a house and not have anything inside and not have water and electricity working would you?

PPL Journey part one

PPL adalah pelajaran yang unik, karena ini adalah pelajaran yang menurut saya paling bebas dari segi cara pendekatannya. Pelajaran ini mengekspos kita ke proses pembuatan perangkat lunak dan memberikan kita kesempatan untuk membuat perangkat lunak yang benar benar akan dipakai di dunia nyata.

Perangkat lunak yang harus dibuat terbagi ke lima kategori berdasarkan klien yang memintanya: Akademik, Ide baru, Startup, Sosial dan Pemda dan Industri IT. Kebetulan kami mengambil yang akademik, dikarenakan tingkat kesulitan perangkat lunak yang harus dibuat disitu merupakan yang paling mudah, dan ini terbukti sangat membantu kami di masa yang akan datang (saya akan menjelaskannya di paragraf yang akan datang).

Perjalanan PPL tidak dimulai dari minggu masuk kuliah, melainkan dimulai sebelum kita kuliah. Pada minggu-minggu sebelum kuliah kita diharuskan untuk menyusun sebuah kelompok, memilih kategori serta aplikasi apa yang kita akan buat. Kemudian, setelah liburan, barulah sesi kelas dimulai.

Pada minggu pertama sampai ke tiga, yaitu masa pra project, kita mempelajari BRP dan beberapa standar yang harus kita ikuti pada saat kita membuat perangkat lunaknya. Standar seperti Penggunaan Git, Development berdasarkan proses Agile dan Scrum, QA menggunakan Sonarqube, Pembuatan UI/UX, serta Definition of Done dipelajari dan dibuat kuis pada akhir minggu ketiga.

Kemudian sampailah kita ke minggu keempat sampai minggu kesembilan yang merupakan periode sprint pertama dan kedua. Kebetulan di saat saya menulis blog post ini saya sudah sampai ke akhir sprint pertama, oleh karena itu saya akan menulis secara detil pengalaman saya pada sprint pertama ini.

Pada sprint pertama ini yang berlangsung selama dua minggu, saya mengerjakan banyak hal. Selain task saya, saya juga menginisialisasi environment development serta mengatur devops untuk kelompok saya. Oleh karena itu, pada sprint ini waktu kerja saya, yaitu 16 untuk minggu pertama dan 36 jam pada minggu kedua, jauh melebihi standar, yaitu 36 jam saja untuk kedua minggu itu.

Hal ini karena dokumentasi untuk men-setup devopsnya kurang memadai dan karena environmentnya tidak diset dengan benar pada awal. Seharusnya mensetup environment adalah kerja tim, tapi yang kerja untuk setup environment hanya Dimas dan saya saja, dan setupnya juga nggak bener jadi harus dikoreksi lagi nanti tapi ga kunjung dikoreksi juga sebelum dibranch jadi akhirnya branchnya salah dan environmentnya juga salah. Fakta bahwa saya harus membetulkan ini semualah yang membuat waktu kerja saya tinggi. Terus fakta bahwa Dimas mau cuti dan Nicky ibunya sakit dan dirinya juga sakit sakitan nggak membantu.

Untunglah akhirnya pada sprint review progressnya dapat dipresentasikan dengan baik dan diterima oleh klien sehingga salah satu PBI dapat selesai.

Sekarang adalah waktunya bagi kami untuk mengerjakan apa yang kita ambil pada sprint kedua, semoga sama seperti sprint ini, kelompok saya juga dapat menyelesaikan apa yang kita ambil dan mempresentasikannya di sprint review selanjutnya.

 

 

Six steps and techniques that you should use when answering a coding interview question.

Whenever we are faced with a coding question, particularly in interviews, we sometimes don’t have a concrete plan as to how we are going to systematically answer the question. This may be due to nervousness, or just general unpreparedness to coding questions. According to the book Cracking The Coding Interview, there exists a six step process into how to solve coding questions. I am going to elaborate on that right now.

  • Listen

Whenever we are doing a coding interview, the question usually won’t be given to you by text. It is usually communicated to you through voice. When the speaker is giving a description on the problem that you are going to have to solve, you need to pay very close attention to any information that is described. Assume that every detail is there for a reason, and write the information on the whiteboard. This is so that you can write an optimal algorithm as the answer to the question.

  • Example

When you hear a question do not try and solve the question in your head. You should draw an example. We should try create an example that is:

  1. Specific: e.g. do not create an ideal BST (with two children). Use numbers and strings.
  2. Sufficiently large:
  3. Not a special case: Use general examples not corner cases.
  • State a brute force

Once you have an example done you must state a brute force. You do this so that the interviewers don’t think that you are struggling to see even the easy solution. Then state the time and space complexity of it. This may not be the optimal solution, but it can help you understand the problem further and could be the starting point for your optimization.

  • Optimize

After stating a brute force algorithm, you should try and optimize it. You can optimize it by:

  1. Looking for unused information
  2. Use a fresh example
  3. Solve it “incorrectly”
  4. Make time vs space tradeoff
  5. Precompute information
  6. Use a hash table
  7. Think about the best conceivable runtime
  • Walk Through

When you have nailed down an optimal solution to the problem, don’t just dive into coding. When you code, you must write code that is nearly perfect, because testing and bug fixing take time. Understand completely the solution that you want to write, then write it.

  • Implement

Once you understand the solution that you want to write, implement it. Start coding in the far left of the whiteboard, and avoid line slant. Write beautiful code. This means that your code must be:

  1. Modular
  2. Error Checks: Some interviewers care about this and some don’t. A good compromise will just be to write a todo first and explain what you are going to implement there.
  3. Use Other classes, structs when appropriate e.g. returning an array that is filled with the two lists that you need to return if you need to return two lists.
  4. Good variable names: Avoid using single letter variable names when possible. Use it only if you think the code will be too long, but don’t use it too much since it may confuse you.

If there is something that you can refactor, decide whether or not it’s worth it to refactor and state the reason why.

If you get confused, walk through the code again.

  • Test

In real life you don’t submit code if you haven’t tested it. Here you need to do that as well. Use this approach whenever you want to test:

  1. Start with a conceptual test: Reading and analyzing what each code does, as if you are explaining it to a reviewer.
  2. Weird looking code: You may wrote that before for a good reason, but double check it again.
  3. Hot spots: These are some but not all cases where your code could cause problems
    1. Base cases in recursive code
    2. Null nodes in binary trees
    3. Start and end iteration of a linked list
  4. Small test cases
    1. Use small ones that can discover the same bugs as the large one.
  5. Special cases
    1. Test your code against null or single element values, the extreme cases or other special cases

If you found any bugs, you should always analyze why it occurred and make the best fix that you can make.

 

Some of the techniques that you can use to help solve the problems are:

Find the BUDs of your algorithm

  1. Bottlenecks: Part of the algorithm that slows down overall runtime.
  2. Unnecessary work: e.g. looping where you could’ve checked using a formula
  3. Duplicated work: Used multiple of the same iterations where you could’ve just used one.

Do it yourself: Usually when you are doing something in real life you intuitively are able to optimize it. Model the problem to real life situations and solve it.

Simplify and generalize: Make an easier version of the problem first, and then adapt it for the more complex version.

Base case and build: Solve problems from the base case first, and get to more complex/interesting cases later.

Data structure brainstorm: Find a data structure that can be applied to solve the problem.

Best conceivable runtime: The runtime that you are going to get if you input the best case input to an algorithm.

Agile and Scrum

“Perfection is not attainable, but if we chase perfection we can catch excellence.”
-Vince Lombardi

agile.png

Agile

Before Agile exists, whenever a software is developed, there may be a time lag between the formulation of business requirements and the delivery of the technology that answered those requirements. This actually led to a cancellation of many projects due to the fact that business requirements may change over time and the final product not meeting those requirements. The Agile principle is created to solve this problem. Rather than developing software from start to finish in a specific time-frame, agile allows an iterative approach to developing software by dividing work into several consumable increments. This way, whenever a change needs to occur, it can be implemented in the next increment directly.

Agile has four values and twelve principles. The four values is written in its manifesto. These are:

1. Individuals and interactions over processes and tools

It’s easy to overlook people when developing applications because we as developers mainly focus on the processes and tools that is necessary to make them. However, the people are the ones that respond to change and drive development processes. Therefore, valuing the people should be the logical thing to do.

In our experience, we had to change the way we think about the software development process. Whenever we are conversing with the client, we tend to want to go back into the details of the frameworks and the code that is written. We have been constantly reminded to not talk about that and instead communicate about what the clients actually understand and whether or not the features are implemented as desired.

2. Working software over comprehensive documentation

In the past, more time is used to create documentation for the final product release. This resulted in delays that should not have existed. However, this does not mean that documentation is not important. The agile methodology does not eliminate documentation, but made it so that developers only write what is necessary for them at the time and not more.

In the work that we have done, the documentation is done last, when the actual feature has been confirmed to work. Even then, the documentation is only done as needed. The things we are planning to put on the documentation are: how to deploy the software, what features are available on it and how to use them and the basic architecture and how each component communicates with each other.

3. Customer collaboration over contract negotiation

Previously, Waterfall was the main development model for many developers. It is the earliest process model to be introduced.

SDLC Waterfall Model

The work in waterfall is divided into several phases, which are: Requirements Analysis Phase, System Design Phase, Introduction Phase, Implementation Phase, Testing Phase, Deployment Phase and lastly, the Maintenance Phase. Each phase must be completed before the next phase can begin and there is no overlapping between phases. With the waterfall model, there is a stage where the customer is involved in the negotiation of features that needs to be implemented and the time-frame that needs to be followed before the project began. However, the customer involvement ends there. The Agile manifesto defines that a customer should always be involved from the start until the end of development to make sure all business requirements are being implemented correctly and whenever there are modifications to the requirements, the developers can be informed.

The fact that the customer is involved with the process from start to the end, is very useful. In my experience, there is a feature that is added mid-way into the development, which is the storage of auto-generated excel files in the cloud. This feature is not easy to implement as it involves adding another component to the architecture. In short, we have to find out a service that can store the files for as little as possible, and make sure that it is compatible with the existing application that is already developed and easy to use as well. We would also need the customer to agree upon this design change in the middle of the development process. If we were to use the waterfall model, we would have scrape and re-do the software from scratch, which includes re-writing the specifications all over again. If there are many changes which is equal or higher in complexity to what I described above, it can lead to the software never getting deployed.

4. Responding to change over following a plan

The problems of traditional software development requires developers to create an elaborate software development plan and executing it until the program is finished. With agile, whenever there is a change in business requirements, the development team can reorganize the priorities of the tasks that they do and add tasks as needed. This allows change to be implemented relatively quicker when compared to traditional software development.

When we are asked to implement the cloud storage feature that was described previously, and another product was added to our product backlog, which is the display of the excel files, it completely screws up our plan as we originally plan on doing one PBI per sprint. This forces us to work on more than one PBI per sprint as we only have 5 sprints for more than 6 PBIs.

Below are the twelve principles that the four principles were based on. To help you make sense of how this principles are implemented in a software developing project, I will also mention my experiences that are related to the principles below.

  • Customer satisfaction through early and continuous software delivery: In each sprint review we try to make sure that all the features are implemented correctly and as desired by the client.
  • Accommodate changing requirements throughout the development process: PBI items may be added or removed depending on the Product Owner’s decisions
  • Frequent delivery of working software: In the first sprint review we present a software that has some features working. Gradual increase in features is presented every sprint review.
  • Collaboration between the business stakeholders and developers throughout the project: We have a representative of the client that is fully involved in the process. The representative is contacted every time there are queries that needs to be addressed to as soon as possible.
  • Support, trust, and motivate the people involved: When we have a developer that left early in the software development process, I try to motivate the remaining team members so that they are more inclined to get the work done in a timely manner.
  • Enable face-to-face interactions: Face-to-face interactions are done every Daily Scrum Meeting, where we talk about what we have done and what we are going to do so that everybody knows.
  • Working software is the primary measure of progress: In each sprint review, if the client has examined the features and accepted it, that means we are one step closer to the finished product.
  • Agile processes to support a consistent development pace: We are heavily encouraged to work according to the work hours (and possibly more since progress is measured according to the working software that we have developed) and the high frequency of reviews made by fellow developers and also product owners and clients makes it so that maintaining a consistent development pace needs to be done in order for us to be successful.
  • Attention to technical detail and design enhances agility: If a feature is not up to what the client wants, it may be rejected. Therefore we try to make sure that each feature is implemented according to the standards defined in the PBI document.
  • Simplicity: Each PBI is separated into several tasks. Each task should be as little as possible to ease development.
  • Self-organizing teams encourage great architectures, requirements, and designs: We are a self-organizing team in the sense that the choice of framework, architecture construction and design is made by us. The requirements though, is based on the needs of the client, which can change over time.
  • Regular reflections on how to become more effective: This is done in the daily scrum meeting and also the sprint retrospective. The third sprint retrospective that we have done really emphasizes on this as we have failed our sprint.

Scrum

In our class we were told that the software development will involve the scrum framework. Therefore I seek to explain what that is and how it is implemented in our class routine here. But before that, I would like to explain a little bit about what scrum is.

According to the Scrum Guide, scrum is “A framework within which people can address complex adaptive problems, while productively and creatively delivering products of the highest possible value”.

It’s a framework that has been used quite a while, actually (since the early 1990s). However, it is still relevant today, and I believe that is the case due to the fact that it’s adaptable. Scrum does not specify the techniques that you need to use, and the processes that you need to employ. You can implement any technique and process that you need to deliver a product, in addition to using the scrum framework. You cannot, however, remove any elements from the framework, and still call it scrum.

The Scrum framework, though, requires you to form a team (called a scrum team) that is not huge (probably less than twelve), and each member of the team needs to have specific roles, some of which are probably unique to the scrum framework. The roles are as follows:

1. The Product Owner

The product owner manages the Product Backlog. In our class this would either be one of the Teaching Assistants, or in the case where a company wants us to develop a software for them, the product owner will be a representative that is directly sent from that particular company. There usually will only one product owner (at least, in our case, only one exists).

2. Scrum Master

The scrum master helps guide the whole team so that the team follows the scrum guidelines defined in the scrum guide. In our class this would be one of the Teaching Assistants.

3. Development Team

The development team is the one doing the actual development of the product and must deliver a releasable increment of “Done” (Defined according to the definition of done) for the product at the end of each sprint. They are given relative autonomy as to how the product is built and delivered.

Once a scrum team has been formed, it’s time for them to encounter events that are exclusively there due to using the Scrum Framework. These events are called ‘Scrum Events’ and these include:

Sprint Planning

This event is done before the sprint and is created by the collaboration of all the members in the team. In this event two main things are being answered:

  • What can be delivered in the Increment resulting from the upcoming Sprint?
  • How will the work needed to deliver the Increment be achieved?

This is one of the most difficult things to do, and if it fails, there will be problems later on in the actual sprint.

(The actual) Sprint

This event is when the development of the program occurs. Based on the planning done on the Sprint Planning Scrum Event, the development team develops software according to what is agreed upon.

Daily Scrum

This is a fifteen-minute time-boxed event in which the development team discusses about what happened in the previous day, which includes what we did, what we have learned, the problems that we have encountered (external and internal) and discusses plans for the next twenty-four hours of work. In our class, one day of scrum lasts for around three days (since we cannot afford to do full time without disregarding other courses) and daily scrums happen on Monday and Wednesday. In addition to those things, we added how many hours have we worked on before the current daily scrum and after the previous daily scrum to one of the things that we told our teammates so that we can make sure that the minimum hours of work that we should do is used up properly. Teammates can also comment on things that can be improved directly after a member has spoken.

Sprint Review

Sprint Review is the time where we meet up with the whole scrum team and all stakeholders (our partner in our case), and these actions are usually the ones that will be performed:

  1. The product owner will explain what Product Backlog Items has been done and also explain the ones that are not done. To inspect whether or not the product backlog is done or not, the product owner will refer to the definition of done and the acceptance criteria for each product backlog item.
  2. The development team will discuss what went well, what problems they encounter and if they have solved it, how they solved it.
  3. The development team will demonstrate the results of the sprint by presenting the software in its current form after development in the sprint. Then for each item in the sprint backlog, the product owner will inspect whether or not they have been completed by referring to the definition of done for that particular item.
  4. What will be done next will be discussed across all the members of the meeting. This will help quicken the sprint planning process. This may also affect the product backlog.
  5. The product backlog will be inspected and revised if needed. PBIs can be added or subtracted as needed, and values could be changed. The result would be a revised product backlog.

What we did was slightly different, in that the client will be the ones that determine whether or not the product is accepted or rejected according to the acceptance criteria, whereas the definition of done, which is more technical (evident due to the presence of the 100% code coverage requirement, which non-tech people will usually not understand), will be inspected by the product owner.

Sprint Retrospective

This is where the team does an evaluation of how the last sprint went and what could be improved upon so that there will be less problems in the next sprint. It is usually done immediately after the sprint review. The participants are the Scrum Masters, Product Owners, and the whole development team. This is usually done within an hour. However, special cases may require more.

The things that are discussed here would usually be guided with these three questions:

  1. What does the team need to start doing?
  2. What does the team need to stop doing?
  3. What does the team need to continue doing?

Of course, depending on the implementation, the guiding questions could be different. It could be more, it could be less. However, as long as the team found ways to improve upon the last sprint, the goal of the sprint retrospective will be achieved.

Sprint Cancellation

If an abrupt situation occurs, a sprint may be cancelled. It is very rare that this occurs. It is not cancelled when the scrum team discovers that it cannot meet it, because it can be poured on to the next sprint. A sprint review determines whether or not it will be poured as is, whether it will be split into multiple PBIs, and to receive feedback on what they should do so that it can be met on the next sprint. The sprint retrospective is important also in this aspect to help developers reflect on why it occured and how they can improve.

If a scrum goal is met early or is projected to be met early there are a variety of things that can be done. These namely include: Renegotiate to take on new tasks, giving free time to the developers as a reward for finishing the tasks, work on improvements such as refactoring or even investigating future sprints. This of course depends on the rules of the organization but typically, new tasks are renegotiated to be taken as long as it does not impact the current sprint goals.

Scrum Artifacts

1. Product Backlog

The product backlog is a list of all features, functions, requirements, enhancements, and fixes that needs to be implemented into the product. Split into PBIs which contains description, order, estimate and value. This document will be maintained by the Product Owner, and the way the value is determined is according to the business logic that needs to be done first.

2. Sprint Backlog

The sprint backlog is a list of the features that have been chosen from the backlog during the sprint planning meeting to be done on a particular sprint.

3. Increment

List of all completed product backlog information from all the sprints.

Artifact Transparency

The concept of artifact transparency is simple. Artifacts must be completely visible and known to the whole team, and the stakeholders. To ensure this, the Scrum Master must work together with the Product Owner, Development Team, and all other parties that are involved with the project to understand if the artifacts are completely transparent. In the presence of incomplete transparency, the Scrum Master must ensure that the artifacts are as transparent as possible, and Scrum Masters can detect their presence by looking at the differences between expected and real results.

The Sprint Goal

According to Visual Paradigm, a Sprint goal shows the desired outcome of an iteration that provides a shared goal to the team, which goal has to be defined before the team starts the Sprint in order to focus to get this goal. It is worked on by the Product Owner, along with the development team, and it is comprised one or two sentences which is elaborated by specific Product Backlog Items that is chosen to be done for a particular sprint.

The User Story

The user story is one of the parts of the product backlog that describes what should be implemented for that product backlog. It consists of three elements:

  1. As A: The type of user that is going to be the subject of the User Story
  2. I want to: The actions that a user wants to do
  3. So that: The direct benefits of the action that the user wants to do

Bundled with it is the acceptance criteria (or acceptance criterias). Acceptance criterias are objective components which a user story’s functionality is judged. When a developer team has taken a PBI to be worked on, the results are tested according to this, and the definition of done. The main difference between an acceptance criteria and the definition of done is that the definition of done is applied for all user stories, whereas each PBI has its own acceptance criteria.

The Definition of Done

The Definition of Done is a living list of requirements that is agreed upon and understood by the scrum team. When all the items on a list is checked for a product increment, the product increment is ready to be released. It is required to be made to ensure transparency in terms of requirements.

When we talk about the contents of The Definition of Done, we should be able to divide it into three main components:

Business or Functional Requirements

Standard Business or Functional Requirements are categorized here. While this may contain other elements, the bare minimum of content that is categorized here is for the acceptance criteria for each PBI to be accepted.

Quality

Coding Standards, Test-Driven Development, Unit Test Coverage, Maintainability Index, Maximum Number of Defects, Maximum Technical Debt, Design Principles are put here.

Non-Functional Requirements

Availability, Maintainability, Performance, Reliability, Scalability, Security, Usability, Compliance/Regulatory and Legal are put here.

As I said before, the definition of done is a living list of requirements. This means that items can be added or subtracted from the list as the time goes on. Depending on how much items are in the list and when it is made, it can be categorized as Initial DoD, Mature DoD and Stringent DoD.

How Agile and Scrum is implemented in our case

Here is a list on how it is implemented to develop our app:

  1. We keep an excel document that we use to track the requirements of the web application. The contents of the document is the same with any other Product Backlog document. It contains the Product Backlog Items, the name of the Product Owner, the project title and the timestamp of the last edit. This makes it clear as to what needs to be implemented, and what does not need to be implemented. This also makes it easier to split the functionalities to be done in multiple sprints, and gives us target features to be delivered on each sprint. Other than that, it makes it easier to know when the document is last edited so that we know why there are discrepancies when there are discrepancies between what we know and what is actually written.
  2. Communication to the client is done through one of our TAs. This is especially important when we want to implement the algorithm that creates the schedules since it needs to be similar to how the client creates the schedule manually (May I remind you that our app is one that automatically generates test schedules?). The TAs help word the questions so that the client can easily understand them and can give us the answers that we need.
  3. The Sprint Planning Meeting is done before a sprint starts. It is usually done on Thursday, which is the first day that a sprint starts, and the day when the sprint ends with a sprint review. The sprint planning for the subsequent sprints is done after the sprint retrospective. This is when we pick a Product Backlog Item to do, and divide the Product Backlog Item into small tasks, then assign them to separate people to be worked on. We divided the tasks to be so small, so that we can accurately portray the work that needs to be done, and so that the people that are doing the tasks aren’t overwhelmed by the complexity of the tasks that are needed to be done. Here we also decide which task to take first and plans to take other tasks later on if we have done the tasks that we have taken.
  4. The development work that we do is based on what we have planned
  5. The Daily Scrum Meeting is done on Mondays and Wednesdays. It should be done everyday but, again, we have to split one day of work into 2-3 days so that we can fit it inside our busy schedule (we are not doing this full time). The last Daily Scrum before the sprint review, in addition to doing the things that is usually done, is when we test the app, if possible, to verify whether or not it works as intended so that there are no hitches when the app is presented to the client on the day of the sprint review.
  6. The Sprint Review Meeting is done on Thursday. In this meeting we present the current iteration of software and for the Product Backlog Items that we have taken, verify whether or not the acceptance criteria has been fulfilled, and whether or not our work satisfies the definition of done. If for a certain Product Backlog Item, both the acceptance criteria and the definition of done is fulfilled, then the product backlog item will be accepted. If one or both is not fulfilled, then the product backlog item will be denied. The one that determines this is our partner.
  7. The Sprint Retrospective Meeting is done on Thursday as well, a few hours after we did our Sprint Review. The delay is due to the fact that we have classes after the sprint review, so it cannot be done immediately. This is done to help us reflect and improve ourselves so that the next sprint could be better. In the case where we fail, we brainstorm plans so that the next sprint will be successful.

Reference:

Atlassian. (n.d.). What is Agile? Retrieved from https://www.atlassian.com/agile
Eby, K. (n.d.). Comprehensive Guide to the Agile Manifesto. Retrieved February 27, 2020, from https://www.smartsheet.com/comprehensive-guide-values-principles-agile-manifesto
What is Scrum? (n.d.). Retrieved from https://www.scrumguides.org/
SDLC – Waterfall Model (n.d.). Retrieved from https://www.tutorialspoint.com/sdlc/sdlc_waterfall_model.htm
What is a Sprint Goal in Scrum (n.d.). Retrieved from https://www.visual-paradigm.com/scrum/write-sprint-goal/
Done Understanding the Definition of Done (2019). Retrieved from https://www.scrum.org/resources/blog/done-understanding-definition-done

 

 

 

 

 

 

 

 

 

 

 

What is a Persona and how does it help us create designs?

Billy Gregory, Senior Accessibility Engineer

What is a persona and why is it important?

Whenever we want to create a design for a product or service, it has become standard practice for us, with the data that we have obtained, to generate a description of the people that will most likely use it. What we have created is called a Persona. It is a realistic way for us to ‘humanize’ data and it helps us to better understand the users so that we can create a design that is catered to them specifically.

Personas are usually created at the start of the project, before any actual development occurs, but after we have collected information about the users. It usually consists of information about their goals (what they want to achieve with the help of the product), skills (what the user can do), frustrations (real life problems that the product will help solve) and their biodata. Do keep in mind that what you are creating is not an actual description of one real individual, but a representation of the user from data that you have collected, so a short description about a particular persona might contain an amalgamation of real descriptions of real individuals, or it could be a wholly new description based on your interpretation of the real descriptions that you’ve obtained (Woah, that’s a mouthful!).

How do you create a persona/personas?

The first thing that you should do before creating a persona is to perform a research on the potential users that will use the product that you make. If you’ve done a stakeholder interview, you should have a rough idea of that. After you’ve known your potential users, you should collect information on them. One of the most popular ways to collect information on your potential users is from user interviews. The goal of collecting data is to understand the user’s goals for using your app, the frustrations that your app can solve, and the skills that the users currently have so that you can tailor the user interface with the purpose of making it easy to understand for them.

From the data that you collected, try to find data that overlaps between each person. From those overlapping data, you can then group them up and use that to help create a persona. The number of personas that you will create is based on the information of the potential users, and the data that you have collected.

Again, do keep in mind that a persona should roughly consist of these elements, but some of the elements may be omitted as needed:

  1. Photo: This will help build the virtual identity of the persona, and will help you more easily recognize it.
  2. Name: Each persona should have a unique name which represents it. This will help you refer to it in discussions and will help make your clients perceive that the personas are really the representations of real users.
  3. Biodata: Biographical data such as the average age, where they generally live and what their positions are wherever they work.
  4. Short Description: Summary of the persona
  5. Goals: The purpose of using the product that you will make.
  6. Frustrations: Real life problems that you can tailor your product to solve.
  7. Skills: What the user can do generally at this time.

Below is an example of the persona that we have created for our class project.

Annotation 2020-02-26 232450
Picture 1: Persona

In the above persona, you can see that we have concocted a name, an age, a job position, a short description of the user, goals, frustrations and skills (denoted as tech above). Included with the text is a picture that we took out of google images. It may look simple, but for the purposes of our project, this is enough.

I should mention that people that are unfamiliar with the concept of a persona will think that the above persona is a description of an actual person (at least our client thinks that it is). You should inform them that it is not an actual person and that it is a personification of data and a representation of the users that are likely to use whatever it is that you created the persona for (in our case it’s an application).

What do you do after you’ve created a persona/personas?

From this persona we can then chart a course with the end goal being the completion of the design of the product. From the goals that the persona above has, it is clear that we have to make an application that can help the persona create an exam schedule in a short period of time with the least effort possible. Therefore it is necessary that we make the program easy enough to navigate. But how easy should we make it?

Let’s look at the tech section of the persona, which represents the skills that a typical user will have. From that, we can see that it can use applications like Microsoft Word and web applications that we can assume are internally used in the workplace really well. Therefore, we can make an interface that is similar to those applications in design.

Now let’s look at the frustrations that a user of the application will typically have. From that we can know that creating a schedule without conflicts is difficult and revisions to exam schedules will increase the effort needed to create the schedules. You may have completely different solutions to these frustrations, but we decided that the generation of exam schedules must be done automatically to ensure that the schedule is always correct, and the user need not do anything other than setting a few parameters and pressing a few buttons.

b.png
Picture 2: Sample user interface that is designed with the help of a persona

Above is an example of the user interface of the app that we are creating. Since we have concluded above that we only want the user to set a few parameters and press a few buttons and we want to make it less time consuming, we made it so that the user only needs to perform six steps in order to generate a valid exam schedule, and the algorithm will take care of the rest. These steps are:

  1. Upload some files related to the generation of the schedule
  2. Click next
  3. Set up the range of dates when the exams will be held
  4. Increment / Decrement sessions per day as needed
  5. Choose in those ranges, the days when the exams will be held
  6. Click next

With this, generating a valid test schedule, assuming that the excel files have been prepped before, will take a maximum of around fifteen minutes.

What if we don’t use a persona?

By this time you may notice how we can easily think out how our application will be with the help of a Persona. Now let’s look at the disadvantages of not using a persona to help think out your designs.

The benefits of using a persona is that the application will be personalized according to the user’s frustrations, motivation and skills. Not using them could lead to the application not being personalized for those things. For small scale apps or apps that already have a predefined user interface, this may not be a problem. However, for large scale applications, this can lead to some detriments, such as (1) The app being not easy to use for the intended users, (2) The app not having the features that is actually needed and/or desired by any/all users (which can lead to a decrease in sales if the app that you are developing is a paid application) and lastly (3) a lack of a vision to help the design team focus on creating a design that works. This may, in turn, lead to increased development time due to the increased amount of revisions that is needed so that the app can actually be useful to the users, and usually UI revisions after a part of the software has been developed is harder to implement than UI revisions before any actual code is written.

That’s really why it has become standard practice for designers to create a persona before developing an actual design of the product. It shortens the time immensely and it eases the pain of development considerably. So, next time you want to create any product, create personas of your users first. Trust me, you’ll thank me for it