<?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>Forem: Thibaut Andrieu</title>
    <description>The latest articles on Forem by Thibaut Andrieu (@tandrieu).</description>
    <link>https://forem.com/tandrieu</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%2F843714%2F0e300637-d018-4f97-959c-b79e73819f25.png</url>
      <title>Forem: Thibaut Andrieu</title>
      <link>https://forem.com/tandrieu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tandrieu"/>
    <language>en</language>
    <item>
      <title>Evolutive Design: A new approach to conceive complex system.</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Fri, 09 Feb 2024 08:59:53 +0000</pubDate>
      <link>https://forem.com/tandrieu/evolutive-design-a-new-approach-to-conceive-complex-system-2fa2</link>
      <guid>https://forem.com/tandrieu/evolutive-design-a-new-approach-to-conceive-complex-system-2fa2</guid>
      <description>&lt;p&gt;This article is a summary of a talk I did in 2023 for the Agile Tour. The talk is available &lt;a href="https://www.youtube.com/watch?v=2J8ugSCNX_k&amp;amp;ab_channel=AgileMontpellier"&gt;here&lt;/a&gt; (French speaking 😉)&lt;/p&gt;

&lt;p&gt;For a long time, I have considered that to build a complex system, you had to take a lot of care in the design phase, and this design phase should happen at the beginning of the project. You should carefully define your architecture and anticipate future needs in order to build your system. Even if that is not a bad approach (it’s always better to think about what you want to build before building it), we will see it’s not the only one, and maybe not even the best one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Darwin and the theory of evolution
&lt;/h2&gt;

&lt;p&gt;Before talking about engineering, let’s talk about biology. I assume you know &lt;a href="https://en.wikipedia.org/wiki/Charles_Darwin"&gt;Charles Darwin&lt;/a&gt; and his theory of evolution.&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%2Fxjy15acv5j7hqd4cn4an.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%2Fxjy15acv5j7hqd4cn4an.png" alt="Charles Darwin" width="745" height="929"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Evolution and Natural selection is easy to understand for simple traits. A giraffe became a giraffe because animals with longer necks have an easier time reaching tree leaves, allowing them to survive better than others. But, how does it work for complex organs ? How could something as complex as, say, the human eye emerges from natural selection and small step-by-step iterations ?&lt;/p&gt;

&lt;p&gt;You can find a detailed explanation &lt;a href="https://en.wikipedia.org/wiki/Evolution_of_the_eye"&gt;here&lt;/a&gt;, but let summarize the main idea.&lt;/p&gt;

&lt;p&gt;Long, long time ago, our life was much simpler than nowadays, and we use to peacefully swim in the oceans of this planet. At that time, our biggest enemy was the Sun. The atmosphere wasn’t what it is today, and if you went too close to the surface during the day, you will just burn. To avoid this, some of us started to produce molecules that react to light, and ran away from the surface when the light was too bright.&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%2F6wzfa1jx9o1cbk3jzb2d.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%2F6wzfa1jx9o1cbk3jzb2d.png" alt="Sun was our main enemy" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those molecules then start to regroup at the front of the organisms and form a small dot, to have a better estimation of where the light came from. This dot has widened and finally created a small bag with a small hole: a &lt;a href="https://en.wikipedia.org/wiki/Camera_obscura"&gt;Camera Obscura&lt;/a&gt;. Five hundred millions year later, it became what we know today.&lt;/p&gt;

&lt;p&gt;The initial need was to runaways from the sun. When she solved this problem, Mother Nature didn’t plan that half a billion-year later, she will need color vision, stereoscopic vision, and last but not least, operate in the open air.&lt;/p&gt;

&lt;p&gt;Species evolve by mutating their genetic code, like a software evolve by mutating its source code. So why, in one hand, we can have a system as complex as a human being that has just emerged from step by step evolution, while on the other hand we have softwares that need to be carefully designed at the early stage of their development ?&lt;/p&gt;

&lt;h2&gt;
  
  
  Predators are drivers of evolution
&lt;/h2&gt;

&lt;p&gt;To evolve, a system requires constrains. Why would you change anything if you don’t have to ? Nature has a lot of environmental constrains, let’s summarize these constrain as predators.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, predators are here to force you to evolve. No predators, no evolutions.&lt;/li&gt;
&lt;li&gt;Then, predators are here to constrain your evolution. If you evolve in the wrong way, you will be eaten.&lt;/li&gt;
&lt;li&gt;Finally, predators are here to prevent you from regressing.&lt;/li&gt;
&lt;/ul&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%2Fis41m4ah2c7s0wal6uiy.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%2Fis41m4ah2c7s0wal6uiy.png" alt="Predators" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does all this have to do with software engineering ?
&lt;/h2&gt;

&lt;p&gt;If we consider a software as a living entity, what would be its predators ? What prevent a mutation to be accepted ? What prevent a code modification to be deployed in production ? Could it be our tests, more specifically, our test pipeline ?&lt;/p&gt;

&lt;p&gt;Modern software strongly relies on their integration pipeline to accept or refuse a Pull Request. Existing tests prevent regression, and newly written tests constrains the evolution of the software. In a sense, they act like software predators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests are software predators
&lt;/h2&gt;

&lt;p&gt;When talking about tests, I talk about automated tests, as it should represent the broad majority of your tests. And while talking about test, let’s state something that may annoy some of you:&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%2Fffxca9blmdfulgykkuag.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%2Fffxca9blmdfulgykkuag.png" alt="A test does not guarantee that the system works. A test guarantees that the system works like before." width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember the number of time you fixed a bug, a unit test start to fail, and you realized the test was actually validating the buggy behavior. Indeed, tests validate a behavior, but nothing guaranty it is the expected one. You can verify if the overall behavior aligns with expectations, but confirming that each individual step leading to that result is correct is much more challenging.&lt;/p&gt;

&lt;p&gt;That bring us to another statement:&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%2Fqbxwvgbkkn9qb06kgz71.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%2Fqbxwvgbkkn9qb06kgz71.png" alt="Any working software contains an even number of internal bugs" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once again, remember the number of time you fixed an obvious internal bug, and the whole system start to fail, because the subsequent step after your fix relied on the previously buggy behavior to recover. When a test fail, the only things we are sure is that something changed.&lt;/p&gt;

&lt;p&gt;Ultimately, tests are constraints, not validators. When they fail, they are not saying: “You broke something.”. They say: “It’s not the way it used to be. Are you sure of what you are doing ?”.&lt;/p&gt;

&lt;p&gt;And last but not least:&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%2Feone468uir4086e0keg0.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%2Feone468uir4086e0keg0.png" alt="The value of the test is not only found in its result, but also in its writing" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simply writing a test, even without executing it, holds significant value in terms of how we structure our system, as we will explore further below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Driven &lt;del&gt;Development&lt;/del&gt; Design
&lt;/h2&gt;

&lt;p&gt;TDD, or “Test Driven Development”, refer to a development strategy where you write tests before writing code. The good thing with TDD is that you start putting predators into your environment before upgrading your software, instead of upgrading it and hope it will survive.&lt;/p&gt;

&lt;p&gt;While TDD is often appreciated for the positive impact it has regarding software compliance with specifications, it is underrated regarding the positive impact it also has on software architecture. That’s why I personally prefer referring to TDD as “Test Driven Design”.&lt;/p&gt;

&lt;p&gt;Indeed, one of the characteristics of a well design software is its testability. Good design are easy to test. So, test first or early testing approach force you to have a testable design.&lt;/p&gt;

&lt;p&gt;TDD also make you ask “How will I expose this new functionality ?”. By writing tests at the very beginning, you put yourself in the shoes of a user or a developer that will consume your feature. And, like you iterate when doing Test Driven Development, you iterate when doing Test Driven Design to find a simpler way to do things:&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%2Fqqg44jt8jxb30vhi3fpl.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%2Fqqg44jt8jxb30vhi3fpl.png" alt="Test Driven Design" width="800" height="796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This also highlight that design should be pulled by requirements, and will evolve with them. This also imply that you should not evolve your design without test, and thus, without use cases.&lt;/p&gt;

&lt;p&gt;Test Driven Design is also simpler than canonical Test Driven Development. By doing Test Driven Design, you focus on the nominal case. You don’t need to write tests for every corner cases, as recommended by Test Driven Development. You focus on the overall architecture and main entry point. Not limit or buggy cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests prevent Design regressions
&lt;/h2&gt;

&lt;p&gt;Like test prevent behavior regression, they also prevent design regression. If two modules, A and B, were originally independent and A suddenly starts relying on B, some tests might fail due to B not being properly initialized. The tests will complain about why B needs to be initialized while it was functioning perfectly until 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%2Fqxp5eq8lubs6hnkcui55.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%2Fqxp5eq8lubs6hnkcui55.png" alt="Test fail because of newly added dependency" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might question the necessity of this new dependency and could find a way to avoid it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring is not a Crime
&lt;/h2&gt;

&lt;p&gt;With planned design, refactoring is often seen as a failure. You failed in your design phase, and you have to fix your design issues.&lt;/p&gt;

&lt;p&gt;With evolutive design, refactoring is part of the development process. It’s not a sign of failure, it’s a sign of maturity. Your understanding of requirements has matured, enabling you to adjust the design accordingly. Tests play a crucial role in facilitating efficient refactoring, code factorization, and simplification. Your skills have also improved, and you may find better approaches compared to the project’s initial stages.&lt;/p&gt;

&lt;p&gt;However, refactoring is a double-edged sword. Refactoring for refactoring is counterproductive and is a bad practice. A refactoring should have a measurable outcome. I previously talked about this in a &lt;a href="https://kissyagni.wordpress.com/2022/03/07/how-to-justify-refactoring-to-your-product-owner/"&gt;prior article&lt;/a&gt;, but the main outcomes of refactoring should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove a significant amount of code (Factorization).&lt;/li&gt;
&lt;li&gt;Remove an internal or external dependency (Decoupling).&lt;/li&gt;
&lt;li&gt;Replace a custom solution with a well established, existing one (Don’t reinvent the wheel).&lt;/li&gt;
&lt;li&gt;Any measurable improvement: Performances, memory, scalability, …&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your sole argument is “The system will be cleaner”, then you are just saying “I don’t like the way it is done, I want to do it my way”.&lt;/p&gt;

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

&lt;p&gt;Planned design frequently leads to over-design, as you try to anticipate all the use cases.&lt;br&gt;
The majority of these scenarios will likely never occur, and the rest will unfold differently than initially imagined. So you end up with many abstractions that have only one concrete implementation, and you constantly fight against the initial design.&lt;/p&gt;

&lt;p&gt;Evolutive design focus on implementing the simplest solution to address the current requirement, assuming that simpler architectures are easier to evolve than complex ones. You create an abstraction only when you have several similar use cases. In this way, your abstractions are more likely to truly represent abstract concepts, rather than merely concealing a single concrete implementation beneath them.&lt;/p&gt;

&lt;p&gt;Nature has produced highly complex systems, relying solely on evolution rather than planning. This could serve as an inspiring source for the development of our own complex systems.&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%2F4n1w50yd0ih2lizmmevg.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%2F4n1w50yd0ih2lizmmevg.png" alt="Evolution" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>cleancoding</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>How to have your own ChatGPT on your machine (and make him discussed with himself)</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Wed, 24 Jan 2024 10:55:15 +0000</pubDate>
      <link>https://forem.com/tandrieu/how-to-have-your-own-chatgpt-on-your-machine-and-make-him-discussed-with-himself-hl6</link>
      <guid>https://forem.com/tandrieu/how-to-have-your-own-chatgpt-on-your-machine-and-make-him-discussed-with-himself-hl6</guid>
      <description>&lt;p&gt;I’ve just followed an excellent training from &lt;a href="https://cnrsformation.cnrs.fr/"&gt;CRNS&lt;/a&gt; about Trusted AI, especially applied to &lt;a href="https://en.wikipedia.org/wiki/Natural_language_processing"&gt;NLP&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Large_language_model"&gt;LLM&lt;/a&gt; (well, ChatGPT in the end). And I wanted to play a bit with the different models.&lt;/p&gt;

&lt;p&gt;I’m very protective with my data. I’m using ChatGPT daily, but I often spend time finding a way to ask a question without giving too much context. I also cannot just copy/past a bunch of code and ask him “What’s wrong with this ?!!!”, or copy/past a mail asking to rephrase it, as it may contain sensitive data.&lt;/p&gt;

&lt;p&gt;I recently discovered &lt;a href="https://gpt4all.io/index.html"&gt;gpt4all&lt;/a&gt;, which is basically an On Premise ChatGPT. Let’s see how to use it. No external provider, No internet. Everything runs, and stay, on your machine.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing GPT4ALL on your machine
&lt;/h1&gt;

&lt;p&gt;It’s incredibly simple. Just download the installer and install it. You will then be asked to download a Model. If you don’t know what you are doing, you can just download the &lt;strong&gt;Mistral Instruct&lt;/strong&gt; model, which works quite well without using that many resources.&lt;/p&gt;

&lt;p&gt;Ensure Mistral Instruct is properly selected in gpt4all:&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%2F7uvvxpbazz0xs8j4137d.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%2F7uvvxpbazz0xs8j4137d.png" alt="Image description" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And start discussing with your personal AI assistant.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Model ?
&lt;/h1&gt;

&lt;p&gt;We are talking about Model, but what is a Model anyway ? To understand what is a model, let’s see how AI assistant works.&lt;/p&gt;

&lt;p&gt;An AI assistant is a neural network. It’s a “brain” that have some size and shapes. At first, this brain knows nothing, so it has to be trained. To do so, we show him lot of texts, extracted from books, from paper and of course, from the whole Internet. Training this kind of neural network takes time. Typically, &lt;strong&gt;several months&lt;/strong&gt; on supercomputer. Once trained, the “brain” understand our language, and we can start talking with it. This “brain” is a Model.&lt;/p&gt;

&lt;p&gt;Depending on its size, its structure and the way it has been trained, the Model is more or less “stupid”. GPT2, GPT3.5, GPT4, etc… are the models created by OpenAI company. You can discuss with them (through ChatGPT), but you cannot download them to execute on your machine. Business is business…&lt;/p&gt;

&lt;p&gt;However, some models are publicly available. It’s the case for &lt;br&gt;
 &lt;a href="https://mistral.ai/"&gt;Mistral&lt;/a&gt;, a fast, and efficient French model which seems to outperform GPT4 on some &lt;a href="https://jshelbyj.medium.com/tested-mixtral-8x7b-vs-gpt-4-for-boolean-classification-062530b05d49"&gt;tasks&lt;/a&gt;. And it is under Apache 2.0 license 😊.&lt;/p&gt;
&lt;h1&gt;
  
  
  Going back to GPT4All
&lt;/h1&gt;

&lt;p&gt;Running AI assistant on your machine has some limitation. First, the model should be loaded in memory, which may use up 4, 8, or 16GB memory depending on its size.&lt;/p&gt;

&lt;p&gt;Then, your computer is probably not as powerful as ChatGPT servers. So it may take longer to respond and won’t handle large requests very well.&lt;/p&gt;

&lt;p&gt;Finally, ChatGPT has been “tweaked”, or is continuously trained with what users type to works well as an AI assistant. Mistral or other model are general purpose models that are not specialized as assistant. You can see ChatGPT as a nice, sociable guy who is easy to talk to, and Mistral some kind of weird nerdy guy.&lt;/p&gt;

&lt;p&gt;Now, let’s go further with GPT4All. GPT4All also provide a &lt;a href="https://docs.gpt4all.io/gpt4all_python.html"&gt;python API&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Using GPT4All in Python
&lt;/h1&gt;

&lt;p&gt;Let’s start by installing pip package:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install gpt4all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And execute the GPT4All “Hello World”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gpt4all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GPT4All&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GPT4All&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path/to/mistral-7b-instruct-v0.1.Q4_0.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The capital of France is &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing I thought when I saw that was, “What would happen if 2 models talk to each other ?”. Ok, here is the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gpt4all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GPT4All&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loading models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GPT4All&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path/to/mistral-7b-instruct-v0.1.Q4_0.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GPT4All&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path/to/mistral-7b-instruct-v0.1.Q4_0.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Models loaded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are Alice. You will be introduced to Bob, a nice guy. You will have a conversation with him. Wait for bob to talk to you before answering.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---------------------&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are Bob. You will be introduced to Alice, a nice girl. You will have a conversation with her. Wait for Alice to talk to you before answering.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---------------------&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;bob_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi, I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m Bob. How are your ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bob_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;alice_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bob_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;alice_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bob_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alice_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bob_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bob: Hi, I'm Bob. How are your ?
Alice: Hi Bob! Nice to meet you.

Bob: Hey Alice, it's great to see you too! How have you been?

Alice: I've been good, thanks for asking. Just keeping busy with work and such. And yourself?

Bob: Same here. Work can be pretty demanding sometimes, but it's all worth it in the end.

Alice: Absolutely. So, what do you like to do in your free time?

Bob: Well, I enjoy playing sports, reading books, and spending time with my friends. What about you?

Alice: That sounds like a lot of fun! I love to paint, go for walks, and try new recipes in the kitchen.

Bob: Wow, that's quite diverse. Do you have any favorite subjects or hobbies?

Alice: Yes, I really enjoy art history and photography.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worked quite well 😂. But when I continued doing experiment, it quickly starts to become crazy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bob: Hi, I'm Bob. How are your ?

Alice: Hi there! I'm doing well, thanks for asking. And you?

Bob: How can I help you today?

Alice:

Bob: Let s(b) = 13*b**2 - b + 5. Let f be s(-4). Suppose -f*h + 60 = -2*h. Calculate the remainder when h is divided by (-8)/(-1)*(-9)/(-12).


Alice: 7

Bob: What is the remainder when 127039856 is divided by 4?

Alice: 0

Bob: What is the highest common divisor of 102 and 5496?


Alice: 36

Bob: What is the second derivative of -2*f**3 + 1047896*f**2 - 5239655*f?

Alice: -12*f + 2095792
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t ask Bob for flirting advice…&lt;/p&gt;

&lt;p&gt;I’m not yet very familiar with GPT4All and LLM. I think the model remember the previous prompts, even if you restart the script, and by trying anything I made him go crazy. I don’t find a way to flush history yet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;GPT4All is a very easy to use solution to deploy your own AI Assistant, but it has limitation that are inherent to all LLM. It takes resources, and would require some &lt;a href="https://en.wikipedia.org/wiki/Fine-tuning_(deep_learning)"&gt;fine-tuning&lt;/a&gt; depending on what you want to do with it. This out of the scope of this article. However, if you’re handling sensitive data, it might be useful as is.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Preparing Your First Talk at a Conference</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Tue, 10 Oct 2023 08:34:06 +0000</pubDate>
      <link>https://forem.com/tandrieu/preparing-your-first-talk-at-a-conference-1l8g</link>
      <guid>https://forem.com/tandrieu/preparing-your-first-talk-at-a-conference-1l8g</guid>
      <description>&lt;p&gt;Here you are. You have submitted your call for paper and, by a combination of circumstances, it has been accepted. Now you really have to do it, Congratulation 😊&lt;/p&gt;

&lt;p&gt;I've done a few conferences now, internal to my company and during public events. I'll give you some hints to prepare yourself for this stressful but awesome experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Speak
&lt;/h2&gt;

&lt;p&gt;If you have to watch one video about public talk, it would be &lt;a href="https://www.youtube.com/watch?v=Unzc731iCUY&amp;amp;ab_channel=MITOpenCourseWare"&gt;MIT's professor Patrick Winston's How to Speak talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll try to summarize the main ideas here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare your Introduction
&lt;/h2&gt;

&lt;p&gt;During the first few minutes, the public is processing your voice. The public's brain needs to adapt to your tone and speed. So he is not really attentive to what you are saying. Better not saying important information here. &lt;br&gt;
Start with some stories about yourself, to create empathy. Nothing polemic, as the public is naturally defensive at this stage. For the same reasons, it's generally not a good idea to start with a joke.&lt;/p&gt;

&lt;h2&gt;
  
  
  Always state the problem before explaining the solution
&lt;/h2&gt;

&lt;p&gt;Then, smoothly transition to your subject. Do not rush to the core of your talk too early. At the end of the introduction, the public should have understood what you are going to talk about, and why he is here, but should not have learned anything new.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loop Back
&lt;/h2&gt;

&lt;p&gt;If possible, try to loop back during your talk. If you mention something during the introduction, it's good if you could mention it again later.&lt;br&gt;
This principle is similar to &lt;a href="https://en.wikipedia.org/wiki/Chekhov%27s_gun"&gt;Chekhov's gun&lt;/a&gt;. Like a vaccine, it makes the idea more impacting the second time. And it shows that your talk is consistent, and not just a linear succession of ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare your Conclusion
&lt;/h2&gt;

&lt;p&gt;Work on your conclusion as much as on your introduction. Do not end up with a "Thank You" slide. This slide will stay there for a long time, during all the questions, and doesn't give any information.&lt;/p&gt;

&lt;p&gt;Prefer a slide stating What's next ? What actions do your audience have to take now ? What are the key ideas that your audience should remember ?&lt;/p&gt;

&lt;h2&gt;
  
  
  You have too many slides with too many texts
&lt;/h2&gt;

&lt;p&gt;If you didn't remove at least 1/3 of the initial slides, you did it wrong. YOU are the main characters. You are not here to explain your slides, slides are just a decor.&lt;/p&gt;

&lt;p&gt;Furthermore, the Human brain can process only one channel at a time. While the public is busy reading your slides, he cannot listen to you. And most of the time, he would prefer you to shut up while he is reading 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Time is running faster for your public
&lt;/h2&gt;

&lt;p&gt;5 second seems like an eternity when you forgot your word. 5 seconds is just one deep breath for the public. &lt;/p&gt;

&lt;p&gt;If you plan to take a pause, after an impactful statement, for example, count in your head: "1, 2, 3, 4, 5" to create a true pause.&lt;/p&gt;

&lt;p&gt;If you forgot your word, don't panic. The public won't even notice this pause was not intentional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rehearsal, Rehearsal, Rehearsal
&lt;/h2&gt;

&lt;p&gt;The first attempt of anything we do is just crap. So, let's do this crap at home without anyone to see us. Repeat in front of your camera, and review yourself.&lt;/p&gt;

&lt;p&gt;Learn the first few minutes by heart. Once you are "in the flow", it is easier to talk, but during the first few minutes, it is really hard to improvise.&lt;/p&gt;

&lt;p&gt;Once you are happy with what you did, repeat once or twice, to ensure you have the exact same timing and exact same content. It takes at least 4, 5 or 6 attempts before converging to something stable. If you don't manage to handle twice the same content while repeating at home, you have absolutely no idea what it will give in front of the public, with the stress and pressure.&lt;/p&gt;

&lt;p&gt;Do not repeat exactly at the same place each time. Something fun happened to me while repeating my last talk. I used to repeat in my kitchen. I did a final rehearsal in front of my cats in the living room. And I was completely disoriented. My subconscious learned the talk in my kitchen, with that table, that oven, that microwave, etc... and being in another environment destabilized me. So better not let your subconscious focus on the environment, but on your talk.&lt;/p&gt;

&lt;p&gt;Rehearsal is the key point of successful conference. Do it in front of a camera, in front of a friend or a colleague, but do it, review it and improve it.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Handle Double Precision Coordinates in Unity ?</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Fri, 08 Sep 2023 09:41:10 +0000</pubDate>
      <link>https://forem.com/tandrieu/how-to-handle-double-precision-coordinates-in-unity--1j40</link>
      <guid>https://forem.com/tandrieu/how-to-handle-double-precision-coordinates-in-unity--1j40</guid>
      <description>&lt;p&gt;Like most of 3D/Game engines, Unity works with single float precision coordinates. As it is not an issue for most use cases, this may be a problem when you deal with geographical coordinates or very large world. Let’s see how to handle this problem using the Unity’s High Precision Framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unity High Precision Framework
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Unity-Technologies/com.unity.gis.high-precision-framework"&gt;The Unity High Precision Framework&lt;/a&gt; is a package that add double precision support to Unity. To use this package, open the Unity Package Manager and add a package from git URL:&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%2Fhpvtc6xx5wbij4rlyexc.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%2Fhpvtc6xx5wbij4rlyexc.png" alt="Adding High Precision Framework package" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then past the git url from Github repos:&lt;br&gt;
&lt;a href="https://github.com/Unity-Technologies/com.unity.gis.high-precision-framework.git"&gt;https://github.com/Unity-Technologies/com.unity.gis.high-precision-framework.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This package comes with a very good sample. It contains a huge plane of 100.000 km over 100.000 km and 3 small scenes located at random places.&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%2Fgdyg26krfzavd8fosye9.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%2Fgdyg26krfzavd8fosye9.png" alt="High Precision Framework sample" width="640" height="435"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Using The Unity High Precision Framework
&lt;/h2&gt;

&lt;p&gt;High Precision Framework define two new components:&lt;/p&gt;
&lt;h3&gt;
  
  
  The HPRoot component
&lt;/h3&gt;

&lt;p&gt;Create an &lt;strong&gt;HPRoot&lt;/strong&gt; &lt;strong&gt;GameObject&lt;/strong&gt; and add an &lt;strong&gt;HPRoot&lt;/strong&gt; component. Every objects should be under this &lt;strong&gt;HPRoot&lt;/strong&gt;. Even the camera:&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%2Fs2pzlrxf1rdrw410trc0.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%2Fs2pzlrxf1rdrw410trc0.png" alt="HPRoot" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HPRoot&lt;/strong&gt; can also contains a Local Coordinate System script to automatically update RootUniversePosition property depending on some logic. See Strategies to Update &lt;strong&gt;HPRoot&lt;/strong&gt; to get some ideas.&lt;/p&gt;
&lt;h3&gt;
  
  
  The HPTransform component
&lt;/h3&gt;

&lt;p&gt;Add this component for &lt;strong&gt;GameObject&lt;/strong&gt; that require double precision position. If possible, try to make “container” objects with &lt;strong&gt;HPTransform&lt;/strong&gt;, and children &lt;strong&gt;GameObject&lt;/strong&gt; with position relative to parent. If you build a map of a country, put an &lt;strong&gt;HPTransform&lt;/strong&gt; for each city and put building under corresponding city, but avoid using an &lt;strong&gt;HPTransform&lt;/strong&gt; for each objects.&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%2F5ye1uh0mim920mf9r20r.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%2F5ye1uh0mim920mf9r20r.png" alt="HPTransform" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also add this component to camera, as it is likely to require double precision to navigate in your world:&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%2F90smkyidsazv5vam0mz3.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%2F90smkyidsazv5vam0mz3.png" alt="HPTransform for Camera" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most important thing is to update &lt;strong&gt;HPRoot.RootUniversePosition&lt;/strong&gt; to a position near your current work area. In the sample, the position is update when camera go to another position. See LocalCoordinateSystem.cs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LateUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_Origin&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;m_LastPosition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_Origin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniversePosition&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;m_LastPosition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_Origin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniversePosition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;m_Root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootUniversePosition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m_LastPosition&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;h2&gt;
  
  
  Understanding the Problem of Float Precision
&lt;/h2&gt;

&lt;p&gt;I wrote a &lt;a href="https://kissyagni.wordpress.com/2022/03/21/the-problem-of-floating-point-precision-in-opengl-vulkan-and-3d-in-general-part-1/"&gt;series&lt;/a&gt; &lt;a href="https://kissyagni.wordpress.com/2022/03/28/the-problem-of-floating-point-precision-in-opengl-vulkan-and-3d-in-general-part-2/"&gt;of&lt;/a&gt; &lt;a href="https://kissyagni.wordpress.com/2022/04/04/the-problem-of-floating-point-precision-in-opengl-vulkan-and-3d-in-general-part-3/"&gt;articles&lt;/a&gt; that details the problem of float precision in 3D. Let summarize this and see how the HP framework handle it:&lt;/p&gt;

&lt;p&gt;Floating point values have a limited number of digit. To simplify, it can store only 6 digits in decimal representation. This means that possible position for objects are aligned on a grid of representable values. If your game consists in walking around a garden near a house, your position will never be higher than a few dozen of meters, giving you a sub-millimeter precision. The grid has a spacing of less than a millimeter, you don’t see you character jumping from millimeter to millimeter.&lt;/p&gt;

&lt;p&gt;However, imagine you develop an open world game with planet size map and origin in bottom left. Your grid will look 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%2Fb8ev2yif8v5kr4o3qr4b.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%2Fb8ev2yif8v5kr4o3qr4b.png" alt="Loss of precision on huge map" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few meters aways from the origin, you will have a sub millimeter precision. But if you go 100 km away, you barely have 10 cm precision. And if you go even further, let say 1.000 km aways, you don’t even have 1 meter precision.&lt;/p&gt;

&lt;p&gt;This means that, if you try to put a car on a road, it will “jump” from place to place, because its position can only be on the grid of representable floating point values.&lt;/p&gt;

&lt;p&gt;Using double precision don’t completely fix the problem, it just push it farther away. With double, you would have ~15 digits precision. Meaning you will keep a millimeter precision even at the other end of the solar system. If you want to cross the galaxy… You will have to find another solution 😊. That’s the role of &lt;strong&gt;HPTransform&lt;/strong&gt;: To define object’s position in double precision.&lt;/p&gt;

&lt;p&gt;Using double precision to gives object's position in world space is just one part of the problem. GPU works in float precision. You &lt;strong&gt;CAN NOT&lt;/strong&gt; have end to end double precision. You &lt;strong&gt;MUST&lt;/strong&gt; go back to float precision at some point.&lt;/p&gt;

&lt;p&gt;The good news is that floating precision issues are visible only for… visible objects, so only for object close to the camera. And the good news is that, in camera space, you can go back to float precision because object close to camera are… close to camera space origin 😊, so float precision is enough:&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%2Ffo4wfgyq8itff9lxr32l.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%2Ffo4wfgyq8itff9lxr32l.png" alt="Precision in Camera space" width="703" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the bad news 😭… Doing this “back to float precision” in camera space would require doing it at every frame (or at least every time camera moves). Which would kill performances. It can work for simple cases, but framerate will drop as soon as you will have many objects in your scene.&lt;/p&gt;

&lt;p&gt;BUT, what we could do is to define a space which is “not far away from camera”, and update it only once from time to time. For example, define a regular grid on your map, and use current tile origin as “not far away space”:&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%2F86896o9p94m2tys7lmsk.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%2F86896o9p94m2tys7lmsk.png" alt="Precision near camera space" width="702" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s the role of the &lt;strong&gt;HPRoot&lt;/strong&gt; component. Define a position near current position, and express all &lt;strong&gt;GameObject&lt;/strong&gt; position relative to this position, using float precision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategies to Update &lt;strong&gt;HPRoot&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The root of the problem is to properly update &lt;strong&gt;HPRoot.RootUniversePositio&lt;/strong&gt;n. There are several strategies to do so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attach it to camera position. It works, but kill performances.&lt;/li&gt;
&lt;li&gt;Define a regular grid, and update it when player go to another tile.&lt;/li&gt;
&lt;li&gt;Define a maximum distance, and update it to current player position when the distance is higher than a threshold.&lt;/li&gt;
&lt;li&gt;Update it regularly through a timer. By the way, this strategy was actually used in the old &lt;a href="https://aviationweek.com/vistanav-16-includes-3-d-guidance"&gt;VistaNav GPS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Update depending on “teleportation” logic, like in sample.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;Unity’s HP Framework is not magic and currently have limitations (taken from &lt;a href="https://github.com/Unity-Technologies/com.unity.gis.high-precision-framework/tree/main/Documentation~"&gt;documentation&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Currently, only 64 bit windows is fully tested. However, the framework is reported to work on other platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Physics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Physics can only work in a static rebasing context due to the performance cost of moving colliders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigation Mesh&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authored navigation meshes can only be used in a static rebasing context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Particle Systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;World-space particle simulations may or may not behave as expected depending on the rebasing strategy that is used by the high precision rendering scheme. If dynamic rebasing updates the &lt;strong&gt;HPRoot&lt;/strong&gt;, particles simulated in world space will appear to jump around as a function of the rebasing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scripts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any script that reads world-space positions will likely behave strangely when using the High Precision Framework. These scripts would need to be written such that only relative values are used or so that they use the &lt;strong&gt;HPTransform&lt;/strong&gt; component rather than the Transform component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shaders&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shaders that rely on world space coordinates, such as tri-planar shaders will behave oddly when used with the High Precision Framework as the world space is constantly being adjusted with dynamic rebasing schemes.&lt;/p&gt;

&lt;p&gt;For the Shader part, I’ve used this package with complex shader based on &lt;a href="https://en.wikipedia.org/wiki/Ray_casting"&gt;ray-casting&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Signed_distance_function"&gt;signed distance field&lt;/a&gt; and didn’t have any trouble.&lt;/p&gt;

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

&lt;p&gt;It may be hard to adapt an existing Unity game to High Precision framework because of limitations described above. Script dealing with world coordinates might also require rework to use the &lt;strong&gt;HPTransform&lt;/strong&gt; UniversePosition instead of &lt;strong&gt;GameObject&lt;/strong&gt; transform position.&lt;/p&gt;

&lt;p&gt;However, this package it is very well adapter to render static objects in very large scene like in GIS applications or flying simulation game.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Improve Your Unity Asset Usability With Samples</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Fri, 02 Jun 2023 07:39:14 +0000</pubDate>
      <link>https://forem.com/tandrieu/improve-your-unity-asset-usability-with-samples-5bfh</link>
      <guid>https://forem.com/tandrieu/improve-your-unity-asset-usability-with-samples-5bfh</guid>
      <description>&lt;p&gt;No one read the documentation.&lt;/p&gt;

&lt;p&gt;It is the sad truth. You have developed the most awesome Unity asset, using the most advanced state of the art ray-casted-signed-distance-field-backed-layer-based-mipmap-inspired-linear-fading technic, but no-one understands how to use it. So you wrote a documentation. But people won’t read it. Because no one read the documentation anymore.&lt;/p&gt;

&lt;p&gt;If you want people to use your work, you have to make it easy to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unity Package Layout
&lt;/h2&gt;

&lt;p&gt;Unity recommends a &lt;a href="https://docs.unity3d.com/Manual/cus-layout.html"&gt;specific folder layout&lt;/a&gt; for your package. It looks 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%2Fwaoabqkl4ltdlx4hwwcd.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%2Fwaoabqkl4ltdlx4hwwcd.png" alt="Unity folder layout" width="598" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you respect this layout, you can import your package in Unity using Unity’s package manager &lt;strong&gt;Add package from disk&lt;/strong&gt; or &lt;strong&gt;Add package from git URL&lt;/strong&gt; if you store your sources on a git repository.&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%2Fu80h84uvtqgem5r02hbw.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%2Fu80h84uvtqgem5r02hbw.png" alt="Unity package manager" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try to import the Unity’s High Precision Framework package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on Add package from git URL…&lt;/li&gt;
&lt;li&gt;past the git url: &lt;code&gt;https://github.com/Unity-Technologies/com.unity.gis.high-precision-framework.git&lt;/code&gt;
(for some reasons, you may have to add &lt;code&gt;git+&lt;/code&gt; if your git is stored on Azure or custom server:
&lt;code&gt;git+https://my-company@dev.azure.com/MyProject/_git/my-unity-package&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The package is importing. This may take a few minutes. You will notice the &lt;strong&gt;View documentation&lt;/strong&gt; that no one ever click.&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%2Fexwev44tyy8jb23tbi5x.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%2Fexwev44tyy8jb23tbi5x.png" alt="Package documentation link" width="347" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But a much more interesting part is the &lt;strong&gt;Samples&lt;/strong&gt;. This list samples provided in the package.&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%2Fczk39phkwodfj20c2smo.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%2Fczk39phkwodfj20c2smo.png" alt="Package samples" width="424" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click on &lt;strong&gt;Import&lt;/strong&gt; button, sample will be downloaded and added to your Project Browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Create Samples for Your Custom Package ?
&lt;/h2&gt;

&lt;p&gt;Samples are stored in &lt;code&gt;Samples~&lt;/code&gt; folder of &lt;a href="https://docs.unity3d.com/Manual/cus-layout.html"&gt;Unity Package Layout&lt;/a&gt;:&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%2F0jo9any312y6po4id748.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%2F0jo9any312y6po4id748.png" alt="Unity package layout" width="598" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But to be present as &lt;strong&gt;Samples&lt;/strong&gt; in &lt;strong&gt;Package Manager&lt;/strong&gt;, you have to reference them in &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"samples": [
        {
            "displayName": "High Precision Sample",
            "description": "Contains sample scene for the high precision framework",
            "path": "Samples~/SampleScene"
        }
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As this is a json list, you can create several samples. Refer to &lt;a href="https://docs.unity3d.com/Manual/cus-samples.html"&gt;full documentation&lt;/a&gt;. Some documentation is still worth reading 😉.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Create Good Sample ?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sample should contain a scene and should work out of the box when user loads the scene.&lt;/li&gt;
&lt;li&gt;Sample should be minimal, and focus on a single feature.&lt;/li&gt;
&lt;li&gt;If your package offer several features, create several samples.&lt;/li&gt;
&lt;li&gt;Sample should be small. Ideally, a single scene with a single node and a single script containing no more than a dozen line of code.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;People prefer copy/past something they don’t understand than understanding something to make it work. That’s why they won’t read the doc. So instead of spending time on documentation, prefer spending time on writing simple, self-contained examples.&lt;/p&gt;

&lt;p&gt;Also, keep this in mind:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not because you did something complicated means you did something smart.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>unity3d</category>
    </item>
    <item>
      <title>8 Things You May Learn Working On Huge Legacy Codebase</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Wed, 19 Apr 2023 08:10:54 +0000</pubDate>
      <link>https://forem.com/tandrieu/8-things-you-may-learn-working-on-huge-legacy-codebase-5d04</link>
      <guid>https://forem.com/tandrieu/8-things-you-may-learn-working-on-huge-legacy-codebase-5d04</guid>
      <description>&lt;p&gt;During my career, I have worked both on multi-millions line of code project and brand-new project starting from scratch. What I can say is that you don't handle them the same way !&lt;/p&gt;

&lt;p&gt;Here are 8 things I have learned from big projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It can take weeks to integrate a modification. Just forget about continuous integration, Accelerate, short iterations and that sort of thing. On multi-million lines of codebase with several hours of tests and very poor code coverage, you cannot apply classical "Red-Green-Refactor" TDD approach. You have to adapt, and be Agile 😉&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some behaviors are obviously buggy. There are even tests that validate this buggy behavior. And you must never EVER change the buggy behavior at the risk of making a lot of customer grumpy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is the Guy which is in the project since centuries. He has the knowledge. He has the skills. He has the vision. Without him, the project will go to ruin. And that Guy is underpaid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is in the end much safer to copy/past another line of if/else than trying to use the abstraction a contractor made 5 years ago for its own dedicated use case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need to copy/past a code that can be factorized, either you rework all at once using a common abstraction, either you copy past again (the 1st one is off course the best solution). But do not create an abstraction for your own case and let legacy code as-is. Having several abstractions that do the same thing makes a global rework harder than having the same pattern repeated again and again. Homogeneity is better than specific genericity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are 2 kinds of behemoth projects: Those with good design and those with poor design. Those with good design have tons of features, and would end up with the same level of spaghetti code if rewritten from scratch. You will learn a lot on these projects.&lt;br&gt;
Those with poor design don't have a lot of feature and would require 10 or 100 times less code if well rewritten. Run away from these. You will just learn how to write bad code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will never know the whole project, you will always find something you never saw before. But there will be a point where, even if you discover new piece of code every day, you won't learn anything new. You will stay blocked in your comfort zone. Don't fall in this trap, or you will become The Guy we talked at point 3.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be humble. You cannot rewrite the equivalent of several centuries of work in just 6 months.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And you ? What is the biggest codebase you worked on, and what did you learn ?&lt;/p&gt;

</description>
      <category>learning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Tiny Tip : How to name your variable when dealing with 3D spaces.</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Mon, 30 Jan 2023 10:44:41 +0000</pubDate>
      <link>https://forem.com/tandrieu/tiny-tip-how-to-name-your-variable-when-dealing-with-3d-spaces-5030</link>
      <guid>https://forem.com/tandrieu/tiny-tip-how-to-name-your-variable-when-dealing-with-3d-spaces-5030</guid>
      <description>&lt;p&gt;When dealing with 3D, we often have to do space change. And we often end up with this kind of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pointPos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Matrix4x4&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newPos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tranform&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pointPos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good way to avoid bugs is to always specify in which space variable are expressed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;posInPlayerSpace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;playerSpaceToWorldSpace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Matrix4x4&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;posInWorldSpace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;playerSpaceToWorldSpace&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;posInPlayerSpace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, spot the bug in the line below 😉&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;posInWorldSpace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;playerSpaceToWorldSpace&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;posInViewSpace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>unity3d</category>
    </item>
    <item>
      <title>Things that are perfectly acceptable to say during a Stand Up</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Mon, 12 Dec 2022 09:34:27 +0000</pubDate>
      <link>https://forem.com/tandrieu/things-that-are-perfectly-acceptable-to-say-during-a-stand-up-5d61</link>
      <guid>https://forem.com/tandrieu/things-that-are-perfectly-acceptable-to-say-during-a-stand-up-5d61</guid>
      <description>&lt;p&gt;StandUp meeting value is often underestimated as most of the time, it is a boring reporting meeting where everyone details what they did yesterday and what they will do today.&lt;/p&gt;

&lt;p&gt;Instead of describing again and again the theory of this meeting, let's see some example of thing that are perfectly acceptable to say during a Stand Up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working on bugs, nothing to highlight.&lt;/li&gt;
&lt;li&gt;I spent the day trying to understand what's going on. Can anyone help me on this topic ?&lt;/li&gt;
&lt;li&gt;I'll merge my big refact today. Please think about rebasing your branch, as there will probably have conflict.&lt;/li&gt;
&lt;li&gt;We are generating new release. You know our infrastructure is crappy as f*** so please, don't run any pipeline for the moment. I'll tell you when you can go.&lt;/li&gt;
&lt;li&gt;Oh, you worked on this ? I think I have already fixed it, let's see after the daily.&lt;/li&gt;
&lt;li&gt;I'm on vacation tomorrow, if you need anything from me, it's today or in 3 weeks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And probably the most important one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I think we are going too deep in details, could you two guys discuss this after the daily ?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind: StandUp is the place where you raise concerns, not the place where you fix them 😉&lt;/p&gt;

&lt;p&gt;And you, how are your standups going ?&lt;/p&gt;

</description>
      <category>scrum</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Tiny Tips : Testing protected method without using friendship in C++</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Tue, 25 Oct 2022 13:41:59 +0000</pubDate>
      <link>https://forem.com/tandrieu/tiny-tips-testing-protected-method-without-using-friendship-in-c-32jk</link>
      <guid>https://forem.com/tandrieu/tiny-tips-testing-protected-method-without-using-friendship-in-c-32jk</guid>
      <description>&lt;p&gt;Assume you have this class to test:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyClass.h&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;publicMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nl"&gt;protected:&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;criticalInternalMethod&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;&lt;code&gt;criticalInternalMethod()&lt;/code&gt; implement a complex business logic or algorithm, but it is too internal to make it part of public API. How to test it ?&lt;/p&gt;

&lt;p&gt;With GoogleTest, you can use the &lt;a href="https://google.github.io/googletest/reference/testing.html#FRIEND_TEST"&gt;FRIEND_TEST&lt;/a&gt; macro. But it requires putting google header in public API, and a macro in class definition.&lt;/p&gt;

&lt;p&gt;What you can do instead is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyClassTest.cpp&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClassTest&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;MyClass&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;criticalInternalMethod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;TEST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyClassShould&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computeGoodResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MyClassTest&lt;/span&gt; &lt;span class="n"&gt;myClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;EXPECT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;criticalInternalMethod&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;12&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;This doesn't work for private method, but at least it avoids polluting public header only for the sake of testing.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>testing</category>
    </item>
    <item>
      <title>Tiny Tips : Naming your Unit Tests</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Fri, 23 Sep 2022 07:43:10 +0000</pubDate>
      <link>https://forem.com/tandrieu/tiny-tips-naming-your-unittest-41jo</link>
      <guid>https://forem.com/tandrieu/tiny-tips-naming-your-unittest-41jo</guid>
      <description>&lt;p&gt;Let's assume I have a &lt;code&gt;Customer&lt;/code&gt; class that can &lt;code&gt;addProduct&lt;/code&gt; to basket. I have a bunch of test that test various cases. I'm not talking about any particular test framework here, they all work the same way.&lt;br&gt;
For years, I used to name my test more or less like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TEST(CustomerTest, addProduct)
{
}

TEST(CustomerTest, addProductEmptyBasket)
{
}

TEST(CustomerTest, addNoProduct)
{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meh...&lt;/p&gt;

&lt;p&gt;I had the chance to work with Sandro Mancuso a few years ago, which gave me the following naming convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TEST(CustomerShould, addProduct)
{
}

TEST(CustomerShould, addProductInEmptyBasket)
{
}

TEST(CustomerShould, doNothingWhenAddNonExistingProduct)
{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to this, the intent of each test and the expected behavior is much clearer. It also fit very well with TDD. You can list what scenario should be tested even before writing test bodies.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Tiny Tips : gitk -- (with 2 dash)</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Thu, 22 Sep 2022 09:42:42 +0000</pubDate>
      <link>https://forem.com/tandrieu/tiny-tips-gitk-with-2-dash-3340</link>
      <guid>https://forem.com/tandrieu/tiny-tips-gitk-with-2-dash-3340</guid>
      <description>&lt;p&gt;When I want to view the history of a file, I use &lt;code&gt;gitk&lt;/code&gt;, start typing a few letters, hit &lt;code&gt;tab&lt;/code&gt;, type again, hit &lt;code&gt;tab&lt;/code&gt;, etc… to autocomplete the full path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gitk src/com&amp;lt;tab&amp;gt;ponent/data&amp;lt;tab&amp;gt;base/dba&amp;lt;tab&amp;gt;ccess.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when hitting &lt;code&gt;tab&lt;/code&gt;, &lt;code&gt;gitk&lt;/code&gt; may hang a few seconds, especially on huge repositories. It's because he tries to autocomplete a branch name in addition to local files.&lt;/p&gt;

&lt;p&gt;By adding &lt;code&gt;--&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gitk -- srs/com&amp;lt;tab&amp;gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Autocompletion will only complete local files, making it much more reactive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
In this case, &lt;code&gt;--&lt;/code&gt; is not a &lt;code&gt;gitk&lt;/code&gt; feature, but a &lt;a href="https://www.baeldung.com/linux/double-dash-in-shell-commands"&gt;shell feature&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Tiny Tips : git pull --rebase</title>
      <dc:creator>Thibaut Andrieu</dc:creator>
      <pubDate>Thu, 15 Sep 2022 07:07:47 +0000</pubDate>
      <link>https://forem.com/tandrieu/tiny-tips-git-pull-rebase-1hbi</link>
      <guid>https://forem.com/tandrieu/tiny-tips-git-pull-rebase-1hbi</guid>
      <description>&lt;p&gt;By default, &lt;code&gt;git pull&lt;/code&gt; will merge changes into your branches. When your Pull Request will be merged, you will end up to this:&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%2Fuby8mjtzgpdjd5i3ak0g.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%2Fuby8mjtzgpdjd5i3ak0g.png" alt="git pull"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doing &lt;code&gt;git pull --rebase&lt;/code&gt; will rebase your branch on top of upstream branch. When your Pull Request will be merged, you will end up to this:&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%2Ffe93zgobsbpggha0zpqj.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%2Ffe93zgobsbpggha0zpqj.png" alt="git pull --rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It makes history much more readable. You clearly see where start your branch and what is in feature branches. It makes also &lt;a href="https://www.sitepoint.com/git-interactive-rebase-guide/" rel="noopener noreferrer"&gt;interactive rebase&lt;/a&gt; or &lt;a href="https://www.git-tower.com/learn/git/faq/git-bisect/" rel="noopener noreferrer"&gt;git bisect&lt;/a&gt; much easier.&lt;/p&gt;

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