<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>NoisySignal</title><link href="https://noisysignal.com/" rel="alternate"></link><link href="https://noisysignal.com/feeds/atom.xml" rel="self"></link><id>https://noisysignal.com/</id><updated>2026-02-08T00:00:00-05:00</updated><entry><title>Copying a git branch from one machine to another</title><link href="https://noisysignal.com/copying-a-git-branch-from-one-machine-to-another.html" rel="alternate"></link><published>2026-02-08T00:00:00-05:00</published><updated>2026-02-08T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2026-02-08:/copying-a-git-branch-from-one-machine-to-another.html</id><summary type="html">&lt;p&gt;How to copy a git branch between two local machines without syncing through GitHub&lt;/p&gt;</summary><content type="html">&lt;p&gt;I often bounce between two Macs when I work. I use a Mac mini with a Studio Display set up in my office, which I use as my main workstation. I also have a MacBook Air that I use when traveling and also when I feel like doing a little work in a new setting in my house.&lt;/p&gt;
&lt;p&gt;Sometimes I’ll be in the middle of implementing a new feature or refactoring code on a project and I want to continue it on the other machine without pushing incomplete changes through GitHub.&lt;/p&gt;
&lt;p&gt;There are a few ways to solve this, but these are the steps I follow and have worked well for me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On the machine where the branch already exists (e.g. my laptop called &lt;code&gt;m3air&lt;/code&gt;): make sure the changes have been committed locally to the branch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the machine where you want to continue the work (e.g. my desktop called &lt;code&gt;mini&lt;/code&gt;): add a remote reference:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git remote add m3air m3air:/path/to/repo/on/m3air&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fetch just that branch:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git fetch m3air the-branch-name&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a local branch from it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git switch -c the-branch-name m3air/the-branch-name&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(Optional) Remove the remote reference if it’s no longer needed (but I keep the reference so next time there is one less step required):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git remote remove m3air&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then you can continue working on the new branch and push it as a new PR or merge it locally.&lt;/p&gt;
&lt;p&gt;Once merged, you can pull &lt;code&gt;main&lt;/code&gt; to the original machine (&lt;code&gt;m3air&lt;/code&gt; in my example) and delete the old branch as the changes are already merged in.&lt;/p&gt;</content><category term="misc"></category><category term="git"></category></entry><entry><title>Building an iOS App With AI</title><link href="https://noisysignal.com/building-an-ios-app-with-ai.html" rel="alternate"></link><published>2026-02-07T00:00:00-05:00</published><updated>2026-02-07T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2026-02-07:/building-an-ios-app-with-ai.html</id><summary type="html">&lt;p&gt;A reflective look at using Codex, ChatGPT, and Xcode’s Coding Assistant to build a new app from scratch.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Lately I&amp;rsquo;ve been reading a lot of stories about how people are using LLMs for developing software with notable success. I&amp;rsquo;ve been experimenting with these models myself, but mostly adding simple features to an existing app or fixing bugs. I wanted to try creating a complete program from scratch leveraging AI tools as much as I could to see how well the process works with various tools and approaches.&lt;/p&gt;
&lt;p&gt;I picked a problem that I thought would be fun but was probably something I wouldn&amp;rsquo;t get around to building if I had to code it all myself. This is one of the promises of LLMs - they lower the effort significantly such that you can create applications and tools that you otherwise wouldn&amp;rsquo;t consider. That&amp;rsquo;s attractive for a lot of personal, &amp;ldquo;hobby&amp;rdquo; level programs.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;The application is an iOS app to track weight workouts. I started with this prompt using Codex.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Create an Xcode iOS app project for the iPhone using SwiftUI that will allow me to track my weightlifting workouts. The app should allow me to create Workouts which are made up of Exercises. Each exercise has a number of Reps and a Weight in lbs. Each day I workout, I can record a completed workout and make any adjustments to the exercises/reps/weights that I actually performed. I can also enter notes for that completed workout. This will build a history of past workouts.&lt;/p&gt;
&lt;p class="prompt"&gt;The app should be easy to navigate and to see the elements of each exercise. The app will exist only on the iPhone - it does not need to work on an iPad or the Mac. It does not need to synchronize data across devices, but I would like to export the data to a file (e.g. JSON or CSV) and also import historical data that I’ve already been tracking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The prompt covers the basic features, but leaves a lot for the model to decide on its own. From this, Codex created an Xcode project with a number of model classes backed by a JSON file store. It created all the required SwiftUI views and a tabbed interface for the app. But when I tried to build the project in Xcode, it didn&amp;rsquo;t compile, primarily due to Xcode/Swift/SwiftUI version incompatibilities.&lt;/p&gt;
&lt;p&gt;This is something you get used to with these tools - LLMs are usually trained on data no more recent than 6 months ago, but coding tools, APIs, and libraries are changing all the time. AI tools often produce code that is slightly outdated. But LLMs are good at solving errors given an error message, so I was able to work through this pretty easily. Here are some examples of the kinds of errors I worked through to get the app to build and run.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;I get one build error in ContentView: Call to main actor-isolated initializer &amp;lsquo;init(fileName:)&amp;rsquo; in a synchronous
  nonisolated context&lt;br/&gt;
&amp;hellip;&lt;br/&gt;
I added @MainActor but am still getting the same error&lt;br/&gt;
&amp;hellip;&lt;br/&gt;
I no longer get the error in ContentView, but now I get two errors in WorkoutArchiveDocument:&lt;br/&gt;
Line 18: Call to main actor-isolated static method &amp;lsquo;decode(from:)&amp;rsquo; in a synchronous nonisolated context&lt;br/&gt;
Line 22: Call to main actor-isolated static method &amp;lsquo;encode&amp;rsquo; in a synchronous nonisolated context&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: I built this app using Xcode 26.0, which introduced Coding Assistant - limited LLM capabilities similar to early versions of GitHub Copilot. Xcode 26.0 did not include support for programming agents like Claude Code or OpenAI Codex, but this was recently added in 26.3 after I built this project; thus, most of my use of LLMs for this project involved using OpenAI Codex from the command line.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Using Codex in the terminal with an Xcode project works fine. Codex knows how to modify an Xcode project to add new files and change project settings, and Xcode recognizes when files have changed and reloads the project and source files.&lt;/p&gt;
&lt;p&gt;Xcode&amp;rsquo;s Coding Assistant is fine for small tasks like fixing bugs, so I used Codex for the larger tasks like adding a new feature or creating a new view. I used Xcode&amp;rsquo;s Coding Assistant for smaller tasks such as fixing a warning or tweaking a SwiftUI view. I also used ChatGPT a little bit using its &amp;ldquo;Work with Apps&amp;rdquo; feature. That works, but it only can see one source file at a time, so it&amp;rsquo;s a bit limited.&lt;/p&gt;
&lt;h2&gt;Pair Programming&lt;/h2&gt;
&lt;p&gt;The initial prompt got me started with an app I could play around with, which helped me refine my ideas. Once the basic functionality was working, my interaction with Codex was more like working with a fellow (albeit junior) programmer. I would report issues, ask for new features or changes in behavior, describe improvements to the UI, and then Codex would make changes to the code base.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;OK. It builds now, and I was able to run it on my phone. I tested the app and found a few issues: 1) an Exercise needs a number of Sets (integer); 2) I should be able to type a number in for Weight - it&amp;rsquo;s too tedious to use a spinner to increase it to 100 lbs for example; 3) I&amp;rsquo;d like to add an Equipment field to Exercise which uses a picker for &amp;ldquo;Barbell&amp;rdquo;, &amp;ldquo;Dumbbell&amp;rdquo;, or &amp;ldquo;Other&amp;rdquo;; 4) rename Plans to Routines; 5) there is a bug when I add more than two exercises where all of the additional ones (2 through n) mirror each other when I edit any property. So if I change the name of Exercise 3, then the names of Exercise 2 and 4 also change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These smaller iterations on the app were easier to manage since the context of a working app helped me create more specific prompts, which in turn helped the LLM&amp;rsquo;s accuracy in terms of hitting the mark that I expected. This interaction felt reminiscent of sitting next to a co-worker, watching what they did, and providing guidance and feedback. I also found myself in more of a directorial role than that of a pure developer. I would make higher-level decisions like UI design changes and specific names to use for labels and classes, and then let Codex work through the implementation details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;I&amp;rsquo;ve added comments to each Equipment enum value with the name of an SF Symbol. I&amp;rsquo;d like to use those in the picker for the exercise. Can you modify the enum to include the SF symbol names as an associated value and then use that to create Labels for the picker with the symbol and text value?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes Codex would make decisions that I didn&amp;rsquo;t agree with, and I would tell it so. Again, that&amp;rsquo;s common when working with junior or peer developers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;I actually prefer the standard picker. Can you revert that last change?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But I also would ask for large-scale changes to the app and let Codex grind away on a solution. I learned to be more specific and to have Codex ask me questions if I wasn&amp;rsquo;t clear enough.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;Add a new feature where the app will call out time reminders as I’m resting between sets and exercises. The way it should work is:&lt;br/&gt;
- once I start a workout, the app should begin listening for audio commands&lt;br/&gt;
- if it hears the word “set” it should start a 45-second countdown as follows: to begin it says “45” then alternating tick/tock sounds every second until it gets to thirty when it calls out “thirty” and then the tick/tock sounds until it calls out “15” and then tick/tock sounds until the last 5 seconds in which case it uses a beep sound until the countdown is done and it finally ends with “done”&lt;br/&gt;
- if it hears the word “rest” it does the same thing but it begins the countdown from 60 instead of 45.&lt;br/&gt;
- once the workout is saved or canceled, it stops listening for audio commands&lt;br/&gt;
&lt;br/&gt;
Since this is a bit of a complex feature, please ask me questions if anything isn’t clear. Also, explain to me how you are going to implement this feature before you begin so I can confirm your approach (e.g. which libraries will you use for speech recognition and audio sounds, and how will you track the background timer activity).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the kind of feature that&amp;rsquo;s fun to add, but if you&amp;rsquo;ve ever worked with Apple&amp;rsquo;s Audio or Speech APIs, you know there is a sizeable learning curve to use them properly. Without the LLM&amp;rsquo;s help, I wouldn&amp;rsquo;t have taken the time to bother with this.&lt;/p&gt;
&lt;h2&gt;The AI/Human Split&lt;/h2&gt;
&lt;p&gt;To track the code I wrote vs. the code an LLM wrote, I tagged &lt;code&gt;git&lt;/code&gt; commits with an &amp;ldquo;(AI)&amp;rdquo; prefix. Then I had ChatGPT create a short Python script using &lt;code&gt;git ls-files&lt;/code&gt; and &lt;code&gt;git blame&lt;/code&gt; to count up the lines of code attributed with each commit comment. While this approach isn&amp;rsquo;t perfect, as I would sometimes make small changes on top of Codex&amp;rsquo;s changes before committing, it&amp;rsquo;s pretty close, and the results align with my expectation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;--reverse&lt;span class="w"&gt; &lt;/span&gt;--oneline
830c646&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;AI&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;initial&lt;span class="w"&gt; &lt;/span&gt;checkin&lt;span class="w"&gt; &lt;/span&gt;after&lt;span class="w"&gt; &lt;/span&gt;fixing&lt;span class="w"&gt; &lt;/span&gt;compilation&lt;span class="w"&gt; &lt;/span&gt;errors
d3f76f3&lt;span class="w"&gt; &lt;/span&gt;Added&lt;span class="w"&gt; &lt;/span&gt;icon.&lt;span class="w"&gt; &lt;/span&gt;Added&lt;span class="w"&gt; &lt;/span&gt;sets,&lt;span class="w"&gt; &lt;/span&gt;equipment,&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;notes&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;Exercise.
143310b&lt;span class="w"&gt; &lt;/span&gt;Renamed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;routine&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;back&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;workout&amp;quot;&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;Added&lt;span class="w"&gt; &lt;/span&gt;symbols&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;Equipment&lt;span class="w"&gt; &lt;/span&gt;enum&lt;span class="w"&gt; &lt;/span&gt;but&lt;span class="w"&gt; &lt;/span&gt;segmented&lt;span class="w"&gt; &lt;/span&gt;Picker&lt;span class="w"&gt; &lt;/span&gt;only&lt;span class="w"&gt; &lt;/span&gt;supports&lt;span class="w"&gt; &lt;/span&gt;text&lt;span class="w"&gt; &lt;/span&gt;OR&amp;gt;
395ab0f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;AI&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Add&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;work&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;calculation&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;Exercises&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;Workout.&lt;span class="w"&gt; &lt;/span&gt;Display&lt;span class="w"&gt; &lt;/span&gt;it&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;History.
b94f95b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;AI&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Added&lt;span class="w"&gt; &lt;/span&gt;StatsView&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;chart&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;history.
d28d8e5&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;AI&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Added&lt;span class="w"&gt; &lt;/span&gt;voice&lt;span class="w"&gt; &lt;/span&gt;commands&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;countdown&lt;span class="w"&gt; &lt;/span&gt;timer.
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The results show that I was responsible for about 12% of the lines of code, and &amp;ldquo;AI&amp;rdquo; was responsible for the other 88%. That&amp;rsquo;s just one data point, but I&amp;rsquo;d say it feels right for this and other similar projects that I&amp;rsquo;ve completed in the last few months. Remember, this is the kind of app that I probably wouldn&amp;rsquo;t have bothered to tackle without the use of an LLM, so I expect it to do the large majority of the work; otherwise, what&amp;rsquo;s the point? If these tools can do 80-90% of the coding and I can just add my tweaks and direction as needed, then it&amp;rsquo;s a big success.&lt;/p&gt;
&lt;h2&gt;AI Hits and Misses&lt;/h2&gt;
&lt;p&gt;I took away a number of observations from this experience, some positive and some negative.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Very short time to &amp;ldquo;personal MVP&amp;rdquo;&lt;/em&gt; - Getting a basic working version of the app up and running quickly creates momentum. Going from an idea, to an initial prompt or spec, and then a basic working app in 15-30 minutes is amazing and gets the ball rolling where it feels easy to add to it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Automates the drudgery&lt;/em&gt; - Researching error messages and trying out fixes is not work I enjoy. The LLMs are very good at proposing solutions to errors. Sometimes it takes a couple of iterations, and you may need to &amp;ldquo;prune&amp;rdquo; the model&amp;rsquo;s solution path to nudge it in the right direction, but overall this is an area where LLMs shine.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;IDE integration is not required&lt;/em&gt; - While LLM coding assistants first appeared in IDEs like GitHub’s Copilot in VS Code, or Cursor&amp;rsquo;s VS Code fork, the best coding assistants today were designed to work in the command line. For this app, I mostly used Xcode to compile the app, play around with SwiftUI previews, and use the iOS Simulator.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prompt history documents the development process&lt;/em&gt; - The history of the prompts and responses provides a story of how the app was built and is helpful in re-familiarizing yourself with the app. I found this quite useful when I came back to the app after a week or so and couldn&amp;rsquo;t remember what I&amp;rsquo;d last done. This is especially true when you are no longer writing most of the code. I used an open source tool &lt;a href="https://github.com/nogataka/codex-viewer"&gt;codex-viewer&lt;/a&gt; to help here. This tool is based off the similar &lt;a href="https://github.com/d-kimuson/claude-code-viewer"&gt;claude-code-viewer&lt;/a&gt; tool for Claude Code.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;LLMs stuck in the recent past&lt;/em&gt; - Because the training data is always a bit out of date for an LLM, they often use slightly old versions of APIs or libraries or even language syntax. I ran into this right away because I was using a new version of Xcode (with new Swift features and new SwiftUI libraries) that was released after Codex was trained. At one point, Codex insisted I was asking it to use a version of the iOS SDK that didn&amp;rsquo;t exist.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="prompt"&gt;I want to use iOS 26. What changes do I need to make to get that to work?&lt;br/&gt;
&lt;br/&gt;
&lt;em&gt;There isn’t an iOS 26 SDK—Xcode only supports version numbers Apple has actually released (currently iOS 17.x, with 18 in preview). You can’t set a deployment target higher than what ships with the SDK, so the project can’t be built for iOS 26. If you meant a real version (say iOS 16 or 17), let me know which, and I’ll walk through the exact project-setting changes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;It pays to be specific&lt;/em&gt; - The LLM version of &amp;ldquo;garbage in, garbage out&amp;rdquo; is probably &amp;ldquo;ambiguity in, confident nonsense out.&amp;rdquo; Taking the time to be more specific with your prompts really helps. If you&amp;rsquo;ve ever outsourced development work to a new developer that isn&amp;rsquo;t familiar with your product or business, this won&amp;rsquo;t be surprising. But there&amp;rsquo;s something about the casualness of typing in a prompt box where you don&amp;rsquo;t feel the need to be explicit and exact in your instructions. And you don&amp;rsquo;t need to overdo it, but being somewhat explicit, offering examples, and asking for clarifying questions go a long way in getting the output you expect.&lt;/p&gt;
&lt;p&gt;Claude Code even has a built-in &amp;ldquo;plan mode&amp;rdquo; focusing on just that aspect of the process. I&amp;rsquo;ve had very good success on other projects using this feature to create a detailed spec, iterating on it a few times to get it right, then asking Claude to execute the implementation plan in the spec. (In hindsight, I probably should have done that for this experiment.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;LLMs are not great at reuse and refactoring&lt;/em&gt; - They don&amp;rsquo;t recognize that they&amp;rsquo;ve done something similar elsewhere in the project where they could extract a class or function, generalize it a bit, and reuse it. You can &lt;em&gt;ask&lt;/em&gt; them specifically to do this, but you need to do the work of identifying those opportunities and requesting the changes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;LLMs can be good debugging assistants&lt;/em&gt; - I ran into some thorny problems with audio, speech recognition, and asynchronous routines. This was compounded by the fact that these aspects of iOS perform differently in the iOS simulator than they do on the actual device. But by giving Codex a detailed description of the behavior, it was able to hypothesize as to what the problems and potential solutions &lt;em&gt;might&lt;/em&gt; be, and that helped me eventually solve them.&lt;/p&gt;
&lt;h2&gt;Considerable Net Positive&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m impressed by what these tools can do and how quickly they&amp;rsquo;ve evolved to this point (this project was developed in early 2026). I find using LLMs analogous to other powerful development tools and languages in the past (debuggers, toolkits, IDEs), but their capabilities are much broader, and their limits seem to keep expanding.&lt;/p&gt;
&lt;p&gt;I recently read an article that talked about two kinds of developers: &lt;em&gt;builders&lt;/em&gt; and &lt;em&gt;coders&lt;/em&gt;. The main idea was that builders enjoy the process of creating something new and seeing it come to life, while coders care more about the process of writing the actual code. The builders see AI coding tools as a huge benefit to their work as it allows them to build more rapidly and try out more ideas with less effort. But the coders are more reluctant to use these tools because it takes away the part of the process that they most enjoy. While I recognize aspects of each of those roles in myself, I&amp;rsquo;ve always leaned more heavily to the builder side. I guess that&amp;rsquo;s why I find LLM tools so interesting and exciting, even if they are changing the way I now write code.&lt;/p&gt;
&lt;p&gt;Throughout my life of developing code and working with software teams, I&amp;rsquo;ve found the continual changes to the profession and the industry the most exciting part of it. This is what first attracted me to a career in technology - that I&amp;rsquo;d never be bored. LLMs are the latest example of how things never stay the same, and for me, it&amp;rsquo;s what continues to make all of this so much fun.&lt;/p&gt;</content><category term="misc"></category><category term="ios"></category><category term="ai"></category></entry><entry><title>A deeper dive into investing</title><link href="https://noisysignal.com/a-deeper-dive-into-investing.html" rel="alternate"></link><published>2025-11-13T00:00:00-05:00</published><updated>2025-11-13T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-11-13:/a-deeper-dive-into-investing.html</id><summary type="html">&lt;p&gt;Learning more about investments, allocation, diversification and risk.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Previously, we covered the basics of saving and investing. Now let’s take a deeper look at how investing actually works — and how to build a portfolio that grows steadily over time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Be fearful when others are greedy. Be greedy when others are fearful.”
&lt;div class="author"&gt;Warren Buffett&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Earlier we introduced stocks and bonds as well as mutual funds and ETFs. Let&amp;rsquo;s expand a bit more on these investments and introduce some important concepts to help understand the basics of investing money.&lt;/p&gt;
&lt;h2&gt;What are stocks?&lt;/h2&gt;
&lt;p&gt;As previously mentioned, shares of stock represent a small piece of ownership in a company. These shares are listed on an exchange where they can be traded with other people or companies. An exchange is like an electronic version of a street market. Stock originally comes from companies that &amp;ldquo;go public&amp;rdquo;, meaning they sell shares of their stock to institutions and individuals. They do this to raise money so they can grow their business.&lt;/p&gt;
&lt;p&gt;You buy and sell shares of stocks through a brokerage account. It&amp;rsquo;s like a bank account but provides access to these exchanges where you can buy and sell stocks and other securities or investments. The brokerage account is also where you hold these positions.&lt;/p&gt;
&lt;p&gt;Stocks have a &amp;ldquo;ticker&amp;rdquo; or identifier. Apple is &amp;ldquo;AAPL&amp;rdquo;, Nike is &amp;ldquo;NKE&amp;rdquo;, Netflix is &amp;ldquo;NFLX&amp;rdquo;. Sometimes they change. Facebook used to be &amp;ldquo;FB&amp;rdquo; but then the company changed its name to Meta and the ticker is now &amp;ldquo;META&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;You can only buy shares in companies that are public. Private companies don&amp;rsquo;t have shares listed to invest in. Someday they might &amp;ldquo;go public&amp;rdquo; to raise money to expand, but for now, they are privately held.&lt;/p&gt;
&lt;h2&gt;How do you make (or lose) money in stocks?&lt;/h2&gt;
&lt;p&gt;If a company returns some of its profits to its shareholders, you&amp;rsquo;ll receive a dividend. For example, if you own 100 shares of AAPL and it pays a fifty-cent dividend per share, then you&amp;rsquo;ll receive $50. It will be deposited in your brokerage account.&lt;/p&gt;
&lt;p&gt;Dividends are one way to make money investing in stocks but most people invest with the expectation for the stock price to appreciate. The price of a stock reflects what people in the market are willing to buy and sell it at. If the company is successful, grows its business, and earns more money, then people are willing to pay more for a share and the price will go up. This can be significant for a consistently successful company over the long term. For example, Apple&amp;rsquo;s stock is up about 70 times since they announced the iPhone in early 2007. You would have gained a lot more from the price increase than the dividends they paid along the way.&lt;/p&gt;
&lt;p&gt;Big established companies that are very profitable but are not growing that much might be attractive for the opposite reason. Their price might move up or down a bit here and there but they pay consistent dividends so you earn good income from them. Some examples are energy stocks, banks, or large conglomerates like GE or IBM. In fact, now that Apple is so big, you might make more in the future from dividend payments than from the price increase, even though in the past it was a fast-growing stock.&lt;/p&gt;
&lt;h2&gt;What are bonds?&lt;/h2&gt;
&lt;p&gt;Bonds are a different way companies raise money. They are loans a company takes out by selling bonds to the public. These usually pay a fixed interest rate, called a coupon, thus bonds don&amp;rsquo;t have the price gain potential that stocks have but also are less risky since they have &amp;ldquo;seniority&amp;rdquo; over stocks. That means the coupon payments have to be made before they can pay out dividends to stockholders.&lt;/p&gt;
&lt;p&gt;Companies aren&amp;rsquo;t the only organizations to raise money by selling bonds. Governments - federal, state, and local - will also sell bonds. Government bonds pay a lower interest than corporate bonds because they are safer - the government guarantees the payments (in most cases) so they don&amp;rsquo;t need to pay as high an interest rate to borrow money as a corporation does.&lt;/p&gt;
&lt;h2&gt;Is “cash” just, well, “cash”?&lt;/h2&gt;
&lt;p&gt;You will see also &amp;ldquo;cash&amp;rdquo; referred to as a type of investment. This doesn&amp;rsquo;t literally mean cash you&amp;rsquo;d keep in your pocket or in a savings account. It means cash-like investments that are essentially risk-free, such as short-term Treasuries. Since these are backed by the US government, they don&amp;rsquo;t have the risk of default or of not being paid back. They do earn interest, however, so are usually part of an investment portfolio.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Don’t look for the needle in the haystack. Just buy the haystack!”
&lt;div class="author"&gt;John Bogle&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are over 6,000 public stocks traded in the US and hundreds of thousands of corporate bonds available. Sifting through all of these to find good opportunities is an impossible task. There are professionals who will do this and pool them together into funds. Then instead of buying stock or bonds in an individual company, you are buying a share of the pool that may contain dozens or hundreds of different stocks or bonds.&lt;/p&gt;
&lt;p&gt;Of course, these funds aren&amp;rsquo;t guaranteed to do any better than you might, and they also charge fees for the work they do so that takes away from your potential gain.&lt;/p&gt;
&lt;p&gt;But there are also funds that don&amp;rsquo;t need to do any real work to pick their stocks. They just buy the same ones that are part of an index. So an S&amp;amp;P 500 fund just owns shares in the 500 largest US companies. Or a Bloomberg US Aggregate Bond fund owns roughly the 10,000 largest corporate bonds in the Bloomberg index. Since the fund managers are just using a published list to determine which stocks or bonds to own, they don&amp;rsquo;t need a big research staff and thus their costs are much lower and the funds have very low fees. When you invest in funds that track a major index, it&amp;rsquo;s like you are buying a very small piece of the entire economy.&lt;/p&gt;
&lt;p&gt;Buying a number of investments or pools of investments is a form of &lt;em&gt;diversification&lt;/em&gt;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Diversification&lt;/p&gt;
&lt;p&gt;Diversification can be summed up as &amp;ldquo;don&amp;rsquo;t put all your eggs in one basket&amp;rdquo;. With investing, there is &lt;em&gt;concentration risk&lt;/em&gt; when buying just a small number of investments. Something bad could happen to the company you are invested in and its stock could crash. It might lose its most important customer, or its products may have a flaw and need to be recalled, or maybe the company broke some laws and is being sued.&lt;/p&gt;
&lt;p&gt;By spreading your bets across a larger number of investments, you reduce the impact of any one of those investments performing poorly for whatever reason.&lt;/p&gt;
&lt;p&gt;Index funds or ETFs are an easy way to get the benefits of diversification without the added work of having to research and choose a number of different investments on your own.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We mentioned stocks, bonds, and cash earlier. Over the last 100 years or so, stocks have returned an average of about 10% a year, bonds about 5%, and cash about 3%. As we&amp;rsquo;ll soon see, in any one one year it can vary a lot, but those are pretty typical averages.&lt;/p&gt;
&lt;p&gt;Since stocks have the potential to grow in price significantly, why not put all your money into stocks? Well, that introduces the concept of risk vs. reward or the risk-reward tradeoff&amp;hellip;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Risk vs. Reward&lt;/p&gt;
&lt;p&gt;Investments that have the potential for larger gains, also have the potential for larger losses. These large movements in the value of the investment over time reflect the risk in that security. Stock prices can move up and down dramatically over short periods of time based on economic news, company-specific news, or just the emotions of the people in the market. There is no &amp;ldquo;correct&amp;rdquo; price for a stock so it&amp;rsquo;s very subjective to gauge whether a certain stock is underpriced or overpriced.&lt;/p&gt;
&lt;p&gt;Bonds, on the other hand, are loans with interest or coupon payments. You know what you are getting and you can calculate an appropriate price for a bond, to a certain degree. So the prices of bonds move around much less than stocks and are therefore considered less risky. But for that lower risk, they offer lower returns.&lt;/p&gt;
&lt;/div&gt;
&lt;h4&gt;No free lunch&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Risk-return tradeoff" src="https://noisysignal.com/images/money/Risk-return tradeoff.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a chart of different types of investment classes or &lt;em&gt;asset classes&lt;/em&gt;, showing their average long-term return and their risk, expressed in the typical annual percentage move (the standard deviation of their price changes).&lt;/p&gt;
&lt;p&gt;You can see that to achieve higher returns you have to be willing to accept more risk, but note that the relationship curves downward and is not linear. That means the additional risk grows faster than the additional return so you have to be cautious about investing in high-return securities.&lt;/p&gt;
&lt;p&gt;From this chart it might appear that you have only a few types of investment choices and none of them may be in the ideal spot on the curve where you would be most comfortable. But you can use a combination of different types of investments to achieve a mixed result that will fall somewhere else on this curve.&lt;/p&gt;
&lt;p&gt;For example, if you choose to put 75% of your investments in Large-cap stocks and 25% in Corporate bonds, that portfolio would fall roughly on the curve between those two points, closer to the Large-cap point. This process of choosing different portions of your money in different types of investments is called &lt;em&gt;asset allocation&lt;/em&gt;.&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concepts: Asset Allocation, Rebalancing, and Averaging&lt;/p&gt;
&lt;p&gt;Asset allocation involves dividing your investment portfolio among different asset classes, most typically stocks, bonds, and cash. By including asset classes with returns that tend to move somewhat independently from each other, you help protect yourself from significant losses and your returns will also tend to be smoother over time, that is, the volatility of the overall portfolio will be lower.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Asset class returns by holding period" src="https://noisysignal.com/images/money/Asset Class Returns by Holding Period.png" /&gt;
&lt;em&gt;Asset class returns by holding period&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This chart compares the performance of different asset classes over the last 75-80 years across different holding periods. For example, the group on the left shows a one-year holding period, which means that in any one year,  stocks—the dark blue bar—had returns that varied between up 62% to down 43%  and averaged up 12.5%. One-year returns of bonds ranged between 35% and -16% averaging 5.6%, and the one-year return of cash (represented by a three-month Treasury bill) ranged between 15% and 0%, averaging 3.8%.&lt;sup id="fnref:trp"&gt;&lt;a class="footnote-ref" href="#fn:trp"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;But notice as you move to the right with increasing holding periods, the variability of the returns compresses while the average moves around just a small amount and we can see in the 20-year band that there were no cases where any of the asset classes lost money.&lt;/p&gt;
&lt;p&gt;The important takeaway here is that for a long investment time horizon, you can ride out market downturns and in the long run will usually experience good returns. Patience pays off in investing.&lt;/p&gt;
&lt;p&gt;But you can also see that if you know you&amp;rsquo;ll need some of your money sooner, then it&amp;rsquo;s going to be safer to put more of it in bonds and even cash.&lt;/p&gt;
&lt;p&gt;Once you start following an asset allocation approach, you&amp;rsquo;ll need to make adjustments periodically to keep your portfolio on track. This is a process called &lt;em&gt;rebalancing&lt;/em&gt;. Let&amp;rsquo;s look at an example to see why it&amp;rsquo;s necessary and how it works.&lt;/p&gt;
&lt;h4&gt;Rebalancing example&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Asset Class&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Allocation Percent&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Allocation Value&lt;/th&gt;
&lt;th style="text-align: right;"&gt;One-year return&lt;/th&gt;
&lt;th style="text-align: right;"&gt;End-year value&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Target&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Amount to add&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Pct to add&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Stocks&lt;/td&gt;
&lt;td style="text-align: right;"&gt;80%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$40,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;12.52%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$45,008&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$48,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$2,992&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;59.83%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Bonds&lt;/td&gt;
&lt;td style="text-align: right;"&gt;15%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$7,500&lt;/td&gt;
&lt;td style="text-align: right;"&gt;-1.10%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$7,418&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$9,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$1,582&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;31.65%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Cash&lt;/td&gt;
&lt;td style="text-align: right;"&gt;5%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$2,500&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2.96%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$2,574&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$3,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$426&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;8.52%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;100%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$50,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$55,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$60,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;$5,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Let&amp;rsquo;s say you had a portfolio of $50,000 and 80% of your portfolio is in stocks, 15% is in bonds and 5% is in cash. That&amp;rsquo;s a pretty typical allocation for someone early in their career say in their 30s.&lt;/p&gt;
&lt;p&gt;This table shows a hypothetical case if you had a return of 12.52% in stocks, -1.1% in bonds, and 2.96% in cash which works out to a total return of exactly 10% in the portfolio, thus a $5,000 gain.&lt;/p&gt;
&lt;p&gt;Now you plan to invest an additional $5000 but you want to bring the new values in each asset class back to their target weights of 80%, 15%, and 5%, respectively.&lt;/p&gt;
&lt;p&gt;Since your stocks were the best performer, the value of those holdings has outpaced the total portfolio (12.52% vs 10%) and thus you need to put less than 80% of the additional money into stocks. In this case, it&amp;rsquo;s about 60%.&lt;/p&gt;
&lt;p&gt;The other two asset classes underperformed the 10% total return so you need to buy &lt;em&gt;more&lt;/em&gt; than their target amounts. For cash, we need to buy 8.52% vs 5% and for bonds, we need to buy 31.65% vs. 15%. That&amp;rsquo;s because bonds actually lost a little money.&lt;/p&gt;
&lt;p&gt;The net effect is that you are buying more of the cheaper asset classes and less of the expensive asset class. This helps your return over the long term because you are buying more of something when it&amp;rsquo;s cheaper and then over time when it goes back up (hopefully),  you&amp;rsquo;ll compound your gain a little bit. This can make a real difference over many years.&lt;/p&gt;
&lt;p&gt;One other concept of note here. When investing money, one thing people sometimes worry about is that they are buying something at the wrong time and that it might go down in price soon after they buy it. But that can lead to indecision and then you have just as much of a chance of the price moving up while you sit on the sidelines, and now if you invest you&amp;rsquo;ve bought the investment at a higher price.&lt;/p&gt;
&lt;p&gt;The best approach is to take a long-term view and not worry so much about the short-term up and down movements. And if you are consistently investing money in the market each month, quarter, or year, then these ups and downs will average out. This process of investing regularly over time is called &lt;em&gt;averaging&lt;/em&gt; and the benefits of this approach are that it will smooth out your investments over time, plus you will end up buying more shares of an investment when prices are lower so it has a very positive impact when investing through recessions and &amp;ldquo;bear&amp;rdquo; markets.&lt;/p&gt;
&lt;p&gt;Asset allocation, rebalancing, and averaging go hand-in-hand when investing.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We&amp;rsquo;ve covered a lot of details about investing. Let&amp;rsquo;s now wrap all of that up into some straightforward advice in terms of managing your investments.&lt;/p&gt;
&lt;h2&gt;Three investment approaches&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s look at three approaches to investing that build on the ideas we&amp;rsquo;ve discussed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The biggest risk of all is not taking one.”
&lt;div class="author"&gt;Mellody Hobson&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In terms of investing, if you were to distill all the things we&amp;rsquo;ve discussed so far and implement the simplest approach that would require the least amount of time to manage, the recommendation would be:&lt;/p&gt;
&lt;div class="admonition tip"&gt;
&lt;p class="admonition-title"&gt;Approach 1: Keep it simple&lt;/p&gt;
&lt;p&gt;Put everything in an S&amp;amp;P 500 Index fund&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;save 20% or more of your earnings each paycheck&lt;/li&gt;
&lt;li&gt;once a year, invest your excess savings (beyond your emergency cash fund) into a large equity index fund or ETF like SPY&lt;/li&gt;
&lt;li&gt;repeat year after year after year&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Putting 100% in the stock market might sound a little scary, but consider your situation. You are young, you have cash on hand, and shouldn&amp;rsquo;t need to dip into your investment portfolio, thus you can afford to take the most risk at this point.&lt;/p&gt;
&lt;p&gt;This is the exact strategy that Warren Buffet recommended in his 2013 letter to shareholders. He said to put 90% in an S&amp;amp;P 500 Index fund and 10% in cash but since you will already have an emergency cash fund set aside, they are effectively the same thing.&lt;/p&gt;
&lt;div class="admonition tip"&gt;
&lt;p class="admonition-title"&gt;Approach 2: Light touch&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shift a small amount of S&amp;amp;P 500 Index fund into bonds&lt;/li&gt;
&lt;li&gt;90% S&amp;amp;P 500 Index fund&lt;/li&gt;
&lt;li&gt;10% Bloomberg US Aggregate Bond Index fund&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;A second approach, that requires only slightly more effort, is to introduce an asset allocation layer across stocks and bonds. In this model, you&amp;rsquo;d maybe put 90% in stocks and 10% in a large bond index fund or ETF like AGG. Then each year when you put your additional accumulated savings in, you&amp;rsquo;d split it up to reach that target allocation &lt;em&gt;after&lt;/em&gt; adding in the additional money, like the previous example we walked through.&lt;/p&gt;
&lt;p&gt;This is slightly more work but since you only need to rebalance once a year, it&amp;rsquo;s not a big deal. And it will get you more familiar with the practice of asset allocation, rebalancing, and averaging.&lt;/p&gt;
&lt;p&gt;You can also shift from the first model into this model down the road, say in your 30s when you don&amp;rsquo;t feel as comfortable with 100% in stocks. Plus, you can expand this approach into other asset classes at that time, say real estate, commodities, or international equities.&lt;/p&gt;
&lt;p&gt;You could stay with this model your entire life and as you get older and closer to retirement, just shift more of the stock allocation into bonds and also into cash, targeting to have maybe an allocation of 60% stocks, 30% bonds, and 10% cash near retirement.&lt;/p&gt;
&lt;h2&gt;Approach 3&lt;/h2&gt;
&lt;div class="admonition tip"&gt;
&lt;p class="admonition-title"&gt;Approach 3: Hands-on&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shift a portion of S&amp;amp;P 500 Index fund into 3-5 stocks&lt;/li&gt;
&lt;li&gt;70% S&amp;amp;P 500 Index fund&lt;/li&gt;
&lt;li&gt;20% 3-5 individual stocks&lt;/li&gt;
&lt;li&gt;10% Bloomberg US Aggregate Bond Index fund&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;The third approach is probably only something you&amp;rsquo;d consider if you really find investing interesting and want to spend more time and attention on it. You could set aside a portion of your portfolio to invest in a few individual stocks. You should start small, putting no more than a quarter of your portfolio and shifting it into 3-5 stocks that you are interested in. That&amp;rsquo;s enough to make a difference if one of them does really well but also small enough that if one of them crashes, it won&amp;rsquo;t set you back too much. Fewer than 3 stocks are risky because you&amp;rsquo;ll end up with too much money in one position. And more than 5 stocks start to become a lot of work to stay on top of them, plus the positions will be small enough that a big gain won&amp;rsquo;t have much of an impact on your overall portfolio.&lt;/p&gt;
&lt;p&gt;This approach will require more time to keep up to date with the stocks in case something changes and you might want to reconsider the investment. You should review your portfolio each quarter instead of annually to see if any of the reasons you originally bought any of the stocks has changed, in which case you might want to sell a position.&lt;/p&gt;
&lt;p&gt;With individual stock positions, there will be more ups and downs in your portfolio. It&amp;rsquo;s easier to get anxious and make a rash decision, which you want to avoid when investing for the long term. That&amp;rsquo;s why this approach isn&amp;rsquo;t for everyone.&lt;/p&gt;
&lt;p&gt;I recommend starting with the first approach and then over time you can grow into the second and even third approach as you develop more interest.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:trp"&gt;
&lt;p&gt;https://www.troweprice.com/personal-investing/resources/insights/asset-allocation-planning-for-retirement.html&amp;#160;&lt;a class="footnote-backref" href="#fnref:trp" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Big financial decisions</title><link href="https://noisysignal.com/big-financial-decisions.html" rel="alternate"></link><published>2025-11-13T00:00:00-05:00</published><updated>2025-11-13T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-11-13:/big-financial-decisions.html</id><summary type="html">&lt;p&gt;Dealing with big financial decisions in life.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Throughout your life, you’ll make a few big financial decisions that can shape your future for decades.&lt;br /&gt;
Some of these choices are unavoidable — others are optional but life-changing. Let’s walk through a few of the biggest ones and how to approach them wisely.&lt;/p&gt;
&lt;h2&gt;Buying a car&lt;/h2&gt;
&lt;h4&gt;The worst investment you&amp;rsquo;ll ever make&lt;/h4&gt;
&lt;p&gt;Cars have two important qualities that make them terrible investments. First, they are expensive, and second, they always depreciate, and do so rapidly. If this wasn&amp;rsquo;t bad enough, you usually need to take a loan out to buy a car so you&amp;rsquo;ll also pay a lot in interest for the right to lose money on your car.&lt;/p&gt;
&lt;p&gt;Cars depreciate rapidly and especially so in the first couple of years of ownership. And people tend to keep cars for only a few years - when they depreciate the most. Because of this, it&amp;rsquo;s become much more common to lease cars instead of buying them. But that&amp;rsquo;s essentially the same as taking a loan out, buying a car, and then three years later giving up the car and canceling the loan. You aren&amp;rsquo;t any better off and in fact, it&amp;rsquo;s more like you are just renting a car three years at a time.&lt;/p&gt;
&lt;p&gt;Whether leasing is better or worse than buying depends on both how long you plan to keep the car and how fast the car will depreciate. It’s not always easy to know the difference. I’ve usually bought cars and kept them for a longer time but when I did the math and considered the maintenance costs, I wasn’t really better off than had I been leasing so more recently I’ve tried leasing a couple of times. Now that interest rates are higher, leasing may not be as competitive, though.&lt;/p&gt;
&lt;p&gt;While cars are a terrible investment, they are also necessary for most people. The US was built around mobility and the assumption that people can get to stores, schools, jobs, and other places by driving. There are some exceptions, like New York City and Boston, but for most of the country, it&amp;rsquo;s difficult to get by day to day without a car.&lt;/p&gt;
&lt;p&gt;In your lifetime, you may see ride-sharing services and self-driving cars become mainstream enough that you don&amp;rsquo;t need to own a car yourself. But we aren&amp;rsquo;t quite there yet.&lt;/p&gt;
&lt;p&gt;Since cars are such a bad investment, the best you can do to minimize the impact is to buy an affordable, good-quality car and hang onto it for a long time. If you know you are going to lose 20% of your &amp;ldquo;investment&amp;rdquo; going in, it&amp;rsquo;s better to buy a $20,000 Kia than a $80,000 BMW.&lt;/p&gt;
&lt;h2&gt;Buying a house&lt;/h2&gt;
&lt;h4&gt;The best investment you&amp;rsquo;ll ever make?&lt;/h4&gt;
&lt;p&gt;Buying a home is the single largest purchase most people will make in their lives. For a number of reasons, it often works out to be the best investment people ever make, even though real-estate returns are not really that great historically. The reasons are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Real estate is usually a long-term investment. The median time people stay in their home is 7.5 years and later in life, many people will stay in their home for decades. As we saw with compound growth, even at a small annual growth rate, time is your friend and can lead to significant long-term appreciation.&lt;/li&gt;
&lt;li&gt;People usually buy a home with a mortgage giving them &lt;em&gt;leverage&lt;/em&gt;. Leverage in investing gives you exposure to a large investment with a smaller amount of money upfront. Most banks suggest putting a 20% down payment on a house before they feel comfortable loaning money to a person, so that translates into 5x leverage. That is, to buy a $500,000 home, you&amp;rsquo;d need to put down $100,000 and borrow the additional $400,000. But if your home&amp;rsquo;s value increases by 20% over 5 years and is now worth $600,000, your gain is $100,000 on a $100,000 initial investment or a 100% gain (5 x 20%). That&amp;rsquo;s the leveraging factor at work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some details I&amp;rsquo;m glossing over here such as the interest on your mortgage, the amount you&amp;rsquo;ve paid down on the loan, and the cost of maintaining your home, but ignoring those details, the key points hold.&lt;/p&gt;
&lt;p&gt;Now just because a home ends up being the best investment many people make in their lives, it doesn&amp;rsquo;t mean it actually is a great investment. You&amp;rsquo;d still probably be better off investing in the stock market over the long term but my guess is that most people never invest as much money in the stock market as they do in their home so they just don&amp;rsquo;t experience that potential better outcome.&lt;/p&gt;
&lt;h4&gt;The homebuying process&lt;/h4&gt;
&lt;p&gt;The process of buying a home is similar to buying a car, but the scale is much larger and the process is more complicated. You’ll usually put a down payment on the house (say 10%-20% of the price of the house but sometimes as little as 5%) and then borrow the rest from a bank. Because home loans are so much larger, their term is typically much longer. Most people in the US have 30-year mortgages.&lt;/p&gt;
&lt;p&gt;As mentioned, people will usually move before paying off their old house so when they do, they will coordinate the sale of their old home and the purchase of their new home at the same time. Hopefully, they will sell the old home at a profit and use the proceeds to pay off the balance of the mortgage and then keep the rest, or apply it to the purchase of the new home.&lt;/p&gt;
&lt;h2&gt;Getting married&lt;/h2&gt;
&lt;h4&gt;(And starting a family)&lt;/h4&gt;
&lt;p&gt;The other two big life decisions that have significant financial implications are getting married and starting a family. While these are separate issues, the first often leads to the second, so I&amp;rsquo;ve put them together.&lt;/p&gt;
&lt;p&gt;Getting married isn&amp;rsquo;t a financial decision in itself (although for some people it may be), but it can have a big financial impact. When you get married and start living with someone, assuming you are both working at that time, you get a lot of financial benefits just by pooling your resources and sharing your expenses. Paying one rent bill or mortgage rather than two, is usually much cheaper, as well as all the other expenses in life like utilities, groceries, health care, vacations, and more. There are also legal and tax benefits to being married.&lt;/p&gt;
&lt;p&gt;At some point, if you decide to have children, you&amp;rsquo;ll embark on a life-long journey that has many benefits and rewards. That said, it&amp;rsquo;s expensive to have and raise kids.&lt;/p&gt;
&lt;p&gt;First, there are significant medical costs throughout pregnancy and in a child&amp;rsquo;s early years. You may want to move to a more expensive location to have access to better schools. You&amp;rsquo;ll need a bigger house or apartment for your growing family. You may need an additional car. If both of you decide to continue to work, you may need to hire a nanny to give you the flexibility to be out of the house during the day. If one of you decides to step back from work to be a primary caregiver, then you&amp;rsquo;ll need to get by on less income.&lt;/p&gt;
&lt;p&gt;Having children is not a financial decision, but it has financial implications so it&amp;rsquo;s good to be aware of these issues and to consider them so you go into it with your eyes wide open.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It is good to have money and the things that money can buy, but it’s good too, to check up once in a while and make sure you haven’t lost the things money can’t buy.”
&lt;div class="author"&gt;George Horace Lorimer&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A final thought on this whole topic: Money isn&amp;rsquo;t the most important thing in life, but learning how to manage it capably and responsibly can give you the financial freedom to enjoy the things that really are important to you.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Building credit</title><link href="https://noisysignal.com/building-credit.html" rel="alternate"></link><published>2025-11-13T00:00:00-05:00</published><updated>2025-11-13T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-11-13:/building-credit.html</id><summary type="html">&lt;p&gt;What is credit, a credit score and a credit rating?&lt;/p&gt;</summary><content type="html">&lt;p&gt;Closely related to debt and loans is your credit score or credit rating. Let&amp;rsquo;s look at what a credit rating is and what you can do to influence it&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“If you don’t take good care of your credit, then your credit won’t take good care of you.”
&lt;div class="author"&gt;Tyler Gregory&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is an entire industry built around evaluating people&amp;rsquo;s creditworthiness, which is summarized in a &amp;ldquo;credit score&amp;rdquo;. You thought you were done being graded after you get out of school, but it never ends!&lt;/p&gt;
&lt;p&gt;A credit score is sort of a prediction of how likely you are to pay a loan back on time. It is based on a number of factors but the most important ones are your payment history on prior loans, on credit cards, on bills, and also how much debt you currently have or could potentially have (say on additional credit cards).&lt;/p&gt;
&lt;p&gt;The score is an important factor used in determining if you can get a specific loan, and also what the terms will be, the most important of which is the interest rate.&lt;/p&gt;
&lt;p&gt;The credit score ranges from 350-800. The higher your score, the lower the interest rate you&amp;rsquo;ll have to pay on a loan. This can end up saving you tens of thousands of dollars over the life of a loan.&lt;/p&gt;
&lt;h2&gt;Building your credit score&lt;/h2&gt;
&lt;p&gt;There are a number of things you can do to maintain a good credit history:
- pay your bills on time every month
- don&amp;rsquo;t use more than 30% of your credit limit. Even better, just pay your credit cards off completely each month. Fun fact, in the industry, people who pay off their credit cards fully each month are referred to as &lt;em&gt;deadbeats&lt;/em&gt; because the companies don&amp;rsquo;t make any money off of them!
- use the same credit cards for many years (don&amp;rsquo;t cancel and get new ones over and over)
- only have a couple of cards active at once - too many hurts your score
- finally, make sure there aren&amp;rsquo;t any errors on your current credit report - you can get a copy of the report free each year from each of the credit agencies. Since all of you are young and just starting out, there will probably be very little information on your credit report but it would still be instructive to look at it.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Protecting against financial risks</title><link href="https://noisysignal.com/protecting-against-financial-risks.html" rel="alternate"></link><published>2025-11-13T00:00:00-05:00</published><updated>2025-11-13T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-11-13:/protecting-against-financial-risks.html</id><summary type="html">&lt;p&gt;Using insurance to protect against certain financial risks.&lt;/p&gt;</summary><content type="html">&lt;p&gt;No matter how carefully you plan, life has a way of surprising you.&lt;br /&gt;
A major repair, a medical emergency, or an accident can derail even the best financial plan.&lt;/p&gt;
&lt;p&gt;That’s why insurance exists — it helps protect you from financial losses when the unexpected happens.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“By failing to prepare, you are preparing to fail.”
&lt;div class="author"&gt;Benjamin Franklin&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However carefully you plan, life will sometimes throw you a curve ball resulting in large unexpected bills or expenses. Insurance is a financial product that can help protect you against many of these potential risks.&lt;/p&gt;
&lt;h4&gt;Key Concept:&lt;/h4&gt;
&lt;h2&gt;Insurance&lt;/h2&gt;
&lt;p&gt;Insurance can be thought of as a &amp;ldquo;just-in-case&amp;rdquo; fund, that is, money that&amp;rsquo;s available to take care of unexpected circumstances. There are many kinds of insurance&amp;hellip;&lt;/p&gt;
&lt;h2&gt;The common types of insurance&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Home insurance&lt;/em&gt; can be used in case there is damage to your home, such as a fire, hail damage or a burglary. The insurance coverage will pay to fix the damage - or even replace your entire house and all its contents, if necessary.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Auto&lt;/em&gt; or &lt;em&gt;Car insurance&lt;/em&gt; can be used in cases such as an accident, or if a tree branch falls on your car and you need to get the car repaired or replaced.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Health insurance&lt;/em&gt; is used to pay for medical expenses and covers cases like a broken arm, or if you need to get your appendix taken out. But it also covers more regular procedures like an annual check-up and for prescription drugs - or at least a portion of them.&lt;/p&gt;
&lt;p&gt;As mentioned, most people have car insurance, home insurance, and health insurance. If you rent an apartment rather than owning your own home, you&amp;rsquo;ll typically get renter&amp;rsquo;s insurance. It covers your possessions but not the apartment itself (that&amp;rsquo;s for the landlord to deal with).&lt;/p&gt;
&lt;h2&gt;How insurance works&lt;/h2&gt;
&lt;p&gt;The way insurance works is that you pay an insurance company a monthly or annual fee, called a premium, and then they cover the charges if and when you need that protection.&lt;/p&gt;
&lt;p&gt;Insurance policies typically have a deductible amount. That&amp;rsquo;s the amount you have to pay out of your own pocket before the insurance kicks in. The higher the deductible, the lower the monthly premium. If you have the ability to pay for smaller repairs or doctor bills when they come up, it can be a lot cheaper to select a high deductible resulting in a lower premium.&lt;/p&gt;
&lt;p&gt;Insurance is sometimes required by law: you can&amp;rsquo;t drive a car in most states unless you are insured. Or it might be required by a company - banks won&amp;rsquo;t lend you money to buy a house unless you have insurance on your home.&lt;/p&gt;
&lt;p&gt;In other cases insurance is optional. You aren&amp;rsquo;t actually required to have health insurance - and unfortunately, many people don&amp;rsquo;t because they can&amp;rsquo;t afford it - but if you don&amp;rsquo;t have it, most doctors won&amp;rsquo;t take you on as a patient.&lt;/p&gt;
&lt;p&gt;Likewise, there is no requirement to have life insurance, but at certain stages in your adulthood, it&amp;rsquo;s a good idea to have some.&lt;/p&gt;
&lt;p&gt;For things that are very valuable (such as a car or home) - or the expense is potentially very high (such as medical procedures) - insurance is a really important financial tool to allow you to get through life knowing that if something unexpected happens, that it won&amp;rsquo;t be financially devastating.&lt;/p&gt;
&lt;h2&gt;Life insurance&lt;/h2&gt;
&lt;p&gt;Some people have life insurance and others don&amp;rsquo;t. Life insurance isn&amp;rsquo;t really for &lt;em&gt;you&lt;/em&gt; - it&amp;rsquo;s for people who &lt;em&gt;depend&lt;/em&gt; on you. If you don&amp;rsquo;t have anyone who depends on your income, you don&amp;rsquo;t need it. But when you do get married or choose to live with someone, then life insurance can make sense.&lt;/p&gt;
&lt;p&gt;There are two major types of life insurance:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Term life insurance&lt;/em&gt; covers you for a specific period of time, say 10 or 20 years. When you are young and healthy, the odds of something happening are low so term insurance is pretty cheap. For a 25-year-old in good health, a 20-year term policy for $1 million in coverage might be a few hundred dollars a year. People often get this when they start a family to protect against the loss of income if a person dies. But maybe in 20 or 30 years when your kids are older and out of the house, and you have money saved up, it&amp;rsquo;s not necessary, so you can just let the policy expire. 98% of term life insurance policies expire without payment.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Whole life insurance&lt;/em&gt; or &lt;em&gt;permanent insurance&lt;/em&gt; is different. It&amp;rsquo;s a policy designed to last until you die and to provide money for your heirs. It&amp;rsquo;s often part of an estate plan. In contrast to term insurance, over 95% of whole-life policies are paid out, thus they are much more expensive, but they have some other features like a buildup of the cash value that can be withdrawn, as well as some tax benefits. Still, it&amp;rsquo;s not really necessary for most people and there&amp;rsquo;s common advice to &amp;ldquo;buy term insurance and invest the difference&amp;rdquo; which is going to be the right choice for most people.&lt;/p&gt;
&lt;h2&gt;Other types of insurance&lt;/h2&gt;
&lt;p&gt;There are a host of other types of insurance:&lt;/p&gt;
&lt;p&gt;Disability insurance protects you if you are unable to work for an extended period of time. More than one in four of today&amp;rsquo;s 20-year-olds can expect to be out of work for a year or more before they retire, because of a disabling condition.&lt;/p&gt;
&lt;p&gt;Disability insurance protects your income in these cases. You pay a premium to the insurance company and in the case you are unable to work, they pay a portion of your income (generally 60%).&lt;/p&gt;
&lt;p&gt;There are short-term policies (they start after two weeks and last up to a year) and long-term policies (they start after a year and last until retirement). The short-term policies are a lot cheaper than the long-term ones but sometimes you can get an affordable long-term policy through your employer.&lt;/p&gt;
&lt;p&gt;Disability insurance protects your income for yourself, in contrast to life insurance, which protects your income for others who depend on it.&lt;/p&gt;
&lt;h2&gt;Types of insurance you probably shouldn&amp;rsquo;t buy&lt;/h2&gt;
&lt;p&gt;There are other kinds of insurance like extended warranties on electronic products such as a TV, computer, or camera. Or travel insurance for certain costs of a planned trip, like airline tickets and hotels.&lt;/p&gt;
&lt;p&gt;These types of insurance are often priced much higher than they should be given the likelihood of a problem occurring. You might pay 10% of the cost of a TV for an extended warranty that lasts for 3 years when the probability of something going wrong with the TV over that time is less than 1%.&lt;/p&gt;
&lt;p&gt;Or these policies have so many exceptions that when you need them, they don&amp;rsquo;t pay off. Travel insurance doesn&amp;rsquo;t cover you if you just change your mind - it typically covers cancellations due to a death in the family, unexpected jury duty, or a job loss. Phone insurance won&amp;rsquo;t cover water damage, for example.&lt;/p&gt;
&lt;p&gt;In these cases, and many others, just having an emergency savings fund can act as your &amp;ldquo;whatever else happens&amp;rdquo; insurance. This is sometimes called &amp;ldquo;self-insuring&amp;rdquo; - you will use your own money to pay for the repair, replacement, or loss on your own and forego the premium charges. The nice thing about an emergency fund is it can be used for anything.&lt;/p&gt;
&lt;p&gt;We also talked about deductibles earlier - having an emergency fund frees you up to select higher deductibles on your insurance policies and save money on the premiums.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Managing debt</title><link href="https://noisysignal.com/managing-debt.html" rel="alternate"></link><published>2025-01-20T00:00:00-05:00</published><updated>2025-01-20T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-01-20:/managing-debt.html</id><summary type="html">&lt;p&gt;Learning how to manage debt responsibly.&lt;/p&gt;</summary><content type="html">&lt;p&gt;There of course will be challenges to reaching your financial goals and one of the biggest ones that prevents people from reaching those goals is runaway debt.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“How did you go bankrupt?”&lt;br/&gt;
“Two ways. Gradually, then suddenly.”
&lt;div class="author"&gt;Ernest Hemingway&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Debt isn&amp;rsquo;t necessarily a bad thing. Borrowing money to buy a car might be necessary for you to accept a job that isn&amp;rsquo;t very close to your home. And as we&amp;rsquo;ll see, borrowing money to buy a home gives you the security of a place to live plus a home can turn into a very good investment over time.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s when people live beyond their means and use expensive debt, like credit cards, that they often get themselves into deep trouble.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look more closely at different kinds of debt&amp;hellip;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Loans and Mortgages&lt;/p&gt;
&lt;p&gt;A loan is an agreement between someone borrowing money and someone lending money on how that loan will be paid back over time and what the cost of borrowing the money will be.
Loans can take different forms. We&amp;rsquo;ve mentioned car loans and mortgages or house loans, but there are many other kinds of loans.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Interesting fact - the term &amp;ldquo;mortgage&amp;rdquo; comes from a French term meaning &amp;ldquo;death pledge&amp;rdquo;. Read into that what you will.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But credit cards are also a type of loan, buy-now-pay-later services are loans, you can get personal loans, home improvement loans, small business loans, and more.&lt;/p&gt;
&lt;p&gt;Loans have a few key terms: the amount being borrowed, the term of the loan (that is, the time to repay it fully), the payment frequency (usually monthly), and the interest rate (quoted annually, but it can be effectively higher due to monthly compounding).&lt;/p&gt;
&lt;/div&gt;
&lt;h4&gt;Comparison of loans, payments, and total interest paid&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Example&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Amount&lt;/th&gt;
&lt;th style="text-align: center;"&gt;Term (years)&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Interest rate&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Monthly payment&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Total interest&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Student loan&lt;/td&gt;
&lt;td style="text-align: right;"&gt;40,000&lt;/td&gt;
&lt;td style="text-align: center;"&gt;10&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6.0%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;444.08&lt;/td&gt;
&lt;td style="text-align: right;"&gt;13,025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Car loan&lt;/td&gt;
&lt;td style="text-align: right;"&gt;30,000&lt;/td&gt;
&lt;td style="text-align: center;"&gt;5&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6.0%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;579.98&lt;/td&gt;
&lt;td style="text-align: right;"&gt;4,626&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Mortgage&lt;/td&gt;
&lt;td style="text-align: right;"&gt;250,000&lt;/td&gt;
&lt;td style="text-align: center;"&gt;30&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6.0%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;1,498.88&lt;/td&gt;
&lt;td style="text-align: right;"&gt;286,911&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Mortgage&lt;/td&gt;
&lt;td style="text-align: right;"&gt;250,000&lt;/td&gt;
&lt;td style="text-align: center;"&gt;15&lt;/td&gt;
&lt;td style="text-align: right;"&gt;5.5%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2,042.71&lt;/td&gt;
&lt;td style="text-align: right;"&gt;116,010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;em&gt;15 v. 30 Savings&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;&lt;em&gt;170,901&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Here are some examples of loans. The monthly payment is determined by the amount of the loan, the term, and the interest rate. There is a mathematical formula for determining the monthly payment that you&amp;rsquo;ll find on calculators and in Google Sheets or Excel called &lt;code&gt;PMT&lt;/code&gt; for &amp;ldquo;payment&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a little more complicated than just calculating the interest and dividing by the number of pay periods because as time goes on, the amount remaining on the loan will go down. But dealing with a monthly mortgage or car loan payment that changes each month is complicated, especially if you want to set up automatic payments, which banks prefer. So there is an &lt;em&gt;amortization formula&lt;/em&gt; that solves for this to produce a constant payment where the interest and principal vary over time.&lt;/p&gt;
&lt;p&gt;Note in the table the two mortgage examples at the bottom. This is an example of a choice you might have when you are buying a house. Typically, you&amp;rsquo;d take out a 30-year loan. But if you are willing to take out a shorter-term loan, in this case, 15 years, you can usually get a slightly lower interest rate. So in this example, the monthly payment is about $500 more but over the full life of the loan, you&amp;rsquo;ll save over $170,000 in interest payments.&lt;/p&gt;
&lt;h4&gt;Debit Cards vs. Credit Cards&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;th style="text-align: center;"&gt;Debit Cards&lt;/th&gt;
&lt;th style="text-align: center;"&gt;Credit Cards&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Interest Charges&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;no&lt;/td&gt;
&lt;td style="text-align: center;"&gt;paid on outstanding balance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Funding&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;linked to bank account&lt;/td&gt;
&lt;td style="text-align: center;"&gt;line of credit (loan)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Purchase Protection&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;limited/none&lt;/td&gt;
&lt;td style="text-align: center;"&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Most of us use both debit and credit cards — but they work very differently.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;debit&lt;/em&gt; card is used to pay for things by taking money directly out of your checking or savings account. Each time you use it, a deduction is made immediately from the linked account. You don&amp;rsquo;t have to &amp;ldquo;pay off&amp;rdquo; debit cards because you are paying for things as you go. If you don&amp;rsquo;t have money in your account to cover the item, the transaction is denied. You don&amp;rsquo;t ever go into debt so there&amp;rsquo;s nothing to pay off.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;credit&lt;/em&gt; card, on the other hand, is a way to borrow money from another company - the card issuer. When you buy something with a credit card, the issuer is actually paying the merchant for the item and lending that amount to you. Over time, you build up a balance which is just a loan. When you make a monthly payment on a credit card, you are paying down some of that loan, including interest in most cases.&lt;/p&gt;
&lt;h4&gt;The real cost of buying with credit&lt;/h4&gt;
&lt;p&gt;Earlier we mentioned the potential danger of overextending yourself with credit card debt. There are three real reasons this is such a problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The interest rates are very high, often 15% to 18% per year.&lt;/li&gt;
&lt;li&gt;Credit card companies make it very easy for people to get cards (because they are so profitable for the issuer). So people often have five or more credit cards.&lt;/li&gt;
&lt;li&gt;The credit card companies also make it easy to continue to carry large balances by requiring only a very small minimum payment each month (as little as 1% of the balance).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you had 5 credit cards with an interest rate of 18%, and each with a balance of $10,000 you&amp;rsquo;d be paying $750 just in interest each month! With such high-interest expenses, it&amp;rsquo;s difficult to ever pay the balances down. This is the trap some people get themselves into.&lt;/p&gt;
&lt;p&gt;Here are some examples of the true cost of buying something on a credit card if you only made the minimum payment each month (a typical amount is $15). A $100 item would only cost you an additional 6% in interest, although it would take 8 months or over half a year to fully pay off.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: right;"&gt;Balance&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Total interest&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Pct of balance&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Months to pay&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Years to pay&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: right;"&gt;100.00&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6.16&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;0.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: right;"&gt;500.00&lt;/td&gt;
&lt;td style="text-align: right;"&gt;198.36&lt;/td&gt;
&lt;td style="text-align: right;"&gt;40%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;47&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: right;"&gt;1,000.00&lt;/td&gt;
&lt;td style="text-align: right;"&gt;923.16&lt;/td&gt;
&lt;td style="text-align: right;"&gt;92%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;113&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: right;"&gt;5,000.00&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6,923.17&lt;/td&gt;
&lt;td style="text-align: right;"&gt;138%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;273&lt;/td&gt;
&lt;td style="text-align: left;"&gt;22.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;But as the amount goes up, the additional interest as a percent of the purchase price gets larger and larger, sometimes even exceeding the original price of the purchase. And it can take many years to fully pay it off. Just think if you bought a $1000 laptop and it took you over 9 years to pay it off but the laptop only lasted 3 years!&lt;/p&gt;
&lt;h2&gt;The high cost of too much debt&lt;/h2&gt;
&lt;p&gt;Maybe a more realistic example of the dangers of too much debt, is someone who makes $100,000 a year, has a $150,000 mortgage, a $40,000 car loan, and $25,000 of credit card debt.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Category&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Breakdown&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Income&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;After taxes&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;75,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Monthly net pay&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;6,250&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Loan&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Balance&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Payment&lt;/th&gt;
&lt;th style="text-align: right;"&gt;% of net pay&lt;/th&gt;
&lt;th style="text-align: right;"&gt;Interest&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Mortgage&lt;/td&gt;
&lt;td style="text-align: right;"&gt;150,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;899.33&lt;/td&gt;
&lt;td style="text-align: right;"&gt;14.4%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;11.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Car loan&lt;/td&gt;
&lt;td style="text-align: right;"&gt;40,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;773.31&lt;/td&gt;
&lt;td style="text-align: right;"&gt;12.4%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Credit cards&lt;/td&gt;
&lt;td style="text-align: right;"&gt;25,000&lt;/td&gt;
&lt;td style="text-align: right;"&gt;625.00&lt;/td&gt;
&lt;td style="text-align: right;"&gt;10.0%&lt;/td&gt;
&lt;td style="text-align: right;"&gt;6.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;Total&lt;/td&gt;
&lt;td style="text-align: right;"&gt;2,297.64&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;36.8%&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: right;"&gt;&lt;strong&gt;19.8%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note how this person would be spending over a third of their take-home pay on loan payments, making it almost impossible to live within the budget goals we talked about earlier. And this is before even paying for mandatory expenses like utilities and groceries. In this case, if the person is two years into both the car loan and mortgage, the interest alone is 20% of their net pay, which is the same amount they should be targeting for saving and investing.&lt;/p&gt;
&lt;p&gt;Debt can quietly consume the space in your budget that’s meant for building wealth. The best defense? Be cautious before taking on new debt — and aggressive about paying down what you already owe.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Saving and investing</title><link href="https://noisysignal.com/saving-and-investing.html" rel="alternate"></link><published>2025-01-16T00:00:00-05:00</published><updated>2025-01-16T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2025-01-16:/saving-and-investing.html</id><summary type="html">&lt;p&gt;Saving money regularly and investing it for the long term.&lt;/p&gt;</summary><content type="html">&lt;p&gt;So you&amp;rsquo;ve got a job, and you&amp;rsquo;re saving money consistently each paycheck &amp;hellip; now what do you do with the money you&amp;rsquo;ve saved up? This is where we shift from &lt;em&gt;saving&lt;/em&gt; money for the short term to &lt;em&gt;investing&lt;/em&gt; money for the long term.&lt;/p&gt;
&lt;p&gt;To understand the importance of focusing on the long-term view with investing, let&amp;rsquo;s take a look at an important and powerful concept&amp;hellip;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Compound Interest (or Compound Growth)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Compound interest is the eighth wonder of the world. He who understands it, earns it … he who doesn’t … pays it.”
&lt;div class="author"&gt;Albert Einstein&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Compound interest, or compound growth, is the process of reinvesting interest or income on an investment to amplify the growth of the investment over time. If you think back to your math classes, it results in exponential growth rather than linear growth.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Effects of compound interest" src="https://noisysignal.com/images/money/Effect-of-compounding.svg" /&gt;
&lt;em&gt;The dramatic effect of compound growth&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example showing the impact of $10,000 saved each year growing 6% annually over a 40-year period. The total contribution is simply 40 x $10,000 or $400,000. That&amp;rsquo;s the yellow line near the bottom. With simple interest, that is, interest earned each year but &lt;em&gt;not&lt;/em&gt; reinvested, that would grow to $891,400 or a little over two times the total amount contributed. That&amp;rsquo;s the red line in the middle.&lt;/p&gt;
&lt;p&gt;The blue line shows the effect of &lt;em&gt;compounding&lt;/em&gt;. You can see the exponential growth of the blue line to a final amount of over $1.5 million or close to four times the amount contributed!&lt;/p&gt;
&lt;p&gt;This demonstrates the power of compounding and also how time works to your advantage. Notice that at 10 years, all three curves are pretty close, but as time goes on they really start to separate. In year 30, for example, the compounding example increases year-over-year by $54,184, but you are only contributing $10,000 so most of that increase is just from the growth of the current account balance.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Compound growth is a snowball effect that builds over time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Investing should be more like watching paint dry or watching grass grow. If you want excitement, take $800 and go to Las Vegas.”
&lt;div class="author"&gt;Paul Samuelson&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We are going to get deeper into investing later on, but for now, the key things to keep in mind are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;as long as you are saving regularly from the simple budgeting approach, you&amp;rsquo;ll accumulate at least 20% of your net income each year. In our previous paycheck example that would be $11,453 a year.&lt;/li&gt;
&lt;li&gt;some of that may be going directly into an investment account through a 401k savings plan and the rest will likely be accumulating in a traditional savings account, which pays some interest, but probably very little (maybe 1% to 3%).&lt;/li&gt;
&lt;li&gt;each year, you can take the additional savings you&amp;rsquo;ve built up and transfer it to your investment or brokerage account and then invest it in ways that can deliver better long-term returns than your savings account will.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Later we will look at the two primary asset classes for investing money: &lt;em&gt;stocks&lt;/em&gt; - pieces of ownership of companies, and &lt;em&gt;bonds&lt;/em&gt; - loans you make to a company (or the government) that pay you interest.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll also look at different structures for those investments: mutual funds and ETFs, which pool lots of different stocks or bonds together that spread the risk and eliminate the need for you to make individual stock or bond selections on your own.&lt;/p&gt;
&lt;p&gt;There are of course, &lt;em&gt;many&lt;/em&gt; other types of investments, but most are variations on these two basic types and you don&amp;rsquo;t need anything more complicated to create a portfolio that will build wealth over time.&lt;/p&gt;
&lt;p&gt;For most people, a large stock index fund, like an S&amp;amp;P 500 fund, and a large bond index fund, like the US Aggregate Bond fund, are all you need to build a sensible portfolio.&lt;/p&gt;
&lt;p&gt;If you simply follow these steps of saving money each month, investing the balance each year in diversified, low-cost index funds, and letting your investments grow over time, you&amp;rsquo;ll have a very high likelihood of being financially set in your retirement and will end up better off than probably 95% of other people.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Inbox Zero with Mailman</title><link href="https://noisysignal.com/inbox-zero-with-mailman.html" rel="alternate"></link><published>2024-12-24T00:00:00-05:00</published><updated>2024-12-24T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-12-24:/inbox-zero-with-mailman.html</id><summary type="html">&lt;p&gt;Mailman is a simple but effective service for managing your Gmail account and preventing chaos in your inbox.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Like most people, I get too much email. Over the years, I’ve tried several approaches to clean up and manage the long list of messages that accumulate in my inbox. I’ve defined inbox rules (“Filters in Gmail”), reported individual emails as spam, and clicked “Unsubscribe” on promotional emails. Yet, new unwanted emails keep arriving, which require more tedious management.&lt;/p&gt;
&lt;h2&gt;SaneBox and the Pitfalls of Machine Learning&lt;/h2&gt;
&lt;p&gt;I learned about &lt;a href="https://sanebox.com"&gt;SaneBox&lt;/a&gt; and gave that a try. At first, it seemed to help. It removed many non-essential emails from my inbox putting them in special folders like “SaneLater” and “SaneNews”. But I found it also required a lot of maintenance and I was often finding unwanted emails still arriving in my inbox, and worse, important emails would sometimes get moved to SaneLater or SaneNews and I’d miss them for a week or more.&lt;/p&gt;
&lt;p&gt;SaneBox uses machine learning, among other techniques, to automatically categorize and label email messages. You can help train it by overriding its decisions - removing a SaneLater label or moving a message to SaneBlackHole. But I found that ineffective. I had a reminder each week to review all the messages in SaneLater and SaneNews and either leave them, remove the label, or move them to SaneBlackHole. It was a lot of tedious work and it seemed to never really get that much smarter about its rules. Week after week I found myself repeating the same process on emails from the same source. It wasn’t helping me. I was still doing all the tedious work to review and manage emails, but the work was now happening across three folders instead of just my Inbox.&lt;/p&gt;
&lt;p&gt;All machine-learning solutions suffer from a tradeoff between &lt;em&gt;false positives&lt;/em&gt; (legitimate emails marked as spam/non-important) and &lt;em&gt;false negatives&lt;/em&gt; (spam/non-important emails &lt;em&gt;not&lt;/em&gt; marked as such). If you tune the algorithm to try and lower one type of error, you increase the rate of the other type of error. And as a feature in an app, you have to live with the tuning that the developer choose and deal with the resulting errors as they arise.&lt;/p&gt;
&lt;p&gt;I wanted a solution that was more explicit, easier to understand how it was applying rules, and didn’t require as much oversight and maintenance. After searching around and researching different applications that address this problem, I came across &lt;a href="https://mailmanhq.com"&gt;Mailman&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Mailman - Simple and Effective&lt;/h2&gt;
&lt;p&gt;Mailman takes a different approach to this problem using a simple workflow that covers four cases:&lt;sup id="fnref:wf"&gt;&lt;a class="footnote-ref" href="#fn:wf"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Important emails pass through directly to your inbox. These are called “VIPs” and use explicit rules for domains, senders, or keywords.&lt;/li&gt;
&lt;li&gt;Emails that you have explicitly blocked are labeled as “Blocked by Mailman” and placed in a “Blocked by Mailman” folder.&lt;/li&gt;
&lt;li&gt;Emails that you have explicitly allowed are labeled as “Mailman” and held to be delivered to your inbox on the next delivery schedule.&lt;/li&gt;
&lt;li&gt;Any new emails that do not match any of the other three rules are held for review once a day in the Daily Digest.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is primarily a whitelisting approach to emails - only people that you explicitly allow are placed immediately in your inbox. But it adds a “hold-and-deliver” feature for other emails you want to receive, but which don’t require your immediate attention. These two rules work together that to your inbox uncluttered. I rarely have more than a handful of emails in my inbox at any time now. I “process” them soon after they arrive (respond if needed, add to my to-do list and archive if I have to take action, or archive if they require no action).&lt;/p&gt;
&lt;p&gt;The other nice feature of Mailman is the Daily Digest workflow. It presents all your new messages in a web app that you can quickly go through and allow or block. You can also do this in bulk to speed things up the first few days when you tend to have more messages in the digest. In contrast, SaneBox had no tool to  “triage” new emails each day. It was left as a workflow for you to define on your own, jumping between your email client and sometimes back to the SaneBox web app to tweak rules. I found that added friction resulted in me doing the maintenance work irregularly, which led to me falling behind even more.&lt;/p&gt;
&lt;h2&gt;Back in Control&lt;/h2&gt;
&lt;p&gt;I’ve been using Mailman for about a month now, and it’s been working extremely well for me. No more missed emails that caused me embarrassment — or worse — made me look lazy or unprofessional. No more repetitive, tedious cleanup of mail messages, and when I see a new email in my inbox now, it’s something I want to see.&lt;/p&gt;
&lt;p&gt;Inbox Zero used to be an aspiration to me — a nice idea but always out of reach. Now it’s my normal state and I no longer have to think about it.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:wf"&gt;
&lt;p&gt;A nice explanation of &lt;a href="https://support.mailmanhq.com/en/article/what-does-my-email-workflow-look-like-with-mailman-hquxcd/"&gt;Mailman’s workflow&lt;/a&gt; is on their support site.&amp;#160;&lt;a class="footnote-backref" href="#fnref:wf" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"></category><category term="productivity"></category></entry><entry><title>Money Management</title><link href="https://noisysignal.com/money-management.html" rel="alternate"></link><published>2024-10-14T00:00:00-04:00</published><updated>2024-10-14T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-10-14:/money-management.html</id><summary type="html">&lt;p&gt;The second article in the series covers the fundamentals of managing money and its importance for everyday life.&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the first article, we set the stage for the the topics that follow. Now let&amp;rsquo;s get into the basics of managing money.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I don&amp;rsquo;t know about you, but where I went to school, Money Management 101 wasn’t offered. Instead, we learned about the War of 1812, which of course is something I use every single day.”
&lt;div class="author"&gt;T. Harv Eker&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s somewhere between a curiosity and a crime that most people finish their education without ever being taught the fundamentals of how money works in our society. It seems to be a topic that you&amp;rsquo;re expected to simply pick up through life, yet that&amp;rsquo;s clearly not working.&lt;/p&gt;
&lt;p&gt;According to some recent polls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;87% of teenagers in the US admit to not understanding their finances.&lt;sup id="fnref:mz"&gt;&lt;a class="footnote-ref" href="#fn:mz"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;61% of Americans are stressed about their personal finances.&lt;sup id="fnref:lwc"&gt;&lt;a class="footnote-ref" href="#fn:lwc"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;71% of adults in the US believe they have high financial literacy levels. Yet those same US adults correctly answered only about half of the questions on a financial literacy exam.&lt;sup id="fnref2:mz"&gt;&lt;a class="footnote-ref" href="#fn:mz"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Banking Basics&lt;/h2&gt;
&lt;p&gt;Most people start theif financial lives with a simple checking and savings account, and also a debit card. Checks are not used very often anymore, and most young adults may have never actually written a check, but they&amp;rsquo;ve probably received them for something like a birthday gift.&lt;/p&gt;
&lt;p&gt;These basic bank accounts are most people’s entry into our financial system. They make it easy to receive money from others and to pay for things.&lt;/p&gt;
&lt;p&gt;But in recent years, new ways to use money have become popular, such as Apple Pay, Venmo, PayPal, or Zelle. These are also convenient ways to both pay for things and to send and receive money from others. But while these services are new and convenient, they aren’t that much different from traditional tools like debit cards or checks. In fact, most of these financial apps need to be connected to a traditional bank account or a credit card so you can get money into them. The apps simply make it more convenient to access the money in those accounts.&lt;/p&gt;
&lt;p&gt;A bank account also allows you to set up direct deposit of your paycheck so your money is easily available when you get paid. Most banks will also offer some sort of bill-paying service so you can pay for rent, your cell phone bill, and other regular payments. In fact, in your life, you may find you rarely need to write a physical check.&lt;/p&gt;
&lt;h2&gt;Income and Expenses&lt;/h2&gt;
&lt;p&gt;The most fundamental rule to financial security may be to simply spend less than you earn. That may sound obvious, but there are lots of challenges and complications that can make this difficult at times.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you may have a job with income that is inconsistent from month to month&lt;/li&gt;
&lt;li&gt;unplanned expenses will occur, seemingly at the worst time&lt;/li&gt;
&lt;li&gt;expenses can increase over time. In fact, that brings us to our first key concept&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Inflation&lt;/p&gt;
&lt;p&gt;Inflation is the tendency for prices to rise over time. It has the effect of making your money feel less valuable, as it doesn&amp;rsquo;t buy as much as it used to.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“A nickel ain’t worth a dime anymore.”
&lt;div class="author"&gt;Yogi Berra&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Inflation is expressed as a rate, just like interest is. So an inflation rate of 3% means something that costs $100 today will cost roughly $103 a year from now. Something costing $5,000 today would cost $5,150 in a year.&lt;/p&gt;
&lt;p&gt;You might have noticed this tendency with the things you buy. For example, maybe you’ve noticed that a cappuccino at Starbucks is now about $4.25, and just three years ago it was about $3.75. That&amp;rsquo;s an increase of 13% over three years or about 4.3% annually.&lt;/p&gt;
&lt;p&gt;Every single thing you spend money on can have its own “inflation rate” but we typically aggregate the costs of all products and services based on what average people buy to get an overall inflation rate.&lt;/p&gt;
&lt;p&gt;While we talk about an overall inflation rate (sometimes you’ll hear it as the CPI or consumer price index), each person will experience inflation differently based on where they live and what they spend their money on.&lt;/p&gt;
&lt;p&gt;The most expensive things in your life will have the biggest impact on the inflation rate you experience personally. If the national inflation rate is 2% but your landlord is raising rent by 10% then your actual inflation rate will be a lot closer to 10% (since rent will likely be one of your biggest expenses).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Product prices since 2005" src="https://noisysignal.com/images/money/Various Product Prices Since 2005.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a chart showing the prices of a variety of products since 2005. You can see that while the prices of different products have moved around quite a bit—and at times some of the prices have even gone down for a while—over the entire time period, they have all increased.&lt;/p&gt;
&lt;p&gt;Note that they all start at a reference value of 1.0 and they end up somewhere between about 1.10 (in the case of airfare, which took a big dive during COVID) and 1.75 or 1.8 (for tuition, healthcare, and rent). On average it looks like they&amp;rsquo;ve fallen somewhere between that range or around 1.5.&lt;/p&gt;
&lt;p&gt;Inflation is typically measured on a broad scale, incorporating prices of lots of different products into one measure. It&amp;rsquo;s not a perfect measure for any one person, but it&amp;rsquo;s a useful tool to see trends over time.&lt;/p&gt;
&lt;p&gt;&lt;img alt="CPI since 2005" src="https://noisysignal.com/images/money/Consumer Price Index Since 2005.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a chart of the CPI or Consumer Price Index over that same period. It&amp;rsquo;s the number that is most often used to talk about inflation in the US. It incorporates the cost of many different products and as we can see, it reflects what we saw in the previous chart with prices moving up from 1.0 to about 1.5 on average over that period.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now that we&amp;rsquo;ve introduced inflation and its effect on increasing expenses over time, let&amp;rsquo;s go back and look more closely at the income side.&lt;/p&gt;
&lt;h2&gt;What’s in a Paycheck?&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at a paycheck to better understand where all your money goes.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Paystub" src="https://noisysignal.com/images/money/Paystub.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a sample paycheck, parts of which may look familiar, but other parts may be new to you.&lt;/p&gt;
&lt;p&gt;This is a semi-monthly paycheck for someone making $75,000 a year. There are a few things to call attention to here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &amp;ldquo;gross pay&amp;rdquo; of $3,125, is the amount paid to you before any deductions are applied. It&amp;rsquo;s simply $75,000 divided by 24 (since there are 2 pay periods per month or 24 per year).&lt;/li&gt;
&lt;li&gt;then you see a long list of deductions starting with various forms of taxes:&lt;ul&gt;
&lt;li&gt;Federal income tax: this is what the US government gets&lt;/li&gt;
&lt;li&gt;Social Security: this is your contribution to current retirees&amp;rsquo; payments&lt;/li&gt;
&lt;li&gt;Medicare: this is your contribution to current retirees&amp;rsquo; healthcare plans&lt;/li&gt;
&lt;li&gt;and State income tax: what the state government gets&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These taxes add up to about 24% or a quarter of your paycheck.&lt;/p&gt;
&lt;p&gt;Then you see a couple of other &amp;ldquo;deductions&amp;rdquo;. These are different than taxes. While they are deducted from your check, they are actually money going into special savings accounts for you to use.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FSA Medical is a &amp;ldquo;flexible spending account&amp;rdquo; that allows you to set aside money before taxes to pay for medical-related expenses. It&amp;rsquo;s an optional program that some employers allow you to enroll in.&lt;/li&gt;
&lt;li&gt;401k is a type of retirement account that allows you to also set aside money before taxes that can be invested for your retirement. Most employers offer some sort of 401k plan and some even provide matching payments. For example, for every dollar you save, your employer might add an additional 50 cents, up to say 6% of your salary. That amounts to a 50% return on your investment for just participating in the plan! Take that deal if you can get it!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This introduces another key concept that&amp;rsquo;s important to understand&amp;hellip;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Tax-deferred Savings&lt;/p&gt;
&lt;p&gt;Certain types of investment accounts allow for &lt;em&gt;tax-deferred&lt;/em&gt;  contributions. Normally, taxes are deducted from your full paycheck (your &lt;em&gt;gross&lt;/em&gt; pay) and then you receive the remaining take-home amount (your &lt;em&gt;net&lt;/em&gt; pay) after taxes.&lt;/p&gt;
&lt;p&gt;But tax-deferred accounts allow contributions &lt;em&gt;before&lt;/em&gt; taxes are taken out. So you have more to invest and then the taxes are deducted from your gross pay after the tax-deferred contributions, reducing your current taxes a bit.&lt;/p&gt;
&lt;p&gt;In the paycheck example, you end up contributing an extra $44.34 to your 401k account each pay period or a little over $1000 per year. And the FSA and 401k deductions before taxes would save you $63.56 in taxes each paycheck.&lt;/p&gt;
&lt;p&gt;Note the term is &lt;em&gt;tax-deferred&lt;/em&gt; and not &lt;em&gt;tax-free&lt;/em&gt;. You still eventually have to pay taxes on this income, but not until you withdraw it in retirement. The bet you are making is at that time, your tax rate will be lower because you aren&amp;rsquo;t working.&lt;/p&gt;
&lt;p&gt;The most common forms of these tax-deferred accounts are the Traditional IRA account and the Employer-based 401k account. There is another form of tax-advantaged savings account called a Roth IRA, which allows you to make &lt;em&gt;after-tax&lt;/em&gt; contributions but take &lt;em&gt;tax-free&lt;/em&gt; withdrawals, later in retirement. Note that the bet here is that you&amp;rsquo;ll be in a &lt;em&gt;higher&lt;/em&gt; tax bracket later in life.&lt;/p&gt;
&lt;h5&gt;Comparison of tax-advantaged accounts&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;th style="text-align: center;"&gt;Traditional IRA/401k&lt;/th&gt;
&lt;th style="text-align: center;"&gt;Roth IRA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;Contributions&lt;/td&gt;
&lt;td style="text-align: center;"&gt;pretax dollars&lt;/td&gt;
&lt;td style="text-align: center;"&gt;after-tax dollars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;Account Growth&lt;/td&gt;
&lt;td style="text-align: center;"&gt;tax deferred&lt;/td&gt;
&lt;td style="text-align: center;"&gt;tax free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;Withdrawals&lt;/td&gt;
&lt;td style="text-align: center;"&gt;taxed&lt;/td&gt;
&lt;td style="text-align: center;"&gt;not taxed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;But the Roth IRA is also beneficial because the capital gains aren&amp;rsquo;t taxed either, and as we will explore later, over the long term, those gains may be significant and can make up the lion&amp;rsquo;s share of the total investment value. The tax-free withdrawals of these gains can amount to a lot of savings.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We were talking about a paycheck, which is of course, received from your employer. People entering the workforce today are expected to have 12 different jobs over their careers&lt;sup id="fnref:zip"&gt;&lt;a class="footnote-ref" href="#fn:zip"&gt;3&lt;/a&gt;&lt;/sup&gt; and move almost as many times over that period.&lt;sup id="fnref:538"&gt;&lt;a class="footnote-ref" href="#fn:538"&gt;4&lt;/a&gt;&lt;/sup&gt; That brings up another important concept&amp;hellip;&lt;/p&gt;
&lt;div class="admonition key"&gt;
&lt;p class="admonition-title"&gt;Key Concept: Cost of Living&lt;/p&gt;
&lt;p&gt;When we discussed inflation, we saw that the prices of everyday items can vary over time. Similarly, the prices of items can vary over location.&lt;/p&gt;
&lt;h4&gt;The cost of items varies greatly by location&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Cost of living" src="https://noisysignal.com/images/money/Cost of Living.pdf" /&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve listed the cost of some different items in various cities in the US. I&amp;rsquo;ve also thrown in a few European cities for comparison.&lt;/p&gt;
&lt;p&gt;The bottom row shows the ratio of the highest and lowest prices of each item across those cities. You can see that rent in New York (the city with the highest rent) is almost four times what it would be in Des Moines (the city with the cheapest rent).&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;index&amp;rdquo; is a measurement factoring in many different products and is based on a value of 100 for New York, the most expensive city. You can see that overall, Denver is about 20% cheaper than New York (that is, an index of 80 vs. 100).&lt;/p&gt;
&lt;p&gt;However, employers have to consider the cost-of-living otherwise they might not be able to convince people to work there, so the last column shows the median monthly take-home salary in each city. You can see that the more expensive cities also generally offer higher salaries to compensate.&lt;/p&gt;
&lt;p&gt;There are a lot of factors to consider when deciding whether to relocate for a job. But cost-of-living is an important one to determine how far your paycheck will go and whether or not you&amp;rsquo;ll actually be better off financially.&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;Creating a Budget&lt;/h2&gt;
&lt;p&gt;So how do you make sure your expenses stay below your income? This is the core role of a budget: a tool to help you pay bills on time, save money and create financial stability in your life. Let&amp;rsquo;s now look at a budget and how you might create one.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“A budget is telling your money where to go instead of wondering where it went.”
&lt;div class="author"&gt;John C. Maxwell&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A budget is a spending plan based on income and expenses. It&amp;rsquo;s a way to prioritize what you do with your money to make sure the important items are paid for while still leaving you room to pay for things you enjoy.&lt;/p&gt;
&lt;p&gt;Budgeting doesn&amp;rsquo;t need to be an overly complicated process. A very high-level budget is to divide your spending into three different categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first category is &lt;em&gt;&lt;strong&gt;needs&lt;/strong&gt;&lt;/em&gt;: these are the expenses you &lt;em&gt;must&lt;/em&gt; pay to get by such as your rent, utility bills, and groceries.&lt;/li&gt;
&lt;li&gt;The next category is &lt;em&gt;&lt;strong&gt;wants&lt;/strong&gt;&lt;/em&gt;: these are the things that you&amp;rsquo;d like to have, but also wouldn&amp;rsquo;t be a big hardship for you if you chose not to buy them right now. These are expenses like dining out, going to a movie, subscribing to Netflix, or buying a new pair of sunglasses.&lt;/li&gt;
&lt;li&gt;And the third cateogry is &lt;em&gt;&lt;strong&gt;savings&lt;/strong&gt;&lt;/em&gt;: the money you are putting aside for emergencies, long-term purchases, like a home, investments, and retirement. Think of this as investing in your future self.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;50/30/20 Budget&lt;/h2&gt;
&lt;p&gt;An often-used budgeting plan around these categories—and one that I&amp;rsquo;ve followed myself—is called the &amp;ldquo;50/30/20 Budget&amp;rdquo;. The idea is to spend no more than 50% of your paycheck on &amp;ldquo;needs&amp;rdquo;, no more than 30% on your &amp;ldquo;wants&amp;rdquo; and at least 20% on savings. Needs and wants are maximums, savings is a minimum.&lt;/p&gt;
&lt;p&gt;The easiest way to follow this is to just change the order to &amp;ldquo;savings&amp;rdquo;, &amp;ldquo;needs&amp;rdquo;, then &amp;ldquo;wants&amp;rdquo;. You&amp;rsquo;ll hear the advice &amp;ldquo;pay yourself first&amp;rdquo; when it comes to saving money.&lt;/p&gt;
&lt;h4&gt;Budgeting in 3 Steps&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;save&lt;/em&gt; 20% of your paycheck&lt;/li&gt;
&lt;li&gt;pay for your &lt;em&gt;needs&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;use what&amp;rsquo;s left over for your &lt;em&gt;wants&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Take 20% of your take-home paycheck and put it in your savings account, then pay for all your &amp;ldquo;needs&amp;rdquo;. What&amp;rsquo;s left over is available for your &amp;ldquo;wants&amp;rdquo;. You don&amp;rsquo;t &lt;em&gt;have&lt;/em&gt; to spend all of that of course, you could save even more, but you &lt;em&gt;can&lt;/em&gt; spend it, free of guilt or stress, knowing that you&amp;rsquo;ve met the most important commitments.&lt;/p&gt;
&lt;p&gt;Here are some additional suggestions and important points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;savings is not the same as just leaving money in your checking account and using it when you want to. Get in the habit of moving it to a different account where you&amp;rsquo;ll be less tempted to dip into it. You can even set up automatic transfers to put money in your savings account each time you get paid.&lt;/li&gt;
&lt;li&gt;save 50% of every salary &lt;em&gt;increase&lt;/em&gt;. At most jobs, you&amp;rsquo;ll get a raise every year or two. If you are already getting by on your current salary, then when you get a raise, that should all be extra, so you can save half of it and leave half for your other expenses.&lt;/li&gt;
&lt;li&gt;save 75% or more of every &lt;em&gt;bonus&lt;/em&gt; (or unplanned) income. Some jobs will pay an additional bonus every year based on how the company is doing. Similar to a salary increase, strive to save the majority of a bonus which is money you shouldn&amp;rsquo;t regularly plan on anway. That&amp;rsquo;s why it&amp;rsquo;s a good idea to put more of it in savings. But it&amp;rsquo;s fine to set some of it aside to treat yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my experience working in finance, where a large portion of people&amp;rsquo;s income came through an annual bonus, it was common to see people who would inflate their lifestyles to a point where they would depend on that annual bonus. Then they were in a tough situation. If they had a bad year, or worse, got laid off, they didn&amp;rsquo;t have anything to fall back on. I&amp;rsquo;d also see people who hated their job but couldn&amp;rsquo;t afford to leave because they became so dependent on that bonus. People use the term &amp;ldquo;golden handcuffs&amp;rdquo; to describe this situation.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a sample budget for a person bringing home $4,250 per month &lt;em&gt;after taxes&lt;/em&gt; have been deducted. You can see that they are able to stay within the thresholds of the &amp;ldquo;needs&amp;rdquo; and &amp;ldquo;wants&amp;rdquo; categories, allowing them to save a little more than the 20% minimum savings goal. This sample shows an appropriate level of detail for your budget categories when you are starting out. It doesn&amp;rsquo;t need to be too detailed or onerous to be useful.&lt;/p&gt;
&lt;h6&gt;Example: Expense tracking and budgeting&lt;/h6&gt;
&lt;p&gt;&lt;img alt="Sample budget" src="https://noisysignal.com/images/money/Sample 50-30-20 Budget.pdf" /&gt;&lt;/p&gt;
&lt;p&gt;One thing related to budgeting is tracking your spending. You can&amp;rsquo;t set up a realistic budget if you don&amp;rsquo;t know where your money is already going. Knowing where your money goes helps you avoid getting into trouble by surprise.&lt;/p&gt;
&lt;p&gt;Tracking your spending has a number of benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it helps you stay within your budget&lt;/li&gt;
&lt;li&gt;it gives you insight into your spending habits and patterns, including areas where you might be wasting money, which could be opportunities to save.&lt;/li&gt;
&lt;li&gt;it will help you manage your debt&lt;/li&gt;
&lt;li&gt;it provides a basis for long-term financial planning. Knowing how much you need to live on is a key component of any financial plan.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are a number of apps that can help with both tracking your spending and managing a budget, which takes a lot of the tedium out of the process and makes it easier to stay on track. I used to use Quicken and also used an app called YNAB (which stands for You Need a Budget). There are other apps like Mint, Personal Capital and Rocket Money that are popular, too.&lt;/p&gt;
&lt;p&gt;Whether you use an app or are fine doing this on your own, the important thing is to pay attention to your spending so you can make informed decisions about what to do with your money.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:mz"&gt;
&lt;p&gt;&lt;a href="https://moneyzine.com/personal-finance-resources/financial-literacy-statistics/#"&gt;https://moneyzine.com/personal-finance-resources/financial-literacy-statistics/#&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:mz" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;a class="footnote-backref" href="#fnref2:mz" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:lwc"&gt;
&lt;p&gt;&lt;a href="https://listwithclever.com/research/stress-in-america-2023/#money"&gt;https://listwithclever.com/research/stress-in-america-2023/#money&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:lwc" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:zip"&gt;
&lt;p&gt;&lt;a href="https://www.zippia.com/advice/average-number-jobs-in-lifetime/"&gt;https://www.zippia.com/advice/average-number-jobs-in-lifetime/&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:zip" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:538"&gt;
&lt;p&gt;&lt;a href="https://fivethirtyeight.com/features/how-many-times-the-average-person-moves/"&gt;https://fivethirtyeight.com/features/how-many-times-the-average-person-moves/&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:538" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>The Very Least You Should Know About Money</title><link href="https://noisysignal.com/the-very-least-you-should-know-about-money.html" rel="alternate"></link><published>2024-10-11T00:00:00-04:00</published><updated>2024-10-11T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-10-11:/the-very-least-you-should-know-about-money.html</id><summary type="html">&lt;p&gt;The first article in a series covering what everyone should know about money.&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the first article in a series covering basic concepts related to money. I first created this content as a presentation for my kids when they were in college to introduce them to important concepts around money and finances. I wanted to give them an overview of how money works in the &amp;ldquo;real&amp;rdquo; world so that when they started working full-time, they would be better informed and prepared on how to manage money responsibly. I&amp;rsquo;ve since adapted it into a set of short  articles for anyone who wants a clearer understanding of how money really works — and how to manage it wisely.&lt;/p&gt;
&lt;h2&gt;Why is This Important?&lt;/h2&gt;
&lt;p&gt;While most of the information presented here might be considered common knowledge, the fact is that most of these topics are not covered in any sort of educational curriculum - at least not in my kids&amp;rsquo; cases - so I wanted to capture what I felt were the essentials and pass them on to my children.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Money can’t buy happiness, but neither can poverty.”
&lt;div class="author"&gt;Leo Rosten&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Money isn’t everything, but the truth is, we live in a world where money is important. Money can provide the means and freedom to make decisions in life, be it in the small, such as where you want to eat, or for things more significant, like where you want to vacation, whether you want to leave your job, or where you want to ultimately live.&lt;/p&gt;
&lt;p&gt;As we’ll see, money has a compounding effect that can work &lt;em&gt;for&lt;/em&gt; you if you form good habits early — or &lt;em&gt;against&lt;/em&gt; you if you don’t.&lt;/p&gt;
&lt;h2&gt;Life’s Three Phases:&lt;br/&gt;Learn, Earn, and Burn&lt;/h2&gt;
&lt;p&gt;A simplistic, but useful way to think of your life is breaking it into three general phases that cover learning through your school years, earning a living through your career, and then spending your retirement savings once you stop working, which I call &amp;ldquo;learn, earn and burn&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The three phases of your financial life" src="https://noisysignal.com/images/money/Three Phases_crop.png" /&gt;
&lt;em&gt;The three phases of your financial life&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you consider that most people live to be 80 or 90, then you will spend roughly the first quarter of your life learning, graduating high school in your late teens, or graduating college in your early 20s.&lt;/p&gt;
&lt;p&gt;Then you’ll spend the next half of your life, say 40-45 years, working and earning money. Hopefully, you&amp;rsquo;ll find something that you enjoy doing and are also good at, enabling you to build a successful career over that period.&lt;/p&gt;
&lt;p&gt;The last quarter of your life will likely be spent in retirement, living off the money you accumulated over those earning years. It’s in this last phase that you’ll &amp;ldquo;burn&amp;rdquo; through your retirement savings doing things like traveling and hopefully enjoying life with all the free time you’ll have in this later stage. This specific path of life isn’t a rule, of course, but the majority of people experience some variation on this theme.&lt;/p&gt;
&lt;h2&gt;Many Questions to Answer&lt;/h2&gt;
&lt;p&gt;Throughout adulthood, you’ll encounter countless financial questions — some big, some small:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What happens to your income?&lt;/li&gt;
&lt;li&gt;What are all those deductions on my paycheck?&lt;/li&gt;
&lt;li&gt;How much of your paycheck should you save?&lt;/li&gt;
&lt;li&gt;Should I follow a budget? It sounds like a pain.&lt;/li&gt;
&lt;li&gt;How is a credit card different than a debit card?&lt;/li&gt;
&lt;li&gt;What should you do with your savings?&lt;/li&gt;
&lt;li&gt;What is a 401k plan? An IRA?&lt;/li&gt;
&lt;li&gt;What does “leasing” a car mean?&lt;/li&gt;
&lt;li&gt;What are stocks? Bonds? ETFs?&lt;/li&gt;
&lt;li&gt;What’s a mortgage? (and why don’t they just call it a loan?)&lt;/li&gt;
&lt;li&gt;How does insurance work? Do I need it?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At first, you may think these questions aren’t important and that understanding how some of these things work isn’t useful information. But before you know it you’ll be facing important financial decisions that can have a big impact on your life.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You’ll be asked to make some decisions at your job about contributing some of your money to a savings plan or health savings account. You will also likely be asked to choose a health insurance plan.&lt;/li&gt;
&lt;li&gt;Your savings plan will require you to make investment elections to determine how that money is actually invested&lt;/li&gt;
&lt;li&gt;You will need to choose where to live and how much you should spend on rent&lt;/li&gt;
&lt;li&gt;You’ll be offered all kinds of deals to sign up for credit cards that seem easy to get and convenient to have&lt;/li&gt;
&lt;li&gt;Later in life, if you need a car, you’ll need to decide if you want to buy it or lease it. If you buy it, you will probably need a loan. You’ll also need to get auto insurance before you can buy the car.&lt;/li&gt;
&lt;li&gt;When you get to the point of buying a home someday, you’ll also need a special loan called a mortgage, and you’ll also need more kinds of insurance for your home.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are some of the questions we’ll address in these posts, along with lots of other important topics around money.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“An investment in knowledge pays the best interest.”
&lt;div class="author"&gt;Benjamin Franklin&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Financial literacy doesn’t just help you avoid mistakes — it gives you &lt;em&gt;options&lt;/em&gt;. It allows you to be in control of your financial life instead of it controlling you.&lt;/p&gt;
&lt;h2&gt;A Tour of What’s Ahead&lt;/h2&gt;
&lt;p&gt;Before diving in, here is a list of topics covered in this series.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Money management&lt;/em&gt;, touching on banking, income, expenses, and budgeting&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Saving and investing&lt;/em&gt; concepts to help you grow the money you save along the way&lt;/li&gt;
&lt;li&gt;Loans and mortgages and the &lt;em&gt;responsible use of debt&lt;/em&gt; as well as the risks of getting into too much debt&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Credit&lt;/em&gt; - how to build your credit history, what a credit score is, and why it’s important&lt;/li&gt;
&lt;li&gt;How insurance works, the many forms of insurance, and how it can be used to &lt;em&gt;protect against financial risks&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;deeper dive into investing&lt;/em&gt; to learn more details, including risk and diversification, before we touch on a few of life’s &lt;em&gt;big financial decisions&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Along the way, we’ll highlight key financial ideas, or &amp;ldquo;key concepts&amp;rdquo;, that will help you interpret the financial world around you and make smarter choices.&lt;/p&gt;</content><category term="misc"></category><category term="money"></category></entry><entry><title>Mac Setup Checklist</title><link href="https://noisysignal.com/mac-setup-checklist.html" rel="alternate"></link><published>2024-09-14T00:00:00-04:00</published><updated>2024-09-14T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-09-14:/mac-setup-checklist.html</id><summary type="html">&lt;p&gt;What I do to set up a new Mac from scratch.&lt;/p&gt;</summary><content type="html">&lt;p&gt;For years I’ve maintained a “Mac Setup Checklist” in a text file to remind me of all the things I need to do when I set up a new Mac or perform a clean install of macOS.&lt;/p&gt;
&lt;p&gt;The checklist is more than just a list of the applications I install. It also includes configuration changes and customizations such as macOS settings, application settings, scheduled tasks, Terminal/shell settings, and more.&lt;/p&gt;
&lt;p&gt;Since this is something I only do every couple of years, it’s easy to forget the details, so the file has been really helpful. But my needs also tend to change over that time so it’s become sort of a living document: each time I use it, I make a new copy as a starting point, work through it as I set up my Mac, and update it accordingly, removing obviated items, adding new items, and updating out-of-date sections.&lt;/p&gt;
&lt;p&gt;This has worked pretty well in a text-file format but recently I wanted to add screenshots of some setting panes to make it easier to follow so I thought I’d put it up here instead and maybe others can get some use from it. This will be a “living” blog post, in a way as I plan to update it as needed.&lt;/p&gt;
&lt;p&gt;I’ve broken this into four sections that mostly follow the order I use. The list of tasks and applications is pretty large, but I don’t really go through this completely when setting up a new computer - I mostly cover the macOS and Utilities sections first so I can just get my new computer in a familiar state and then I selectively pick and choose other applications on an as-needed basis, but I’m trying to include everything here so I have one point of reference for all the applications I use, even if infrequently.&lt;/p&gt;
&lt;h2&gt;macOS&lt;/h2&gt;
&lt;p&gt;After installing a fresh copy of macOS, the first part of my setup process is to configure and customize the OS. I always use the same login name and then log into iCloud to begin the process of syncing files, photos, credentials, and other data stored in the cloud.&lt;/p&gt;
&lt;p&gt;Note that this “configuration” step includes the installation of one third-party application, 1Password, just to make it easy to access credentials I’ll need along the way.&lt;/p&gt;
&lt;p&gt;If I’m reinstalling macOS from scratch, or replacing an existing machine and will be selling or trading in the old one, there are a few additional steps required to decommission the old machine.&lt;/p&gt;
&lt;h3&gt;Pre-flight Steps for Old Machine&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deactivate AirBuddy (it supports five active installs and tracks the number of active devices using it, so you need to deactivate an old install if you are no longer using it)&lt;/li&gt;
&lt;li&gt;For newer Macs, you can just erase everything\
    System Settings &amp;gt; General &amp;gt; Transfer or Reset &amp;gt; Erase All Content and Settings&amp;hellip;&lt;/li&gt;
&lt;li&gt;For older Macs, you need to do a few extra things&lt;ul&gt;
&lt;li&gt;System Settings &amp;gt; [Apple ID] &amp;gt; iCloud &amp;gt; Find My Mac (may need to click “Show More Apps&amp;hellip;” first) &amp;gt; “Turn Off&amp;hellip;”&lt;/li&gt;
&lt;li&gt;System Settings &amp;gt; [Apple ID] &amp;gt; “Sign Out&amp;hellip;”&lt;/li&gt;
&lt;li&gt;Messages &amp;gt; Settings&amp;hellip; &amp;gt; iMessage &amp;gt; Sign Out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1Password&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Login to 1password.com (requires user ID, Secret Key and password from 1Password on my iPhone or another Mac)&lt;/li&gt;
&lt;li&gt;My Account &amp;gt; “Get the Apps”, download the app and run it&lt;/li&gt;
&lt;li&gt;1Password &amp;gt; Settings&amp;hellip; &amp;gt; Browser, follow process to add the 1Password for Safari extension&lt;ul&gt;
&lt;li&gt;Safari, Settings&amp;hellip;, AutoFill, uncheck “User names and passwords”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1Password Command Line&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brew install 1password-cli&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;1Password &amp;gt; Settings&amp;hellip;, Developer, check “Integrate with 1Password CLI”&lt;/li&gt;
&lt;li&gt;&lt;code&gt;op vault list&lt;/code&gt; to verify&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Configuration changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;System Settings&lt;ul&gt;
&lt;li&gt;General&lt;ul&gt;
&lt;li&gt;Sharing&lt;ul&gt;
&lt;li&gt;Screen Sharing: on&lt;/li&gt;
&lt;li&gt;Remote Login: on&lt;/li&gt;
&lt;li&gt;Local hostname &amp;gt; “Edit&amp;hellip;”, change to &lt;code&gt;[name].local&lt;/code&gt;, (the text doesn’t look editable but it is)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Touch ID &amp;amp; Password &amp;gt; Apple Watch: on&lt;/li&gt;
&lt;li&gt;Desktop &amp;amp; Dock &amp;gt; Position on screen: Right&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Finder&lt;ul&gt;
&lt;li&gt;Settings&amp;hellip; &amp;gt; Sidebar, check “Hard disks” and “david/Home”&lt;/li&gt;
&lt;li&gt;Change default view to List everywhere&lt;ul&gt;
&lt;li&gt;Open a Finder window&lt;ul&gt;
&lt;li&gt;Change view to List&lt;/li&gt;
&lt;li&gt;View &amp;gt; Show View Options&lt;/li&gt;
&lt;li&gt;check “Always open in list view”&lt;/li&gt;
&lt;li&gt;check “Browse in list view”&lt;/li&gt;
&lt;li&gt;click “Use as Defaults” at bottom&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Safari&lt;ul&gt;
&lt;li&gt;View, Show Status Bar&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Desktop Mac&lt;/h4&gt;
&lt;p&gt;There are some special settings for my desktop, which I keep on all the time, so I can run scheduled tasks, plus I have external backup drives attached to it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disk Utility &amp;gt; “Bootable Backup” &amp;gt; Mount, enter the password for my external USB “Bootable Backup” drive and save this in Keychain&lt;/li&gt;
&lt;li&gt;System Settings &amp;gt; Siri &amp;amp; Spotlight &amp;gt; Spotlight Privacy, add “Bootable Backup” and “OWC2TB” to Privacy list&lt;/li&gt;
&lt;li&gt;Photos &amp;gt; Settings &amp;gt; iCloud &amp;gt; Download Originals to this Mac: on&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mail &amp;gt; Settings &amp;gt; Accounts &amp;gt; Google &amp;gt; Download Attachments: All&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Turn off sleeping&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System Settings &amp;gt; Battery &amp;gt; Options&amp;hellip;, &amp;ldquo;Prevent automatic sleeping when the display is off”: on&lt;/li&gt;
&lt;li&gt;Set daily sleep/wake schedule&lt;br/&gt;
&lt;code&gt;sudo pmset repeat wakeorpoweron MTWRFSU 06:00:00 sleep MTWRFSU 23:00:00&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Verify the schedule&lt;br/&gt;
&lt;code&gt;pmset -g sched&lt;/code&gt; (look at the &amp;ldquo;Repeating power events&amp;rdquo; at the top)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Repeating power events:
  wakepoweron at 6:00AM every day
  sleep at 11:00PM every day
...   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Utilities&lt;/h2&gt;
&lt;h3&gt;Tailscale&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;li&gt;Run Tailscale, login with Google account&lt;/li&gt;
&lt;li&gt;Settings &amp;gt; Launch Tailscale at login&lt;/li&gt;
&lt;li&gt;If this is a replacement machine, Settings &amp;gt; Accounts &amp;gt; Admin Console, delete old machine, rename the new one&lt;/li&gt;
&lt;li&gt;Settings &amp;gt; Accounts &amp;gt; Admin Console, &amp;hellip;&lt;ul&gt;
&lt;li&gt;Edit machine name&lt;/li&gt;
&lt;li&gt;Disable key expiry&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tailscale status&lt;/code&gt; to confirm&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;LaunchControl&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from https://www.soma-zone.com/download/&lt;/li&gt;
&lt;li&gt;License key in Craft&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Keyboard Maestro&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from https://www.keyboardmaestro.com/main/&lt;/li&gt;
&lt;li&gt;Serial number in Craft&lt;/li&gt;
&lt;li&gt;File &amp;gt; Start Syncing Macros&amp;hellip; &amp;gt; Open Existing&amp;hellip;, iCloud/Documents/Keyboard Maestro Macros.kmsync&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Development Tools&lt;/h2&gt;
&lt;h3&gt;zsh&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;set \~/.zshenv to contain
  export ZDOTDIR=/Users/david/Library/Mobile\ Documents/com\~apple\~CloudDocs/Documents/zsh&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Terminal&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Terminal &amp;gt; Settings &amp;gt; Profiles&lt;/li&gt;
&lt;li&gt;Select “Silver Aerogel”, set as Default&lt;/li&gt;
&lt;li&gt;Text&lt;ul&gt;
&lt;li&gt;Color &amp;amp; Effects&lt;ul&gt;
&lt;li&gt;Normal windows: 100% Opacity and Blur&lt;/li&gt;
&lt;li&gt;Inactive windows: 40% Opacity, 50% Blur&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set cursor color to red&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Window&lt;ul&gt;
&lt;li&gt;Columns: 120, Rows: 60&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Shell&lt;ul&gt;
&lt;li&gt;When the shell exits: Close if the shell exited cleanly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Man pages&lt;ul&gt;
&lt;li&gt;Terminal &amp;gt; Settings &amp;gt; Man Page &amp;gt; Text&lt;ul&gt;
&lt;li&gt;Background, Colors &amp;amp; Effects: Pencils, Tungsten&lt;/li&gt;
&lt;li&gt;Text, Text: Pencils, Silver&lt;/li&gt;
&lt;li&gt;Text, Bold Text: Pencils, Lavender&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;xman ls&lt;/code&gt; to verify&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ssh&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Configure for remote, &lt;a href="https://noisysignal.com/passwordless-ssh-access.html"&gt;password-less &lt;code&gt;ssh&lt;/code&gt; access&lt;/a&gt; to other Macs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Homebrew&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Install brew&lt;br/&gt;
  &lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If you get &lt;code&gt;zsh: complicit&lt;/code&gt; errors after installing homebrew, run &lt;code&gt;compaudit&lt;/code&gt; to see which directories are causing this, then run &lt;code&gt;sudo chown -R 755 &amp;lt;directory&amp;gt;&lt;/code&gt; to fix the permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Python&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brew install python&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;VS Code&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;Setup Settings Sync with Github&lt;ul&gt;
&lt;li&gt;Gear icon &amp;gt; Turn on Settings Sync&amp;hellip; &amp;gt; Sign in with Github&lt;/li&gt;
&lt;li&gt;(This will bring over extensions and other settings)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Scheduled Tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;On desktop Mac&lt;ul&gt;
&lt;li&gt;daily activity report&lt;/li&gt;
&lt;li&gt;checkout &lt;code&gt;findash&lt;/code&gt; Github repo&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cp com.noisysignal.daily_activity_report.plist \~/Library/LaunchAgents/.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run LaunchControl to test and debug&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SF Symbols&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from developer.apple.com&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Xcode&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;git&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;(comes with Xcode Command Line Tools)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;brew install gh&lt;/code&gt; (github credential manager)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gh auth login&lt;/code&gt; (follow prompts, can do this for multiple Github accounts)&lt;ul&gt;
&lt;li&gt;Account: GitHub.com&lt;/li&gt;
&lt;li&gt;Protocol: HTTPS&lt;/li&gt;
&lt;li&gt;Use GitHub credentials: Yes&lt;/li&gt;
&lt;li&gt;Login with browser&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Sketch&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;Login with account in 1Password&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Docker&lt;/h3&gt;
&lt;h2&gt;Applications&lt;/h2&gt;
&lt;p&gt;Install these on-demand when/if needed&lt;/p&gt;
&lt;h3&gt;Back Blaze&lt;/h3&gt;
&lt;h3&gt;AirBuddy&lt;/h3&gt;
&lt;h3&gt;Audio Hijack&lt;/h3&gt;
&lt;h3&gt;Backblaze&lt;/h3&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Note: Enable this at the end of setting up the computer to give iCloud, Spotlight, and Photos a chance to download and process data, otherwise it goes kind of crazy trying to keep up with all the file changes.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;If this is a new machine, add it as such. If instead, this is replacing an existing machine, use Inherit Backup.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CCC&lt;/h3&gt;
&lt;h3&gt;Chrome&lt;/h3&gt;
&lt;h3&gt;Craft&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;li&gt;Sign in with Gmail address&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Final Cut Pro&lt;/h3&gt;
&lt;h3&gt;iA Presenter&lt;/h3&gt;
&lt;h3&gt;iA Writer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;li&gt;Settings &amp;gt; Accounts &amp;gt; + Ghost&lt;/li&gt;
&lt;li&gt;Add in Admin API Key and Admin URL from 1Password&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Kagi Search&lt;/h3&gt;
&lt;h3&gt;Microsoft Office&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;li&gt;Login with “David Microsoft Live” credentials in 1Password&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Moom&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;Key in Craft&lt;/li&gt;
&lt;li&gt;Settings (gear)&lt;ul&gt;
&lt;li&gt;Separate windows by 5pt&lt;/li&gt;
&lt;li&gt;check “Launch automatically on login”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;NetNewsWire&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;NetNewsWire &amp;gt; Settings &amp;gt; Accounts, add iCloud, deactivate On My Mac&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Paprika&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App Store&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ScanSnap ix1500 - ScanSnap Manager V7&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from https://www.scansnapit.com/uk/support/downloads&lt;/li&gt;
&lt;li&gt;Currently requires Rosetta as there is no Apple Silicon version. It will prompt you to install it during the setup process.&lt;/li&gt;
&lt;li&gt;You need to connect the scanner to the Mac with a USB cable during setup. At the end it will ask you to setup Wi-Fi access and walk you through it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Setapp&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;Install common apps&lt;ul&gt;
&lt;li&gt;Bartender&lt;/li&gt;
&lt;li&gt;Clean Shot X&lt;ul&gt;
&lt;li&gt;Settings, check “Start at Login”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hand Mirror&lt;/li&gt;
&lt;li&gt;iStat Menus&lt;/li&gt;
&lt;li&gt;TablePlus&lt;/li&gt;
&lt;li&gt;Timing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Slack&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from website&lt;/li&gt;
&lt;li&gt;Launch and will redirect to web to login&lt;/li&gt;
&lt;li&gt;Select channels&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;TextExpander&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Log into website&lt;/li&gt;
&lt;li&gt;Get the app&lt;/li&gt;
&lt;li&gt;Install it&lt;/li&gt;
&lt;li&gt;Log in&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Things&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Download from App store&lt;/li&gt;
&lt;li&gt;Things &amp;gt; Settings &amp;gt; Things Cloud: on&lt;/li&gt;
&lt;li&gt;Login using 1Password credentials&lt;/li&gt;
&lt;li&gt;Things &amp;gt; Settings &amp;gt; Quick Entry &amp;gt; Enable shortcut for Quick Entry with Autofill: on\
(Takes you to Things website to download Things Helper, run it, then delete it)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Zoom&lt;/h3&gt;</content><category term="misc"></category><category term="mac"></category></entry><entry><title>Passwordless ssh access</title><link href="https://noisysignal.com/passwordless-ssh-access.html" rel="alternate"></link><published>2024-09-14T00:00:00-04:00</published><updated>2024-09-14T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-09-14:/passwordless-ssh-access.html</id><summary type="html">&lt;p&gt;How to set up a computer for ssh access without the need for a password.&lt;/p&gt;</summary><content type="html">&lt;p&gt;To allow paswordless &lt;code&gt;ssh&lt;/code&gt; access from host C (client) to host S (server), you need to copy C’s public authentication key, typically &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; to S and append it to S’s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;You can copy this in two ways:&lt;/p&gt;
&lt;p&gt;From client C:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat ~/.ssh/id_rsa.pub | ssh &amp;lt;user&amp;gt;@&amp;lt;server&amp;gt; &amp;quot;cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or more simply, if the &lt;code&gt;ssh-copy-id&lt;/code&gt; command is available:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-copy-id &amp;lt;user&amp;gt;@&amp;lt;server&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If C is a new computer without &lt;code&gt;ssh&lt;/code&gt; set up on it yet, you need to first create the &lt;code&gt;~/.ssh&lt;/code&gt; folder&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir -p ~/.ssh
chmod 700 ~/.ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and then create the authentication key with a blank password (press &lt;code&gt;Return&lt;/code&gt; at the prompt):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="misc"></category><category term="mac"></category></entry><entry><title>The Apple Vision Pro Demo</title><link href="https://noisysignal.com/the-apple-vision-pro-demo.html" rel="alternate"></link><published>2024-02-10T00:00:00-05:00</published><updated>2024-02-10T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-02-10:/the-apple-vision-pro-demo.html</id><summary type="html">&lt;p&gt;My first impressions of the Apple Vision Pro.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A few days ago I received a demonstration of the Apple Vision Pro headset. Here are my thoughts after the 30-ish minute experience.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Vision Pro" src="https://noisysignal.com/images/vision-pro/vision-pro-card-50-acmi-202401.jpeg" /&gt;&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;The Vision Pro requires several customizations to be fit and adjusted to each individual. Apple has done a nice job of making that process as easy as possible. I wear prescription glasses for reading so the first step in the process was to scan my glasses in the “lensometer” — a device they designed just for this purpose.&lt;/p&gt;
&lt;p&gt;I asked the person helping me why they didn’t simply have me submit my prescription information online when I scheduled the demo. He said if they asked for that, they would have had to adhere to HIPAA privacy regulations and they wanted to keep this information anonymous. The lensometer calculates this information from your eyeglasses and relays it to an employee in the back who gathers the optical inserts (and later, the light seal) but doesn’t know your name.&lt;/p&gt;
&lt;p&gt;Next, you download the Apple Store app on your phone and scan your face for the light seal fit. This gives them the information they need to set up a personalized device. After a few minutes, someone from the back of the store came out and delivered the device with the appropriate light seal and corrective lenses.&lt;/p&gt;
&lt;p&gt;For the demo, I sat the whole time. They had a table and chair dedicated for the demo but the Greenwich store didn’t have a dedicated space with a sofa like they have done other stores. In fact, my guide for the demo suggested I keep my feet on the floor as some people move suddenly when they react to the 3D videos.&lt;/p&gt;
&lt;p&gt;When you first put on the device, after some fitting adjustments, you go through the onboarding process. That involves adjusting the device for the distance between your pupils with the digital crown, then I looked at the Apple rep’s iPhone which had a special code on it for my lens inserts. That told the Vision Pro how to adjust itself for the corrective lenses that had been inserted.&lt;/p&gt;
&lt;p&gt;After that you &lt;em&gt;should&lt;/em&gt; be able to see clearly in the device and can continue with the training exercise for eye tracking and tapping. In my case, however, the icons in the display were still pretty blurry. I had to adjust the headstrap and the placement of the device on my face a bit before the display became more clear. It seems to be quite sensitive to the fit of the device and I can imagine there will be some tweaking every time you put it on. Maybe that’s more of an issue for those with corrective lenses, though.&lt;/p&gt;
&lt;p&gt;The eye-tracking and finger-tapping exercise is simple and intuitive and in just a few seconds it felt natural to “look-and-tap” my way around the interface.&lt;/p&gt;
&lt;h2&gt;Using the Vision Pro&lt;/h2&gt;
&lt;p&gt;After the onboarding, the pass-through mode is enabled and it’s really impressive. It looked as though I was looking through ski goggles at the Apple store. There was no perceptible lag or motion blur from people moving around. It just appears a little darker, like you are looking through sunglasses. I’ve read that this is adjustable and is done purposely so the user interface elements stick out more from the background.&lt;/p&gt;
&lt;p&gt;Photos looked incredible, especially the panoramic ones where you could look to either side as if you were surrounded by them. But even for just standard photos, the experience of seeing them so large and in such detail was notably better than when I normally view photos on my iMac. All of the external clutter of my desk, or light from lamps and windows is absent so there’s just the image in front of you. This creates a much more personal experience when reliving old memories.&lt;/p&gt;
&lt;p&gt;Watching movie clips was also amazing. They showed a short section from the recent Avatar movie, and it’s not just that Avatar is a 3D movie, but more the captive feeling of being in a theater without the typical noise, distractions, and obstructions.&lt;/p&gt;
&lt;p&gt;The sound was really impressive too. It felt like the best home theater system I’ve ever experienced and in that context, $3500 is not a lot of money. Some of my friends have spent $10k-$15k on home theater systems and I’m usually underwhelmed with the experience, especially the audio. Home theater audio systems seem to be designed to work well for one person sitting precisely in one spot.&lt;/p&gt;
&lt;p&gt;In my case, when watching movies at home, it’s hard to avoid some sort of reflection on my TV and the screen is not that big anyway. Plus I can see banding in dark scenes. In the Vision Pro, it was just perfect.&lt;/p&gt;
&lt;p&gt;As for interacting with the visionOS software environment, moving windows around, scrolling, opening, and closing them was all very intuitive. I didn’t get a lot of time to try out a lot of different situations, though, so I’d like to experience using two or three apps at the same time and switching between them, as you would normally do on a computer.&lt;/p&gt;
&lt;p&gt;The 3D photos and videos are surreal. It feels like you are inside the image, sharing the same space with the subjects. But after my initial sense of amazement, I wonder if it’s any better than flipping through a scrapbook. Pictures are triggers that evoke memories and it’s the memories that are meaningful. I don’t have an iPhone 15 Pro right now so it’s not an option to start capturing those pictures and videos, but if I did I might do it occasionally, but not all the time.&lt;/p&gt;
&lt;p&gt;The 3D immersive experiences where you can look around the environment and see what you want to inside the virtual space felt quite real. There was a little bit of distortion on the edges and some parts of the frame were not in focus, but that could be from the depth-of-field that was used in filming the scene.&lt;/p&gt;
&lt;p&gt;The demo covers very short clips of Alicia Keys in a studio, a mountain climber setting up ropes on a ledge, a tightrope walker walking across a crevasse, and also two sports clips. &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; These experiences are where the Visiono Pro excels and as Apple and its partners produce more of this content, I think it will be the thing that gets people to want to buy one of these devices, at least at this point.&lt;/p&gt;
&lt;p&gt;The 3D immersive environment was also incredible. I was in a field viewing a lake with mountains in the background. I looked behind me and could see the rest of the field. And I could hear raindrops as they fell on the surface of the lake. You could really lose yourself in that environment and it would be great for meditation, or shutting out your physical environment to read, listen to music or an audiobook, or just relax.&lt;/p&gt;
&lt;p&gt;The demo is very scripted (the representative sits next to you and watches what you are seeing on an iPad mini and prompts you to stay on track through the demo). Sadly, they do not cover the Mac Virtual Display in the demo, nor is there an opportunity to use an attached keyboard or trackpad. It’s difficult to know what it would be like to say, enter a search phrase in Safari, open a few pages, switch tabs, and click on a few links — all the things I take for granted when using a Mac to do work.&lt;/p&gt;
&lt;h2&gt;Observations&lt;/h2&gt;
&lt;p&gt;I did not notice the weight of the device during the demo. Of course, the session is quite short — less than half an hour — so it might have been more of an issue had I watched a two-hour movie.&lt;/p&gt;
&lt;p&gt;In some cases, you can see the edges of the field of view. It’s not distracting — you have to look for it, but when you do it breaks the illusion of being somewhere else. But in the immersive environment that wasn’t an issue.&lt;/p&gt;
&lt;p&gt;Apple is promoting this device as a new form of computing, which they call &lt;em&gt;spatial computing&lt;/em&gt;. The Vision Pro lives up to that — you can place items in your environment and they stick right where you placed them as if they are physically in the virtual space. It’s quite an amazing effect.&lt;/p&gt;
&lt;p&gt;While I don’t disagree that this device offers a new computing paradigm, it also needs to be useful with existing tools and workflows so people can incorporate it into their current process. It’s just not clear to me at this point that I could use it to say, write code, pay bills, or even write this blog post, and would find that an equal or better experience than I have right now with a traditional computer. On this point, Apple still has some convincing to do.&lt;/p&gt;
&lt;h2&gt;Would I Buy One?&lt;/h2&gt;
&lt;p&gt;While the device may be the most advanced hardware I’ve ever had a chance to experience, I didn’t walk out of the store with a burning desire to buy one — at least not yet.&lt;/p&gt;
&lt;p&gt;There are three reasons for my skepticism.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Price.&lt;/strong&gt; $3500 is a lot of money, more so than I’ve ever spent on a computer. And since I need corrective lenses and would probably want a carrying case, the actual price would be closer to $4000. If I was a hardcore movie buff and the kind of person who would spend thousands or even tens of thousands of dollars on a home theater system, then $4k doesn’t sound that bad. But I’m not — I have a $350 4k Hisense TV that I bought from Amazon and I watch it using the built-in speakers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limitations of Guest mode.&lt;/strong&gt; Right now, the device doesn’t support multiple user profiles so it’s not easy to share with someone else in your home. There is a guest mode that you can activate that allows someone else to use it in a limited capacity for a limited time, but each time you initiate guest mode, the guest user needs to go through the onboarding process. It doesn’t remember the old settings, so that makes it more difficult for another person in the household to use it regularly.&lt;/p&gt;
&lt;p&gt;Additionally, each guest might need their own light seal and corrective lenses so you’d need to swap those out each time. While that’s relatively easy to do as they use magnets to “snap in”, it’s just more friction.&lt;/p&gt;
&lt;p&gt;For me, I’d feel bad if I bought this device, &lt;em&gt;raved&lt;/em&gt; about how great it was, and then couldn’t easily share it with my wife and kids. It feels a bit selfish.&lt;/p&gt;
&lt;p&gt;This is an area Apple could improve a lot through software. iOS and iPad OS have always been limited to one user in this way and visionOS is based on iPad OS. But while that design choice makes sense for an iPhone — a very personal device — the iPad is often something families like to share. They can do this by sharing the screen-lock code but the device will always be limited to one iCloud account and that one person’s messages, email, documents, and applications. That’s true for the visionOS right now, too.&lt;/p&gt;
&lt;p&gt;I think Apple’s missing something here. The only way to truly appreciate the Vision Pro is to try it. If they made it easier for a friend to just put it on and initiate some sort of scripted demo, it would be a great way to organically market the product. Right now, the limitations and clunkiness of the guest mode experience may leave a negative impression on someone trying it out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uncertainty about Mac integration.&lt;/strong&gt; The last reason I’m hesitant to purchase the device right now is that for me, the use case of integrating this with a Mac desktop or laptop is very important. But the demo doesn’t cover that use case so I have no first-hand experience of the Mac Virtual Display mode. And from what I’ve read from reviews so far, there are some important limitations with this mode, such as the number of virtual displays allowed, and the use of “look-and-tap” within the Mac window.&lt;/p&gt;
&lt;p&gt;However, these issues can also likely be improved through software, so I’ll keep an eye on how the product evolves over the year.&lt;/p&gt;
&lt;p&gt;The Vision Pro is an amazing technological accomplishment and provides an experience, unlike anything I’ve encountered before. I’m reserving judgment on whether I would buy the device until it’s had some time to evolve and mature. I didn’t buy the first iPhone, nor the first Apple Watch. But I have them now and am very happy with them. I can imagine a similar path for the Vision Pro.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;For some reason, my demo did not include the dinosaur environment with the butterfly landing on your hand. I don’t know if my guide just forgot to have me open it, or if it was cut from my version of the tour video. I didn’t realize until after I’d left.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"></category><category term="apple"></category></entry><entry><title>Fujifilm Film Simulations</title><link href="https://noisysignal.com/fujifilm-film-simulations.html" rel="alternate"></link><published>2024-01-21T00:00:00-05:00</published><updated>2024-01-21T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-01-21:/fujifilm-film-simulations.html</id><summary type="html">&lt;p&gt;Fujifilm&amp;rsquo;s film simulations create beautiful JPEGs right out of the camera and provide an extra bit of creativity for the photographer.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Fujifilm cameras are well known for their built-in film simulations. These are the algorithms and settings that convert the raw sensor data to a JPEG image. Every digital camera has some sort of profile or set of profiles for controlling this conversion process, but often cameras have just one standard profile and then some additional adjustments you can dial in if desired.&lt;/p&gt;
&lt;p&gt;Building on Fujifilm&amp;rsquo;s rich history in analog film, they have developed film simulations to emulate the color science and chemistry of many of their popular film stocks. My Fujifilm X100V comes with 17 film simulations—8 color, 8 black &amp;amp; white, and Sepia.&lt;/p&gt;
&lt;p&gt;Film simulations are different than &lt;em&gt;filters&lt;/em&gt; which are popular in consumer digital cameras, photo editing software, and social media apps. Filters are adjustments made to a JPEG image to provide an effect such as &lt;em&gt;warm&lt;/em&gt;, &lt;em&gt;vivid&lt;/em&gt;, or &lt;em&gt;cool&lt;/em&gt;. They do not process the original raw sensor data, however, so they are already starting from an image that has been converted and adjusted to produce the source JPEG.&lt;/p&gt;
&lt;p&gt;Fujifilm&amp;rsquo;s film simulations were designed to specifically emulate the color sensitivity, tone, and grain of actual analog film stock. Choosing film stock was a degree of creativity analog photographers had at their disposal and has been somewhat lost with the shift to digital photography. Fujifilm has brought that back in a convincing way.&lt;/p&gt;
&lt;h2&gt;Film Simulation Examples&lt;/h2&gt;
&lt;p&gt;Custom film simulations can also be programmed into Fujifilm cameras and there is a community of photographers who have created their own simulations to emulate other film stocks such as those from Kodak and Agfa. The site Fuji X Weekly &lt;a href="https://fujixweekly.com/recipes/"&gt;maintains a catalog&lt;/a&gt; of these &amp;ldquo;recipes&amp;rdquo; for each type of Fujifilm camera.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Film Simulation Samples" src="https://noisysignal.com/images/film-simulations/Film-Simulations.png" /&gt;
&lt;em&gt;Examples of color film simulations. St Salvator&amp;rsquo;s Hall, St. Andrews, UK&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Above are examples of the eight built-in color film simulations on the X100V plus one custom recipe I programmed in my camera. The center image using Provia is the default film simulation in Fujifilm cameras and the one I shoot with most often. You can see how it compares to the other seven built-in simulations. The custom simulation, &lt;a href="https://fujixweekly.com/2021/11/22/fujifilm-x-trans-iv-film-simulation-recipe-retro-gold/"&gt;Retro Gold&lt;/a&gt;, in the lower right corner, is an example of how you can use the same feature to program filters or effects if you like.&lt;/p&gt;
&lt;h2&gt;Using Film Simulations&lt;/h2&gt;
&lt;p&gt;To experiment with film simulations, you&amp;rsquo;ll want to shoot RAW or RAW+JPEG. If you shoot JPEG only, you can only select one film simulation and won&amp;rsquo;t be able to change it afterward. But if you have the RAW image, you can apply different simulations and adjustments later and convert the RAW image to a new JPEG using those settings. This conversion process can be performed on camera or using their &lt;a href="https://fujifilm-x.com/en-us/products/software/x-raw-studio/"&gt;FUJIFILM X RAW STUDIO&lt;/a&gt; application.&lt;/p&gt;
&lt;p&gt;Once you get used to the settings that you like for different situations, you can program your favorites into one of the quick access buttons or knobs and shoot only JPEG, if you prefer. There is even a bracketing mode for shooting three simulations at once.&lt;/p&gt;
&lt;p&gt;I find these film simulations fun to experiment with and a nice way of adding a degree of creativity for choosing a specific film without overdoing it and the feature is one of the reasons I opted for a Fujifilm camera. I like the quality and look of the JPEGs as they are captured rather than having to spend a lot of time editing and adjusting them later.&lt;/p&gt;</content><category term="misc"></category><category term="photography"></category></entry><entry><title>Refreshing Data in the Background in Swift</title><link href="https://noisysignal.com/refreshing-data-in-the-background-in-swift.html" rel="alternate"></link><published>2024-01-11T00:00:00-05:00</published><updated>2024-01-11T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2024-01-11:/refreshing-data-in-the-background-in-swift.html</id><summary type="html">&lt;p&gt;Create a background processing loop with ease using Swift&amp;rsquo;s new concurrency features.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Sometimes in an application, there is the need to periodically update data or perform some processing in the background. There are several different ways this can be accomplished, but with the newer Swift concurrency features this can be done in a relatively simple way.&lt;/p&gt;
&lt;p&gt;Here is an example of an object responsible for fetching stock quotes in the background and updating an observable dictionary when new quotes are received.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Observable&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuoteManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Quote&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="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;refreshTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Never&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;

  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;startUpdating&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;refreshTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;repeat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;refreshQuotes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nanoseconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60_000_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;stopUpdating&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;refreshTask&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;refreshQuotes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;async&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;ticker&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;refreshQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ticker&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="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;refreshQuote&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;ticker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MainActor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="bp"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are a few items to note here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We are using the new &lt;code&gt;@Observable&lt;/code&gt; macro which automates a lot of the boilerplate code we would have previously needed with &lt;code&gt;ObservableObject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We create a &lt;code&gt;Task&lt;/code&gt; in &lt;code&gt;startUpdating()&lt;/code&gt; which simply repeats in a loop to do the background work of fetching new quotes each minute. We also save the task item in a variable to simplify canceling the background process in &lt;code&gt;stopUpdating()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;refreshQuote(for:)&lt;/code&gt; we use await to fetch the new data and then update the quotes dictionary on the main thread via &lt;code&gt;MainActor.run&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before Swift 5.5, we could have done this with &lt;code&gt;DispatchQueue&lt;/code&gt; using &lt;code&gt;.main.async&lt;/code&gt; for code in the main thread and &lt;code&gt;.global(qos: .background).async&lt;/code&gt; for the background processing, but I find the newer approach easier to understand. &lt;/p&gt;</content><category term="misc"></category><category term="swift"></category></entry><entry><title>Finding Possible Solutions to Wordle</title><link href="https://noisysignal.com/finding-possible-solutions-to-wordle.html" rel="alternate"></link><published>2023-01-27T00:00:00-05:00</published><updated>2023-01-27T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2023-01-27:/finding-possible-solutions-to-wordle.html</id><summary type="html">&lt;p&gt;A Python script to find valid words for solving the Wordle game&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Article image" src="https://noisysignal.com/images/wordle/wordle.png" /&gt;&lt;/p&gt;
&lt;p&gt;I read Dr. Drang’s &lt;a href="https://leancrew.com/all-this/"&gt;post about his Wordle script&lt;/a&gt; and found it an interesting approach to finding possible solutions to Wordle. Like many other people, I also wrote a script to help find possible matches to Wordle back when it became so popular about a year ago.&lt;/p&gt;
&lt;p&gt;Dr. Drang first solved this using a sequence of two &lt;code&gt;egrep&lt;/code&gt; commands which he described in &lt;a href="https://leancrew.com/all-this/2023/01/not-cheating-at-wordle/"&gt;Not cheating at Wordle.&lt;/a&gt; The approach then was to use the first &lt;code&gt;egrep&lt;/code&gt; command to find all words &lt;em&gt;excluding&lt;/em&gt; those with the absent characters  (marked in gray) but also including known (green) characters in their proper location. The results were piped to a second &lt;code&gt;egrep&lt;/code&gt; which then filtered that list for words that &lt;em&gt;include&lt;/em&gt; any present characters without a known location (yellow).&lt;/p&gt;
&lt;p&gt;His follow-up post replaced this with a Python script that followed a similar approach but borrowed a feature from John Gruber’s Perl solution to pass in the list of letters that must appear (yellow) with known invalid locations in the form &lt;code&gt;a23&lt;/code&gt; that is, the word must contain the letter &lt;code&gt;a&lt;/code&gt; but not in position 2 or 3. From that, he builds a set of regular expressions that are applied to find matching words.&lt;/p&gt;
&lt;p&gt;My script used a different approach in that you enter the results of each guess encoded in a way that represents the response Wordle produces. Each character in a Wordle response can be in one of three states: gray for a letter that is absent in the word, yellow for a letter that is present in the word but not in that location, and green for a letter that is in the correct location.&lt;/p&gt;
&lt;p&gt;Unfortunately, there isn’t an easy way to represent each letter in three different states from the command line. Two states are easy, using uppercase and lowercase characters. For a third state I simply chose to follow correct letters with an &lt;code&gt;=&lt;/code&gt; so a guess might look like&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stA=rE&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;to indicate that &lt;code&gt;s&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;and &lt;code&gt;r&lt;/code&gt;should be absent (gray), &lt;code&gt;e&lt;/code&gt;should be present but not in the fifth position (yellow) and &lt;code&gt;a&lt;/code&gt;should be present and in the third position (green).&lt;/p&gt;
&lt;p&gt;This allows you to just enter the guesses you’ve made so far without too much thinking.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The full script is below. For input it accepts any number of guess “patterns” encoded as I described above. After reading in the dictionary of all possible words (valid guesses and solutions), the valid words are determined by successively eliminating words that are not valid.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;find possible solutions to wordle&lt;/span&gt;
&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;Enter one or more guess &amp;quot;patterns&amp;quot; using lowercase characters for&lt;/span&gt;
&lt;span class="s2"&gt;letters that must be absent in the word (black), uppercase characters&lt;/span&gt;
&lt;span class="s2"&gt;for letters that must be present in the word (yellow) and an&lt;/span&gt;
&lt;span class="s2"&gt;uppercase character followed by &amp;quot;=&amp;quot; for characters that must be in&lt;/span&gt;
&lt;span class="s2"&gt;that location (green). For example, stA=rE indicates that &amp;#39;s&amp;#39;, &amp;#39;t&amp;#39;&lt;/span&gt;
&lt;span class="s2"&gt;and &amp;#39;r&amp;#39; are not in the word, &amp;#39;a&amp;#39; is in the third position and &amp;#39;e&amp;#39; is&lt;/span&gt;
&lt;span class="s2"&gt;in the word but not in the fifth position.&lt;/span&gt;

&lt;span class="s2"&gt;Supply additional patterns for the result of each guess.&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;pattern&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Five-character guess result, e.g. stA=rE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&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;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wordle.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;

    &lt;span class="n"&gt;allinclude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&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;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;exclude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^a-z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^A-Z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[a-z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;([a-z])(?!=)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^\1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;([a-z])=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;^&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

        &lt;span class="n"&gt;allinclude&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;include&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;wrds&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;grouped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrds&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; possible matches&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allinclude&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;guess for next word: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;grouped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;return groups of `size` items at a time from `vals` list&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;size&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="nb"&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;choose a good word for the next guess based on the count of remaining untried characters&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;difference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;known&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt; &lt;span class="n"&gt;w&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;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;guesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guesses&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The interesting part of the script takes place in the first &lt;code&gt;for&lt;/code&gt; loop.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;exclude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^a-z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^A-Z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[a-z]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;([a-z])(?!=)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^\1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;([a-z])=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;^&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Each guess pattern that is passed in is processed to generate three variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;exclude&lt;/code&gt; contains the characters that must be absent from the word&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include&lt;/code&gt; contains the characters that must be present in the word&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pattern&lt;/code&gt; is a regex pattern produced from the guess that matches words with the two rules, one for correct letters in the wrong position and one for correct letters in the right position&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To assign the &lt;code&gt;exclude&lt;/code&gt; and &lt;code&gt;include&lt;/code&gt; variables, a simple regular expression is used to remove the characters we aren&amp;rsquo;t interested in, leaving those we desire. The variable &lt;code&gt;include&lt;/code&gt; will contain both the characters in the right position (green) and the wrong position (yellow).&lt;/p&gt;
&lt;p&gt;Creating the variable &lt;code&gt;pattern&lt;/code&gt; takes a little more explanation. We want it to match valid words but since we are handling characters to include and exclude separately, the regular expression can be much simpler. So in lines 30-32 we map the exclude (lowercase) characters to a &lt;code&gt;.&lt;/code&gt; so they can match anything, and we map uppercase characters &lt;em&gt;not&lt;/em&gt; followed by &lt;code&gt;=&lt;/code&gt; to &lt;code&gt;[^x]&lt;/code&gt; (where &lt;code&gt;x&lt;/code&gt; is the matched character) to allow any character &lt;em&gt;except&lt;/em&gt; that letter. Uppercase characters followed by &lt;code&gt;=&lt;/code&gt; are preserved (without the &lt;code&gt;=&lt;/code&gt;) to match only that character.&lt;/p&gt;
&lt;p&gt;The regular expression pattern on this line may look a little confusing.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;([a-z])(?!=)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[^\1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The second parenthetical group &lt;code&gt;(?!=)&lt;/code&gt; is a &lt;em&gt;negative lookahead assertion&lt;/em&gt; which means it will only match if a lowercase letter is found that is &lt;em&gt;not&lt;/em&gt; followed by an equal sign.&lt;/p&gt;
&lt;p&gt;So after these three substitutions, a pattern like &lt;code&gt;stA=rE&lt;/code&gt; is translated to the regular expression &lt;code&gt;..a.[^e]&lt;/code&gt; pattern.&lt;/p&gt;
&lt;p&gt;Next, we filter the possible words in succession. First we remove words with &lt;em&gt;any&lt;/em&gt; of the &lt;code&gt;exclude&lt;/code&gt; characters in them, then we keep only words containing &lt;em&gt;all&lt;/em&gt; of the &lt;code&gt;include&lt;/code&gt; characters, and finally, we refine the list once more with words matching the character position constraints in the regex &lt;code&gt;pattern&lt;/code&gt;, and by repeating this process for each guess pattern passed into the program, we get the final list of possible words.&lt;/p&gt;
&lt;p&gt;The last few lines of the script print the candidate words out in six columns using the &lt;code&gt;grouped&lt;/code&gt; iterator function which returns a fixed group of items on each iteration.&lt;/p&gt;
&lt;h2&gt;Suggesting a good guess&lt;/h2&gt;
&lt;p&gt;At the very end of the script, it will select one word out of the remaining words as a suggestion for the next attempt. This uses the &lt;code&gt;guess&lt;/code&gt; function near the end of the script. The function takes as input the remaining words and a set of all letters that must be included in the words. The &lt;code&gt;chars&lt;/code&gt; variable is assigned a set of all letters in all the remaining words after removing those that must be included. This will be the list of letters that have yet to be tried that are present in any of the remaining words.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;counts&lt;/code&gt; variable is the result of a list comprehension that contains tuples of the count of these untried characters paired with each word. We sort it to get the highest count at the end, and then we filter it by just those words that all have the highest count. We randomly choose one word from this list as a suggestion.&lt;/p&gt;
&lt;p&gt;The idea here is to choose a word that has the highest number of untried letters which should be a good choice for reducing the number of possible candidates. (Another approach could have been to rank the words by how commonly used they are or by the frequency of use of the untried letters, but this was a good first cut.)&lt;/p&gt;
&lt;h2&gt;Sample Use&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s an example run of the script using the puzzle on Friday, January 27th, 2023. My first guess was &amp;ldquo;stare&amp;rdquo; and the response was&lt;/p&gt;
&lt;p&gt;&lt;img src="https://noisysignal.com/images/wordle/stare.png" width="200"&gt;&lt;/p&gt;
&lt;p&gt;Running that results through the script returns 71 possible matches and suggests &amp;ldquo;fiord&amp;rdquo; which is &lt;em&gt;not&lt;/em&gt; a good choice as it&amp;rsquo;s not one of the more common words in the list. Better choices are &amp;ldquo;chord&amp;rdquo;, &amp;ldquo;glory&amp;rdquo;, &amp;ldquo;ivory&amp;rdquo;, and &amp;ldquo;whirl&amp;rdquo;, but that&amp;rsquo;s the problem with picking the word randomly.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;% python wordle.py staR=e
bidri blurb bourd bourg bourn burro
burry chirk chirm chiro chirp chirr
chord churl churm churn churr cirri
courb curry dowry durry fibry fiord
firry flory flurn flurr frory furry
glory gorry gourd gurry houri hurry
hydro indri inorb inurn ivory knurl
kodro kukri lorry lurry mbori micro
moorn moory mourn mucro myrrh ochro
piuri porry purry quirk quirl umiri
undry unorn unurn upcry updry vidry
whirl whorl worry yourn zorro
71 possible matches
guess for next word: fiord
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So I ignored the advice from my own program and chose &amp;ldquo;chord&amp;rdquo; for my second guess, resulting in&lt;/p&gt;
&lt;p&gt;&lt;img src="https://noisysignal.com/images/wordle/chord.png" width="200"&gt;&lt;/p&gt;
&lt;p&gt;Running the script again with both inputs reveals just 10 matches. Again, the suggested word &amp;ldquo;yourn&amp;rdquo; is a poor choice as it&amp;rsquo;s not a common word (I had to look it up, it means &lt;em&gt;a regional or archaic form of &amp;ldquo;yours&amp;rdquo;&lt;/em&gt;, so that should come in handy). Instead, I picked &amp;ldquo;worry&amp;rdquo; which was the actual answer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;% python wordle.py staR=e chOR=d
bourg bourn burro gorry lorry mourn
porry worry yourn zorro
10 possible matches
guess for next word: yourn
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Wrap Up&lt;/h2&gt;
&lt;p&gt;I don’t actually use this script when I play—I like the challenge of completing Wordle myself—but it’s an interesting problem and a nice programming exercise, and judging from the different approaches others have taken, there isn’t one obvious best way to solve it. I find those types of problems to be the most interesting ones to tackle.&lt;/p&gt;</content><category term="misc"></category><category term="python"></category></entry><entry><title>Plotting Time Series in Plotly</title><link href="https://noisysignal.com/plotting-time-series-in-plotly.html" rel="alternate"></link><published>2023-01-23T00:00:00-05:00</published><updated>2023-01-23T00:00:00-05:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2023-01-23:/plotting-time-series-in-plotly.html</id><summary type="html">&lt;p&gt;Handle day and time gaps in time-series data using Plotly&amp;rsquo;s rangebreaks option&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="A time series plot that correctly handles gaps for non-trading periods" src="https://noisysignal.com/images/rangebreaks/daily_price_data.png" /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://plotly.com/python/"&gt;Plotly&lt;/a&gt; graphics library is a rich, fully-featured toolkit with support for many types of charts and data visualizations. I use it regularly for creating plots of time-series data such as stock prices, and have usually found that regardless of whatever special feature or customization I’m looking for, Plotly has a way to support it. However, sometimes it can be difficult to figure out &lt;em&gt;how&lt;/em&gt; to accomplish what I&amp;rsquo;m trying to do because of the large set of options in the library. Even with its excellent documentation, I sometimes am not sure what the feature I’m looking for is called so it can be difficult to find the right option or technique when you don&amp;rsquo;t know what to search for.&lt;/p&gt;
&lt;h2&gt;Day Gaps&lt;/h2&gt;
&lt;p&gt;One example that comes up frequently with time-series data is excluding natural time gaps inherent in the data. For example, stock prices are only available on valid trading days (non-holiday weekdays) and during times when the exchange is open (usually 9:30 am to 4:00 pm). Without making adjustments, a plot of the data can give the wrong impression that the price did not vary across these periods. For example, look at the price between May 28th and June 1st below.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Plotting data with lines can hide natural gaps in the time series" src="https://noisysignal.com/images/rangebreaks/daily_price_data_-_zoomed_in.png" /&gt;&lt;/p&gt;
&lt;p&gt;One might conclude that the price gradually declined over those four days. Showing the same data again, but this time with markers instead of lines reveals dates with no data. In this case, May 29th and 30th were a weekend and May 31st was an exchange holiday. Gaps are also made clear for the weekends of June 5-6, and June 12-13.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Plotting the same data as markers, along with gridlines aligned to each day, makes the gaps obvious" src="https://noisysignal.com/images/rangebreaks/daily_price_data_-_points_showing_gaps.png" /&gt;&lt;/p&gt;
&lt;p&gt;To address this, Plotly offers the &lt;a href="https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-rangebreaks"&gt;&lt;code&gt;rangebreaks&lt;/code&gt;&lt;/a&gt; option for the &lt;em&gt;x&lt;/em&gt;- and &lt;em&gt;y&lt;/em&gt;-axes, but the option can be a little confusing to use. You pass it a list of &lt;code&gt;dict&lt;/code&gt;s that define ranges or individual points to exclude from the axis.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_xaxes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;rangebreaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sat&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;mon&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2021-05-31&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# Memorial Day&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;Here we are saying that all weekends and one specific date should be hidden from view. But the &lt;code&gt;bounds&lt;/code&gt; form is a little confusing as it is left-&lt;em&gt;inclusive&lt;/em&gt; but right&lt;em&gt;-exclusive,&lt;/em&gt; so the range &lt;code&gt;["sat", "mon"]&lt;/code&gt; says that Saturday and Sunday—but &lt;em&gt;not&lt;/em&gt; Monday—should be excluded.&lt;/p&gt;
&lt;p&gt;Here is a plot with the &lt;code&gt;rangebreaks&lt;/code&gt; applied and you can see those dates have now been removed. The plot is now more representative of how the price evolved each day where trading occurred.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The dates and ranges specified in rangebreaks are now removed from the chart" src="https://noisysignal.com/images/rangebreaks/daily_price_data_-_points_no_gaps.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Intraday Gaps&lt;/h2&gt;
&lt;p&gt;Natural gaps also occur in data with a higher resolution than daily observations. Here we are showing prices covering one-minute &amp;ldquo;bars&amp;rdquo; over a 12-day period. Note that relatively small intervals where there is any sort of price action compared to the larger, linear sections of the chart. The active ranges occur during the hours where the stock market was open (9:30am to 4:00pm EST). That&amp;rsquo;s only 6.5 hours out of a 24-day interval so you can see that the majority of the time periods are really just gaps with no data samples.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Intraday data only covers a small portion of the day" src="https://noisysignal.com/images/rangebreaks/minute_price_data.png" /&gt;&lt;/p&gt;
&lt;p&gt;Once again, this is clear when we use markers rather than lines to plot the data. Below you can see the overnight gaps (between 4pm and 9:30am on T+1) and also the large weekend gap between 4pm on December 9th through 9:30am on December 12th.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Using markers reveals how little of the period contains samples" src="https://noisysignal.com/images/rangebreaks/minute_price_data_-_points.png" /&gt;&lt;/p&gt;
&lt;p&gt;We can use the same technique to remove the overnight gaps but this time we use numbers for the hour range we want to skip and add the &lt;code&gt;pattern&lt;/code&gt; option to specify how the &lt;code&gt;bounds&lt;/code&gt; values should be interpreted.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_xaxes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;rangebreaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;9.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;hour&amp;quot;&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;This removes the overnight gaps, yielding a plot that&amp;rsquo;s much more understandable to the viewer.  However, we still have the weekend gap spanning December 10th-11th.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Overnight gaps are hidden but the weekend gap is still present" src="https://noisysignal.com/images/rangebreaks/minute_price_data_-_no_overnight_time_gaps.png" /&gt;&lt;/p&gt;
&lt;p&gt;That can be fixed by combining the method we used for hiding weekend days with the form for removing intraday gaps.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_xaxes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;rangebreaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sat&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;mon&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;9.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;hour&amp;quot;&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;The final result produces a chart that shows how the price evolved minute-by-minute over a multi-day period without the visual clutter of large gaps where no prices occurred.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Hiding all gaps greatly improves the chart" src="https://noisysignal.com/images/rangebreaks/minute_price_data_-_no_overnight_or_weekend_gaps.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;A notebook and sample datasets for these examples are available &lt;a href="https://gist.github.com/davraamides/2b8f82aa8e95fd19a6610386d9b7bca7"&gt;here&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"></category><category term="python"></category></entry><entry><title>Things Daily Schedule Shortcut</title><link href="https://noisysignal.com/things-daily-schedule-shortcut.html" rel="alternate"></link><published>2022-10-08T00:00:00-04:00</published><updated>2022-10-08T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2022-10-08:/things-daily-schedule-shortcut.html</id><summary type="html">&lt;p&gt;Create a Task Schedule for Things&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="A daily plan of tasks in Things" src="https://noisysignal.com/images/things_schedule/things_schedule.png" /&gt;&lt;/p&gt;
&lt;p&gt;I’ve played around with &lt;em&gt;lots&lt;/em&gt; of different task management solutions over the years. Too many, to be honest. I&amp;rsquo;ve even &lt;a href="https://marketplace.visualstudio.com/items?itemName=davraamides.todotxt-mode"&gt;written my own todo utility&lt;/a&gt;. But while it&amp;rsquo;s fun to try out a new tool and a potentially new way of thinking about managing tasks, in the end, the important part is &lt;em&gt;doing&lt;/em&gt; the tasks, not managing them.&lt;/p&gt;
&lt;p&gt;So after reflecting on all the tools I had tried in the past, I went back to an old friend that I had first used over 10 years ago: &lt;a href="https://culturedcode.com/things/"&gt;Things&lt;/a&gt;. Things is an intuitive, powerful, and polished app with many features, but most importantly, it has the features that meet my needs nicely and has a great user interface which is a pleasure to use.&lt;/p&gt;
&lt;p&gt;However, there was one other app that I really &lt;em&gt;wanted&lt;/em&gt; to like but it just fell short in a few areas so I gave up on it. That app was &lt;a href="https://www.sortedapp.com"&gt;Sorted&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; (extra points for having a superscript in your app name). As a pure task management solution, it wasn&amp;rsquo;t quite as nice as Things, but it had a different perspective on task management that I found compelling. Sorted&lt;sup&gt;3&lt;/sup&gt; is built around a concept it calls &lt;em&gt;hyper-scheduling&lt;/em&gt; or otherwise referred to as &lt;em&gt;time-blocking&lt;/em&gt;. This is the idea of scheduling out all your activities throughout the day, like a daily plan on a calendar. Sorted&lt;sup&gt;3&lt;/sup&gt; took this idea one step further with its “Auto Schedule” feature, which schedules out your day in time blocks integrating your calendar appointments and the task items that you had planned for the day. It presents you with a detailed schedule for all your day’s activities that is &lt;em&gt;realistic&lt;/em&gt; since it takes into account the time you have free and the estimated time to complete each task (you have to assign time estimates to tasks for this to work, more on that later).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Sorted&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;'s Schedule view" src="https://noisysignal.com/images/things_schedule/sorted3_mac.png" /&gt;&lt;/p&gt;
&lt;p&gt;Sorted&lt;sup&gt;3&lt;/sup&gt; and its Auto Schedule feature addressed one problem I had always grappled with: signing up for more tasks in a day than I could actually get done. That’s easy to do when you just have a list of tasks staring you in the face. But when you lay them out on a timeline that includes other commitments, you immediately see whether you have enough time to finish the things you need to. If you’ve over-scheduled yourself, you can review your items and potentially defer some to the next day and refresh the schedule to get an updated plan for the day.&lt;/p&gt;
&lt;p&gt;This approach to scheduling tasks was very appealing to me when I was working in a corporate environment and had a very busy calendar. It helped me prioritize my important tasks and find slivers of time throughout the day to get the right things done.&lt;/p&gt;
&lt;h2&gt;Things Schedule&lt;/h2&gt;
&lt;p&gt;I no longer work in an environment that is calendar-driven so I thought I wouldn’t miss the scheduling feature when I switched back to Things. But recently, I’ve been running into the same problem where I have more tasks on my list than I can get done in a day so I wanted to figure out a “sanity check” for my Things Today list that I could use to plan and review my work each day.&lt;/p&gt;
&lt;p&gt;One stumbling block is that Things doesn’t have the notion of a time estimate for completing a task. Instead, I needed to create a convention that I could use for that purpose. Thing does support arbitrary tags for tasks, though, and it turned out that could work quite well.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Tags in Things for estimated times are easily applied with a keyboard shortcut" src="https://noisysignal.com/images/things_schedule/things_tags.png" /&gt;&lt;/p&gt;
&lt;p&gt;I use tags such as “5m”, “15m” and “60m” to estimate a task&amp;rsquo;s time and then assign convenient shortcuts to each tag so, for example, I can just press &lt;code&gt;Ctrl-4&lt;/code&gt; to set a task&amp;rsquo;s estimated time to 45 minutes.&lt;/p&gt;
&lt;p&gt;Now that I had a way to add time estimates to my tasks, I needed to retrieve the tasks and process them, creating the daily schedule. When Things 3 launched back in 2017, they introduced comprehensive AppleScript support to the app, and using AppleScript, it’s fairly straightforward to get a list of tasks out of Things. Here’s the code I use in my shortcut.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="nb"&gt;run&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;todoList&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="no"&gt;text item delimiters&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nb"&gt;application&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Things3&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;theTodos&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;dos&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Today&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;repeat&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;aToDo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;theTodos&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;theTitle&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;aToDo&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;tagNames&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="na"&gt;tag&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;aToDo&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;theTask&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;title:&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;theTitle&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; tags:&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;tagNames&lt;/span&gt;
            &lt;span class="nb"&gt;copy&lt;/span&gt; &lt;span class="nv"&gt;theTask&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;the&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;todoList&lt;/span&gt;
            &lt;span class="c"&gt;-- display dialog theTask&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;repeat&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;tasks&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;todoList&lt;/span&gt; &lt;span class="k"&gt;as &lt;/span&gt;&lt;span class="nc"&gt;text&lt;/span&gt;
    &lt;span class="no"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;tasks&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="nb"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It runs through the tasks in the “Today” list and creates a text representation of the task in this format&lt;/p&gt;
&lt;p&gt;&lt;code&gt;title:Pick up milk on the way home tags:15m&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and returns all of the tasks as one text block with one task per line.&lt;/p&gt;
&lt;p&gt;The real work is done in a Python script which receives this block of text, parses it into tasks with their time and creates a schedule in HTML and opens it in a browser. A link to the complete script is included at the end of this post, but I’ll just describe the interesting parts below. The &lt;code&gt;parse_things_tasks()&lt;/code&gt; routine below reads the tasks passed to it from the AppleScript action and parses them into two lists: one of &lt;code&gt;timed_tasks&lt;/code&gt; (tuples of a duration and the task title) and one of &lt;code&gt;untimed_tasks&lt;/code&gt; (that have no time estimate tag on them).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_things_tasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TD&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
    &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;untimed_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&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;task&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^title:(.*) tags:(.*)$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;est_mins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_estimated_minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;est_mins&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;est_mins&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;est_mins&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;NO_TIME_ESTIMATE&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;default_duration&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;default_duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;untimed_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;unmatched: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&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;timed_tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;untimed_tasks&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_estimated_minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&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;tag&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\d+m&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;NO_TIME_ESTIMATE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The function reads from &lt;code&gt;sys.stdin&lt;/code&gt; so you need to set &amp;ldquo;Pass Input&amp;rdquo; to &amp;ldquo;to stdin&amp;rdquo; in the “Run Shell Script&amp;rdquo; action in Shortcuts. It then looks for lines matching the format described above (which should be every line) and extracts the title and duration. The function &lt;code&gt;parse_estimated_minutes()&lt;/code&gt; looks for the first tag matching a number followed by &lt;code&gt;m&lt;/code&gt; and returns that value or a special &lt;code&gt;NO_TIME_ESTIMATE&lt;/code&gt; value if none is found, in which case the tasks is considered an untimed task and won’t be included in the scheduled portion of the report.&lt;/p&gt;
&lt;p&gt;The other interesting part of the script is the &lt;code&gt;build_schedule()&lt;/code&gt; function which takes the &lt;code&gt;untimed_tasks&lt;/code&gt; returned from above and builds a daily schedule from it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;midnight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="n"&gt;schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;sdt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;midnight&lt;/span&gt;
            &lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timed_tasks&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="c1"&gt;# add the task if it will fit in before the next event&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dur&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;sdt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;task&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;timed_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&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="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;dur&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="c1"&gt;# didn&amp;#39;t add either, tick forward by 5 minutes&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&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;schedule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since I’m not including calendar events, this logic is pretty simple. I just need to run through the list of timed tasks assigning a start time to each one and then stepping forward in time by the duration of the task. The one case to consider is if there is enough time left in the day (before midnight) to fit the task. When either all the tasks are scheduled, or we spill over to the next day, we are done scheduling the tasks.&lt;/p&gt;
&lt;h2&gt;The Final Shortcut&lt;/h2&gt;
&lt;p&gt;The final shortcut is really simple utilizing just two actions to do all the work. This shortcut doesn’t benefit much from being in the Shortcuts app but it’s nice to be able to say “Hey Siri, Things Schedule” and see the page pop up. And by using Shortcuts, it would be easy to extend it, say, by running each morning and emailing the report to me.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The final shortcut uses just two actions to combine the scripts" src="https://noisysignal.com/images/things_schedule/things_shortcut.png" /&gt;&lt;/p&gt;
&lt;p&gt;The complete AppleScript and Python source code are &lt;a href="https://gist.github.com/davraamides/487e6d7cabf5f53419a9c337a03f8b37"&gt;available here&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"></category><category term="shortcuts"></category></entry><entry><title>A Shortcut That Reminds You to Charge Your Watch</title><link href="https://noisysignal.com/a-shortcut-that-reminds-you-to-charge-your-watch.html" rel="alternate"></link><published>2022-10-05T00:00:00-04:00</published><updated>2022-10-05T00:00:00-04:00</updated><author><name>David Avraamides</name></author><id>tag:noisysignal.com,2022-10-05:/a-shortcut-that-reminds-you-to-charge-your-watch.html</id><summary type="html">&lt;p&gt;Make sure your watch is charged up before you go to sleep each night.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Notifications" src="https://noisysignal.com/images/watch_shortcut/watch_notifications.png" /&gt;&lt;/p&gt;
&lt;p&gt;Recently I&amp;rsquo;ve been trying to be more consistent about wearing my Apple Watch to bed each night so I can track my sleep over time. The one challenge has been remembering to charge my watch during the day such that it has a good enough charge to get me through the night &lt;em&gt;and&lt;/em&gt; to get me through my morning dog walk.&lt;/p&gt;
&lt;p&gt;Previously, I had not spent much time playing around with Shortcuts on the Mac, but this little problem provided just the motivation I needed to dig into the app a bit more and see if I could create a useful shortcut to remind me to charge my watch.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;/h2&gt;
&lt;p&gt;For my solution, I didn&amp;rsquo;t simply want a calendar reminder or a recurring task in Things each day as I felt that it would be hard to schedule the reminder for an opportune time and thus, too easy to ignore. Instead, I wanted the shortcut to consider the relevant &lt;em&gt;context,&lt;/em&gt; specifically the current battery level on my watch and if I was currently using one of my desktop Macs (where I have watch chargers conveniently available).&lt;/p&gt;
&lt;p&gt;With that background, I came up with this problem statement:&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;When I&amp;rsquo;m using either my home iMac or work Mac Studio, if my watch&amp;rsquo;s battery level is below 60% (and it&amp;rsquo;s not currently charging), remind me to charge my watch. Additionally, if the watch is charging and has reached a full battery level, remind me to put it back on.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There’s no need to remind me to charge my watch if it has a nearly full charge or if it’s already connected to a charging cable. And I don’t want to forget about it and leave it connected to the charger all day, so it should let me know when it’s done so I can put it back on.&lt;/p&gt;
&lt;p&gt;To create such a Shortcut, I needed to figure out solutions to three problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How do I know when I&amp;rsquo;m using one of my two Mac computers (so I can be reminded when I’m near a charging cable)?&lt;/li&gt;
&lt;li&gt;How do I get the watch&amp;rsquo;s current battery level?&lt;/li&gt;
&lt;li&gt;How do I know if the watch is currently charging?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the first problem, I really just need to know if I&amp;rsquo;m logged into either of the computers. But that isn&amp;rsquo;t an “event” I could use to trigger a shortcut.&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; However, I do unlock the Mac regularly throughout the day (I have my Mac set to lock the screen after 15 minutes). So the act of unlocking my Mac would provide a suitable trigger to run the shortcut. Unfortunately, the Shortcuts app on macOS today only supports running shortcuts via a user action such as a keyboard shortcut, the Menu Bar, the Services menu, or a Finder Quick Action. Fortunately, &lt;a href="https://www.keyboardmaestro.com/main/"&gt;Keyboard Maestro&lt;/a&gt; supports many kinds of triggering events, including &amp;ldquo;when the Mac is unlocked&amp;rdquo;, and Keyboard Maestro also supports running a shortcut through its “Execute Shortcut” action.&lt;/p&gt;
&lt;p&gt;The second two problems are closely related, but again, Shortcuts does not include actions that can help here. But the excellent &lt;a href="https://v2.airbuddy.app"&gt;AirBuddy 2&lt;/a&gt; added a &lt;a href="https://support.airbuddy.app/articles/how-to-use-the-shortcuts-actions-provided-by-airbuddy/"&gt;number of great Shortcut actions&lt;/a&gt; in a recent update and solves both of these problems nicely. It provides a few sample shortcuts, one of which–“Check AirPods Battery”–is very close to what we need here.&lt;/p&gt;
&lt;h2&gt;The Shortcut&lt;/h2&gt;
&lt;p&gt;&lt;img alt="The complete watch charging reminder shortcut, along with AirBuddy's actions" src="https://noisysignal.com/images/watch_shortcut/watch_shortcut.png" /&gt;&lt;/p&gt;
&lt;p&gt;The shortcut is pretty simple and is a pretty direct translation of the problem statement. It leverages two AirBuddy actions: &lt;code&gt;Get Device State&lt;/code&gt; and &lt;code&gt;Get Device Battery Information&lt;/code&gt; to get the watch&amp;rsquo;s current battery state. The &lt;code&gt;If&lt;/code&gt; statements just check the current &lt;code&gt;Charging State&lt;/code&gt; and &lt;code&gt;Level&lt;/code&gt; of the battery to decide if a notification should be displayed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Using Keyboard Maestro to trigger the shortcut when the screen unlocks" src="https://noisysignal.com/images/watch_shortcut/watch_trigger.png" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, Keyboard Maestro uses the “When the Mac is unlocked” trigger to run the shortcut.&lt;/p&gt;
&lt;h2&gt;Shortcut Misses&lt;/h2&gt;
&lt;p&gt;While this was a good experience to learn the Shortcuts tool through a simple example, it also demonstrates some of the real limitations of Shortcuts today. First, to provide a useful automation–especially one that reminds me of something I tend to forget–I don&amp;rsquo;t want to have to remember to &lt;em&gt;run the shortcut&lt;/em&gt; throughout the day. But Shortcuts is limited in how a shortcut can be triggered (at least on the Mac). I had to use a third-party app to solve this. Additionally, while there are some applications and services with good Shortcuts support, the coverage is spotty and inconsistent. It seems to me that getting the current battery charge level of my Apple Watch on my Apple Mac using Apple&amp;rsquo;s Shortcuts app should be easy to do. Again, I had to solve this with a third-party app.&lt;/p&gt;
&lt;p&gt;That does say something positive about the state of the Mac software ecosystem, however. There are lots of great apps out there to help bridge the gap between the promise of a tool like Shortcuts and its actual out-of-the-box capabilities.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Whether or not I&amp;rsquo;m logged into the computer is a &lt;em&gt;state&lt;/em&gt; and for triggering a shortcut we want a &lt;em&gt;state change&lt;/em&gt;. While I could have a shortcut run repeatedly and check if I&amp;rsquo;m currently logged in, my preference was to avoid a polling solution.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"></category><category term="shortcuts"></category></entry></feed>