<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Rendox</title>
    <description>The latest articles on DEV Community by Daniel Rendox (@danielrendox).</description>
    <link>https://dev.to/danielrendox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1050901%2Faab1bb56-2b61-4fb3-b3d9-6ea0b66292d4.jpg</url>
      <title>DEV Community: Daniel Rendox</title>
      <link>https://dev.to/danielrendox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danielrendox"/>
    <language>en</language>
    <item>
      <title>How to not mess up your first project</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Tue, 12 Mar 2024 15:02:20 +0000</pubDate>
      <link>https://dev.to/danielrendox/how-to-not-mess-up-your-first-project-35l7</link>
      <guid>https://dev.to/danielrendox/how-to-not-mess-up-your-first-project-35l7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; That’s simply not possible. We’re all humans so it’s hard to make something good on the first try. But it’s possible to minimize the number of mistakes and effectively fix everything later.&lt;/p&gt;

&lt;p&gt;I've recently completed writing my latest program, and I must say, it's one of the most decent ones I've ever created. However, it wasn’t without its challenges and I hit the wall quite a few times. This experience taught me several valuable lessons, which I'll be sharing in this article. Here, you won’t find a bunch of cliche advice from ChatGPT but rather practical insights gained from my mistakes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Thoroughly think over everything before writing any code
&lt;/h2&gt;

&lt;p&gt;The program I was working on is a habit-tracking app. Not a simple one though. The matter is, many habit trackers and planner apps out there do not work as I’d expect. When I miss completing the habit on a due date, I expect the program to tell me about this backlog later. And vice versa, when I complete a habit on a non-due day, I want the next scheduled occurrence to be canceled. So I created my own that does exactly that.&lt;/p&gt;

&lt;p&gt;It also calculates a habit streak. And after all calculations, it should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvab045u3rm4g68iwho0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvab045u3rm4g68iwho0l.png" alt="A screenshot from a habit tracker app displaying a January 2024 calendar used to monitor a fitness goal of ‘Go to the gym.’ Days are highlighted in dark green to indicate gym visits and in dark red to denote missed sessions. A lighter shades of green and red mark skipped days. The transition from green to red visually represents a break in the exercise streak." width="596" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sounds simple in theory but in reality, you’re gonna hit some major pitfalls. To determine habit dueness, it’s not enough to check whether it’s due on the current date or not. If the habit has been over-completed previously, we want to cancel the current occurrence. And if the habit was failed on a certain date, we can’t surely say it’s failed because this backlog may have been sorted out later. &lt;/p&gt;

&lt;p&gt;So how do we determine whether it’s actually due or not? By calculating the number of times it should’ve been completed and then comparing it with the actual number of completions? How do we calculate these numbers? By checking whether each date is due or not? Is it performant? How do we store all of these in a database? And remember that the results will be different depending on whether the given date is in the future or in the past. Finally, how do we then calculate streaks?&lt;/p&gt;

&lt;p&gt;So, instead of thinking over all of those, I decided to write the code first. And, honestly, it didn’t turn out well. 🫠 I ended up creating an architecture where &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it wasn’t possible to compute habit status for a certain date without affecting other dates;&lt;/li&gt;
&lt;li&gt;I had to compute everything up to the current date;&lt;/li&gt;
&lt;li&gt;and the worst part, all this was stored persistently so I had to somehow update everything every time something changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I won’t go into the details of how awfully everything was implemented, but trust me, it was simply unmanageable. &lt;/p&gt;

&lt;p&gt;That’s why we have to thoroughly think through every aspect of a project before touching the keyboard. While it might seem like a slower approach, I now understand that it leads to cleaner, more efficient code that is far easier to maintain and extend. Because it’s usually a lot more complicated than we think it is. Rushing to write the implementation will often lead to a huge amount of time spent for refactoring later. For this very reason, seniors spend a lot more time thinking than juniors.&lt;/p&gt;

&lt;p&gt;Also, our thoughts do not extend to every single edge case. That’s where AI comes into play! It’s a good thing to ask AI about that, especially if you don’t have anyone else to discuss it with. I discovered that just recently when I asked about my next project’s implementation. And it dropped some really good points, which I’d otherwise not consider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding features is easy, but maintaining them is hard
&lt;/h2&gt;

&lt;p&gt;Some functionality may not be as useful as it seems. I had to drop some of my app's features because they were not worth the effort. I learned to avoid adding or expanding features on a whim or without a clear purpose. Be a lazy developer!&lt;/p&gt;

&lt;p&gt;The thing is, even if some functionality seems easy to add, you have to remember that you will also have to maintain it, fix bugs, test and enhance it, integrate it with the rest of the app, optimize its performance, make sure it works on different devices, and so on. It will be frustrating if you eventually realize that you have to drop this functionality because it is not needed by the user or it actually hurts the user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow git best practices
&lt;/h2&gt;

&lt;p&gt;When I started working on my project, I didn't have a clear plan in mind. I was jumping from one task to another, resulting in a messy codebase because everything was done all at once. I ended up building on top of functionality that wasn’t working properly and wasn’t tested thoroughly. Debugging such a structure was also quite challenging. Not only could I not identify what wasn't working, but I also struggled to easily revert to the latest working state.&lt;/p&gt;

&lt;p&gt;What I've learned is that it's crucial to have a clear goal for each part of the project and to focus on one task at a time. After completing a small chunk of work, test it thoroughly — either manually or automatically — to ensure it functions correctly. Only then should you move on to the next task.&lt;/p&gt;

&lt;p&gt;This approach aligns perfectly with git best practices—making your commits small so that you can easily pinpoint the exact change that caused the issue. With this method, you’ll also be able to roll back to a previous commit without losing unrelated work.&lt;/p&gt;

&lt;p&gt;I also discovered the power of pull requests. They are not only useful for team projects but also for personal ones. While you would typically want to keep your commits as small as possible, you can gather them in a pull request to form a feature. This way, you’ll have a clear separation of what you’re working on.&lt;/p&gt;

&lt;p&gt;Whenever you start working on another feature, create a new branch and commit to it instead of committing directly to the main branch. And here’s the important part: you have to be confident in your code each time you hit the merge button. This ensures you don’t build further on top of broken code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40q6c5arhesqc300ci5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40q6c5arhesqc300ci5q.png" alt="Screenshot of Andrea's LinkedIn post. " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adopting this workflow has other benefits. For example, you can leverage AI code reviews by setting up a GitHub action that will automatically review your pull requests. This way, you can discover things you might otherwise be unaware of because, after all, we don’t know what we don’t know.&lt;/p&gt;

&lt;p&gt;This approach will also make it less tempting to make changes to unrelated code and instead focus on building the planned functionality. Follow the single responsibility principle!&lt;/p&gt;

&lt;p&gt;Additionally, I suggest documenting your changes by writing descriptive commit messages. You’ll thank yourself in the future because future you won’t necessarily remember those details. You can also provide more context in the pull request details than you can in commit descriptions including images and videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is actually an MVP
&lt;/h2&gt;

&lt;p&gt;Finally, I made it work. And now &lt;a href="https://github.com/DanielRendox/RoutineTracker" rel="noopener noreferrer"&gt;Routine Tracker&lt;/a&gt;’s code is clean and works properly. But here comes the last insight from building this program. &lt;/p&gt;

&lt;p&gt;When it was time to write the readme, I realized one important thing. I actually haven’t achieved the functionality I wanted to make initially. Apart from other habit-tracking apps, my app was supposed to display the habit’s progress and the estimated completion date. You see, I thought that I would first create a minimum viable product and then fill it with cool features. &lt;/p&gt;

&lt;p&gt;However, what I discovered too late was that an MVP doesn’t presume a project with minimum features. It presumes a project with minimum functionality &lt;strong&gt;that is required to test whether people find your idea useful&lt;/strong&gt;. So what kind of feedback can users give you if you provide an app that copies features from already existing projects and the only thing that differentiates your project is that it is immature and buggy? Instead, the MVP should contain those very features that set your app apart. In my case what I should’ve built first is habit’s progress and completion date estimation functionality.  &lt;/p&gt;

&lt;p&gt;How do you build those cool features if the foundation isn’t ready yet? The answer is in this tweet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2plyynmpm73s0x7joq40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2plyynmpm73s0x7joq40.png" alt="Florian Walther on Twitter: It can even make sense to start with a " width="755" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was so focused on making that core functionality work that I forgot about the very purpose of the app. 😅 That was fine though because its core functionality is also kinda non-trivial. &lt;/p&gt;

&lt;p&gt;Also, while pet projects are a playground for skill development, applying such business principles to them brings a whole new set of benefits. From faster development and preparation to a real-world scenario to these projects bringing more chances to give you a job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write the Readme first
&lt;/h2&gt;

&lt;p&gt;You may have noticed that I gained the last insight while writing the readme. Why? Because the readme is where we have to outline the mission of our project, how it achieves it, and what makes it unique. So I had an opportunity to better think about that in the final stage of development. Cool, but it’s not very smart. What if we turn things around and write the readme on the planning stage of the project before writing any code? This is called &lt;a href="https://tom.preston-werner.com/2010/08/23/readme-driven-development.html" rel="noopener noreferrer"&gt;Readme Driven Development&lt;/a&gt; and it’s not a new idea. &lt;/p&gt;

&lt;p&gt;This also makes it possible to receive some initial feedback by sending this readme to other people and asking what they think. &lt;/p&gt;

&lt;h2&gt;
  
  
  👋 Hi, I’m Daniel
&lt;/h2&gt;

&lt;p&gt;I’m a native Android developer. I’m currently focused on building a strong portfolio, improving my skills, and establishing an online presence. If you want to collaborate with me in any way, please let me know.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>7 Key Insights That Made Me A Better Developer</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Thu, 22 Feb 2024 17:56:52 +0000</pubDate>
      <link>https://dev.to/danielrendox/7-key-insights-that-made-me-a-better-developer-5bd3</link>
      <guid>https://dev.to/danielrendox/7-key-insights-that-made-me-a-better-developer-5bd3</guid>
      <description>&lt;p&gt;Throughout my software developer journey, I've had several "Aha!" moments, which made me take my skills to the next level. In this article, I'd like to share those realizations with you! I've arranged them in chronological order so that everything flows seamlessly from one topic to another. So we’re gonna start with the most newbie topic and then move to deeper insights.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to choose your first programming language
&lt;/h2&gt;

&lt;p&gt;I know that such decisions as choosing your first programming language are the most challenging ones. It’s like choosing what college program you’re gonna apply to, and what country you wanna move to. The challenge is that when you don’t know where to start, you just don’t know where to start. There is nothing you can do about that. Sadly, such confusion sometimes keeps people from starting in the first place.&lt;/p&gt;

&lt;p&gt;But the good part is that if you’re just starting out, you don’t have to care about that. Seriously, my first language was Java only because I wanted to learn some programming and found a free boot camp where I was supposed to learn Java. &lt;/p&gt;

&lt;p&gt;As a beginner, you need to understand that what actually matters is the tech stack you are working on. If you switch your tech stack, it’s almost a new world for you and you need to start all over again. But if you already know one programming language, it’s not an issue for you to learn another one. That means you can start by learning the essential concepts in any language you want and later decide which tech stack you want to proceed with.&lt;/p&gt;

&lt;p&gt;And that’s what I did. After getting the hang of Java, I decided to delve into the world of Android development. And nowadays, there is no way to thrive in the realm of Android without the knowledge of Kotlin. So I had to learn Kotlin and I’m happy to say it didn’t take long because I already knew Java at the moment. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But wait a second. Have you already chosen the area you want to specialize in? For some reason aspiring devs struggle with the language-question and seem to not even think about what kind of products they actually want to develop. That may be making web apps, desktop apps, mobile apps, making games, developing artificial intelligence, etc. There are many options. And there is no secret solution to this. You’ll have to pick something that just feels closer to your heart! Or use can my next advice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alright, but you are an intelligent developer. You don’t want to pick the language randomly, do you? Plus, how do you approach this problem when you’re already at the stage where you need to choose your tech stack? &lt;/p&gt;

&lt;p&gt;I think the most reasonable approach here is to choose one that will give you a job. So what I mean by that is you can research technologies for such factors as how many job openings there are, what are the salaries, what people think about the technology, what would they learn if they could start over, what are the trends, and so on. This way, you can figure out what is in demand and what is the most appropriate option for you. The situation may be different depending on where you live.&lt;/p&gt;

&lt;p&gt;You can start with such websites as &lt;a href="https://survey.stackoverflow.co/2023/" rel="noopener noreferrer"&gt;Stack Overflow Developer Survey&lt;/a&gt; or simply check out vacancies on LinkedIn, where you can also find out about the requirements for the job. In addition, you can find some sources that post info related to your location. For example, in Ukraine, we have &lt;a href="http://dou.ua" rel="noopener noreferrer"&gt;dou.ua&lt;/a&gt; that shares insightful statistics.&lt;/p&gt;

&lt;p&gt;And don’t just choose whatever is the most popular. If something is popular, it means that there is also a lot of competition for it. I used to be concerned that there aren't as many job openings for a native Android dev position as there are for, say, a web developer position. But if we think about it from another perspective, there also aren't nearly as many applicants. So mobile devs have much less competition now despite the saturated tech market.&lt;/p&gt;

&lt;p&gt;Or consider another situation. You wanted to learn Spring Boot for example, but then you did a research and found out that .NET is actually in higher demand in your region, and there is less competition for it. So this way, you can discover such things and make an optimal decision for yourself.&lt;/p&gt;

&lt;p&gt;The reason why I think choosing a technology that will give you a job is the best approach here is because you don’t have any personal preferences yet. Unfortunately, it’s impossible to determine whether you enjoy working with some technology or not before you dedicate a substantial amount of time to it. So job market demand is essentially the only decent criteria you have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The choice is everywhere!
&lt;/h2&gt;

&lt;p&gt;As you proceed in your programming journey you discover that choices are everywhere. You now need to choose between libraries, frameworks, and various coding practices. As much as there is choice, there are lots of people's opinions. For example, some people think native apps are better than cross-platform ones. Some people think that dynamically typed languages are preferable to statically typed languages. Some people think that doing everything in the command line is “the right way” of doing things. The list goes on and on.&lt;/p&gt;

&lt;p&gt;Of course, every technology is there for a reason. Each one aims to solve some specific problem. But when it comes to choosing which one you’ll use for your project, the choice usually depends on &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what kind of product one wants to make;&lt;/li&gt;
&lt;li&gt;the current state of the project;&lt;/li&gt;
&lt;li&gt;decisions that have been already made in the past;&lt;/li&gt;
&lt;li&gt;personal preferences of the team members.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See why these decisions are tricky for beginners? They usually don’t have enough information to make them. One can research about what is more appropriate for them. However, a big part of such decisions usually depends on the insights gained from real-world experience. Because the devil is in the details. No article, video, or tutorial will open up all the potential pitfalls that you can face if you use some framework or library.&lt;/p&gt;

&lt;p&gt;Programmers face these decisions every now and then. So how to deal with that? Well, IMO the wise approach for a beginner would be, again, choosing those technologies that they are more likely to use in the real job setting. For example, in Android development, these decisions are usually dictated by Google. Why is that? Because it is what is the first party, supported the most, and well documented. As a result, it's what people tend to use more often. &lt;/p&gt;

&lt;p&gt;For example, when developing an Android app, you need to use some navigation library. There is an official solution but it’s not mature enough to satisfy all the needs. Many developers hate the absence of type safety in the official library. And some use third-party solutions instead. Does it mean that it’s better to learn a third-party library instead of the official one? Absolutely not! Because no matter how good that library is, it can’t compare with the official solution in terms of documentation, support, and the number of people that know this technology. Regardless of how much better other solutions are, many people will still choose whatever is recommended in the official documentation. And this makes you much better off using it as well. Plus, you’ll not understand why it’s sometimes not suitable if you don’t even try applying it. &lt;/p&gt;

&lt;p&gt;The more experience you get, the wiser decisions you make. And remember: programmers can't agree on many topics so there is usually no “right approach”. “It depends” is usually the best answer in tech. In some cases, you will have to choose something that you feel is better, because you just don’t have any other criteria. This is cool too because you’ll get insights and form your own opinion about that. &lt;/p&gt;

&lt;p&gt;At a certain point, this gave me a lot of freedom because I understood I could essentially do anything I wanted. I’m not restricted to what some other guy on the web thinks is right. I can make my own decisions. As long as I’m responsible for them, of course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech is so opinionated!
&lt;/h2&gt;

&lt;p&gt;Due to human nature, we tend to become addicted to our favorite toolset and propagate it not admiring the benefits of others. In my experience, this approach is neither good in programming nor in life. So it’s sad to hear something like “&lt;a href="https://www.quora.com/Why-do-developers-hate-Python" rel="noopener noreferrer"&gt;Why Java programmers hate python&lt;/a&gt;?”&lt;/p&gt;

&lt;p&gt;Throughout my journey, I learned to ditch my personal preferences in a professional job setting and get out of my comfort zone. That’s because when you become addicted to your favourite tool set you stop developing and miss out on the opportunity to look at some things from another perspective. Programmers are lifelong learners and real programmers do not hate any technology. They understand that if something is the most optimal choice in their situation, they need to learn it and use it no matter whether they enjoy using it or not. &lt;/p&gt;

&lt;p&gt;It’s easier to say that to do and not fall into that trap, so I’m gonna provide an example. &lt;/p&gt;

&lt;p&gt;In mobile development, there is a term “native user experience” that typically requires a user interface that is native to a specific platform, super fast data loading, etc. In terms of user experience, websites usually can’t compete with that. However, in mobile development, we can instead use web views that essentially look the same as the mobile version of the website. But everything will get loaded a lot slower.&lt;/p&gt;

&lt;p&gt;So should I as a mobile developer propagate using native components? I should, but only if the business requires it. Because most of the time the goal of the business is to quickly get the product into the hands of the customers and only then think about the user experience. And in terms of speed of development, webviews are many times faster.&lt;/p&gt;

&lt;p&gt;I learned that from &lt;a href="https://www.donnfelker.com" rel="noopener noreferrer"&gt;Donn Felker&lt;/a&gt;. A person who was a native Android developer in the past now propagates the &lt;a href="https://www.donnfelker.com/native-where-you-need-it/" rel="noopener noreferrer"&gt;Native where you need it&lt;/a&gt; approach, which involves first building everything with webviews and then gradually replacing them with native components in the parts of the app that require that. &lt;/p&gt;

&lt;p&gt;So even though the web is not my area of specialty and it’s not what I like doing, shouldn’t I instead of arguing that native is better appreciate how convenient things are in web, how many developers know HTML, CSS, and JavaScript, and acknowledge the versatility they offer? &lt;/p&gt;

&lt;p&gt;If a customer approaches you requesting a project within your area of expertise, and you recommend another technology that would better suit their needs, rather than simply agreeing for the sake of earning money, I believe you demonstrate a higher level of professionalism. &lt;/p&gt;

&lt;p&gt;And as much as it’s not okay to hate some technology it’s also bad to become addicted to one. Better appreciate the whole variety of them and be eager to learn. &lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t get stuck in the rabbit hole of learning everything
&lt;/h2&gt;

&lt;p&gt;Tutorial hell is a common thing in tech. It happens because of people’s natural desire to stay in their comfort zone. Unfortunately, in our world, it’s hard to achieve something when you stay in your comfort zone. So in terms of learning programming, I think the #1 reason why tutorial hell happens is because one doesn’t want to make personal projects. This is absolutely convenient to stick to following some tutorials given that they indeed teach you stuff. But, as proven by science, we start to remember and understand something only when we question it or when we try to apply that in practice. &lt;/p&gt;

&lt;p&gt;For example, when it comes to learning a foreign language, I noticed that learners who don't rely on their tutor too much, have intrinsic motivation, and are willing to investigate something on their own become much more successful and do that in a shorter time than those who just go to some courses. &lt;/p&gt;

&lt;p&gt;There are areas in life where tutors are almost indispensable like in sports, dancing, acting, etc. And there are areas where the situation is completely the opposite, such as learning foreign languages and programming. Although mentors can save you lots of time by directing you in the right direction, creating a structured roadmap for you, and telling you what you don’t know, you can totally manage without the mentor.&lt;/p&gt;

&lt;p&gt;That's why I always propagate the practical approach to programming. Here is how it works. You certainly can’t manage without the foundation, so at the beginning, I recommend still following some tutorials or courses that can teach the main idea of how everything works. And I mean not when you are the absolute beginner, it may be that you have some development background in another area or another tech stack. But as soon as you get enough knowledge that allows you to build something simple, which can even be a command line app, think about what program you’d like to build and jump right into the development. Regardless of your unawareness about things like how to set up a database structure, how to make everything scalable, and how to apply the best practices. You’ll learn that on the go. And this will be the practical knowledge from the outset, no going deep into any rabbit holes.&lt;/p&gt;

&lt;p&gt;This approach also allows you to stress less about what you don’t know because you acquire the mindset that if it’s necessary, you’ll learn that fast. If I’m developing an app and I discover that I need to implement some functionality that requires some custom layouts, I won’t search for a course that will teach me everything about custom layouts. I will instead search for some quick tutorials or code snippets on the web and try to replicate them for my needs. And only if I discover that it’s not enough, I will investigate deeper. If I did otherwise, I’d probably spend a large amount of time learning something that I’d eventually forget because I wouldn’t use it that much. &lt;/p&gt;

&lt;p&gt;Even though I followed that paradigm throughout most of my learning journey I still fell into that trap at one point. I wanted to create an app but couldn’t start developing it because I thought I didn’t know enough. The matter is that you’ll never do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t be naive
&lt;/h2&gt;

&lt;p&gt;Everyone tends to run after new and shiny but I’ve come to realize that it’s usually not a good idea to be the first adopter of cutting-edge tech. The reasons are simple. Such technologies are immature, not thoroughly tested, and not well-documented. You can’t count on community support because too few people use it. And the devil is in the details so it may be a lot harder to implement some functionality than you think.&lt;/p&gt;

&lt;p&gt;But a more interesting thing is why everyone is obsessed with new and shiny. I think that’s because there is always hype around new technologies. It’s advantageous for content creators to follow the trends and post about something new. Few resources make a comprehensive overview of these things. They only highlight the benefits of the technology and usually leave out its drawbacks entirely. And if they do, they often either don't consider all of them or these drawbacks are far-fetched for the overview to look more competent. This is understandable though because you need to use something yourself in a real job setting to make informed decisions about it. So what we get is just hyping, which only results in the technology becoming more trendy. &lt;/p&gt;

&lt;p&gt;But have you ever wondered who creates this hype around new shiny? I noticed it’s often the creators themselves! You see, given the open-source nature of the tools we are using, I used to think that the main motivation for developing new tech is to make it better, simpler, and more effective. However, I have to remind you that, unfortunately, we are not living in the ideal world and few people are ready to invest lots of their time and resources for the genuine desire to make something better.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s usually business needs that drive the development of new tech. And usually, the main motivation for creating something new is to &lt;strong&gt;make money&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, every technology is there for a reason and each solves some specific problem. And yet the main motivation stays the same.&lt;/p&gt;

&lt;p&gt;For example, I used to not even question the appearance of Kotlin. It's such a pleasant language to work with. So I thought that as part of the continuous improvement of technology, people who learned from other languages saw the power of Java and decided to create a better version of it. Bullshit!&lt;/p&gt;

&lt;p&gt;What really happened was Google had billion-dollar-worth lawsuits with Oracle about Google’s use of Java APIs. So it became no longer reasonable for Google to heavily rely on Java. They needed to find a replacement for it and think about the backup for Android devs in case they lost these lawsuits. So they started creating Kotlin as a replacement for Java and developing Flutter, which is now a cross-platform mobile framework.&lt;/p&gt;

&lt;p&gt;So rather than blindly chasing the latest trends, evaluate whether adopting new tech aligns with your own goals and needs. I know these things feel nowel and exciting but we must be pragmatic. List all the pros and cons to adequately decide whether it's worth using that technology or not. Then bring these arguments to the team to decide on the implementation together. &lt;/p&gt;

&lt;h2&gt;
  
  
  Al will replace developers 🤩
&lt;/h2&gt;

&lt;p&gt;There was an event in my country called Junior Online Conference. Speakers from different tech backgrounds were invited: backend, frontend, DevOps, test automation, etc. But there was one speaker named Lukasz Fliegel &lt;a href="https://www.youtube.com/live/3T8p8AafBVk?si=Nfi9Bup68c9rgVuM&amp;amp;t=9517" rel="noopener noreferrer"&gt;whose talk&lt;/a&gt; resonated with me the most.&lt;/p&gt;

&lt;p&gt;He brought up the concept of &lt;a href="https://www.amazon.com/Antifragile-Things-That-Disorder-Incerto/dp/0812979680" rel="noopener noreferrer"&gt;Antifragility&lt;/a&gt; and how it can help one become a better software developer. The idea is that while fragile things break easily and durable things remain unaffected by damage when something is antifragile, it actually gets better when subjected to chaos or disruption.&lt;/p&gt;

&lt;p&gt;Luckily, humans are antifragile. For instance, when you engage in physical exercise, whether it's weightlifting, running, or any form of physical activity, your body experiences stress. This stress breaks down muscle fibers, causing temporary discomfort or soreness. However, as you recover, your muscles rebuild themselves to become stronger than they were before. Apart from fitness, this works in many other areas of our lives, including programming.&lt;/p&gt;

&lt;p&gt;Now, whenever I hear such things as AI will replace developers, it’s impossible to find a job in the current tech market, Java is gone, native Android development will be replaced by web and cross-platform technologies, and so on, I perceive this as an opportunity for me to learn and grow. I don’t deny that AI can indeed replace many developers in the future and that the job market is indeed hard right now. But I’m sure that my antifragility will not let me down. Because I’m willing to improve, learn new things, and get out of my comfort zone.  And even in the worst-case scenario, I’ll find a way to solve my problems somehow.&lt;/p&gt;

&lt;p&gt;Sadly, instead, many developers adopt the “whiner” mindset where they complain about literally every problem that exists in tech. But I don’t get it! I think his mindset is exactly what keeps people from achieving their goals.&lt;/p&gt;

&lt;p&gt;Later on in the talk, Lukasz was asked what he thought about the future of developer jobs given the rapid development of AI. And he just said something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don’t know. I don’t like to predict the future. Actually, I don’t think one should be even worried about this because we anyway can’t change anything with our concerns. Right now there’s need for software developers. If that changes in the future, being antifragile will already put you in the better position than your competitors. And if I am affected by a drastic decrease in job positions, I’ll probably do something else. Attending dance lessons, maybe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can add that in the case of such a worst-case scenario, dance lessons are not the only option out there. Food delivery, taxi driving, and barista positions offer plenty of opportunities as well. Just kidding. 😁 &lt;/p&gt;

&lt;p&gt;Of course, following stoic principles alone will not help much. But I hope you get the point here. It can be tough at times. Don’t give up and be patient. I believe if you love what you’re doing, success becomes inevitable over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect with people
&lt;/h2&gt;

&lt;p&gt;I noticed that many developers consider themselves introverts. And I can hear that from those who attend events, network online, post blogs, do open source, etc. So if these people are introverts, it’s logical to presume that there are even more introverted people who we are unaware about because they do not open themselves up to the world in any way.&lt;/p&gt;

&lt;p&gt;When we are starting, we overestimate our abilities due to the unawareness of how difficult some things are and how much time they take to develop. Developing some big things like a social media app with backend, frontend, and mobile is as complex as building a house using your own hands. And even if you manage to build the whole structure, you then need to maintain it, make sure it works properly, make everything scalable, market the app, process the feedback received from the users, and so on. Also don’t forget about such things as design and legal stuff. So it’s just impossible to make everything yourself.&lt;/p&gt;

&lt;p&gt;Therefore, it’s crucial to develop soft skills and learn how to work in a team. Effective networking and collaboration also make one’s growth multiple times faster. And it’s actually a lot easier than it seems. There are many ways you can socialize.&lt;/p&gt;

&lt;p&gt;Apart from passing tutorials and codelabs I also started listening to technical podcasts, attending online events, and communities and it was so much fun! I got lots of valuable advice, which I’m now sharing with you in this very article, BTW. I found out that I was not the only one who had certain problems. Oftentimes, we don’t know what we don’t know. So this a great way to find out about such things. This way you can also stay updated with the latest trends. &lt;/p&gt;

&lt;p&gt;Entering a university turned out to be a great way of socializing too. You can find like-minded people and potentially team up with them to work on a project. I think it works with boot camps too, doesn’t it? &lt;/p&gt;

&lt;p&gt;Posting on Twitter/X was a game changer for some people. You’re networking, sharing your knowledge, getting insights from others, becoming noticed in tech, and showing yourself as a great candidate. With the recent changes though, LinkedIn became a much better social network by a quality of content alone. Nowadays, you'll find it far easier to gain popularity and visibility on LinkedIn compared to Twitter/X. &lt;/p&gt;

&lt;p&gt;I also started posting on DEV just because I had something to share, and wanted to share that. And now people say “You have your own blog? Cool!” Putting yourself out there is a great way to get noticed, especially in the current time when one needs to do things above average.&lt;/p&gt;

&lt;p&gt;Putting myself out there is one of the first goals on my priority list right now. So, if you enjoyed this article, I bet you’ll enjoy the one coming up next week. And let's connect on &lt;a href="https://www.linkedin.com/in/danielrendox/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading. All the best!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>learning</category>
      <category>advice</category>
    </item>
    <item>
      <title>AI-Powered Pull Requests: CodiumAI vs GitHub Copilot</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Thu, 21 Dec 2023 19:24:07 +0000</pubDate>
      <link>https://dev.to/danielrendox/ai-powered-pull-requests-codiumai-vs-github-copilot-35d0</link>
      <guid>https://dev.to/danielrendox/ai-powered-pull-requests-codiumai-vs-github-copilot-35d0</guid>
      <description>&lt;p&gt;In the past year, AI has become an essential part of developers’ lives. Back then, it could only write simple code snippets, now it can analyze and refactor whole codebases. With the rapid development of AI, we’ve raised our expectations and we’re now waiting for something even better.&lt;/p&gt;

&lt;p&gt;With our eyes on the horizon for the next features in &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Copilot X&lt;/a&gt;, a representative from CodiumAI reached out to me, suggesting the creation of an article showcasing features that we can try out right away. Particularly an AI copilot for writing and reviewing pull requests.&lt;/p&gt;

&lt;p&gt;Imagine there was an AI copilot that could help in describing PR changes, reviewing them, and suggesting improvements to them. The life of many open-source contributors and maintainers could be so much easier. Well, &lt;a href="https://www.codium.ai/products/git-plugin/" rel="noopener noreferrer"&gt;CodiumAI PR-Agent&lt;/a&gt; is exactly that tool!&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Alright, so here’s how it works. Add a comment to any public pull request on GitHub with the following text:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@CodiumAI-Agent /review


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;After ~30 seconds you’ll see a comment from &lt;strong&gt;&lt;a href="https://github.com/CodiumAI-Agent" rel="noopener noreferrer"&gt;CodiumAI-Agent&lt;/a&gt;&lt;/strong&gt; with bullet points about the PR (such as theme, summary, type, estimated effort to review, etc.) and some feedback on it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the same way, you can replace &lt;code&gt;/review&lt;/code&gt; with one of many other commands to get various descriptions, suggestions, and feedback from the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write better PR descriptions with the help of AI
&lt;/h2&gt;

&lt;p&gt;Find me a developer who had dedicated a substantial amount of time to implementing a feature or resolving a challenging bug and then didn’t feel want to finally send the code to production. In that moment of exhaustion, all you want to do is hit the merge button and take a well-deserved break. &lt;/p&gt;

&lt;p&gt;Although it’s quite understandable, this often results in PRs like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fixed some things&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I made some changes to improve the data processing in the &lt;code&gt;data_handler.py&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn’t provide any specific details about what improvements were made. The pull request lacks context about the motivation behind the changes. Neither does it mention whether the changes have been tested.&lt;/p&gt;

&lt;p&gt;Both GitHub Copilot and CodiumAI aim to fix this problem by generating PR descriptions with a summary and a detailed list of changes.&lt;/p&gt;

&lt;p&gt;Let’s take the previous example, where I had a pull request that improves the logic of habit status computation in a habit-tracking app. Here’s the CodiumAI Agent’s review of the PR:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;PR Analysis&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;
        &lt;ul&gt;
          &lt;li&gt;🎯 &lt;strong&gt;Main theme:&lt;/strong&gt; Refactoring and improving the logic of habit status computation&lt;/li&gt;
          &lt;li&gt;📝 &lt;strong&gt;PR summary:&lt;/strong&gt; This PR refactors the 'Routine' class to 'Habit' and rewrites the logic of habit status computation. It replaces 'HistoricalStatus' and 'PlanningStatus' with 'HabitStatus' and adds additional statuses for clarity. The computation of historical and future statuses is now done on the go instead of being cached in the database.&lt;/li&gt;
          &lt;li&gt;📌 &lt;strong&gt;Type of PR:&lt;/strong&gt; Enhancement&lt;/li&gt;
          &lt;li&gt;🧪 &lt;strong&gt;Relevant tests added:&lt;/strong&gt; No&lt;/li&gt;
          &lt;li&gt;⏱️ &lt;strong&gt;Estimated effort to review [1-5]:&lt;/strong&gt; 4, because the PR contains a significant amount of changes in the logic of habit status computation and renaming of classes and variables, which requires a thorough understanding of the existing codebase to review effectively.&lt;/li&gt;
          &lt;li&gt;🔒 &lt;strong&gt;Security concerns:&lt;/strong&gt; No security concerns found&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;First, it determines the main theme, which may serve as a title. It suggests the PR summary that indeed matches what is done. Then, it determines the type of PR and whether the relevant tests were added. In addition, it estimates the effort to review and tells if there are any security concerns.&lt;/p&gt;

&lt;p&gt;If you choose one of the different ways to use the agent, which we’ll cover later on in the article, it will be able to automatically update the title and description and also add labels to the PR. Use &lt;code&gt;/describe&lt;/code&gt; command for that:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;CodiumAI’s PR-Agent can also write a detailed list of changes and update your &lt;code&gt;CHANGELOG.md&lt;/code&gt;. For that, use the &lt;code&gt;update_changelog&lt;/code&gt; command:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;Among the mentioned features, GitHub Copilot’s abilities are limited to crafting titles and descriptions with the help of &lt;code&gt;copilot:summary&lt;/code&gt;. It also can write a detailed list of changes through &lt;code&gt;copilot:walkthrough&lt;/code&gt; command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get feedback and suggestions
&lt;/h2&gt;

&lt;p&gt;Alongside PR analysis, the agent gave the following PR feedback upon running the &lt;code&gt;/review&lt;/code&gt; command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;General suggestions:&lt;/strong&gt; The PR includes a significant amount of refactoring and changes in the logic of habit status computation. It would be beneficial to include unit tests to ensure the new logic works as expected and to prevent potential regressions in the future. Additionally, it would be helpful to provide more context in the PR description about why these changes were necessary and how they improve the codebase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what it’s just done is address two main issues that may prevent this pull request from being merged: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The PR does not include unit tests.&lt;/li&gt;
&lt;li&gt;The motivation behind the changes is missing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally, it provided detailed code feedback with references to specific files and even lines of code:&lt;/p&gt;

&lt;p&gt;
  🤖 &lt;strong&gt;Code feedback&lt;/strong&gt;
  

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;relevant file&lt;/th&gt;
&lt;th&gt;core/database/src/main/java/com/rendox/routinetracker/core/database/routine/RoutineLocalDataSourceImpl.kt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;suggestion&lt;/td&gt;
&lt;td&gt;Consider using a data mapping layer or a mapper function to convert between the database entity and the domain model. This can help to keep the conversion logic in one place and make the code more maintainable. [important]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;relevant line&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-96a0c9cda6be7f77af13589758d30c625a761d0b1aca0e4fc5980b966fb8baecR13" rel="noopener noreferrer"&gt;https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-96a0c9cda6be7f77af13589758d30c625a761d0b1aca0e4fc5980b966fb8baecR13&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;relevant file&lt;/th&gt;
&lt;th&gt;core/domain/src/main/java/com/rendox/routinetracker/core/domain/completion_history/use_cases/GetRoutineStatusUseCase.kt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;suggestion&lt;/td&gt;
&lt;td&gt;It would be better to separate the logic of prepopulating history with missing dates into a separate function or use case. This would make the code more modular and easier to test. [important]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;relevant line&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-a8044fd1c82f20ee81e28bdab1ff37151be709abc2ce52f5d96fba1e645de6f6R58" rel="noopener noreferrer"&gt;https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-a8044fd1c82f20ee81e28bdab1ff37151be709abc2ce52f5d96fba1e645de6f6R58&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;relevant file&lt;/th&gt;
&lt;th&gt;core/domain/src/test/java/com/rendox/routinetracker/core/domain/routine/schedule/ScheduleIsDueTest.kt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;suggestion&lt;/td&gt;
&lt;td&gt;Consider using parameterized tests or data-driven tests for testing the same logic with different inputs. This can help to reduce the amount of repetitive test code and make the tests more readable. [medium]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;relevant line&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-41e217a89b141d2ec28631d7767ce69b186ef4bdb61ded70ad6e5af91af09007R4" rel="noopener noreferrer"&gt;https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-41e217a89b141d2ec28631d7767ce69b186ef4bdb61ded70ad6e5af91af09007R4&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;relevant file&lt;/th&gt;
&lt;th&gt;core/domain/src/main/java/com/rendox/routinetracker/core/domain/completion_history/use_cases/GetRoutineStatusUseCase.kt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;suggestion&lt;/td&gt;
&lt;td&gt;Consider using a strategy pattern or a similar design pattern for computing future statuses. This can help to make the code more flexible and easier to extend in the future. [medium]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;relevant line&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-a8044fd1c82f20ee81e28bdab1ff37151be709abc2ce52f5d96fba1e645de6f6R90" rel="noopener noreferrer"&gt;https://github.com/DanielRendox/RoutineTracker/pull/4/files#diff-a8044fd1c82f20ee81e28bdab1ff37151be709abc2ce52f5d96fba1e645de6f6R90&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;/p&gt;




&lt;p&gt;But hold on, there is something even more impressive. You can ask follow-up questions! Check this out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvu7v0dtufyelf1d9coy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvu7v0dtufyelf1d9coy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Moreover, it can also modify the code that needs to be improved with the help of the &lt;code&gt;improve&lt;/code&gt; command. This can be something simple such as a naming inconsistency that your IDE has not been able to detect:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rename the variable 'routineId' to 'habitId' to match the new naming convention:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Existing code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 Kotlin
val previousStreak = streakRepository.getStreakByDate(
    routineId = habit.id!!,
    dateWithinStreak = date.minus(DatePeriod(days = 1)),
)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Improved code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 Kotlin
val previousStreak = streakRepository.getStreakByDate(
    habitId = habit.id!!,
    dateWithinStreak = date.minus(DatePeriod(days = 1)),
)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or it may point to a missing test case:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6tu6jqrg8kmmtzuegnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6tu6jqrg8kmmtzuegnc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Isn’t that cool? It now motivates me to submit pull requests for my personal projects, where I'm the only contributor because there is no one else to review my code. &lt;/p&gt;

&lt;p&gt;With all this automatic feedback, people can not only learn how to write good pull requests but also learn about programming practices that they might otherwise overlook. Take, for instance, one of the code feedback suggestions that recommended utilizing parameterized tests. One might be unaware that such a thing exists. &lt;/p&gt;

&lt;p&gt;GitHub Copilot currently does not provide any of the functionality described in this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even more commands!
&lt;/h2&gt;

&lt;p&gt;Unlike Copilot, CodiumAI also supports commands like: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;similar_issue&lt;/code&gt;: retrieves and presents similar issues;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;generate_labels&lt;/code&gt;: suggests custom labels based on the PR code changes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add_doc&lt;/code&gt;: adds documentation to undocumented functions/classes.&lt;/p&gt;

&lt;p&gt;Moreover, commands can be appended with a parameter from the &lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml" rel="noopener noreferrer"&gt;configuration.toml&lt;/a&gt; file. For example,&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;/describe --extra_instructions = "Emphasize that ..."&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Supported platforms and different ways to use&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;For simple usage, it may be enough to call &lt;code&gt;@CodiumAI-Agent&lt;/code&gt; every time. However, this approach has several limitations, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple comments from the agent can potentially clutter the conversation. You may want to write everything on your behalf so that you can easily delete these comments. &lt;/li&gt;
&lt;li&gt;CodiumAI-Agent can’t edit comments, files, and PRs.&lt;/li&gt;
&lt;li&gt;It can't be used for private repositories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fortunately, there are solutions to all the listed cases, as well as numerous other scenarios where a more nuanced control is desired. To cater to any of these situations, you’ll need to install the agent in one of the following ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locally&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#use-docker-image-no-installation-required" rel="noopener noreferrer"&gt;Using Docker image (no installation required)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-from-source" rel="noopener noreferrer"&gt;Run from source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub specific methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-as-a-github-action" rel="noopener noreferrer"&gt;Run as a GitHub Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-as-a-polling-server" rel="noopener noreferrer"&gt;Run as a polling server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-as-a-github-app" rel="noopener noreferrer"&gt;Run as a GitHub App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#deploy-as-a-lambda-function" rel="noopener noreferrer"&gt;Deploy as a Lambda Function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#aws-codecommit-setup" rel="noopener noreferrer"&gt;AWS CodeCommit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitLab specific methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-a-gitlab-webhook-server" rel="noopener noreferrer"&gt;Run a GitLab webhook server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;BitBucket specific methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-as-a-bitbucket-pipeline" rel="noopener noreferrer"&gt;Run as a Bitbucket Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-on-a-hosted-bitbucket-app" rel="noopener noreferrer"&gt;Run on a hosted app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#bitbucket-server-and-data-center" rel="noopener noreferrer"&gt;Bitbucket server and data center&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BTW, you may have noted that in contrast to Copilot, CodiumAI's availability is not limited to GitHub. It also gives you a choice between different AI models, such as GPT-4, GPT-3.5, Anthropic, Cohere, and Llama2 models.&lt;/p&gt;

&lt;p&gt;However, it’s important to note that in order to install the PR agent, an API key of one of the supported models is required. In this case, CodiumAI’s services stay free, but the requests to the model itself may require additional fees.&lt;/p&gt;

&lt;p&gt;It’s also possible to run the PR-Agent in VS Code or any of JetBrains IDEs. This functionality is included in the &lt;a href="https://www.codium.ai/products/ide-plugin/" rel="noopener noreferrer"&gt;CodiumAI IDE plugin&lt;/a&gt;. But note that it requires a &lt;a href="https://www.codium.ai/pricing/" rel="noopener noreferrer"&gt;CodiumAI Teams subscription&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Response time
&lt;/h2&gt;

&lt;p&gt;Both Copilot and CodiumAI respond in approximately 30 seconds on average. Roughly 10 seconds after submitting a command, the 👀 emoji appears to indicate that the result is loading. &lt;/p&gt;

&lt;p&gt;Among the things I didn’t like is that when some exception occurs, you don’t see any response at all. You’re left wondering whether it’s still loading or not. It would also be great if the generated part of the response was visible while it was being constructed. &lt;/p&gt;

&lt;p&gt;Nevertheless, this differs when it comes to the CodiumAI PR-Agent within the IDE. It does display partial responses, so you don’t need to wait. Additionally, I noticed that its response time is a lot quicker in the IDE, typically taking 15–20 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating tests
&lt;/h2&gt;

&lt;p&gt;One of the most common things that don’t allow PRs to get merged is the lack of necessary unit tests, which makes generating them directly in pull requests one of the most promising things AI tools can provide. &lt;/p&gt;

&lt;p&gt;GitHub plans to solve this problem by introducing a GenTest feature that will offer suggestions on resolving issues that would analyze the PR for missing tests and then create another pull request that suggests the necessary unit tests. Unfortunately, this feature is still not released publicly.&lt;/p&gt;

&lt;p&gt;For now, CodiumAI does not have such a feature either, although the PR-Agent does address the absence of unit tests.&lt;/p&gt;

&lt;p&gt;However, you can use the &lt;code&gt;/ask&lt;/code&gt; command to get detailed test suggestions and then go back to your IDE and write them there. That’s exactly what they specialize in when it comes to their &lt;a href="https://www.codium.ai/products/ide-plugin/" rel="noopener noreferrer"&gt;IDE code assistant&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ghost text
&lt;/h2&gt;

&lt;p&gt;This one is actually where the GitHub Copilot is most likely to win. It’s about the subdued, inline suggestions that appear as you type in the editor.&lt;/p&gt;

&lt;p&gt;When it comes to the Copilot IDE plugin, these suggestions have been proven to be one of the most convenient ways AI can integrate into the development workflow. Now they are working on bringing this UX to the pull request experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwvtc4k6hisizgxkp5n3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwvtc4k6hisizgxkp5n3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is better?
&lt;/h2&gt;

&lt;p&gt;Alright, so both assistants have great potential to improve our workflow, save time, and automate tedious tasks. I’m looking toward the future where such tools integrate seamlessly into the development process.&lt;/p&gt;

&lt;p&gt;As we are waiting for the new cool AI features, let's now determine which of these two is currently superior.&lt;/p&gt;

&lt;p&gt;Let’s address the elephant in the room, from all the described features, GitHub Copilot only has &lt;a href="https://githubnext.com/projects/copilot-for-pull-requests#suggestions-for-your-pull-request-description" rel="noopener noreferrer"&gt;PR summaries&lt;/a&gt; available at the moment. To get access to this tool, you must sign up for a &lt;a href="https://github.com/github-copilot/copilot_enterprise_waitlist_signup/join" rel="noopener noreferrer"&gt;waitlist&lt;/a&gt; for &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Copilot Enterprise&lt;/a&gt;, which costs 39$ per user/month. But to sign up, you need &lt;a href="https://github.com/pricing" rel="noopener noreferrer"&gt;GitHub Enterprise Cloud&lt;/a&gt;, which, in turn, costs 21$ per user/month. Other GitHub Copilot features are currently not available at all! For now, they are only planned as a part of the Copilot X prototype.&lt;/p&gt;

&lt;p&gt;But let’s not underestimate it. According to &lt;a href="https://githubnext.com/projects/copilot-for-pull-requests" rel="noopener noreferrer"&gt;GitHub Next&lt;/a&gt;, the planned features are quite promising and it may be great for user experience in the future.&lt;/p&gt;

&lt;p&gt;CodiumAI, on the other hand, lets us try the cutting-edge technology right now. It provides more commands, is &lt;a href="https://github.com/Codium-ai/pr-agent/tree/main" rel="noopener noreferrer"&gt;open-source&lt;/a&gt;, and is well-documented. It also gives us ample opportunities for customization. In terms of pricing, we can use it for free, or opt for one of the &lt;a href="https://www.codium.ai/pricing/" rel="noopener noreferrer"&gt;paid plans&lt;/a&gt; that offer more features. &lt;/p&gt;

&lt;p&gt;CodiumAI has plans on its &lt;a href="https://github.com/Codium-ai/pr-agent/tree/main?tab=readme-ov-file#roadmap" rel="noopener noreferrer"&gt;roadmap&lt;/a&gt; too. For example, enforcing &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; guidelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I’m quite impressed with the power of these tools. We can now automate AI responses for our repositories however we want. I can see such PR agents operate in tandem with tools like CI/CD pipelines in the future, and serve as efficient and quick-to-respond intermediaries for creating and reviewing PRs.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>git</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Challenge finished — reflections</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Mon, 02 Oct 2023 17:49:00 +0000</pubDate>
      <link>https://dev.to/danielrendox/challenge-finished-reflections-4k45</link>
      <guid>https://dev.to/danielrendox/challenge-finished-reflections-4k45</guid>
      <description>&lt;p&gt;My 2 months of learning and building in public challenge is over! Time to summarize the results!&lt;/p&gt;

&lt;p&gt;So I set two goals for myself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learn all I need to build a scalable Android app.&lt;/li&gt;
&lt;li&gt;Create an MVP of my app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now I don’t really know whether I completed the challenge or not because, on the one hand, I fully achieved the first goal, on the other hand, my app is still far from an MVP.&lt;/p&gt;

&lt;p&gt;However, these 2 months were really fun and productive because I&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;found my blogging path;&lt;/li&gt;
&lt;li&gt;established the best way of learning that works for me;&lt;/li&gt;
&lt;li&gt;kept myself exposed to the world;&lt;/li&gt;
&lt;li&gt;had an ending point in learning and made it before the deadline;&lt;/li&gt;
&lt;li&gt;entered university, had my daily routine changed, and met new people.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have seen that all the benefits of learning and building in public I wrote about indeed apply. By summarizing my progress I organize myself, keep being motivated, and keep my goals clear.&lt;/p&gt;

&lt;p&gt;Although I’m kind of a productivity beast, I struggle to keep up with habits, especially those that provide long-term and not short-term benefits. I found a cool solution: share progress with others to stay accountable.&lt;/p&gt;

&lt;p&gt;Now I’m going to heavily focus on building my app, and I’ll keep sharing my progress. I’ll make it an article only when this is a really worth-sharing achievement, though. That’s because writing such articles is like a burden for me now, I perceive them as something serious, not as short reflections in a couple of sentences. As a result, I don’t have time to write other articles that I’d like to write more. I think I’ll be good with comments on threads like “What was your win this week?” This will actually keep me more accountable.&lt;/p&gt;

&lt;p&gt;I think the decision to take this challenge was worth it. However, everyone follows their own path and I learned there is no one-size-fits-all solution. It’s important to just do what you like and follow your passion.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Finally connecting everything together 😊</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Wed, 20 Sep 2023 07:51:44 +0000</pubDate>
      <link>https://dev.to/danielrendox/finally-connecting-everything-together-2efm</link>
      <guid>https://dev.to/danielrendox/finally-connecting-everything-together-2efm</guid>
      <description>&lt;p&gt;On the 2nd of August, I promised to document my progress during these two months. Here’s a report of my past two weeks of learning and building in public.&lt;/p&gt;

&lt;p&gt;In the last time, honestly, I didn’t have much desire to be active in this digital world of developers. That’s because my higher education has started, and there are so many new connections out there that it’s actually too much for me. 😆&lt;/p&gt;

&lt;p&gt;However, I need to summarise what I’ve done to feel the progress towards the end goal and be motivated, purposive, and consistent. While I'm delighted to return to my comfort zone and savor this exceptional phase of my life, it's important that I remain engaged in all its facets.&lt;/p&gt;

&lt;p&gt;About two weeks ago, I was struggling with balancing learning and building. That’s because I wanted to build my program, and at the same time I didn’t know enough to actually start without messy code. Although I started in some aspects  — UI, business logic, and data storage, I couldn’t connect everything together. &lt;/p&gt;

&lt;p&gt;However, a few days ago, I was so happy to discover that I actually know everything I need to build my program! Of course, my knowledge isn’t deep, but it’s enough to create a base of a scalable program without messy code and following all the recommended best practices.&lt;/p&gt;

&lt;p&gt;I don’t know whether it’s because I developed that mindset for learning only the necessary concepts and leaving the rest for the time I actually need a certain thing or it’s because I already knew much and just underestimated my progress, but in the first week of this period I learned all the remaining concepts I needed and discovered such pleasing truth. Seriously, look at the plan I’ve been following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Android basics&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Jetpack Compose basics&lt;/li&gt;
&lt;li&gt;Advanced state, side effects, and Gradle&lt;/li&gt;
&lt;li&gt;Inline functions, testing, introduction to Coroutines and Flow ◀️&lt;/li&gt;
&lt;li&gt;Databases and modularization&lt;/li&gt;
&lt;li&gt;Interaction with remote API&lt;/li&gt;
&lt;li&gt;Dependency injection&lt;/li&gt;
&lt;li&gt;Architecture (MVVM, MVI) and other stuff 🏆&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;◀️ — where I was two weeks ago&lt;/p&gt;

&lt;p&gt;🏆 — where I am now&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now the plan is to catch up on building my program, fill in the gaps in knowledge while working, and actually complete the challenge in the remaining time. (at least I’ll try).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, and here's what I've learned:&lt;/p&gt;

&lt;h3&gt;
  
  
  Interaction with remote API
&lt;/h3&gt;

&lt;p&gt;Nothing interesting in remote API itself actually. The basics are not difficult at all and I don’t need it for now. Contrary to what I expected, it didn’t help me better understand coroutines either.&lt;/p&gt;

&lt;p&gt;However, it was a good introduction to Rest API. It also helped me a lot in understanding dependency injection.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://developer.android.com/courses/android-basics-compose/unit-5" rel="noopener noreferrer"&gt;course&lt;/a&gt; I’m speaking about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency injection (di)
&lt;/h3&gt;

&lt;p&gt;I learned the basics of Hilt with the help of this &lt;a href="https://developer.android.com/codelabs/android-hilt" rel="noopener noreferrer"&gt;amazing codelab&lt;/a&gt;. This helped me understand how di and di frameworks work overall. And it’s not about learning Hilt because I actually don’t plan to use it in my app.&lt;/p&gt;

&lt;p&gt;I don't really understand why people perceive dependency injection as a complex thing. For now, I see it just as a workaround in situations when I can't pass dependencies in constructors (a typical situation in Android). According to what I've seen in the codelab, manual di requires almost the same amount of code. So it currently looks simpler and safer to me.&lt;/p&gt;

&lt;p&gt;I would appreciate it if someone explained to me what all the fuss is about.&lt;/p&gt;

&lt;p&gt;Anyway, I probably just don't know something because &lt;a href="https://www.techyourchance.com/dagger-vs-hilt-vs-koin/" rel="noopener noreferrer"&gt;experienced guys say di is very important&lt;/a&gt;. I was right about the manual di, though. It is indeed a great option because it eliminates the overhead created by di frameworks. But this is not an option for me because frameworks provide some template while doing it manually gives me so much freedom that I risk of creating a monster, riddled with bugs.&lt;/p&gt;

&lt;p&gt;So I learned hilt and found out that I couldn't use it in my project right after that. 😁 I can't use it because I aim to expand my project to iOS using Kotlin Multiplatform, but Hilt is a pure Android thing. So I'll use the second most popular di framework — Koin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Databases
&lt;/h3&gt;

&lt;p&gt;When I first met the concept of databases, I found out that database programming is very limited compared to object-oriented programming. Lately, when I got back to this topic again, I found out that it’s not difficult at all, and you don’t need to read a book or pass a crash course to correctly design database schemes. &lt;/p&gt;

&lt;p&gt;The first tricky thing is database inheritance. There are three approaches here — look at &lt;a href="https://stackoverflow.com/a/3579462/22295134" rel="noopener noreferrer"&gt;this answer&lt;/a&gt; on Stack Overflow. Due to limitations of the framework and other considerations, I picked the first one.&lt;/p&gt;

&lt;p&gt;The second tricky thing is modeling relationships such as one-to-many and many-to-many. This is perfectly explained &lt;a href="https://medium.com/@gilesjeremydev/room-through-a-complete-example-ce5c9ed417ba" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When it comes to choosing the framework, Room is the obvious choice for Android. But this is once again a pure Android thing that doesn’t work with KMM, so I use SQLDelight instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modularization
&lt;/h3&gt;

&lt;p&gt;Checked the information about the &lt;a href="https://youtu.be/qX6zmKY4KP0?si=VIrTm1Ui9UZPfeCX" rel="noopener noreferrer"&gt;recommended architecture&lt;/a&gt; of a project that consists of data, domain, and presentation layers. Also found out about CLEAN architecture from &lt;a href="https://youtu.be/8YPXv7xKh2w?si=dJvPzlIzqr3i1f3h" rel="noopener noreferrer"&gt;this example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I didn’t dive into modularization itself though. That’s because I’ll introduce it later when my project grows.&lt;/p&gt;

&lt;p&gt;There need to be 3 main modules: app, feature, and core. For now, I decided to use packages instead of modules and have several sub-packages for data, domain, and presentation. &lt;/p&gt;

&lt;h3&gt;
  
  
  MVVM vs MVI
&lt;/h3&gt;

&lt;p&gt;Finally, when it comes to a serious Android project, there are lots of considerations. One of them is whether to use mvvm or mvi. Other solutions are generally not an option because they are too legacy. I decided to use MVI because of its benefits. There are many drawbacks too, but we can work around them. One of the decisive factors is that it’s more modern and Google recommends MVI for Jetpack Compose projects now. 😎&lt;/p&gt;

&lt;p&gt;With XML, the situation is different because, AFAIK MVI isn’t good for performance there. It causes the whole UI to rerender each time something changes, which is not true about compose since its compiler is smart enough.&lt;/p&gt;

&lt;p&gt;Thanks, Philipp for the great &lt;a href="https://youtu.be/cnU2zMnmmpg?si=HPqtzYzgUiuTRli-" rel="noopener noreferrer"&gt;explanation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;There is another interesting thing, by the way. Although it’s better for beginners to follow the recommended practices and decide on something only when they get some experience, one can essentially do everything they want and use their own solutions as long as everything works correctly, the code is readable and still follows the best practices.&lt;/p&gt;

&lt;p&gt;For example, the matter of whether to use &lt;code&gt;ViewModel&lt;/code&gt; is questionable. I recently discovered that the main reason we use it is because it caches the data so that we don’t need to execute network requests when nothing changes. We also save resources by not fetching data when a configuration change occurs. There are other benefits of &lt;code&gt;ViewModel&lt;/code&gt;. Here is a great &lt;a href="https://youtu.be/pCX9wvu-Bq0" rel="noopener noreferrer"&gt;talk&lt;/a&gt; related to this topic.&lt;/p&gt;

&lt;p&gt;However, there are alternative approaches to achieving that. For example, compose provides rememberSaveable for saving state across configuration changes and even across activity recreations.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.techyourchance.com/you-dont-need-android-viewmodel/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s---UHHCtaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.techyourchance.com/wp-content/uploads/2022/06/viewmodel-alternatives1.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.techyourchance.com/you-dont-need-android-viewmodel/" rel="noopener noreferrer" class="c-link"&gt;
          You Don't Need Android ViewModel, Here is Why
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Explanation of why you don't need ViewModel component in your Android application and a list of alternative solutions that I use.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--NJ3jwWe1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.techyourchance.com/wp-content/uploads/2020/08/icon.svg" width="500" height="500"&gt;
        techyourchance.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;So there are lots of ways for achieving the same thing and it’s not necessary to use only recommended solutions. Getting more experience, I’m becoming more and more convinced in that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;I wrote this article for myself mainly. But if you read this far, thanks for being interested in me. 🤗&lt;/p&gt;

&lt;p&gt;If you're learning Android and struggling with some of these topics, you can DM me on &lt;a href="https://twitter.com/DanielRendox" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or email me (&lt;a href="https://mailto:daniel.rendox@gmail.com/" rel="noopener noreferrer"&gt;daniel.rendox@gmail.com&lt;/a&gt;) and we'll figure it out together.&lt;/p&gt;

</description>
      <category>android</category>
      <category>learning</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>The Last Days of my Total Time Freedom</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Tue, 05 Sep 2023 08:32:08 +0000</pubDate>
      <link>https://dev.to/danielrendox/the-last-days-of-my-total-time-freedom-2d20</link>
      <guid>https://dev.to/danielrendox/the-last-days-of-my-total-time-freedom-2d20</guid>
      <description>&lt;p&gt;Roughly 1 month ago, I took a challenge for myself that focuses on learning and building in public. It’s time to reflect on what I’ve achieved.&lt;/p&gt;

&lt;p&gt;I focused on learning and building, so writing blogs was not a priority. And I decided that today is the best time to make a review of my past 2 weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learned
&lt;/h2&gt;

&lt;p&gt;Lately, I’ve been learning Kotlin coroutines and flow. It was more of a quick introduction to this topic because I plan to learn databases, so I’ll need to understand it. Although now I’d want to do things differently, it was interesting to dip my toe into reactive programming.&lt;/p&gt;

&lt;p&gt;Coroutines are scheduled code within a thread. And the fact that a new thread is not necessarily started confuses me. For now, the traditional way of multithreading with threads and callbacks is actually more clear and readable for me. But I’m sure that’s only because I haven’t worked with coroutines much, especially in the practical setting.&lt;/p&gt;

&lt;p&gt;When it comes to flows, they are essentially placeholders for values that come in a certain period of time. That’s why they are called streams of data.&lt;/p&gt;

&lt;p&gt;I also learned the Compose Navigation library that is AFAIU here just for convenience so that we don’t need to hold everything in state, write a huge &lt;code&gt;when&lt;/code&gt; expression, manually deal with animations, and manually integrate with other Jetpack Compose components.&lt;/p&gt;

&lt;p&gt;I also was surprised by the simplicity of MVI. Met this thing unexpectedly. So the main idea is that you put all the states in one data class as plain &lt;code&gt;val&lt;/code&gt;s and then put the whole class to a single state. First, I doubted how optimized this approach is, because I thought that an update to a state would cause unnecessary recompositions. But this turned out to be not true because they are skippable as Compose is smart enough. This is not true about xml views though. However, MVI introduces some hassle if you want to save the state to the &lt;code&gt;SavedStateHandle&lt;/code&gt; and can also cause race conditions [&lt;a href="https://youtu.be/cnU2zMnmmpg?si=suJTdt2hcs7dB1jc" rel="noopener noreferrer"&gt;source&lt;/a&gt;] so I think I’m good with MVVM for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Here are some resources that helped me learn this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coroutines
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/codelabs/basic-android-kotlin-training-introduction-coroutines" rel="noopener noreferrer"&gt;Introduction to coroutines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/codelabs/kotlin-coroutines?authuser=1" rel="noopener noreferrer"&gt;Use Kotlin Coroutines in your Android App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/cr5xLjPC4-0?si=10dRemzPBdhMh1Lm" rel="noopener noreferrer"&gt;5 Fatal Coroutine Mistakes Nobody Tells You About&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/aniketbhoite/kotlin-flow-simple-yet-powerful-implementation-39jp"&gt;Kotlin Flow: Simple yet Powerful Implementation&lt;/a&gt; — This helped me understand how they actually work.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLQkwcJG4YTCQHCppNAQmLsj_jW38rU9sC" rel="noopener noreferrer"&gt;The Ultimate Guide to Kotlin Flows&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;⚠️ However, I rethought my learning approach.&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;According to &lt;a href="https://dev.to/danielrendox/the-art-of-balancing-learning-and-building-45fa"&gt;my new mindset&lt;/a&gt;, I should’ve begun with the following pathways right away. ⬇️ Especially given that they do not require knowledge of coroutines and flow. It is actually taught there.&lt;br&gt;&lt;br&gt;1. Android Basics with Compose — &lt;a href="https://developer.android.com/courses/android-basics-compose/unit-5" rel="noopener noreferrer"&gt;Unit 5: Connect to the internet.&lt;/a&gt;&lt;br&gt;2. Android Basics with Compose — &lt;a href="https://developer.android.com/courses/android-basics-compose/unit-6" rel="noopener noreferrer"&gt;Unit 6: Data persistence.&lt;/a&gt;
&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  + &lt;a href="https://developer.android.com/codelabs/jetpack-compose-navigation?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fjetpack-compose-for-android-developers-3%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fjetpack-compose-navigation" rel="noopener noreferrer"&gt;Jetpack Compose Navigation Codelab&lt;/a&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Progress
&lt;/h2&gt;

&lt;p&gt;I modified my roadmap a bit and now I’m in the middle of my path 🎉&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Android basics&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Jetpack Compose basics&lt;/li&gt;
&lt;li&gt;Advanced state, side effects, and Gradle&lt;/li&gt;
&lt;li&gt;Inline functions, testing, introduction to Coroutines and Flow ◀️&lt;/li&gt;
&lt;li&gt;Databases and modularization&lt;/li&gt;
&lt;li&gt;Interaction with remote API&lt;/li&gt;
&lt;li&gt;Dependency injection&lt;/li&gt;
&lt;li&gt;Architecture (MVVM, MVI) and other stuff&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe44mus51cg5d661crpgm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe44mus51cg5d661crpgm.jpg" alt="Two lables and progress bars: 1. Make my app — 8; 2. Learn android — 55%." width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See that “Make my app — 5%”? I actually managed to let go and it doesn’t bother me. But what I contemplated is that it’s not OK. I can already write business logic and the UI, only then add data storage. I also shouldn’t care about best practices that much. So to stay both practical and motivated, I decided to focus on building now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oh, and I entered a university
&lt;/h2&gt;

&lt;p&gt;Actually, I did it in the summer, but the lectures traditionally start in September.&lt;/p&gt;

&lt;p&gt;And that’s coming from a person who is a big fan of the practical approach and says that higher education is a scam. 🌚&lt;/p&gt;

&lt;p&gt;I’m honestly, indeed very skeptical about the higher education for developers. But, first, it’s free for me. Second, here are my expectations in descending priority:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More opportunities to find a job.&lt;/strong&gt; I can get an internship or eventually go overseas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication.&lt;/strong&gt; Very high chances of finding great friends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan B.&lt;/strong&gt; Being self-taught and having a degree at the same time is a win-win, especially for someone of my age.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get the foundation, support, and confidence.&lt;/strong&gt; However skeptical I was, that’s what schools do well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is insufficient for me to justify the amounts of money people spend. My time is already a significant investment! 😼&lt;/p&gt;

&lt;p&gt;I used to spread the information that classes only would take ~6 hours a day. People felt sorry for me, but it actually turned out not true. 😆 I just confused some stuff. In reality, it’s about 4.5 h. And Friday is a day off.&lt;/p&gt;

&lt;p&gt;I’m enjoying it so far and feel like my expectations are going to be met. Who knows, I may change my decision in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance (adjusted to 2 weeks)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;a href="https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1#challenge"&gt;My challenge&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;✔️ 7/10 tweets&lt;/p&gt;

&lt;p&gt;✔️ 2/3 articles&lt;/p&gt;

&lt;h3&gt;
  
  
  Healthy habits
&lt;/h3&gt;

&lt;p&gt;I’d better not tell you 🤭&lt;/p&gt;

&lt;h3&gt;
  
  
  Changes
&lt;/h3&gt;

&lt;p&gt;So I allowed myself to fall behind a bit. And until now I’ve been only increasing my goals. But now that I’m not going to have that much time, I think it’s an opportunity to focus only on a few of them. And finally, get back to the comfort zone.&lt;/p&gt;

&lt;p&gt;And I also have exactly four weeks until my challenge finishes. So now I don’t have room for error.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more tweets. I’ll tweet only when I want.&lt;/li&gt;
&lt;li&gt;I will do programming at least 6 days a week, but won’t count the hours anymore.&lt;/li&gt;
&lt;li&gt;Back to 1 article a week.&lt;/li&gt;
&lt;li&gt;Also deleted a couple of habits I already have, and switched to &lt;a href="https://play.google.com/store/apps/details?id=com.habitnow&amp;amp;hl=en_GB" rel="noopener noreferrer"&gt;HabitNow&lt;/a&gt; for habit tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;I wrote this article for myself mainly. But if you read this far, thanks for being interested in me. 🤗&lt;/p&gt;

&lt;p&gt;If you're learning Android and struggling with some of these topics, you can DM me on &lt;a href="https://twitter.com/DanielRendox" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or email me (&lt;a href="//mailto:daniel.rendox@gmail.com"&gt;daniel.rendox@gmail.com&lt;/a&gt;) and we'll figure it out together.&lt;/p&gt;

</description>
      <category>android</category>
      <category>learning</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>The Art of Balancing Learning and Building</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Sun, 03 Sep 2023 15:44:13 +0000</pubDate>
      <link>https://dev.to/danielrendox/the-art-of-balancing-learning-and-building-45fa</link>
      <guid>https://dev.to/danielrendox/the-art-of-balancing-learning-and-building-45fa</guid>
      <description>&lt;p&gt;I've been experimenting with my learning approach for a long time now, made dozens of mistakes, and I think I finally came to a conclusion. Eager to share the gained insights with you!&lt;/p&gt;

&lt;h2&gt;
  
  
  🐰 The rabbit hole is open
&lt;/h2&gt;

&lt;p&gt;This summer, I had a lot of free time for programming. So, knowing a bit about Android, I quickly learned the basics of the new UI framework and started applying these things in my program that I think I have a good idea of. Having tried to write some simple stuff, I realized that there was a whole mountain of things that I didn’t know.&lt;/p&gt;

&lt;p&gt;While creating some labels, buttons, and checkboxes is easy, making them actually work and doing some more complex stuff requires a lot more knowledge. Imagine, I want to create a functional screen. I need to first write business logic and UI. Then it would be good to add databases, which also requires knowledge of multithreading. And only then I can connect everything, and preferably, write tests to make sure everything works correctly. This is the whole bunch of stuff not even mentioning, interaction with remote API, dependency injection, and following best practices.&lt;/p&gt;

&lt;p&gt;Then you actually try to figure all this stuff out and find other pitfalls which is really frustrating, especially when you don’t understand something. You don’t even know what you don’t know!&lt;/p&gt;

&lt;p&gt;Here is the answer to why beginners feel very confused about how to cope with everything.&lt;/p&gt;




&lt;p&gt;As you can guess, I fall right into that trap. But luckily, I regularly listen to some programming podcasts and I once found some great advice in one of them. I encourage you to watch this 50-second clip ⬇️&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.youtube.com/clip/UgkxVQscN6oi4T_ZHe2_UGTjpcIw4KNDw8eJ?si=PBZiWc1rw4MfDE5w" rel="noopener noreferrer"&gt;
      youtube.com
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I obviously needed some time to digest it but when I did, it ended my frustration. Here is the breakdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤯 #1 Have fun and experiment with stuff
&lt;/h2&gt;

&lt;p&gt;When you encounter a problem that requires you to learn some new things, approach it with the right mindset — be excited that you’re gonna significantly increase your skills.&lt;/p&gt;

&lt;p&gt;Of course, this podcast wasn’t the only thing that pointed me in the right direction. It’s usually a confluence of circumstances that causes people to rethink something.&lt;/p&gt;

&lt;p&gt;I remember another Android dev who having found out that I was trying to learn Android and build my app, said to me smth like “You must be following a lot of Google codelabs and just experimenting with stuff”.&lt;/p&gt;

&lt;p&gt;And this stuck to my mind. Just having fun and experimenting with stuff — that’s what I should do. One step at a time. Find an interesting guide for a topic, try to implement, and switch to another one.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤯 #2 Build your program!
&lt;/h2&gt;

&lt;p&gt;So I decided to savor learning and really enjoyed getting into these rabbit holes. However later on I realized another equally important thing. &lt;/p&gt;

&lt;p&gt;I made some kind of a roadmap for myself that involved passing codelabs and making small programs to practice my knowledge and play around. This was pretty close to what Philipp Lackner recommends in &lt;a href="https://youtu.be/AhUL5tHF3uc?si=z8gilzz6S0lPx8VI" rel="noopener noreferrer"&gt;his video&lt;/a&gt; — learning stuff and then making programs to apply this in practice. For example, you’ve learned a programming language and UI framework — now you can build a calculator, then you learn how to store data and build a to-do app, and so on.&lt;/p&gt;

&lt;p&gt;Given that to make a scalable project, you need to consider lots of things from the beginning. E.g., for Andriod, it would be good to, first, care about dependency injection and architecture, it would be even better to make sure that your code is properly abstracted and tested. [&lt;a href="https://www.techyourchance.com/new-android-project-the-most-important-decisions/" rel="noopener noreferrer"&gt;source&lt;/a&gt;]. So as I just didn’t know all this stuff, I decided that I would learn it and then get back to my program.&lt;/p&gt;

&lt;p&gt;And I ditched it for an unidentified period of time.&lt;/p&gt;

&lt;p&gt;Fortunately for me, at some point, I had a little dispute about “the right learning way” with my dad who is a developer and had made all these mistakes either. He said that I was learning too much and should’ve focused on building instead. And I was like, that’s what I’m doing, I’m creating these learning projects to practice and they all involve the knowledge acquired previously so as not to forget anything.&lt;/p&gt;

&lt;p&gt;But he told me that it’s very important to have an ending point. There is always gonna be other stuff to learn, and you’ll never be ready to continue working on your project. He’d fallen into that trap and eventually found himself knowing a lot but not having actual results.&lt;/p&gt;

&lt;p&gt;Like when you spend a significant amount of time preparing yourself for the big venture and then your friends ask what you’ve accomplished so far, what you’re gonna respond? Alright, I can name a bunch of technical things to impress people, but what can I actually show? &lt;/p&gt;

&lt;h2&gt;
  
  
  What if we flip it upside down?
&lt;/h2&gt;

&lt;p&gt;And then I realized that the best way of studying is not learning theory and then seeking the possibility to practice but on the contrary &lt;strong&gt;trying to make something, figuring out what’s needed, and learning that&lt;/strong&gt;. Right away with the practical approach! 🙌&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn only the stuff that you actually need
&lt;/h3&gt;

&lt;p&gt;It’s crucial to learn only those things that you really need for building your program. When I started learning programming, it was my biggest mistake. I just learned things that indeed helped me understand concepts, the programming language, and the whole structure. But even though, I quickly forgot them, and could be so much better off not wasting time on those things and following the practical approach right away. &lt;/p&gt;

&lt;p&gt;I still make these mistakes and this advice is also very to misinterpret. For you to understand, here are certain scenarios. ( ✔️ — correct approach, ❌ — incorrect approach, according to the described mindset)&lt;/p&gt;




&lt;p&gt;To save your program’s data, you need to learn databases. But the prerequisite is that you should know concurrency first.&lt;/p&gt;

&lt;p&gt;❌ Go find a course for mastering concurrency and after that, switch to databases.&lt;/p&gt;

&lt;p&gt;✔️ Start with databases right away, and when you don’t understand something about concurrency, find a quick explanation on the web and go on. If you eventually feel that this concurrency knowledge is not enough, take that course.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t run after new and shiny
&lt;/h3&gt;

&lt;p&gt;You want to create a program and already know how to make a simple app, but a new shiny framework comes out, and you feel like you need to learn it.&lt;/p&gt;

&lt;p&gt;❌ Learn the new framework. This will allow you to fill in the gaps, get more confidence, and see things from a different perspective.&lt;/p&gt;

&lt;p&gt;✔️ Congrats! You are ready to start building your app. This will keep you motivated, you’ll retain your knowledge, and stay practical. In addition to that, you’ll eventually get all the benefits described above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Even applicable to absolute beginners
&lt;/h3&gt;

&lt;p&gt;You're just starting out and have an idea of an app you want to create. Before that, you certainly need to learn the programming language.&lt;/p&gt;

&lt;p&gt;❌ Go find a crash course about that language.&lt;/p&gt;

&lt;p&gt;✔️ Go find a course that will allow you to stay practical right away. For instance, &lt;a href="https://developer.android.com/courses/android-basics-compose/course" rel="noopener noreferrer"&gt;here is one for Android development&lt;/a&gt;. If you can’t find one, learn the basics and jump to creating something yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t get overwhelmed with best practices and give up on your program
&lt;/h3&gt;

&lt;p&gt;You find out that to make your app scalable from the outset, you need to know many things. You consider what to do next.&lt;/p&gt;

&lt;p&gt;❌ Ditch your program, learn all these things, and only then get back to it.&lt;/p&gt;

&lt;p&gt;✔️ Carry on with your program. Start small. First, write business logic, then add UI. Boom! Pre-MVP is ready. Then try and add data storage — MVP is ready. 🎉 And don’t really worry about making it scalable.&lt;/p&gt;

&lt;p&gt;There is no point in being concerned that your code is not clean enough. It won’t ever be perfect. Trying to optimize every class you write and learn all the best practices at once will only take up your time and spoil your nerves.&lt;/p&gt;

&lt;p&gt;It’s good to occasionally look into these things, but being overwhelmed with them is bad.&lt;/p&gt;




&lt;p&gt;As you may guess, I made each of the mistakes above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adopting the mindset to build any app
&lt;/h2&gt;

&lt;p&gt;If you rewatch that clip from the podcast, you’ll discover that the first piece of advice (🤯 #1) was actually produced by my imagination, while the thing the guys actually emphasize is exactly the importance of building your own stuff. &lt;/p&gt;

&lt;p&gt;In the beginning, Mitch says: “It’s like what you said earlier.” And that earlier was at &lt;a href="https://www.youtube.com/live/ZOUzXAnRuew?si=IAvj05dg0aFKFz2h&amp;amp;t=3720" rel="noopener noreferrer"&gt;1:02:00&lt;/a&gt;, where they answered one of the listener's question: “How can I get an attitude that I can make everything, that I can make any app?”&lt;/p&gt;

&lt;p&gt;The answer is actually in developing such mentality that I described above. Being able to learn, and just carry on. Like Mitch says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Get confortable with being uncomfortable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My favorite learning approach is free
&lt;/h2&gt;

&lt;p&gt;It’s one of the things that I love about it. You don’t need to pay for any books or courses. In fact, with all this information available for free, paid higher education seems to be nothing more than a scam either.&lt;/p&gt;

&lt;p&gt;In the marketing world, salesmen put discounts to make us buy things that we don’t need. The business of making courses works in the same way. I’m not saying that it’s bad though. Products are good and we’re happy to buy them, the same thing with courses.&lt;/p&gt;

&lt;p&gt;I love &lt;a href="https://www.youtube.com/@PhilippLackner" rel="noopener noreferrer"&gt;Philipp’s channel&lt;/a&gt; and benefited very much from all the knowledge he shares. But why would I pay ~100€ for a course on his website if everything is available on his YouTube channel? What these books and courses really offer is the information gathered and structured in a systematic way. They also artificially make you feel comfortable because you have support.&lt;/p&gt;

&lt;p&gt;Then the question of whether to buy or not boils down to how willing I am to collect all this information and solve problems on my own. In my opinion, if this stuff is available legally and for free, buying a course is a way to spend money and get tutorial hell, whereas the project-based approach lets you adopt this very mindset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;Now that I’ve defined the most important things about learning programming, here is how I’m gonna change my approach. First, I’m going to make building my app the first area of focus and allot no less than 50% to it.&lt;/p&gt;

&lt;p&gt;I think it’s imperative though to still embrace learning in parallel and dive into these lovely rabbit holes, but only for a limited time. This way, I can be sure that I stay on the right track and do not reinvent the wheel due to the lack of knowledge.&lt;/p&gt;

&lt;p&gt;I’m still searching, so I’m curious to hear about your favorite way of learning. Advice and insights will be much appreciated!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Quick summary of my past 9-day week</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Tue, 22 Aug 2023 14:01:04 +0000</pubDate>
      <link>https://dev.to/danielrendox/quick-summary-of-my-past-9-day-week-239j</link>
      <guid>https://dev.to/danielrendox/quick-summary-of-my-past-9-day-week-239j</guid>
      <description>&lt;p&gt;18 days ago I took a &lt;a href="https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1#challenge"&gt;challenge&lt;/a&gt; for myself that focuses on learning and building in public. It’s time to reflect on what I’ve achieved.&lt;/p&gt;

&lt;p&gt;In this post, I decided not to beat around the bush and quickly summarize what I did during the last 9 days and go on.&lt;/p&gt;

&lt;p&gt;My week consists of 9 days now 😁, but that’s OK because I planned the challenge to last 2 months, not 8 weeks. It started on the 4th of August and will finish on the 4th of October, so I have 61 days in fact. Is it a legitimate move? 🤔 Should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick summary
&lt;/h2&gt;

&lt;p&gt;Anyway, during this week I focused on managing state in Android. It’s important because otherwise, we lose user’s input when they turn the screen, switch to dark/light mode, etc. The same happens when the system kills the app’s process to save memory.&lt;/p&gt;

&lt;p&gt;That’s not as easy as it looks! Using &lt;code&gt;remember { mutableStateOf() }&lt;/code&gt; is not enough, unfortunately.&lt;/p&gt;

&lt;p&gt;We also have side effects — code that goes out of the scope of a composable function. Philipp Lackner has a &lt;a href="https://youtu.be/gxWcfz3V2QE?si=bHJGyPhqVLggyhIO" rel="noopener noreferrer"&gt;great video&lt;/a&gt; on this topic. But watching it is not enough for understanding. So I played around with it.&lt;/p&gt;

&lt;p&gt;Also struggled to understand &lt;code&gt;derivedStateOf&lt;/code&gt;, but the answers to &lt;a href="https://slack-chats.kotlinlang.org/t/14159421/can-anyone-help-me-understand-an-example-from-the-https-deve#992aa322-3a3a-489b-83e5-3e6a83eb8ee0" rel="noopener noreferrer"&gt;my question in Kotlin Slack&lt;/a&gt; and some research made it clear. In short, use &lt;code&gt;derivedStateOf&lt;/code&gt; only in rare cases. But in those rare cases, it’s extremely useful for performance.&lt;/p&gt;

&lt;p&gt;Also learned new things about Gradle. Mainly that we can use different product flavors for &lt;code&gt;minSdk&lt;/code&gt;. So I refactored &lt;a href="https://github.com/DanielRendox/RoutineTracker" rel="noopener noreferrer"&gt;my project&lt;/a&gt; to use core library desugaring only when running on devices with Android versions less than 26.&lt;/p&gt;

&lt;p&gt;Found out how to create a release APK version. And finally relieved when my app launched faster on release than on debug. That’s because I had thought there was a performance issue and I did smth wrong. 🤨&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning resources
&lt;/h2&gt;

&lt;p&gt;Here are the resources that helped me learn this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced state and side effects
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/codelabs/jetpack-compose-advanced-state-side-effects" rel="noopener noreferrer"&gt;Advanced State and Side Effects in Jetpack Compose  |  Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/T8vApYJlW8o?si=JR058ZQU4S7sTOAY" rel="noopener noreferrer"&gt;Should You Use Compose State or StateFlow in Your ViewModels?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/gxWcfz3V2QE" rel="noopener noreferrer"&gt;Full Guide to Jetpack Compose Effect Handlers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slack-chats.kotlinlang.org/t/14159421/can-anyone-help-me-understand-an-example-from-the-https-deve#992aa322-3a3a-489b-83e5-3e6a83eb8ee0" rel="noopener noreferrer"&gt;My question in Kotlin Slack about derivedStateOf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/Zhuinden" rel="noopener noreferrer"&gt;Gabor&lt;/a&gt; explains how to create a state holder but one that can be saved in &lt;code&gt;SavedStateHandle&lt;/code&gt; and thus will survive the process death — &lt;a href="https://stackoverflow.com/questions/76767202/what-is-the-best-way-to-pass-a-default-initial-value-to-a-jetpack-compose-textfi" rel="noopener noreferrer"&gt;What is the best way to pass a default/initial value to a Jetpack Compose TextField?&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Gradle
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://youtu.be/4PCCiEThhbE" rel="noopener noreferrer"&gt;Sorting and Reporting Your Dependencies with Gradle with Ed George, Android Worldwide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/o0M4f5djJTQ?si=N5AfXiFfz6_ZJaXX" rel="noopener noreferrer"&gt;Gradle for Beginners (Build Types, Product Flavors, Build Variants, Source Sets)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Progress
&lt;/h2&gt;

&lt;p&gt;This week I decided to focus on learning. Although I added some features to my recent learning project, I didn’t work on my real app. &lt;/p&gt;

&lt;p&gt;AFAIK, here are the main concepts that I need to know to build an MVP:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Android basics&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Jetpack Compose basics&lt;/li&gt;
&lt;li&gt;Advanced state, side effects, and Gradle ◀️&lt;/li&gt;
&lt;li&gt;Navigation and performance&lt;/li&gt;
&lt;li&gt;Advanced Kotlin, Coroutines, and Flow&lt;/li&gt;
&lt;li&gt;Databases and modularization&lt;/li&gt;
&lt;li&gt;Dependency injection&lt;/li&gt;
&lt;li&gt;Architecture (MVVM, MVI)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;◀️ — Where I was in the past week&lt;/p&gt;




&lt;p&gt;So I’m glad to increase this “Learn Android” bar by 5% 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvnbv1btaknhtqbehl44.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvnbv1btaknhtqbehl44.jpg" alt="Two lables and progress bars: 1. Make my app — 5%, 2. Learn android — 45%." width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make my app still remains at 5%. I used to feel bad about it, but in the past week, I realized something that ended that feeling. I’ll probably make a separate blog post about it.&lt;/p&gt;




&lt;p&gt;Performance adjusted to the brand new 9-day week 🙃&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1#challenge"&gt;My challenge&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;✔️ 5/6 tweets&lt;/p&gt;

&lt;p&gt;✅ 1/1 article (this one)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/virtualcoffee/join-virtual-coffee-in-the-healthy-habits-for-happy-devs-monthly-challenge-5b7h"&gt;VC’s Healthy Habits challenge&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;✔️ &lt;strong&gt;Programming:&lt;/strong&gt; 45/48&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Household:&lt;/strong&gt; did at least 1 household chore 6 days a week&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Physical activity:&lt;/strong&gt; 6/6 times&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Rest:&lt;/strong&gt; had at least 1h each day&lt;/p&gt;

&lt;p&gt;😱 &lt;strong&gt;Learn English:&lt;/strong&gt; 14/42&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Daily review:&lt;/strong&gt; summarized what I did every day&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates to the challenge
&lt;/h3&gt;

&lt;p&gt;It’s great to start small and then improve over time. So here are my improvements to the challenge’s rules:&lt;/p&gt;

&lt;p&gt;➕ New habit — &lt;strong&gt;Follow the schedule&lt;/strong&gt; every day. I discovered that I am still out of sync with my defined schedule. So I tweaked it and added this habit. This is mainly to get up at 7 AM and close my eyes at 11:30–12:00 PM.&lt;/p&gt;

&lt;p&gt;⬆️ &lt;strong&gt;Work 1h more each day.&lt;/strong&gt; This is actually not a problem for me. I usually work more than planned because I love programming and can’t put it aside. My problem is to not forget about other activities and not take their time. But as I said, I changed my schedule and now it should be OK.&lt;/p&gt;

&lt;p&gt;⬆️ &lt;strong&gt;2 articles a week&lt;/strong&gt; (or 9 days 😁). I have a lot of ideas, drafts, and notes, but can’t find time for writing. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;I wrote this article for myself mainly. But if you read this far, thanks for being interested in me. 🤗&lt;/p&gt;

&lt;p&gt;If you're learning Android and struggling with some of these topics, you can dm me on &lt;a href="https://twitter.com/DanielRendox" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or email me (&lt;a href="mailto:daniel.rendox@gmail.com"&gt;daniel.rendox@gmail.com&lt;/a&gt;) and we'll figure it out together.&lt;/p&gt;

</description>
      <category>android</category>
      <category>learning</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Starting from the blank canvas, trying to be lazy, and other insights from the 1st week</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Sun, 13 Aug 2023 14:36:44 +0000</pubDate>
      <link>https://dev.to/danielrendox/starting-from-the-blank-canvas-trying-to-be-lazy-and-other-insights-from-the-1st-week-4hon</link>
      <guid>https://dev.to/danielrendox/starting-from-the-blank-canvas-trying-to-be-lazy-and-other-insights-from-the-1st-week-4hon</guid>
      <description>&lt;p&gt;1 week ago I decided to take a &lt;a href="https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1#challenge"&gt;challenge&lt;/a&gt; for myself that focuses on learning and building in public. It’s time to reflect on what I’ve achieved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from the blank canvas
&lt;/h2&gt;

&lt;p&gt;This week I’ve been mostly working on the business logic of my app. Fortunately, since the day when I got the idea of it, I’ve collected enough information to know what I want to build now. I analyzed similar apps, wrote down emerging ideas, and even thought about the design.&lt;/p&gt;

&lt;p&gt;But even so, I feel like I’m starting from a blank canvas. 😅 That’s because, when I think about how to actually implement those features, I realize that there are still lots of things to consider.&lt;/p&gt;

&lt;p&gt;However, I really enjoy designing and building something that will certainly help me and is likely to help many people in the future. Here is the &lt;a href="https://github.com/DanielRendox/RoutineTracker" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;, BTW.&lt;/p&gt;

&lt;p&gt;Speaking about design, I don’t use any design tool like Figma. All the UI is currently in my head and other apps I use for references 😆 That’s because I tried using design tools and discovered that it really takes time. I think, I’m a lot better off just drawing sketches on paper and writing the UI programmatically at once (but we’ll see).&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying to be a lazy developer
&lt;/h2&gt;

&lt;p&gt;My app development started with a challenge. I started with writing UI cause I’d passed a codelab about the framework and wanted to practice a bit. In my app’s design, I imagined a collapsing toolbar with an image. But the matter is that the framework does contain built-in functionality for collapsing toolbar, but doesn’t allow putting custom content such as an image into it.&lt;/p&gt;

&lt;p&gt;I spent a lot of time figuring out a way how to do that and eventually found one. Here is an example layout for you to understand ⬇️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtmif8sqaesnhpnvmuq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtmif8sqaesnhpnvmuq5.png" alt="Mobile app's screen with an image right at the top of the screen and toobar icons on the top of it" width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem was not only in the image. I was not sure whether the title should be collapsible too. This is a disadvantage of not using a design tool, BTW.&lt;/p&gt;

&lt;p&gt;Spend time figuring that out as well. But you know what? I eventually realized that the effort was not necessary because I could simply make it nicely appear on the toolbar when a user scrolls down. Moreover, I recently came up with a more nice and modern design solution that actually does not require a collapsing toolbar at all!&lt;/p&gt;

&lt;p&gt;For sure, I gained knowledge and experience, but next time I’ll try to be as lazy as possible. And I’ll think twice when I’m about to start something difficult I’m not sure about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring other people’s projects
&lt;/h2&gt;

&lt;p&gt;I thought it was a great idea to find out how certain features are implemented in other people’s projects. I know two open-source apps that are similar to what I want to build: &lt;a href="https://github.com/iSoron/uhabits" rel="noopener noreferrer"&gt;uhabits&lt;/a&gt; and &lt;a href="https://github.com/tasks/tasks" rel="noopener noreferrer"&gt;tasks.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But I discovered that finding the correct implementation takes lots of time cause the codebases are complex. You should jump through those classes and to actually understand how something is done there, you need to understand the whole structure. In addition, although these apps are native Android, people use different technologies that may be not suitable in my case.&lt;/p&gt;

&lt;p&gt;So I decided not to waste time for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bit of technical stuff
&lt;/h2&gt;

&lt;p&gt;My app is going to heavily use some API that deals with time. So this week, I decided to learn &lt;code&gt;kotlinx-datetime&lt;/code&gt; library. I hadn’t known how to work with &lt;code&gt;LocalDate&lt;/code&gt;s, &lt;code&gt;Instant&lt;/code&gt;s, and other things so I met these concepts for the first time.&lt;/p&gt;

&lt;p&gt;I found out that what’s very important in dealing with time is to store the time of events scheduled for the future in &lt;code&gt;LocalDateTime&lt;/code&gt; instead of &lt;code&gt;Instant&lt;/code&gt;s. That’s because otherwise if some country decides to suddenly change their timezone (e.g. decides to introduce/revoke DST), my app’s notifications will tell the user the wrong time of the event. I even made a &lt;a href="https://gist.github.com/DanielRendox/e0050c5724c4cd4808b7206f28ff9726" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt; with some notes on this library. &lt;/p&gt;

&lt;p&gt;Why &lt;code&gt;kotlinx-datetime&lt;/code&gt; when there is &lt;code&gt;java.time&lt;/code&gt;? I want to first develop my app on Android and then expand it to iOS with the help of Kotlin Multiplatform. Even though &lt;code&gt;kotlinx-datetime&lt;/code&gt; is yet alpha, I decided to use it, cause there currently is no other option.&lt;/p&gt;

&lt;h2&gt;
  
  
  My progress
&lt;/h2&gt;

&lt;p&gt;Alright, it’s about time I summarized my performance this week.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1#challenge"&gt;My challenge&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;✅ 6/5 tweets&lt;/p&gt;

&lt;p&gt;✅ 1/1 article (this one)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/virtualcoffee/join-virtual-coffee-in-the-healthy-habits-for-happy-devs-monthly-challenge-5b7h"&gt;VC’s &lt;strong&gt;Healthy Habits challenge&lt;/strong&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;☑️ &lt;strong&gt;Make my app:&lt;/strong&gt; worked for 44 hours (goal = at least 40h)&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Household:&lt;/strong&gt; did at least 1 household chore 6 days a week&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Physical activity:&lt;/strong&gt; 4/5 activities&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Rest:&lt;/strong&gt; had at least 1h each day&lt;/p&gt;

&lt;p&gt;☑️ &lt;strong&gt;Learn English:&lt;/strong&gt; learned 42/42 new words&lt;/p&gt;

&lt;h2&gt;
  
  
  I’m late for 2 days 😬
&lt;/h2&gt;

&lt;p&gt;I should’ve published this post on Thursday or Friday but while writing it, I came up with an idea of a simple learning app, which is not connected to the main one. Started working, and that’s what I was unexpectedly doing during these two extra days cause I initially thought it would take 1 hour at most 😅.&lt;/p&gt;

&lt;p&gt;Taking into account that my performance was OK, I’m gonna start over as if the 2nd week started now. I think I may do that (I hope so 😄).&lt;/p&gt;

&lt;p&gt;This is also a great thing about this weekly challenge type. Though I’ve messed up on the previous week, I have a perception that I’m starting over on the next one, which gives me a bit more motivation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Made a simple program for tracking my progress
&lt;/h2&gt;

&lt;p&gt;So here is that program that took me two days (damn).&lt;/p&gt;

&lt;p&gt;I like to visualize my progress with progress bars. That’s what this app is about. It allows users to enter a name of a routine and its progress, and displays it in a nice way. So here is how I roughly estimate mine for now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmb47w68yoestwkw4h6o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmb47w68yoestwkw4h6o.jpg" alt="A mobile app's screen with two lables and progress bars at the center: 1. Make my app — 5%, 2. Learn android — 40% . Other UI elements, such as screen title, FAB also present." width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, while I worked even more than planned, I didn’t do much actually. 😐 I set a goal to make my app with basic functionality in two months but I think my pace is currently too slow. Yet I’m happy that I already know about 40% of what I need to build this (not the whole Android, of course).&lt;/p&gt;

&lt;p&gt;And getting back to the app, while making this simple layout is indeed not so difficult, I also decided to make it work properly and introduce the “add routine” functionality, which was a challenge for me. I will improve it later, making the code more optimized and adding a database cause now the data gets lost when you close the app. The code is available in this &lt;a href="https://github.com/DanielRendox/PerformanceTracker" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, making such projects are my favourite learning style. I watch tutorials and then apply that knowledge in practice right away while creating something that is actually useful to me and other people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvements
&lt;/h2&gt;

&lt;p&gt;So there are some improvements to be made in both my work and life.&lt;/p&gt;

&lt;p&gt;First, I noticed that I don’t have a strict plan of what I should be doing at a time. So I just continue what I was doing the day before or come up with an idea and start working. This isn’t very productive in my experience. I’d better create a plan.&lt;/p&gt;

&lt;p&gt;I can’t really make a plan for building my app because I’m doing it for the first time and vaguely imagine the next thing I’ll have to deal with. But luckily, that’s not true for learning. So I’ve collected the necessary resources for the next two weeks or so and defined how much time I should spend on each. I’ll also try to apply the gained knowledge right away in my project so I do have some kind of a plan for building my app either.&lt;/p&gt;

&lt;p&gt;Second, I initially planned to do tasks in specific time blocks and not exceed the time of each. The challenge is that we usually have some distracting things that break our schedule. I found a solution to simply change the order of these tasks, which I call routines, and at the end, spend the planned amount of time on each. Honestly, I've completely failed with this one. It’s quite challenging but I think this can significantly increase productivity so I tweaked my schedule and I’ll try again.&lt;/p&gt;

&lt;p&gt;Also allotted some time for daily review, reading, and writing articles, cause I now have 160 only in my DEV reading list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring time, not work
&lt;/h2&gt;

&lt;p&gt;With all these improvements, I’ll remember that I’m not a superman to achieve everything. &lt;/p&gt;

&lt;p&gt;Here is one productivity tip that works for me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Measure how many hours you worked, not how much work you did.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s because, at first glance, you may appear not to have done much, but, in fact, this 20% that you’ve done contribute to 80% of the overall amount. It’s especially relevant to programming, where you usually have to spend lots of time fixing a bug or reading code and not appear to be very productive.&lt;/p&gt;

&lt;p&gt;BTW, that’s why I don’t really understand people who advise to apply the Pareto Principle, cause if this law exists, you can’t avoid it whatever you did.&lt;/p&gt;

&lt;p&gt;Of course, one may get distracted all the time and indeed not do much. Then this trick won’t work. But I’m sure that’s not true about me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;Anyway, the takeaway from this week will be that contributing to learning and building in public is indeed helpful for me. I enjoy it and see the increase in productivity. That’s because if I didn’t share my progress, I would’ve quit the challenge in a couple of days. That’s how it used to be.&lt;/p&gt;

&lt;p&gt;Alright, thanks for reading this article, good luck with &lt;strong&gt;your&lt;/strong&gt; projects and see you later. 👋&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>showdev</category>
      <category>learning</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Finding My Blogging Path: Lessons from My Journey</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Fri, 04 Aug 2023 07:00:00 +0000</pubDate>
      <link>https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1</link>
      <guid>https://dev.to/danielrendox/finding-my-blogging-path-lessons-from-my-journey-31d1</guid>
      <description>&lt;p&gt;If you’re starting out in writing, you probably have little idea about what to blog about and where to do it, but the last thing you want to do is to follow my mistakes. Take a look at my journey, and find answers to these questions.&lt;/p&gt;

&lt;p&gt;
  Table of contents
  &lt;ol&gt;
&lt;li&gt;Starting out 👶&lt;/li&gt;
&lt;li&gt;The mistake 🤦‍♂️&lt;/li&gt;
&lt;li&gt;Reflection 🤔&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learning and building in public 🧠&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You document your progress&lt;/li&gt;
&lt;li&gt;You meet new people, give and get help along the way&lt;/li&gt;
&lt;li&gt;You make notes about what you’re studying, which helps you remember it.&lt;/li&gt;
&lt;li&gt;This ignites your motivation to continue learning and building.&lt;/li&gt;
&lt;li&gt;You build your brand, but that’s secondary.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you want to start 📣&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What blogging platform?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What am I going to do? 📅&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Teaching is not the best learning technique!&lt;/li&gt;
&lt;li&gt;2. It takes A LOT of time for little gain&lt;/li&gt;
&lt;li&gt;Plans for the future&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Challenge 💪&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My SMART goal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclusion&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting out 👶
&lt;/h2&gt;

&lt;p&gt;In March this year, I registered on DEV community. I vaguely imagined what was the actual reason for doing that. But what I knew for sure, was that coding alone, I wouldn’t go far. The initial plan was to share my programming notes to possibly help others and gain followers. This way, I wanted to show myself to the world and meet new people.&lt;/p&gt;

&lt;p&gt;To realize these plans, I started making tutorials about what I was learning. That’s because no one would’ve read my notes unless I’d made guides from them. And I discovered that these were not easy to make. It, first of all, took A LOT of time. But being goal-oriented, I tried to make everything to get them popular, to read how I can make my tutorials better, improve them in various ways, learn about SEO, and even switch the platform.&lt;/p&gt;
&lt;h2&gt;
  
  
  The mistake 🤦‍♂️
&lt;/h2&gt;

&lt;p&gt;But that approach turned out to be a mistake. I found myself learning things only for the sake of making tutorials. In fact, now I have bad impressions of multithreading in Java, only because I spent a lot of time on that. Although this knowledge will certainly come in handy, I could be so much better off doing what I do now. &lt;/p&gt;

&lt;p&gt;I’ve loved writing since my childhood. But, honestly, I didn’t really enjoy the process when I was writing those articles. In addition, except for the one that was successful, they didn’t get very popular and useful for others. So I decided to turn up to &lt;a class="mentioned-user" href="https://dev.to/jmfayard"&gt;@jmfayard&lt;/a&gt; for some advice. He told me a very interesting thing that got stuck in my head for a long time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On your blog, you are currently writing about race exceptions, threads, that kind of Java things.&lt;/p&gt;

&lt;p&gt;If I had magical growth hacking techniques, and would make your blog more popular, what kind of people would you attract?&lt;/p&gt;

&lt;p&gt;The kind of people whose primary interest are race exceptions in Java and such technico-technical questions.&lt;/p&gt;

&lt;p&gt;There is no point in going faster in the wrong direction. Start writing about you and your projects. Write for and with your real audience.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was relieved that I found a solution to my problem and that I no longer needed to write those tutorials. And it seems very logical, cause what you do should be aligned with your goals. My goals are:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to meet new people and showcase my work to others. My dream is to work in a team of passionate developers who are friends with each other and work together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think that communication is one of the key things on the way to success, and a very important one if I want that dream to come true. Attracting people that are interested in me, not in my tutorials, makes so much sense here. And while I chose the right blogging platform that meets my goals, I wasn’t doing the right things there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reflection 🤔
&lt;/h2&gt;

&lt;p&gt;However, my initial plans and ideas didn’t come from nowhere. And if you do the same thing, you probably didn’t come up with this idea yourself.&lt;/p&gt;

&lt;p&gt;Lots of people make tutorials and succeed. There are many good educators whom I follow and who give out very helpful information in an understandable way, and help lots of other devs. I think, there is some part of their followers, who are interested in them and are ready to work with them if they invite. And the bigger audience they have, the more people are in that part.&lt;/p&gt;

&lt;p&gt;Educating work assures a potential recruiter about your experience in a certain field. Teaching others is also known as a great learning technique. What if I possess a latent passion for educating and if I make things right, I'll enjoy the process and achieve my desires?&lt;/p&gt;

&lt;p&gt;So, I was torn between these two, by sight, contradicting choices. I couldn’t start doing both because I usually do something only when I clearly see what my goals are and how I achieve them.&lt;/p&gt;

&lt;p&gt;The common sense pushed me to choose the second approach. But, I didn’t know what I could write about myself and my projects, unlike when it comes to writing about technical things.&lt;/p&gt;

&lt;p&gt;Meanwhile, life went on, I engaged on DEV, and once found a post about the Virtual Coffee community. I was interested by the described level of communication. There were regular Zoom conferences and a Slack channel where people could support each other, give and get advice, talk about their wins and challenges, and work together. I was really impressed by how all of these meet my goals, I could also get an opportunity to speak to native English speakers for the first time in my life. Imagine my surprise when I found out that I was approved to enter!&lt;/p&gt;

&lt;p&gt;But the reason I’m telling you that is that Virtual Coffee was exactly what caused me to discover the learning and building in public concept. Before that, I’d, honestly, found things like the following weird:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/devteam" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1%2Fd908a186-5651-4a5a-9f76-15200bc6801f.jpg" alt="The DEV Team" width="800" height="800"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38578%2F5cadc1f1-fbca-496d-a375-667c21d9c122.jpg" alt="" width="800" height="758"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/devteam/what-was-your-win-this-week-5fll" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;What was your win this week?&lt;/h2&gt;
      &lt;h3&gt;Michael Tharrington for The DEV Team ・ Jul 28 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#weeklyretro&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/codenewbieteam" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2167%2F818710f4-d438-447d-aee3-3dff760c74a3.jpg" alt="CodeNewbie" width="800" height="800"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38578%2F5cadc1f1-fbca-496d-a375-667c21d9c122.jpg" alt="" width="800" height="758"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/codenewbieteam/what-you-learning-about-this-weekend-3oe2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;What you learning about this weekend?&lt;/h2&gt;
      &lt;h3&gt;Michael Tharrington for CodeNewbie ・ Jul 29 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#codenewbie&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#learning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/virtualcoffee" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3610%2F42d75122-d731-47ba-9473-cf192c6293a6.png" alt="Virtual Coffee" width="800" height="800"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F345658%2Fa72b6b8b-b954-47fb-8919-ab380905f26b.jpg" alt="" width="800" height="1058"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/virtualcoffee/build-in-public-week-one-check-in-4dai" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Build in Public: Week One Check-in&lt;/h2&gt;
      &lt;h3&gt;BekahHW for Virtual Coffee ・ Jul 7 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#learning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I thought, like, “Who cares about what you are learning or building?” and didn’t understand the guys who shared this info.&lt;br&gt;
People are selfish. They wanna find something valuable for themselves in your articles.&lt;br&gt;
But the warmth of the Virtual Coffee community in their monthly challenge, caused me to do some more research on this topic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Learning and building in public 🧠
&lt;/h2&gt;

&lt;p&gt;It appears that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some people actually do care;&lt;/li&gt;
&lt;li&gt;that’s exactly you who should not care whether somebody cares or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tried to see things from a different perspective. What do people who share their progress get? Turns out there are plenty of benefits:&lt;/p&gt;
&lt;h3&gt;
  
  
  You document your progress 📝
&lt;/h3&gt;

&lt;p&gt;You don’t just blindly go in an indefinite direction. You track your progress by regularly writing about what you achieved, what setbacks you encountered, and what your future plans are. &lt;/p&gt;

&lt;p&gt;When you face up to a challenge, you can look back, appreciate how far you've come, and how many adversities you’ve already encountered, and get determined and motivated to continue.&lt;/p&gt;

&lt;p&gt;Moreover, it may be even beneficial to your career, cause future employers will see the evidence that you've gained the knowledge over time.&lt;/p&gt;
&lt;h3&gt;
  
  
  You meet new people, give and get help along the way
&lt;/h3&gt;

&lt;p&gt;Sharing your journey sparks a conversation, and lets you meet new people. Talking about ourselves is what we are usually doing in daily conversations, that's what creates new relationships.&lt;/p&gt;

&lt;p&gt;There are so many people, who faced and will face the challenges you encounter, so you may give help to less experienced, and get it from more experienced. &lt;/p&gt;
&lt;h3&gt;
  
  
  You make notes about what you’re studying, which helps you remember it.
&lt;/h3&gt;

&lt;p&gt;As explained in the “&lt;a href="https://www.amazon.com/Make-Stick-Science-Successful-Learning/dp/0674729013" rel="noopener noreferrer"&gt;Make It Stick&lt;/a&gt;” book, recalling what you’re learning helps to put that knowledge into long-term memory, and is a great studying technique.&lt;/p&gt;

&lt;p&gt;Everything gets forgotten over time though, no matter how hard you try. But taking notes minimizes forgetting. It will be also easier to recall the knowledge if you have notes. &lt;/p&gt;
&lt;h3&gt;
  
  
  This ignites your motivation to continue learning and building.
&lt;/h3&gt;

&lt;p&gt;To my mind, the most important benefit of this activity is that making some public promises forces you to continue learning and building consistently. If I promise to post at least 5 tweets and 1 article a week documenting my progress, I’ll not break this promise. That’s because people will expect me to do that, and if I don’t, they’ll see me as a not responsible person.&lt;/p&gt;
&lt;h3&gt;
  
  
  You build your brand, but that’s secondary.
&lt;/h3&gt;

&lt;p&gt;Your blog may get many views, after all. If that happens, you achieve all of these goals. Your next project will get seen and used, your future employers will appreciate your audience, your knowledge, and your experience. &lt;/p&gt;

&lt;p&gt;However, this benefit is secondary. You write for yourself in the first place. You actually get most of the benefits even if you do it privately, publicity only introduces some more cool things and motivates you. Following this approach and trying to become famous is the last thing you wanna spend time on. Here is the reasoning ⬇️&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1683857360756809729-997" src="https://platform.twitter.com/embed/Tweet.html?id=1683857360756809729"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1683857360756809729-997');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1683857360756809729&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;p&gt;BTW, I also started to notice that even educators don’t post only about technical things. Talking about their journeys and giving advice to other devs is an integral part of their work. For example: &lt;a href="https://www.youtube.com/playlist?list=PLrnPJCHvNZuA73XM1lqZ67wShYExxDZhT" rel="noopener noreferrer"&gt;Florian Walther&lt;/a&gt;, &lt;a href="https://youtu.be/MSQr65bcUpY" rel="noopener noreferrer"&gt;Donn Felker&lt;/a&gt;, &lt;a href="https://youtu.be/0WSfv1vRV0s" rel="noopener noreferrer"&gt;Rahul Pandey&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you want to start 📣
&lt;/h3&gt;

&lt;p&gt;If you plan to start learning and building in public, definitely check out this post ⬇️ for lots of valuable advice from an experienced person.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/blackgirlbytes" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F302741%2F5ed2ea8e-056a-4065-9bed-57d24a96b607.png" alt="blackgirlbytes"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/blackgirlbytes/how-to-learn-in-public-1coh" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to learn in public&lt;/h2&gt;
      &lt;h3&gt;Rizèl Scarlett ・ Dec 18 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#learninpublic&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#career&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#leadership&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#community&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  What blogging platform?
&lt;/h3&gt;

&lt;p&gt;Speaking about the blogging platform, I’ll never regret choosing DEV, cause thanks to this platform, I found Virtual Coffee. I feel like DEV is the most suited for my needs.&lt;/p&gt;

&lt;p&gt;If you, like many people, also consider &lt;a href="https://medium.com" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, DEV is about the community, whereas on Medium you’re a product. They aim for their membership program. I don't want my articles to ever become paid.&lt;/p&gt;

&lt;p&gt;There are other platforms, but if you're on DEV and like it here, why not stay? For people like me, I see little benefit in cross-posting unless you have your own website or cross-post to LinkedIn.&lt;/p&gt;

&lt;p&gt;I think, having a personal website is great in terms of promoting, being a better specialist in the eyes of an employer, keeping all your work in one place, and owning it. &lt;/p&gt;

&lt;p&gt;But blogging on DEV is also a great thing to do. Don't wait until you get a website or any other resource that stops you from doing what you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  What am I going to do? 📅
&lt;/h2&gt;

&lt;p&gt;All of those look appealing, but what did you decide at the end, Daniel?&lt;/p&gt;

&lt;p&gt;Well, first of all, I’m certain that tutorials are not a way to go. That’s still a great way if you want to be an educator, but I don’t. &lt;/p&gt;

&lt;p&gt;And if you’re in a similar position, I would encourage you to consider learning and building in public instead of making tutorials because of these two reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Teaching is not the best learning technique!
&lt;/h3&gt;

&lt;p&gt;There are many people who will tell you the opposite. Lies! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There has never been a better learning technique than &lt;strong&gt;practice&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;University professors may know more, but they don’t do a good job if they don’t practice in side projects, or don't work at some company. On the contrary, good educators often work as freelancers or make their own projects. &lt;/p&gt;

&lt;p&gt;I don’t argue that teaching is great. It's the best after practice. It's great when you quickly explain a learned concept to your mate, but a different story when you spend a lot of time when you could be better off applying that knowledge to personal projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. It takes A LOT of time for little gain
&lt;/h3&gt;

&lt;p&gt;As I see it, to get successful in educating, you should do that seriously and firmly by growing your social media, publishing consistently, eventually transitioning to YouTube, etc. Otherwise, you will not get popular and will not make a profit from this. Therefore IMO, this does not worth that amount of time.&lt;/p&gt;

&lt;p&gt;In addition, there are lots of people who are already in that business. They are doing well. The are a lot of great learning resources nowadays. So there is a lot of competition and if you want your guides to really help people, you should make them better than existing ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plans for the future
&lt;/h3&gt;

&lt;p&gt;However, understand me correctly, if I’m learning a difficult topic and I don’t seem to find any resources that would explain it well, I’ll certainly make my own article with an explanation. That’s what I did in this post ⬇️&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/danielrendox" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1050901%2Faab1bb56-2b61-4fb3-b3d9-6ea0b66292d4.jpg" alt="danielrendox"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/danielrendox/delegation-vs-inheritance-in-kotlin-d48" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Delegation vs Inheritance in Kotlin&lt;/h2&gt;
      &lt;h3&gt;Daniel Rendox ・ Jul 5 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#kotlin&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#oop&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;On the other hand, the concept of learning and building in public combines almost all the benefits of talking about your journey and writing about technical things. This approach is the most suited for beginners. That’s what I plan to do in the first place.&lt;/p&gt;

&lt;p&gt;And I’ll try to make these posts helpful for other people so that they could benefit from my journey and get some advice.&lt;/p&gt;

&lt;p&gt;And there are also general topics when you write about your experience in life, programming, etc. This, obviously, attracts more people than some tutorials about Race conditions. And these people are my real audience. That’s what I plan to do in the second place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenge 💪
&lt;/h2&gt;

&lt;p&gt;For me, this idea of learning and building in public seems very exciting. This really stirs up my productivity soul, taking into account that &lt;a href="https://dev.to/danielrendox/comment/28bba"&gt;last time I’m trying to stabilize my schedule&lt;/a&gt;. So I wanna take the following challenge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the end of each day, at least 5 days a week I’ll post on &lt;a href="https://twitter.com/DanielRendox" rel="noopener noreferrer"&gt;my Twitter&lt;/a&gt; about what I’ve learned and made today.&lt;/li&gt;
&lt;li&gt;And over on DEV, I'll write at least 1 summary article every week, talking about what I did, what I learned, my wins, and difficulties.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My SMART goal
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Specific&lt;/strong&gt;: I want to learn Android to get a freelance job and create an Android app to practice my skills, get myself organized, and help other people.&lt;br&gt;
&lt;strong&gt;Measurable&lt;/strong&gt;: I'll spend at least 40 hours a week learning and working.&lt;br&gt;
Attainable: I'm already familiar with Jetpack Compose, Kotlin, and the View system, so I have about 30% knowledge of Android.&lt;br&gt;
&lt;strong&gt;Relevant&lt;/strong&gt;: After I achieve my goal I see further development in Kotlin multiplatform, Android is widely used and in demand, and I’ll certainly get relevant knowledge that’ll come in handy in my career.&lt;br&gt;
&lt;strong&gt;Time-bound&lt;/strong&gt;: I’ll give myself 2 months. In this period of time, I should have the app with the basic functionality.&lt;/p&gt;

&lt;p&gt;The challenge starts today!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So write about you and your projects. Absolutely recommend considering learning and building in public. Don't care much about getting famous, write for yourself in the first place.&lt;br&gt;
With that being said, I think I'm on the right way now, I hope you're too, my dear reader. Either way, let's just do what we like and follow our passion.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>beginners</category>
      <category>career</category>
      <category>community</category>
    </item>
    <item>
      <title>Delegation vs Inheritance in Kotlin</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Wed, 05 Jul 2023 14:33:18 +0000</pubDate>
      <link>https://dev.to/danielrendox/delegation-vs-inheritance-in-kotlin-d48</link>
      <guid>https://dev.to/danielrendox/delegation-vs-inheritance-in-kotlin-d48</guid>
      <description>&lt;p&gt;Hello, everyone! Welcome to the article about class delegation in Kotlin. This tutorial will help you understand how to use class delegation in Kotlin and when to use it instead of inheritance.&lt;/p&gt;

&lt;p&gt;The examples in this article are not mine and were taken from &lt;a href="https://medium.com/androiddevelopers/delegating-delegates-to-kotlin-ee0a0b21c52b" rel="noopener noreferrer"&gt;this article&lt;/a&gt; with some changes applied. It provides a good explanation but, to my mind, lacks some things crucial for understanding. So I brought them up here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use delegation instead of inheritance
&lt;/h3&gt;

&lt;p&gt;Let’s say we want a list’s item to be recoverable after deletion. To achieve this, we need to implement &lt;code&gt;MutableList&lt;/code&gt;, override the &lt;code&gt;remove&lt;/code&gt; function, and create our own &lt;code&gt;recover&lt;/code&gt; function. But to do this, we need to override other methods that the &lt;code&gt;MutableInterface&lt;/code&gt; tells us. So we essentially need to create our own implementation of &lt;code&gt;MutableList&lt;/code&gt;. That’s not a cool thing to do as all the code is already written for us.&lt;/p&gt;

&lt;p&gt;To avoid creating our own list, we can extend &lt;code&gt;ArrayList&lt;/code&gt; instead. But this approach is not good for abstraction. We don’t want this list to be an ArrayList. We don’t need &lt;code&gt;ArrayList&lt;/code&gt;'s specific methods like &lt;code&gt;trimToSize&lt;/code&gt;, &lt;code&gt;ensureCapacity&lt;/code&gt;, &lt;code&gt;grow&lt;/code&gt;, etc. We just want to have an additional function. &lt;/p&gt;

&lt;p&gt;So there is a better way to achieve this. And this is delegation. We want to have only &lt;code&gt;MutableList&lt;/code&gt;'s functions overridden by &lt;code&gt;ArrayList&lt;/code&gt; and our own implementation of &lt;code&gt;remove&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the delegation pattern works
&lt;/h3&gt;

&lt;p&gt;We need to create a new variable of the &lt;code&gt;ArrayList&lt;/code&gt; type and, at the same time, implement &lt;code&gt;MutableList&lt;/code&gt;. And then in all the overridden functions’ bodies, respective &lt;code&gt;ArrayList&lt;/code&gt;'s methods should be called. For example,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListWithTrash&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;innerList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// the variable for storing the last deleted item&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;deletedItem&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;deletedItem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="c1"&gt;// calling ArrayList's method, not our implementation&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;innerList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// here is our own function for recovering elements&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deletedItem&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// calling ArrayList's method, not our implementation&lt;/span&gt;
        &lt;span class="n"&gt;innerList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In this example, we override only &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;remove&lt;/code&gt; &lt;code&gt;MutableList&lt;/code&gt;'s methods. But we have a bunch of other methods we have to override for this to compile. That’s a lot of boilerplate code!&lt;/p&gt;
&lt;h3&gt;
  
  
  How to delegate using &lt;code&gt;by&lt;/code&gt; keyword
&lt;/h3&gt;

&lt;p&gt;Luckily, we don’t need to do this. That’s how it works internally. Kotlin provides first-party support for delegation, and all this is done automatically under the hood. A developer's task is to use the simple &lt;code&gt;by&lt;/code&gt; keyword:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListWithTrash&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;innerList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;innerList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;deletedItem&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;deletedItem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;innerList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deletedItem&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In this example, the &lt;code&gt;innerList&lt;/code&gt; variable was also moved into the constructor to let the users of &lt;code&gt;ListWithTrash&lt;/code&gt; provide their own &lt;code&gt;ArrayList&lt;/code&gt;. This allows them to specify the desired list’s properties, for example, its size.&lt;/p&gt;

&lt;p&gt;This is called delegation because along with our own implementations, the rest of the functions are delegated to the other classes. In our case, we delegate &lt;code&gt;MutableList&lt;/code&gt; implementation to &lt;code&gt;ArrayList&lt;/code&gt;. The necessary functions are “provided by” &lt;code&gt;ArrayList&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Again, &lt;code&gt;ArrayList&lt;/code&gt;'s specific functions won’t work:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;listWithTrash&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ListWithTrash&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//    listWithTrash.trimToSize() // → exception! (ListWithTrash doesn't have this function)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If you need them, extend from &lt;code&gt;ArrayList&lt;/code&gt; directly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Multiple delegation is… allowed
&lt;/h3&gt;


&lt;div class="ltag__stackexchange--container"&gt;
  &lt;div class="ltag__stackexchange--title-container"&gt;
    
      &lt;div class="ltag__stackexchange--title"&gt;
        &lt;div class="ltag__stackexchange--header"&gt;
          &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fstackoverflow-logo-b42691ae545e4810b105ee957979a853a696085e67e43ee14c5699cf3e890fb4.svg" alt=""&gt;
          &lt;a href="https://stackoverflow.com/questions/44231619/how-kotlin-delegation-is-useful/44238951#44238951" rel="noopener noreferrer"&gt;
            &lt;span class="title-flare"&gt;answer&lt;/span&gt; re: How kotlin delegation is useful?
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="ltag__stackexchange--post-metadata"&gt;
          &lt;span&gt;May 29 '17&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;a class="ltag__stackexchange--score-container" href="https://stackoverflow.com/questions/44231619/how-kotlin-delegation-is-useful/44238951#44238951" rel="noopener noreferrer"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fstackexchange-arrow-up-eff2e2849e67d156181d258e38802c0b57fa011f74164a7f97675ca3b6ab756b.svg" alt=""&gt;
        &lt;div class="ltag__stackexchange--score-number"&gt;
          11
        &lt;/div&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fstackexchange-arrow-down-4349fac0dd932d284fab7e4dd9846f19a3710558efde0d2dfd05897f3eeb9aba.svg" alt=""&gt;
      &lt;/a&gt;
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--body"&gt;
    
&lt;p&gt;Also remember that you're not restricted to just one delegate. Kotlin's way of implementing delegation is similar to &lt;code&gt;traits&lt;/code&gt; implementation in languages like Groovy. You can compose different functionality via delegates. Kotlin's way can also be considered more powerful because you can "plug in" different implementations too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;interface Marks {&lt;/code&gt;&lt;/pre&gt;…
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--btn--container"&gt;
    &lt;a href="https://stackoverflow.com/questions/44231619/how-kotlin-delegation-is-useful/44238951#44238951" class="ltag__stackexchange--btn" rel="noopener noreferrer"&gt;Open Full Answer&lt;/a&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Delegation vs Inheritance
&lt;/h3&gt;

&lt;p&gt;Inheritance allows to get a ready implementation by extending from the respective class. Whereas class delegation allows making a custom inheritant without lowering the class in the hierarchy. This is done by “copying” the ready implementation from the delegate. Here is the scheme for our situation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13qxqwpex003lux7krtb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13qxqwpex003lux7krtb.png" alt="Scheme with squares and arrows that demonsrates inheritance on the left side and delegation on the right side. Inheritance: ListWithTrash extends from ArrayLIst, which in turn implements MutableList. Delegation: both ArrayList and ListWithTrash implement MutableList, and there is a connection between ArrayList and ListWithTrash."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This scheme is not entirely correct because &lt;code&gt;ArrayList&lt;/code&gt; doesn’t extend from &lt;code&gt;MutableList&lt;/code&gt; in Kotlin. But the idea stays the same — our class (&lt;code&gt;ListWithTrash&lt;/code&gt;) and the delegate (&lt;code&gt;ArrayList&lt;/code&gt;) are on the same level in the hierarchy. Check out the cover of this article.&lt;/p&gt;

&lt;p&gt;When to use which? Use inheritance only when you are sure that your class and the class you inherit from share all the common traits. If you think your class doesn’t need some variables or methods from its possible parent, and “is a” relationship doesn’t apply, it’s better to use delegation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That’s it! If this article was helpful, please, like it and follow for more. If you have any questions or corrections, feel free to write in the comments.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>kotlin</category>
      <category>tutorial</category>
      <category>oop</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Simple Technique to Achieve Your Goals with Consistent Action</title>
      <dc:creator>Daniel Rendox</dc:creator>
      <pubDate>Mon, 03 Jul 2023 13:59:32 +0000</pubDate>
      <link>https://dev.to/danielrendox/a-simple-technique-to-achieve-your-goals-with-consistent-action-415k</link>
      <guid>https://dev.to/danielrendox/a-simple-technique-to-achieve-your-goals-with-consistent-action-415k</guid>
      <description>&lt;p&gt;Hello, devs! After trying out various tools and systems people use to organize their time and projects, I think I finally found a simple yet effective technique that works for me. And I'm happy to share it with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Find out what you actually should do
&lt;/h2&gt;

&lt;p&gt;So you have a goal. You vaguely imagine what steps you are going to take to achieve that goal. But if you don't know what you actually should do, you might end up simply going with the flow and working without a clear direction.&lt;/p&gt;

&lt;p&gt;Let me provide an example. There are lots of people who want to learn English. But most of them fall into the common trap. From time to time, they need English and realize how many opportunities it opens for them. They get super excited, start reading books, learning grammar, etc. However, as time goes on, they find out how much effort is needed to learn English and start thinking: "I've managed just fine without English all this time..." Consequently, their learning comes to a halt, only to resume when the same cycle repeats itself.&lt;/p&gt;

&lt;p&gt;I'm not a native English speaker, and I used to fall into that trap too. So don't make this mistake. Find out how much effort is needed at the beginning and make a firm decision.&lt;/p&gt;

&lt;p&gt;Divide that big goal into the smaller ones that you can achieve in a week or month. This way, you will be happy to complete the goal and feel motivated to pursue the other ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Make it a routine
&lt;/h2&gt;

&lt;p&gt;Having a concrete plan is good, but you won't go far if you don't take action. It's always recommended to take action consistently and make it a habit.&lt;/p&gt;

&lt;p&gt;But I don't really like the word "habit". That's because a habit is meditating every day, going to bed at the same time, giving up smoking, and so on. You just do the same action consistently to, hopefully, improve your life. To track a habit, you don't need much information. You either completed the task or not. That again reminds me of going with the flow.&lt;/p&gt;

&lt;p&gt;Whereas "routine" refers to a habit with a concrete goal and a plan. To track a routine, you should know what you actually did and at what pace you are going.&lt;/p&gt;

&lt;p&gt;So allot a separate time to consistently move towards your goal. Make it a routine, and make sure that you complete the planned amount of tasks each week. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Track your progress
&lt;/h2&gt;

&lt;p&gt;I prefer to always know the time frames. Deadlines may not help because it's often difficult to estimate the time required for each task.&lt;/p&gt;

&lt;p&gt;I propose a different approach. Transform the tasks you set in the previous step in a way that they take roughly the same time. And just start doing these tasks. You'll eventually determine the pace you are moving at and will be able to roughly estimate the date of the completion day.&lt;/p&gt;

&lt;p&gt;This way, you'll be motivated to continue doing the tasks. That's because otherwise, the completion day will get further from you.&lt;/p&gt;

&lt;p&gt;This also helps when you want to do some other things for which you don't have enough time. Knowing how much it's going to take will help to rationally allocate your time among the routines.&lt;/p&gt;

&lt;p&gt;For example, I often initially imagine small-scale projects, but over time, they tend to grow more ambitious. If I were to go with the flow, I would immediately dive into developing new features. However, adopting this approach forces one to think whether it's reasonable to start doing that at the present moment. Maybe it's more appropriate to add the desired features later when the core is ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;To give you a real picture of how it works, I'll provide an example.&lt;/p&gt;

&lt;p&gt;Last time I've been learning Kotlin. The first thing I did when I started was find good learning resources and make a plan. Then I decided to dedicate 6 hours of work each day to this goal and started working.&lt;/p&gt;

&lt;p&gt;As I knew Java, it took me approximately a week to learn the essentials of Kotlin. But then I estimated the time needed to learning the higher-level things. I found out that it'll take me another week or even more. &lt;/p&gt;

&lt;p&gt;But I planned to learn Jetpack Compose. And dedicating nearly the whole workday to learning the advanced Kotlin stuff didn't seem so attractive. Putting Jetpack Compose off may have led to burnout since I wouldn't get much closer to building my Android app.&lt;/p&gt;

&lt;p&gt;I knew that advanced stuff wasn't so necessary to understand Jetpack Compose. So I decided to dedicate 4 hours of work to Jetpack and only 2 to higher-level Kotlin instead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That's why estimating the time is the most important thing here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I believe that if you use this simple technique, eventually, it will be easier to determine time frames. The work will become habitual. And you may magically complete your goal on the desired day without even realizing how you reached that point.&lt;/p&gt;

&lt;p&gt;But remember that no organization tool or productivity technique will help if you don't like what you are doing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have a goal that excites you, productivity will come from alone. [&lt;a href="https://www.instagram.com/p/CuMCUmgA8Hh/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==" rel="noopener noreferrer"&gt;author&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Spend time doing what it takes not searching for the best tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vakfyxpd32q21g2f2we.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vakfyxpd32q21g2f2we.gif" alt="Man in front of the green screen shouting "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for this article. I hope it'll help you! What are your thoughts about this? How do you get organized? I'd love to hear from you in the comments!&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
  </channel>
</rss>
