<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Блоги: заметки с тегом Software development</title>
<link>https://blogengine.me/blogs/tags/software-development/</link>
<description>Автоматически собираемая лента заметок, написанных в блогах на Эгее</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.0 (v4079e)</generator>

<itunes:subtitle>Автоматически собираемая лента заметок, написанных в блогах на Эгее</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Scrabble in C</title>
<guid isPermaLink="false">126033</guid>
<link>https://dsokolovskiy.com/blog/all/scrabble-in-c/</link>
<pubDate>Sun, 25 Feb 2024 18:38:13 +0500</pubDate>
<author>Daniel Sokolovskiy</author>
<comments>https://dsokolovskiy.com/blog/all/scrabble-in-c/</comments>
<description>
&lt;p&gt;&lt;a href="https://dsokolovskiy.com/blog/"&gt;Daniel Sokolovskiy&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;In the second week of &lt;a href="/blog/tags/cs50/"&gt;CS50&lt;/a&gt;, I was introduced to the notion of arrays and then given the following problem to solve as a practice:&lt;/p&gt;
&lt;div class="question"&gt;&lt;p&gt;In the game of &lt;a href="https://www.scrabblepages.com/scrabble/rules/"&gt;Scrabble&lt;/a&gt;, players create words to score points, and the number of points is the sum of the point values of each letter in the word. For example, if we wanted to score the word “CODE”, we would note that the ‘C’ is worth 3 points, the ‘O’ is worth 1 point, the ‘D’ is worth 2 points, and the ‘E’ is worth 1 point. Summing these, we get that “CODE” is worth 7 points.&lt;/p&gt;
&lt;p&gt;Implement a program in C that determines the winner of a short Scrabble-like game. Your program should prompt for input twice: once for “Player 1” to input their word and once for “Player 2” to input their word. Then, depending on which player scores the most points, your program should either print “Player 1 wins!”, “Player 2 wins!”, or “Tie!” (in the event the two players score equal points).&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;First, I outlined the general steps needed to solve this problem:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Get text inputs from the user;&lt;/li&gt;
&lt;li&gt;Calculate the score of each input;&lt;/li&gt;
&lt;li&gt;Show the winner.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the first step, I’ll creat two variables named &lt;i&gt;word1&lt;/i&gt; and &lt;i&gt;word2&lt;/i&gt; respectively, and assign each to the value of the respective user input using the &lt;i&gt;get_string&lt;/i&gt; function from the CS50 library:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;#include &amp;lt;cs50.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(void)
{
    // Prompt the user for two words
    string word1 = get_string(&amp;quot;Player 1: &amp;quot;);
    string word2 = get_string(&amp;quot;Player 2: &amp;quot;);

    // Compute the score of each word

    // Print the winner
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That was easy. The trickiest part here, of course, is the second step, which is to assign each letter of the alphabet its unique score points value.&lt;/p&gt;
&lt;p&gt;Here are the values:&lt;/p&gt;
&lt;div class="e2-text-table"&gt;
&lt;table cellpadding="0" cellspacing="0" border="0"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;A&lt;/td&gt;
&lt;td style="text-align: center"&gt;B&lt;/td&gt;
&lt;td style="text-align: center"&gt;C&lt;/td&gt;
&lt;td style="text-align: center"&gt;D&lt;/td&gt;
&lt;td style="text-align: center"&gt;E&lt;/td&gt;
&lt;td style="text-align: center"&gt;F&lt;/td&gt;
&lt;td style="text-align: center"&gt;G&lt;/td&gt;
&lt;td style="text-align: center"&gt;H&lt;/td&gt;
&lt;td style="text-align: center"&gt;I&lt;/td&gt;
&lt;td style="text-align: center"&gt;J&lt;/td&gt;
&lt;td style="text-align: center"&gt;K&lt;/td&gt;
&lt;td style="text-align: center"&gt;L&lt;/td&gt;
&lt;td style="text-align: center"&gt;M&lt;/td&gt;
&lt;td style="text-align: center"&gt;N&lt;/td&gt;
&lt;td style="text-align: center"&gt;O&lt;/td&gt;
&lt;td style="text-align: center"&gt;P&lt;/td&gt;
&lt;td style="text-align: center"&gt;Q&lt;/td&gt;
&lt;td style="text-align: center"&gt;R&lt;/td&gt;
&lt;td style="text-align: center"&gt;S&lt;/td&gt;
&lt;td style="text-align: center"&gt;T&lt;/td&gt;
&lt;td style="text-align: center"&gt;U&lt;/td&gt;
&lt;td style="text-align: center"&gt;V&lt;/td&gt;
&lt;td style="text-align: center"&gt;W&lt;/td&gt;
&lt;td style="text-align: center"&gt;X&lt;/td&gt;
&lt;td style="text-align: center"&gt;Y&lt;/td&gt;
&lt;td style="text-align: center"&gt;Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;8&lt;/td&gt;
&lt;td style="text-align: center"&gt;5&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;10&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;8&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Now that I know about arrays, I can create an array called &lt;i&gt;points&lt;/i&gt; with a size of 26 and the type of integer, and assign values as follows:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;#include &amp;lt;cs50.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(void)
{
    // Prompt the user for two words
    string word1 = get_string(&amp;quot;Player 1: &amp;quot;);
    string word2 = get_string(&amp;quot;Player 2: &amp;quot;);

    // Compute the score of each word
    int points[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};

    // Print the winner
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I don’t quite like the length of that like, but it seems there is not much to do about it since all values are set by the rules of the game.&lt;/p&gt;
&lt;p&gt;Now that I know a little bit about functions too, I’ll create a separate function for computing the score. This should make the code more efficient and better designed, especially since I need to use it twice for calculating the score for each word.&lt;/p&gt;
&lt;p&gt;I’ll call this function &lt;i&gt;calculate_score&lt;/i&gt;, with one input parameter of the type of string, and output of integer. I can also straight away create a variable called &lt;i&gt;score&lt;/i&gt; with the type of integer, as this is ultimately what I want to get from this function:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;int calculate_score(string word)
{
    int score = 0;

    return score;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, the big question is how to assign each letter a corresponding score value. Well, turns out that every string is basically just an array of characters. Let’s take the word CODE as an example. We can imagine it as an array as follows, keeping in mind the zero-based indexing of arrays, i.e. starting counting from 0:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;c word[i]
word[0] = C
word[1] = O
word[2] = D
word[3] = E&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Knowing this, I can create a loop to ‘scan’ through the word character by character. For this loop to work, I would to know the length of the word, and luckily such a function already exists in the &lt;i&gt;string.h&lt;/i&gt; library and is called &lt;i&gt;strlen&lt;/i&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;for (int i = 0; i &amp;lt; strlen(word); i++)
{
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What I don’t quite like about this loop though, is that every time it works, it makes the function repeat that many times. To optimise this, let me create another variable called &lt;i&gt;len&lt;/i&gt; with its value equal to the length of a word, and then use this variable as the condition of the loop:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;for (int i = 0, len = strlen(word); i &amp;lt; len; i++)
{
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, how to make the loop ‘know’ which score value corresponds to each letter? There is actually a trick that still blows my mind even after completing this task. Since every character has its numeric value in the &lt;a href="https://www.w3schools.com/charsets/ref_html_ascii.asp"&gt;ASCII code&lt;/a&gt;, we can use this information to ‘offset’ characters from one array to another and this way map them together.&lt;/p&gt;
&lt;p&gt;Let’s take the capital letter ‘C’ from the word CODE as I used the example. Its numeric value in ASCII is 67, and the trick is to subtract the value of the letter A, which equals 65. Why A? Because it’s the first letter of the alphabet, and if we subtract it from another letter, we’ll know its place in the array. So &lt;i&gt;67 – 65 = 2&lt;/i&gt;, and that is exactly the index number we need from the &lt;i&gt;points&lt;/i&gt; array.&lt;/p&gt;
&lt;p&gt;To make it more visual, here is a similar exercise for all letters of the word CODE:&lt;/p&gt;
&lt;div class="e2-text-table"&gt;
&lt;table cellpadding="0" cellspacing="0" border="0"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Letter&lt;/td&gt;
&lt;td style="text-align: center"&gt;ASCII&lt;/td&gt;
&lt;td style="text-align: left"&gt;Index&lt;/td&gt;
&lt;td style="text-align: right"&gt;Points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;C&lt;/td&gt;
&lt;td style="text-align: center"&gt;67&lt;/td&gt;
&lt;td style="text-align: left"&gt;67 – 65 = [2]&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;O&lt;/td&gt;
&lt;td style="text-align: center"&gt;79&lt;/td&gt;
&lt;td style="text-align: left"&gt;79 – 65 = [14]&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;D&lt;/td&gt;
&lt;td style="text-align: center"&gt;68&lt;/td&gt;
&lt;td style="text-align: left"&gt;68 – 65 = [3]&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;E&lt;/td&gt;
&lt;td style="text-align: center"&gt;69&lt;/td&gt;
&lt;td style="text-align: left"&gt;69 – 65 = [4]&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;... which means the word CODE gives the Scrabble score of 7 (as 3 + 1 + 2 +1), and that is indeed correct. It works like a charm!&lt;/p&gt;
&lt;p&gt;To make array indexing a little more obvious, I’ll add it to the score table too:&lt;/p&gt;
&lt;div class="e2-text-table"&gt;
&lt;table cellpadding="0" cellspacing="0" border="0"&gt;
&lt;tr&gt;
&lt;td&gt;Letter:&lt;/td&gt;
&lt;td style="text-align: center"&gt;A&lt;/td&gt;
&lt;td style="text-align: center"&gt;B&lt;/td&gt;
&lt;td style="text-align: center"&gt;C&lt;/td&gt;
&lt;td style="text-align: center"&gt;D&lt;/td&gt;
&lt;td style="text-align: center"&gt;E&lt;/td&gt;
&lt;td style="text-align: center"&gt;F&lt;/td&gt;
&lt;td style="text-align: center"&gt;G&lt;/td&gt;
&lt;td style="text-align: center"&gt;H&lt;/td&gt;
&lt;td style="text-align: center"&gt;I&lt;/td&gt;
&lt;td style="text-align: center"&gt;J&lt;/td&gt;
&lt;td style="text-align: center"&gt;K&lt;/td&gt;
&lt;td style="text-align: center"&gt;L&lt;/td&gt;
&lt;td style="text-align: center"&gt;M&lt;/td&gt;
&lt;td style="text-align: center"&gt;N&lt;/td&gt;
&lt;td style="text-align: center"&gt;O&lt;/td&gt;
&lt;td style="text-align: center"&gt;P&lt;/td&gt;
&lt;td style="text-align: center"&gt;Q&lt;/td&gt;
&lt;td style="text-align: center"&gt;R&lt;/td&gt;
&lt;td style="text-align: center"&gt;S&lt;/td&gt;
&lt;td style="text-align: center"&gt;T&lt;/td&gt;
&lt;td style="text-align: center"&gt;U&lt;/td&gt;
&lt;td style="text-align: center"&gt;V&lt;/td&gt;
&lt;td style="text-align: center"&gt;W&lt;/td&gt;
&lt;td style="text-align: center"&gt;X&lt;/td&gt;
&lt;td style="text-align: center"&gt;Y&lt;/td&gt;
&lt;td style="text-align: center"&gt;Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Score:&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;8&lt;/td&gt;
&lt;td style="text-align: center"&gt;5&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;10&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;8&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index:&lt;/td&gt;
&lt;td style="text-align: center"&gt;0&lt;/td&gt;
&lt;td style="text-align: center"&gt;1&lt;/td&gt;
&lt;td style="text-align: center"&gt;2&lt;/td&gt;
&lt;td style="text-align: center"&gt;3&lt;/td&gt;
&lt;td style="text-align: center"&gt;4&lt;/td&gt;
&lt;td style="text-align: center"&gt;5&lt;/td&gt;
&lt;td style="text-align: center"&gt;6&lt;/td&gt;
&lt;td style="text-align: center"&gt;7&lt;/td&gt;
&lt;td style="text-align: center"&gt;8&lt;/td&gt;
&lt;td style="text-align: center"&gt;9&lt;/td&gt;
&lt;td style="text-align: center"&gt;10&lt;/td&gt;
&lt;td style="text-align: center"&gt;11&lt;/td&gt;
&lt;td style="text-align: center"&gt;12&lt;/td&gt;
&lt;td style="text-align: center"&gt;13&lt;/td&gt;
&lt;td style="text-align: center"&gt;14&lt;/td&gt;
&lt;td style="text-align: center"&gt;15&lt;/td&gt;
&lt;td style="text-align: center"&gt;16&lt;/td&gt;
&lt;td style="text-align: center"&gt;17&lt;/td&gt;
&lt;td style="text-align: center"&gt;18&lt;/td&gt;
&lt;td style="text-align: center"&gt;19&lt;/td&gt;
&lt;td style="text-align: center"&gt;20&lt;/td&gt;
&lt;td style="text-align: center"&gt;21&lt;/td&gt;
&lt;td style="text-align: center"&gt;22&lt;/td&gt;
&lt;td style="text-align: center"&gt;23&lt;/td&gt;
&lt;td style="text-align: center"&gt;24&lt;/td&gt;
&lt;td style="text-align: center"&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This system doesn’t quite work for the lowercase letters though, because the ASCII values of the lowercase letters are different from the capital letters. However, it simply means that we need to subtract the value of the lowercase letter ‘a’ instead of the capital ‘A’.&lt;/p&gt;
&lt;p&gt;So it seems I need an &lt;i&gt;if statement&lt;/i&gt; within the loop to calculate the score depending on the case of the letters using &lt;i&gt;isupper&lt;/i&gt; and &lt;i&gt;islower&lt;/i&gt; functions from the &lt;i&gt;ctype.h&lt;/i&gt; library, which I’ll include in the header too:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;int calculate_score(string word)
{
    // Keep track of the score
    int score = 0;

    // Compute the score for each character
    for (int i = 0, len = strlen(word); i &amp;lt; len; i++)
    {
        if (isupper(word[i]))
        {
            score += points[word[i] - 'A'];
        }
        else if (islower(word[i]))
        {
            score += points[word[i] - 'a'];
        }
    }
    return score;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since I’m using the &lt;i&gt;points&lt;/i&gt; array in this function, I need to move it out from the main’s local scope to the global scope. The rest is easy: all I need to do is to call the function &lt;i&gt;calculate_score&lt;/i&gt; (twice, for each word) and then compare players’ scores to determine the winner.&lt;/p&gt;
&lt;p&gt;And here is my final code:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;#include &amp;lt;cs50.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

// points assigned to each letter of the alphabet
int points[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};

int calculate_score(string word);

int main(void)
{
    // Prompt the user for two words
    string word1 = get_string(&amp;quot;Player 1: &amp;quot;);
    string word2 = get_string(&amp;quot;Player 2: &amp;quot;);

    // Compute the score of each word
    int score1 = calculate_score(word1);
    int score2 = calculate_score(word2);

    // Print the winner
    if (score1 &amp;gt; score2)
    {
        printf(&amp;quot;Player 1 wins!\n&amp;quot;);
    }
    else if (score1 &amp;lt; score2)
    {
        printf(&amp;quot;Player 2 wins!\n&amp;quot;);
    }
    else
    {
        printf(&amp;quot;Tie!\n&amp;quot;);
    }
}

int calculate_score(string word)
{
    // Keep track of the score
    int score = 0;

    // Compute the score for each character
    for (int i = 0, len = strlen(word); i &amp;lt; len; i++)
    {
        if (isupper(word[i]))
        {
            score += points[word[i] - 'A'];
        }
        else if (islower(word[i]))
        {
            score += points[word[i] - 'a'];
        }
    }
    return score;
}&lt;/code&gt;&lt;/pre&gt;</description>
</item>

<item>
<title>Fixed deadlines, flexed scopes</title>
<guid isPermaLink="false">120535</guid>
<link>https://dsokolovskiy.com/blog/all/fixed-deadlines-flexed-scopes/</link>
<pubDate>Sat, 18 Feb 2023 23:51:28 +0500</pubDate>
<author>Daniel Sokolovskiy</author>
<comments>https://dsokolovskiy.com/blog/all/fixed-deadlines-flexed-scopes/</comments>
<description>
&lt;p&gt;&lt;a href="https://dsokolovskiy.com/blog/"&gt;Daniel Sokolovskiy&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;In the recent episode of The Rework Podcast titled &lt;a href="https://37signals.com/podcast/your-estimates-suck/" class="nu"&gt;“&lt;u&gt;Your Estimates Suck&lt;/u&gt;”&lt;/a&gt;, David Heinemeier Hansson and Jason Fried, the co-founders of 37signals, discussed an exciting technique that allows their company to be productive. 37signals is a software development company, so the discussion was related to that topic, but I think you can use this approach in many other areas in general.&lt;/p&gt;
&lt;p&gt;So the premise is that people are terrible at estimating how long it takes to complete a particular task if it includes any novelty. If you make something cookie-cutter for the tenth time, you might be somewhat decent in your estimations but still not perfect. And if the process includes any form of creativity, making something new that you haven’t done before, then your estimates surely suck, as the podcast episode title suggests. And that’s okay; it’s just how our brains naturally work.&lt;/p&gt;
&lt;p&gt;In practice, in many companies, it works like that. Let’s say someone wants to make a website. Some person, a project manager or a developer, usually gives their estimate: “It will take us six weeks to build it”, for example. By the 4th week, the team realised they hadn’t done even a half because certain features took them longer than expected. So after negotiating with the client, which took another week, they decided to postpone the launch for a month to give the team more time. Then the same happens again and again, and eventually, the demoralised team built a product that no longer reflects the client’s needs. On top of that, the company or the client had to pay for this much more than initially estimated because time is money.&lt;/p&gt;
&lt;p&gt;I had experience working as a project manager in software development, so I know for a fact that my made-up example above is a pretty accurate illustration of what often happens in the industry.&lt;/p&gt;
&lt;p&gt;So how is David’s and Jason’s approach different? First, it starts with acknowledging that estimates are no better than guessing, and guesses are not a reliable source for planning weeks, months, and especially years ahead. Second, they fix the timeframe and the deadline and never change them. And third, they ship the product on time no matter what, even when the resulting product isn’t quite what was planned. Instead of delivering a set-in-stone product that would take an unknown amount of time to make, they set the deadline in stone and ship what they believe is the best version of that product possible to make during that timeframe. With this approach, they basically say, “let’s spend an X amount of time to solve this problem, and once X is passed, we are done”.&lt;/p&gt;
&lt;p&gt;Sounds controversial, right?&lt;/p&gt;
&lt;p&gt;The key here is that you cannot sacrifice quality. Things you deliver must be good. What you can discuss and possibly cut, though, is the scope. Going back to that website example, using this approach, they would ship it after six weeks, but probably with fewer features. And having fewer features is not necessarily a bad thing. What’s important is that the company or the client would have an actual, good working product exactly &lt;i&gt;when&lt;/i&gt; they wanted, even though the product might be slightly different. And that alone sometimes is enough to start generating profit or making decisions on further iterations based on real-life user interaction with your product rather than theorycrafting for months while your product is stuck in a never-ending “work in progress”.&lt;/p&gt;
&lt;p&gt;I believe that this mindset of fixed deadline rather than the scope might be helpful outside of software development in things like marketing, personal projects, or even music production.&lt;/p&gt;
&lt;p&gt;I’ve been hosting &lt;a href="/blog/tags/rave-podcast/"&gt;my monthly music podcast&lt;/a&gt; for more than a decade, and you know how often I would like to have &lt;i&gt;just a little bit more time&lt;/i&gt; to find some new tracks to include in the show? Every time, pretty much! Luckily, I have a fixed deadline, so I keep delivering new episodes every month, even though each episode usually isn’t as ideal as I would like it to be. I’m sure I wouldn’t make nearly as many episodes if I’d kept polishing each one until perfection.&lt;/p&gt;
&lt;p&gt;I think this paradigm of “fixed deadlines but flexed scopes” might be especially useful and act as a self-protective mechanism for creative work where it’s so tempting to keep working until a so-called “perfection” (which sometimes means infinite). And as they say, done is better than perfect.&lt;/p&gt;
</description>
</item>


</channel>
</rss>