<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carmen Huidobro</title>
    <description>The latest articles on DEV Community by Carmen Huidobro (@hola_soy_milk).</description>
    <link>https://dev.to/hola_soy_milk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F285599%2Fe995acfc-25c9-432b-a753-f6d58771cfaa.jpg</url>
      <title>DEV Community: Carmen Huidobro</title>
      <link>https://dev.to/hola_soy_milk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hola_soy_milk"/>
    <language>en</language>
    <item>
      <title>How Objective-C Made Me a Versatile Software Engineer</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Thu, 20 Apr 2023 06:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/how-objective-c-made-me-a-versatile-software-engineer-4jma</link>
      <guid>https://dev.to/hola_soy_milk/how-objective-c-made-me-a-versatile-software-engineer-4jma</guid>
      <description>&lt;p&gt;&lt;em&gt;Special thanks to the incomparable &lt;a href="https://twitter.com/SylwiaVargas" rel="noopener noreferrer"&gt;Sylwia&lt;br&gt;
Vargas&lt;/a&gt; for helping me structure and focus this post better, as well as to &lt;a href="https://chaos.social/@uliwitness" rel="noopener noreferrer"&gt;Uli&lt;/a&gt; for making kind corrections.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Late last week, I posted on social media about going back to an old macOS Objective-C codebase I’ve worked on for over a decade, prompting the question “what is Objective-C used for”?&lt;/p&gt;

&lt;p&gt;After nerding out in a thread about it, I realised there was so much to Objective-C, the time it’s from, and why I’m so grateful I learned it early in my career. That’s where this post comes in.&lt;/p&gt;

&lt;p&gt;But to be clear, the purpose of this post is not to advocate for learning Objective-C, but to appreciate the lessons I learned from it towards becoming a more versatile engineer. I don’t write much Objective-C anymore, but it has a special place in my heart.&lt;/p&gt;
&lt;h2&gt;
  
  
  Some context on me and Objective-C
&lt;/h2&gt;

&lt;p&gt;My first paid work as a software engineering freelancer was in fixing bugs for existing macOS apps. This was back in 2009: the operating system was called Mac OS X (I’ll be calling it macOS in this post to keep things consistent), its apps were written in Objective-C, and Xcode, Apple’s software development, was in version 3. Today? We have macOS with apps written in Swift, and Xcode is in version 14.&lt;/p&gt;

&lt;p&gt;It’s a language that, as the name might imply, is an object-oriented extension of C. It has changed significantly over the years as the Apple development environment and language standards have evolved.&lt;/p&gt;

&lt;p&gt;While I would recommend choosing Swift for modern native Apple development, looking at my time with Objective-C in hindsight helped me appreciate the Computer Science fundamentals I learned from it that I find cropping up later in my career. This post covers some of them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Different syntax offers different perspectives
&lt;/h2&gt;

&lt;p&gt;Remember when you first learned to code, and how things didn’t fully click at first? For example, to many new developers concepts like dot notation (for example: &lt;code&gt;user.email&lt;/code&gt; or &lt;code&gt;button.setLabel("Reset")&lt;/code&gt;) take a moment to settle in. Oftentimes, it doesn’t feel intuitive that dot notation is used for calling functions or retrieving data. This is something I’ve run into often when introducing folks to programming concepts.&lt;/p&gt;

&lt;p&gt;Turns out that while Objective-C uses dot notation for C-like getters and&lt;br&gt;
setters, most complex method calls will require square-bracket notation.&lt;/p&gt;

&lt;p&gt;Let’s illustrate this with the following example. When coding a macOS app in Swift, if we wanted to get the title of the &lt;a href="https://developer.apple.com/documentation/appkit/nswindow?language=objc" rel="noopener noreferrer"&gt;app’s main window&lt;/a&gt;, we’d call the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NSWindow.mainWindow.title

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

&lt;/div&gt;



&lt;p&gt;In Objective-C, each message sent (that is, function called or data retrieved) has to be done with square brackets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[NSWindow mainWindow] title];

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

&lt;/div&gt;



&lt;p&gt;Let’s look at a breakdown of each pair of square brackets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;[NSWindow mainWindow]&lt;/code&gt; sends the message mainWindow to the NSWindow class, which returns the application's main window as an object.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[[NSWindow mainWindow] title]&lt;/code&gt; sends the message title to the main window object, which returns the window's title in the form of a string.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What about when we want to call a method that takes a parameter? Let’s look at the following example that sets the label of a button in a window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[preferencesWindow resetButton] setLabel: @"Reset"];

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So here's a fun fact&lt;/strong&gt;: Objective-C is based on a programming language called &lt;a href="https://learnxinyminutes.com/docs/smalltalk/" rel="noopener noreferrer"&gt;Smalltalk&lt;/a&gt;, which is particularly significant for laying the foundations for how we write object-oriented code today. Languages like Python, Ruby, Dart, Go, Java, Scala, and more have all been influenced by Smalltalk! Which yes, includes Objective-C.&lt;/p&gt;

&lt;p&gt;While not common, square bracket syntax has a few advantages, such as being able to have a clearer separation of object and message when the dot notation is replaced with a whitespace. Furthermore, dot notation in Objective-C &lt;a href="https://bignerdranch.com/blog/dot-notation-syntax/" rel="noopener noreferrer"&gt;adds a layer of ambiguity&lt;/a&gt; in not being 100% clear whether a method is being called or a property is being accessed, whereas bracket notation always makes it clear that we're sending a message.&lt;/p&gt;

&lt;p&gt;Having this versatility for changing languages and embracing new syntaxes has helped me grasp concepts like &lt;a href="https://thinkingelixir.com/course/code-flow/module-1/pipe-operator/" rel="noopener noreferrer"&gt;Elixir’s pipe operator&lt;/a&gt; smoothly!&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointers on Objective-C Pointers
&lt;/h2&gt;

&lt;p&gt;In Objective-C, a variable is a named memory location that can hold a value of a particular type, just like in other programming languages. A pointer, on the other hand, is a variable that stores the memory address of another variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hold on, a memory what?
&lt;/h3&gt;

&lt;p&gt;A memory address can be thought of as a bookshelf location in a library. Just like a book has a specific location on a shelf, a piece of data in a computer’s memory has a specific address, or location. The memory address serves as a unique identifier that can be used to locate and retrieve the data stored in memory. They’re usually represented in the hexadecimal format, such as &lt;code&gt;0x7fff5fbff8f8&lt;/code&gt;. Just as a librarian needs to know the bookshelf location of a book in order to retrieve it, a program needs to know the memory address of data in order to access it.&lt;/p&gt;

&lt;p&gt;Let’s have a look at how pointers are declared and used in Objective-C:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Declare a variable 'myBook' and assign it a value of 42
int myBook = 42;

// Declare a pointer 'myBookmark' and assign it the memory address of 'myBook'
int *myBookmark = &amp;amp;myBook;

// Print the value of 'myBook'
NSLog(@"The value of myBook is %d", myBook);

// Print the memory address of 'myBook'
NSLog(@"The memory address of myBook is %p", &amp;amp;myBook);

// Print the value stored at the memory address pointed to by 'myBookmark'
NSLog(@"The value stored at the memory address pointed to by myBookmark is %d", *myBookmark);

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

&lt;/div&gt;



&lt;p&gt;In Objective-C, &lt;code&gt;NSLog&lt;/code&gt; prints to the console, and is the equivalent of &lt;code&gt;puts&lt;/code&gt; in Ruby.&lt;/p&gt;

&lt;p&gt;The output would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The value of myBook is 42
The memory address of myBook is 0x7ffee2d01a6c
The value stored at the memory address pointed to by myBookmark is 42

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Use Pointers?
&lt;/h3&gt;

&lt;p&gt;We use pointers in programming languages like Objective-C for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient memory usage: Pointers allow us to pass data by reference, rather than by value. This means we can avoid copying large amounts of data when passing it between functions, leading to more efficient memory usage.&lt;/li&gt;
&lt;li&gt;Data structures: Many data structures in Objective-C, such as linked lists and trees, rely on pointers to store and manipulate data.&lt;/li&gt;
&lt;li&gt;Dynamic memory allocation: More on that shortly 👀&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And guess what, although a lot of higher-level languages don’t use them, modern ones certainly do, like Rust or Golang. I’ve found this to be helpful when understanding how &lt;a href="https://wasmbyexample.dev/examples/webassembly-linear-memory/webassembly-linear-memory.rust.en-us.html" rel="noopener noreferrer"&gt;WebAssembly’s Linear Memory&lt;/a&gt; works, for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mastering Manual Memory Management
&lt;/h2&gt;

&lt;p&gt;Nowadays, most programming languages have a built-in automatic &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management#garbage_collection" rel="noopener noreferrer"&gt;garbage collection mechanism&lt;/a&gt;. Garbage collection is a way for a computer program to automatically clean up the memory that is no longer being used by the program. It helps to free up space in the computer’s memory so that it can be used for other things.&lt;/p&gt;

&lt;p&gt;Objective-C did later on add their own mechanism for garbage collection, but not when I started.&lt;/p&gt;

&lt;p&gt;This means that as a programmer, I am responsible for allocating memory for data structures or objects, and then releasing that memory when it is no longer needed. In programming languages like C, you would need to specify the number of bytes you needed to create a variable containing a &lt;code&gt;string&lt;/code&gt;. In Objective-C, this was done dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NSString *myString = [[NSString alloc] init];

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

&lt;/div&gt;



&lt;p&gt;This code declares a pointer variable named “myString” that points to an instance of the NSString class in Objective-C.&lt;/p&gt;

&lt;p&gt;The statement &lt;code&gt;[[NSString alloc] init]&lt;/code&gt; creates a new instance of the NSString class using dynamic memory allocation, and initializes it with a default value. The pointer to this new object is returned by the alloc and init methods.&lt;/p&gt;

&lt;p&gt;With that said and done, we can go ahead and use this in a method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)myMethod {
    NSString *myString = [[NSString alloc] init];
    // Do something with myString
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here's the thing&lt;/strong&gt;: The memory has been allocated, but it will then need to be released.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need to release memory?
&lt;/h3&gt;

&lt;p&gt;Computers have a limited amount of memory. If you do not release the memory allocated for the object, it will not be freed and won’t be able to hold any other data. Sure, this isn’t a huge deal for, say, one string, but what if we’re failing to release dozens, hundreds or thousands of strings?&lt;/p&gt;

&lt;p&gt;This can result in a memory leak, which can lead to a shortage of memory, which in turn can cause the program to slow down or crash. In extreme cases, the entire system may become unstable, and other programs may also be affected.&lt;/p&gt;

&lt;p&gt;We can release the memory manually, with the &lt;code&gt;release&lt;/code&gt; message, available to all objects in Objective-C.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)myMethod {
    NSString *myString = [[NSString alloc] init];
    // Do something with myString
    [myString release];
}

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

&lt;/div&gt;



&lt;p&gt;This indicates that we’re done with &lt;code&gt;myString&lt;/code&gt; and can release the memory allocated to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cool, but I work with a garbage collected programming language. Is there a reason this is good to know?
&lt;/h3&gt;

&lt;p&gt;I’ll do you one better — here’s four reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Debugging: While garbage collection automatically manages memory for you, there may still be cases where the program is not functioning as expected due to memory problems. Understanding manual memory management can help you diagnose and fix these issues.&lt;/li&gt;
&lt;li&gt;Performance optimization: Garbage collection can be resource-intensive, and there may be situations where manual memory management can provide a performance boost. Understanding manual memory management can help you identify these situations and write code that is more efficient.&lt;/li&gt;
&lt;li&gt;Portability: Not all programming languages use garbage collection, and not all environments support ones that do. For example, when trying writing code for microcontrollers, I had to use a low-level C language and had to carefully, manually manage memory.&lt;/li&gt;
&lt;li&gt;Code optimization: Even in languages with Garbage Collection, understanding manual memory management can help you write code that runs quicker. For example, you can use techniques like &lt;a href="https://en.wikipedia.org/wiki/Object_pool_pattern" rel="noopener noreferrer"&gt;object pooling&lt;/a&gt; to reuse memory instead of allocating and deallocating memory frequently. &lt;strong&gt;Fun fact&lt;/strong&gt;: this is how long lists can be rendered in mobile apps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The advantage of manual memory management is that it provides a high degree of control over how memory is used in a program. However, it also requires careful attention to detail.&lt;/p&gt;

&lt;p&gt;But, you may be wondering, what happens when you want to use that allocated memory elsewhere, say in…&lt;/p&gt;

&lt;h2&gt;
  
  
  Low-level concurrent programming
&lt;/h2&gt;

&lt;p&gt;In short, learning Objective-C helped me understand concurrent programming, which is the practice of allowing multiple tasks or processes to execute simultaneously.&lt;/p&gt;

&lt;p&gt;This is something we do very often in our daily coding lives. For example, in JavaScript, we use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;promises&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" rel="noopener noreferrer"&gt;async functions&lt;/a&gt; for HTTP requests or to update a database.&lt;/p&gt;

&lt;p&gt;When coding macOS apps, we can call upon a background thread to perform asynchronous tasks. Let’s say we have an object for an &lt;code&gt;ApiWrapper&lt;/code&gt; with a method called &lt;code&gt;postData(jsonData)&lt;/code&gt; that makes a &lt;code&gt;POST&lt;/code&gt; request. We can call upon it in a background thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[apiWrapper performSelectorInBackground:@selector(postData:) withObject:jsonData];

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

&lt;/div&gt;



&lt;p&gt;How about if we wanted to update the UI of our app in that &lt;code&gt;postData&lt;/code&gt; method?&lt;/p&gt;

&lt;p&gt;Here's the thing: &lt;a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/AboutThreads/AboutThreads.html#//apple_ref/doc/uid/10000057i-CH6-SW21" rel="noopener noreferrer"&gt;macOS requires you to only update the UI on the main thread&lt;/a&gt;. So what do we do in &lt;code&gt;postData()&lt;/code&gt;? Fortunately, we have a solution for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)postData:(NSData *)jsonData {
    // Perform HTTP request

    [self performSelectorOnMainThread:@selector(updateUI:) withObject:[response parsedJsonData] waitUntilDone:NO];
}

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

&lt;/div&gt;



&lt;p&gt;This way, we get direct access to the main thread.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s all fun and games until a race condition arises
&lt;/h3&gt;

&lt;p&gt;When coding multi-threaded applications, we need to make sure that accessing shared resources is done so safely. Let’s check out an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)updateSharedValue {
    // This method runs on a background thread
    self.sharedValue += 1;
}

- (void)startBackgroundTask {
    [self performSelectorInBackground:@selector(updateSharedValue) withObject:nil];
}

// Start two background tasks that update the shared value
[self startBackgroundTask];
[self startBackgroundTask];

// Wait for the tasks to complete
[NSThread sleepForTimeInterval:1.0];

// At this point, the shared value should be 2, right?
NSLog(@"Shared value: %ld", self.sharedValue); // Output: Shared value: 1

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

&lt;/div&gt;



&lt;p&gt;What happened? Both background tasks are updating the same shared variable concurrently. Depending on the timing and scheduling of the threads, one task might overwrite the value updated by the other task, leading to incorrect or inconsistent results. This is known as a race condition. A race condition is a type of software bug where two or more threads or processes access a shared resource concurrently. In such a case, the final result depends on the order of execution, which can be unpredictable.&lt;/p&gt;

&lt;p&gt;It’s like a game of musical chairs where the number of chairs is less than the number of players. When the music stops, everyone rushes to grab a chair, but some players are left standing without a seat. The outcome is unpredictable and depends on the timing of the players’ actions. While this is fun for humans, you wouldn’t want your serious app to behave this way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutexes to the rescue
&lt;/h3&gt;

&lt;p&gt;Luckily, we have the ability to use a mutex to control shared resources in Objective-C. A mutex is a tool for ensuring that only one thread can access a shared resource (like a variable or a piece of memory) at a time. It works by allowing a thread to “lock” the resource while it’s using it, which prevents other threads from accessing it until the first thread “unlocks” it.&lt;/p&gt;

&lt;p&gt;In Objective-C, this is done by invoking the &lt;code&gt;@synchronized&lt;/code&gt; directive. Let’s see it in action by using it in the previous multithreaded example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)updateSharedValue {
    // This code can only run if nothing else is synchronized on the sharedValue property
    @synchronized(self.sharedValue) {
        self.sharedValue += 1;
    }
}

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

&lt;/div&gt;



&lt;p&gt;With the above change, only one thread can execute this block of code at a time if they are synchronized on the same object. This ensures that modifications to the shared value are made in a thread-safe way. No more musical chairs, all threads know how to queue to access the value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this relevant in modern-day language use?
&lt;/h3&gt;

&lt;p&gt;Absolutely! Modern languages have found ways to ensure developers comply with thread safety. For example, the Rust programming language has the &lt;a href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html" rel="noopener noreferrer"&gt;ownership model built-in as a feature&lt;/a&gt;with concurrent coding and memory safety in mind.&lt;/p&gt;

&lt;p&gt;Overall, understanding thread safety helped me write more robust and performant code, avoid bugs and crashes, and create a better user experience for the users of the applications I developed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning from history
&lt;/h2&gt;

&lt;p&gt;Having been around the programming language for over 10 years, it’s been fascinating to see Objective-C evolve as a language, taking influence by new competencies and priorities in the tech industry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Reference Counting (ARC)
&lt;/h3&gt;

&lt;p&gt;Remember all that stuff I wrote about manual memory management? Apple seems to have agreed that this wasn’t the most optimal way to write code, and created ARC, which automates this process by inserting retain and release calls at compile time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grand Central Dispatch (GCD)
&lt;/h3&gt;

&lt;p&gt;To improve multithreaded code, Apple created the &lt;a href="https://developer.apple.com/documentation/dispatch?language=objc" rel="noopener noreferrer"&gt;Grand Central Dispatch&lt;/a&gt;API , making several improvements on the safety, code readability and level of control for multithreaded code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blocks
&lt;/h3&gt;

&lt;p&gt;Blocks are a language feature that allow developers to create anonymous functions or closures in Objective-C. They are similar to lambda expressions in other languages and are often used for asynchronous programming and concurrent programming.&lt;/p&gt;

&lt;p&gt;That's right! They didn't exist in the language at first. Below is an example of one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void (^myBlock)(int) = ^(int num) {
    NSLog(@"The number is %d", num);
};
myBlock(42);

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

&lt;/div&gt;



&lt;p&gt;The syntax for defining a block looks a bit unusual because it uses the caret&lt;br&gt;
symbol (^) and parentheses to specify its parameters. This is designed to be&lt;br&gt;
similar to &lt;a href="https://www.learnc.net/c-tutorial/c-function-pointer/" rel="noopener noreferrer"&gt;C's function pointer&lt;br&gt;
syntax&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Literals
&lt;/h3&gt;

&lt;p&gt;Creating objects like arrays or dictionaries used to be quite unwieldly. Not anymore!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Old way of creating an NSArray:
NSArray *myArray = [NSArray arrayWithObjects:@"apple", @"banana", @"cherry", nil];

// New way of creating an NSArray:
NSArray *myArray = @[@"apple", @"banana", @"cherry"];

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up: How Objective-C makes me feel today
&lt;/h2&gt;

&lt;p&gt;Looking back at it, I’m so grateful for having spent a good chunk of my early years with Objective-C 😌. I often say that it taught me computer science, in that it helped me grasp several concepts that go into my daily work.&lt;/p&gt;

&lt;p&gt;More than anything, it taught me to be versatile.&lt;/p&gt;

&lt;p&gt;Learning the lower-level concepts helped me understand better how computers work, giving me a better frame of reference when designing optimal architectures.&lt;/p&gt;

&lt;p&gt;Knowing how the underlying system works can help you better understand the root cause of bugs or issues and work one of our most important technical muscles: Problem solving.&lt;/p&gt;

&lt;p&gt;Lastly, having a strong foundation in computer science can make it easier for you to learn and adapt to new technologies and programming languages. Versatility is at the heart of this, and I treasure this skill immensely to this day.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>codenewbie</category>
      <category>career</category>
    </item>
    <item>
      <title>Asking for Help Effectively as a Software Developer</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Sun, 13 Nov 2022 07:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/effectively-asking-for-help-as-a-software-developer-3454</link>
      <guid>https://dev.to/hola_soy_milk/effectively-asking-for-help-as-a-software-developer-3454</guid>
      <description>&lt;p&gt;Let’s face it, getting stuck on a programming problem stinks, doesn’t it?&lt;/p&gt;

&lt;p&gt;When it comes to asking for help, especially when starting out in our careers or when onboarding onto a new codebase/project, I’ve found that we tend to fall into two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We ask for help the moment/shortly after we get stuck.&lt;/li&gt;
&lt;li&gt;We &lt;del&gt;wait a while&lt;/del&gt;  &lt;del&gt;wait ages&lt;/del&gt; never ask for help, no matter how long we’ve been stuck for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll be the first to admit that I very strongly fall into the latter category, even going as far as to say that to this day, having over 12 years of experience as a software developer, I struggle to accept when it’s time to reach out for help.&lt;/p&gt;

&lt;p&gt;Is one better than the other, however? I’d argue neither, really:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spending too little time on trying to solve a problem blocks us from practicing, learning problem solving, and/or catch bugs/UX/DX issues in a project.&lt;/li&gt;
&lt;li&gt;On the other hand, however, taking too long or never asking for help can hold a timeline or team back. Maybe someone can offer their perspective and be the saving grace because of their unique perspective or because they’re especially knowledgeable in the problem!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What helps is to have a consistent amount of time to try going at a problem before you reach out for help.&lt;/p&gt;

&lt;h2&gt;
  
  
  How long should I wait before reaching out for help?
&lt;/h2&gt;

&lt;p&gt;The specific amount might vary from situation to project to situation, but I find it’s important to be consistent about it in that context. For example, one heuristic that I developed over time is to give a problem no longer than 30 minutes before reaching out for a helping hand.&lt;/p&gt;

&lt;p&gt;This amount of time could be different for you, of course!&lt;/p&gt;

&lt;h2&gt;
  
  
  Asking for help &lt;strong&gt;effectively&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Right, so the title of this post is not just about how to ask for help, but how to do so effectively. How can we maximise the time for ourselves as well as the person helping us out?&lt;/p&gt;

&lt;h3&gt;
  
  
  Asking narrow, pointed questions
&lt;/h3&gt;

&lt;p&gt;I spent many years working in software support and teaching children to code, and I’m sure a lot of you can relate that the following tends to not be very helpful when being asked for help:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Could you please help me? My code is broken and nothing works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s not bad, of course! But it can be better. What I recommend doing is offering as much information as possible upfront in order to get the person helping you to start thinking right away about a solution:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, I’m having some trouble logging in since updating to the latest login dependency, could you please take a look? I’m updated to 3.1.4.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This way, we’re priming everyone for the problem as we arrange a time to pair on the issue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing what you’ve tried
&lt;/h3&gt;

&lt;p&gt;Another helpful thing to do is to immediately start knocking out possible solutions that might seem like clear suspects to the person helping us. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ve already deleted &lt;code&gt;node_modules&lt;/code&gt;, made sure I’m on node 16, and restarted Docker, just in case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Reproducing the problem
&lt;/h3&gt;

&lt;p&gt;Another way one can help the person that’ll lend us their help is to outline the precise set of steps to reproduce the problem that’s got us stuck:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok so first I ran &lt;code&gt;npm install&lt;/code&gt;, then I started up the dev environment with &lt;code&gt;npm run dev&lt;/code&gt;, and then navigated to &lt;code&gt;localhost:4000/login&lt;/code&gt; and then got the error message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Requesting a pairing session
&lt;/h3&gt;

&lt;p&gt;It’s been demonstrated that &lt;a href="https://en.wikipedia.org/wiki/Pair_programming" rel="noopener noreferrer"&gt;pair programming&lt;/a&gt; is a highly effective software development [Cockburn, Alistair, and Laurie Williams. “The costs and benefits of pair programming.” Extreme programming examined (2000): 223-247.], and this absolutely extends to problem solving with regards to getting unstuck. Having someone sit down with you to step through the code, one of you navigating and the other driving is super helpful!&lt;/p&gt;

&lt;p&gt;And hey, why just keep it at two?&lt;/p&gt;

&lt;h3&gt;
  
  
  The more, the merrier: Requesting an ensemble session
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://ensembleprogramming.xyz/" rel="noopener noreferrer"&gt;Ensemble programming&lt;/a&gt; builds upon the concepts of pair programming by having not just a driver and a navigator, but also an ensemble of folks collaborating on a single coding session, looking up documentation, throwing out suggestions, and rotating at regular intervals. If there are resources to do so, this can be an incredible help session!&lt;/p&gt;

&lt;p&gt;This is something we’ve practised before while open source coding live with &lt;a href="https://distributeaid.org/" rel="noopener noreferrer"&gt;Distribute Aid&lt;/a&gt;, live on stream with the chat as our ensemble. This has proven to be a lot of fun and useful for getting unstuck.&lt;/p&gt;

&lt;p&gt;And those are some of the ways I’ve practised asking for help!&lt;/p&gt;

&lt;h2&gt;
  
  
  What about asynchronous work?
&lt;/h2&gt;

&lt;p&gt;With so many of us working in remote teams, taking asynchronous communication and collaboration into account is necessary. There’s not too much to differ here, is there? The good thing about asynchronous collaboration is that we can send off a help request as early as we feel necessary, and continue trying alternatives.&lt;/p&gt;

&lt;p&gt;The added time also gives us the ability to, once again, asynchronously add further context as we go along. We can also try different avenues for help, be it posts on forums or communication platforms, &lt;a href="https://xkcd.com/979/" rel="noopener noreferrer"&gt;being helpful and keeping these up to date&lt;/a&gt;, too.&lt;/p&gt;

&lt;p&gt;Update! &lt;a href="https://twitter.com/Chad_R_Stewart" rel="noopener noreferrer"&gt;Chad&lt;/a&gt; was kind enough to add some of his own experience:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When working on a problem, open a PR and if you run into an issue, push the code. Now you can ask for help asynchronously and can show the problem directly!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thank you so much for sharing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Asking for help is an essential part of software development
&lt;/h2&gt;

&lt;p&gt;Just wanted to end this with a reminder: A lot of software is developed collaboratively. And this collaboration not only involves reviewing each others’ code, setting up helpful automations, or planning. It also involves getting others unstuck. Being on the side of offering that help is also tremendously gratifying.&lt;/p&gt;

&lt;p&gt;I’d love to hear from you! What tips do you have around asking for help when stuck? Get in touch! I’m on &lt;a href="https://mastodon.online/@hola_soy_milk" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My experience speaking at DevRelCon 2021</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Mon, 15 Nov 2021 07:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/my-experience-speaking-at-devrelcon-2021-3kge</link>
      <guid>https://dev.to/hola_soy_milk/my-experience-speaking-at-devrelcon-2021-3kge</guid>
      <description>&lt;p&gt;What a year! In 2021, when I started &lt;a href="https://ramonh.dev/2021/04/24/devrel-first-months/" rel="noopener noreferrer"&gt;my first role in DevRel&lt;/a&gt; I also spoke at this year’s edition of &lt;a href="https://2021.devrel.net/" rel="noopener noreferrer"&gt;DevRelCon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;DevRelCon is a series of conferences related to DevRel, or Developer Relations, since &lt;a href="https://developerrelations.com/events/devrelcon-london-2015" rel="noopener noreferrer"&gt;2015&lt;/a&gt;. This year, it was held in an &lt;a href="https://2021.devrel.net/" rel="noopener noreferrer"&gt;online format&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I had the honour of speaking with some of the most thoughtful, clever people. I’m so thankful for this opportunity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming up with my talk proposal
&lt;/h2&gt;

&lt;p&gt;When the time came to propose a talk, I thought about what it was that I did a lot of during this year that I could turn into a talk.&lt;/p&gt;

&lt;p&gt;That’s when it hit me: Streaming! I’ve been doing loads of it this year! Here’s &lt;a href="https://github.com/meetandeat-at/takeaway-app/pull/366" rel="noopener noreferrer"&gt;an example&lt;/a&gt; of me streaming with &lt;a href="https://twitter.com/thamyk" rel="noopener noreferrer"&gt;Thamara&lt;/a&gt; from the &lt;a href="https://github.com/thamara/time-to-leave/" rel="noopener noreferrer"&gt;Time to Leave&lt;/a&gt; project, getting onboarded to the project for the first time and making a pull request.&lt;/p&gt;

&lt;p&gt;This is what my proposal looked like:&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming to you live! Inclusive, effective, fun live streaming for DevRel
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Adapting to having events online has been a learning experience for us all. How can we keep a constant, steady, interactive experience for our audience?&lt;/p&gt;

&lt;p&gt;In this talk, we’ll cover how we created Open Source Thursdays, including the tools we used, the accessibility considerations, as well as how we’ve improved it over time. Anyone can be a great live streamer!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And wouldn’t you know it, my talk got accepted! I was overjoyed and so nervous!&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing to give my talk
&lt;/h2&gt;

&lt;p&gt;Everybody prepares talks differently. My approach tends to be as follows:&lt;/p&gt;

&lt;p&gt;First, the topic pops into my head, and with it a global outline: 4-5 points or pieces of advice I want to offer.&lt;/p&gt;

&lt;p&gt;Next, having written the above title and abstract, I set out to build my slides. My process is to build one ‘title’ slide for each point, and let each section and its corresponding slides grow from there.&lt;/p&gt;

&lt;p&gt;Finally, when it comes to practise, again, everybody has a different technique. Here, mine is to get a script or general gist going in my head, and give the talk to myself a handful of times before being satisfied.&lt;/p&gt;

&lt;p&gt;That said, I was quite nervous having my debut DevRel talk, so I practised over 5 times, once even an hour before the talk itself! I’ll admit I was happy to have done that.&lt;/p&gt;

&lt;p&gt;One piece of feedback I was given during the tech check was to shift my setup or position to face the camera. I recently changed the angle of my phone (heh, indeed, &lt;a href="https://reincubate.com/camo/" rel="noopener noreferrer"&gt;I use my phone as my webcam&lt;/a&gt;) to be at an angle, as I felt this was more immersive for streams, as shown in the screenshot of one of my personal live streams below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgysrt027w99crs67tr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgysrt027w99crs67tr4.png" alt="Screenshot of my personal stream, showing the camera pointing at me at an angle" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The solution was therefore to re-orient myself to try and face the camera in such a way that still allowed me to have that camera angle but still be able to use Google Slides’ speaker notes mode comfortably to offer my presentation.&lt;/p&gt;

&lt;p&gt;But then came the first day of the conference!&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1: Defining DevRel and surprise MC session
&lt;/h2&gt;

&lt;p&gt;The day started great! It was great to hear from wonderful folks, especially the panel on “What do dev advocates actually do?” with Yashovardhan, Srushtika, Daniel and Jess.&lt;/p&gt;

&lt;p&gt;Halfway through the day, I was DM’ed to be asked if I could fill last-minute in for somebody as co-MC. How could I possibly say no?&lt;/p&gt;

&lt;p&gt;If you haven’t MC’ed and are curious about it, I can highly recommend it! It can be a little indimidating at first, but I try to keep a few things in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The audience wants you to succeed, relax!&lt;/li&gt;
&lt;li&gt;Your job overall is to keep an eye out for questions and make the speakers shine! Play off of their energy.&lt;/li&gt;
&lt;li&gt;I like to have a set of related questions handy, just in case. There are no bad questions!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Day 2: Management and metrics
&lt;/h2&gt;

&lt;p&gt;The second day had talks in a variety of topics, including how to prove the value of DevRel to management, sideways management, which is how DevRel fits in with adjacent departments, and finally managing a DevRel team.&lt;/p&gt;

&lt;p&gt;Sadly I couldn’t stick around for a lot of the talks, but particularly appreciated Tim’s talk on value driven DevRel and Bear’s talk on managing your first developer relations team. All the talks I saw I really loved!&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 3: DevRel around the world, speaking, startups, my talk!
&lt;/h2&gt;

&lt;p&gt;The day started wonderfully with 3 talks on DevRel focussing on tailoring your DevRel work to different regions from Kay, Akanksha and Shedrack.&lt;/p&gt;

&lt;p&gt;Next up was the section on “Speaking as part of DevRel”, with yours truly going first! Personally, I was super nervous leading up to it, but it tapered off quickly as I got into the talk, &lt;a href="https://www.youtube.com/watch?v=3eea-AzrWpk" rel="noopener noreferrer"&gt;as it usually does&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After Layla and Naomi’s wonderful talks on live coding, and crafting and delivering demos, we then had a lovely panel discussion on topics related to streaming cadence, authenticity and the different topics to stream about.&lt;/p&gt;

&lt;p&gt;After that, the relief of being done felt like a rush of adrenaline going away! I broke for lunch and errands, back in time for the section on events, with informative talks from Siddharth, Philipp and Kevin.&lt;/p&gt;

&lt;p&gt;I had to work the rest of the day, so I caught a few more talks before breaking for the day. I definitely made sure to catch a few more highlights before being done. My colleague and dear friend &lt;a href="https://twitter.com/nahrinjalal" rel="noopener noreferrer"&gt;Nahrin&lt;/a&gt; was co-MC’ing during the “DevRel for Startups” portion of the day, which included insightful talks by Shivay and Alex! I also made sure to catch my good friend &lt;a href="https://twitter.com/SuzeShardlow" rel="noopener noreferrer"&gt;Suze&lt;/a&gt;’s talk on Marketing! Loved those slides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Having online conferences has been particularly difficult. I find that my best experiences have come from a dedicated audience that interacts and keeps things going! I was so happy to see the community come together and ask questions, share experiences and resources.&lt;/p&gt;

&lt;p&gt;It was a joy to be able to contribute. Thank you to &lt;a href="https://twitter.com/matthewrevell/" rel="noopener noreferrer"&gt;Matt&lt;/a&gt; and the rest of the team for having me and providing such a good speaking experience. 💜&lt;/p&gt;

</description>
      <category>career</category>
      <category>devrel</category>
      <category>community</category>
    </item>
    <item>
      <title>How to Get Unstuck</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Mon, 12 Jul 2021 13:05:13 +0000</pubDate>
      <link>https://dev.to/codesee/how-to-get-unstuck-1o5k</link>
      <guid>https://dev.to/codesee/how-to-get-unstuck-1o5k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post is a part of CodeSee's Emerging Developer Track. Learn more and find out how you can participate &lt;a href="https://www.codesee.io/blog/emerging-developer-track" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've all been there. Coding away, solving a problem when all of a sudden we hit a blocking point. The thing we're trying to do doesn't work, or the problem seems completely out of reach. Heck, sometimes we might not even know how to begin solving the problem!&lt;/p&gt;

&lt;p&gt;This might sound familiar, recent, even! After 10 years of working as a software builder, I still find myself getting stuck. I'll run into a bug that I can't reproduce reliably, I'll come up against an API that I can't seem to communicate with, trying to update a dependency will break others, or my CI builds just keep failing.&lt;/p&gt;

&lt;p&gt;Let's take a look at a few tips to help you get unstuck!&lt;/p&gt;

&lt;h2&gt;
  
  
  Areas we'll be covering
&lt;/h2&gt;

&lt;p&gt;If you'd like to jump ahead to a specific section, feel free!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take a break, step away from the code!&lt;/li&gt;
&lt;li&gt;Reframing the problem&lt;/li&gt;
&lt;li&gt;Looking things up effectively&lt;/li&gt;
&lt;li&gt;Leveraging debugging&lt;/li&gt;
&lt;li&gt;
Reaching out for help

&lt;ul&gt;
&lt;li&gt;How long should I wait before asking for help?&lt;/li&gt;
&lt;li&gt;How to ask for help&lt;/li&gt;
&lt;li&gt;Pairing&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Let's be clear, it's ok to get stuck&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Take a break, step away from the code!
&lt;/h2&gt;

&lt;p&gt;This tip has helped me many times in the past, so much so that &lt;a href="https://www.youtube.com/watch?v=6T_6THrR5Qo" rel="noopener noreferrer"&gt;I gave a talk on this very topic&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;When I get stuck in a particularly sticky problem, I tend to get bogged down by it and try and hammer away at it, attempting to push through the frustration and/or exhaustion. It ends up in time not well used, or worse, my solutions might miss the mark.&lt;/p&gt;

&lt;p&gt;So as the title implies, it helps to just, leave it for the time being! Depending on the time and looming deadline, this can vary in efficacy, but I find that if I go for a walk, or stop for the day, I can let my mind either work on the problem in the background or even coming back can bring in a fresher perspective that really jumpstarts a better solution!&lt;/p&gt;

&lt;h2&gt;
  
  
  Reframing the problem
&lt;/h2&gt;

&lt;p&gt;Oftentimes when stuck on something, it might help to consider looking at the problem differently! Having a different perspective might even make us ask the question of whether the problem we're trying to solve is the right one. As written by &lt;a href="https://wedellsblog.com/research/reframing-a-key-problem-solving-tool/" rel="noopener noreferrer"&gt;Thomas Wedell-Wedellsborg&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most people are fairly good at solving problems – but they are bad at diagnosing the right problems to solve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Breaking the problem down into smaller problems
&lt;/h3&gt;

&lt;p&gt;This approach to problem-solving is similar to that applied by &lt;a href="https://en.wikipedia.org/wiki/Divide-and-conquer_algorithm" rel="noopener noreferrer"&gt;Divide and Conquer Algorithms&lt;/a&gt;, where, as the name implies, we reframe the problem as a set of smaller problems, whose solutions are smaller by extension. What we can then do is approach each of these in isolation. This frees up our mind space to laser focus on those smaller problems and lets the larger solution build up! &lt;/p&gt;

&lt;p&gt;One example of a tool to divide and conquer is &lt;a href="https://git-scm.com/docs/git-bisect" rel="noopener noreferrer"&gt;&lt;code&gt;git-bisect&lt;/code&gt;&lt;/a&gt;. Yep, built into your git tools!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; is a command built into &lt;code&gt;git&lt;/code&gt; with the purpose of helping us find out at which point we introduced a change to our codebase that we didn't want to add. By splitting all of the git history and checking whether the problem persists in each split, we drill down quickly to find out the commit that introduced it! This is also known as a &lt;a href="https://en.wikipedia.org/wiki/Binary_search_algorithm" rel="noopener noreferrer"&gt;Binary Search&lt;/a&gt;:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Looking things up effectively
&lt;/h2&gt;

&lt;p&gt;No matter the skill level, it's super-valuable to look things up! Be it via online search engines or documentation.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://betterprogramming.pub/12-tricks-to-master-the-art-of-googling-as-a-software-developer-1e00b7568b7d" rel="noopener noreferrer"&gt;brilliant technical guides&lt;/a&gt; out there for how to look stuff up on Google or DuckDuckGo, such as using quotation marks for terms that have to be included, or gradually making search phrases longer. Beyond that, some tips I've picked up over the years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Look up that error message as-is&lt;/strong&gt;: Loads of folks have likely run into the same problems. Even if they don't match 1:1, you'll likely unlock something!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plug in that Stack Overflow solution&lt;/strong&gt;: I recently learned that Stack Overflow's &lt;a href="https://stackoverflow.com/help/licensing" rel="noopener noreferrer"&gt;license&lt;/a&gt; allows reuse under Creative Commons Attribution-ShareALike, meaning you can reuse the code providing you add attribution. That said, in order to improve your understanding of a solution, it's encouraged to try and refactor that code, putting it into the best way that works with the style of your codebase. You'll often find that's required anyway!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look up that aspect of a library in their Github repository&lt;/strong&gt;: When something hasn't quite clicked in a library I'm using, it helps me to go into their repo online and see either what issues have been brought up on the topic, or even start trying to diagnose the issue in the library and potentially make a contribution!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13gj83hx8hrs0ytf7ac1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13gj83hx8hrs0ytf7ac1.png" alt="Screenshot of a GitHub search for the query " width="800" height="438"&gt;&lt;/a&gt;&lt;br&gt;
The screenshot above shows lots of issues when I look up "compileDebugJavaWithJavac". I need to clean up my notifications, I know!&lt;/p&gt;

&lt;h3&gt;
  
  
  Leveraging debugging
&lt;/h3&gt;

&lt;p&gt;Although we have tools to help us debug, this doesn't make all those tools debuggers.&lt;/p&gt;

&lt;p&gt;One of my most-used tools is a print statement. It goes by many names in different programming languages, be it &lt;code&gt;console.log&lt;/code&gt;, or &lt;code&gt;puts&lt;/code&gt;, or &lt;code&gt;printf&lt;/code&gt;, or &lt;code&gt;System.out.println()&lt;/code&gt;. I've even gone and used &lt;code&gt;alert&lt;/code&gt; in React Native projects!&lt;/p&gt;

&lt;p&gt;And this is totally fine. If it helps you drill down to what's causing the problem, why not?&lt;/p&gt;

&lt;p&gt;Various platforms will have debuggers on them too, like the web! Most browsers will have their own debuggers built-in, such as &lt;a href="https://developer.mozilla.org/en-US/docs/Tools" rel="noopener noreferrer"&gt;Firefox's Developer Tools&lt;/a&gt; or those from &lt;a href="https://developer.chrome.com/docs/devtools/overview/" rel="noopener noreferrer"&gt;Google Chrome&lt;/a&gt;, both of which are extensively documented. But this isn't just limited to the web, we've also got specific debugging tools, like &lt;a href="https://lldb.llvm.org/" rel="noopener noreferrer"&gt;LLDB&lt;/a&gt; for all your macOS/iOS debugging needs, &lt;a href="https://github.com/pry/pry" rel="noopener noreferrer"&gt;pry&lt;/a&gt; for Ruby, and so on! &lt;/p&gt;

&lt;p&gt;Indeed, even editors like VSCode have their &lt;a href="https://code.visualstudio.com/docs/editor/debugging" rel="noopener noreferrer"&gt;own debugging tools built-in for several languages&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Also hey, we're actually working on tools to help you with this! If you're keen on checking out our tools for understanding complex codebases in a streamlined fashion, &lt;a href="https://www.codesee.io/architecture-diagram" rel="noopener noreferrer"&gt;consider signing up for our beta&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The most important part of debugging for me is to leave no stone unturned and try every theory I might have. You never know which piece of the puzzle is faulty!&lt;/p&gt;

&lt;h2&gt;
  
  
  Reaching out for help
&lt;/h2&gt;

&lt;p&gt;Sometimes, with our heads buried in a problem, our perspective can get clouded. Having someone else step in with either more experience in the area or with their fresh perspective can be so handy in unlocking the answer!&lt;/p&gt;

&lt;h3&gt;
  
  
  How long should I wait before asking for help?
&lt;/h3&gt;

&lt;p&gt;This is one of the trickiest parts. Spending too little time on trying to solve a problem blocks us from practicing and/or learning problem solving, but taking too long or never asking for help can hold a timeline or team back (I'm definitely in the latter camp myself, (maybe even to this day a little (working on it!))).&lt;/p&gt;

&lt;p&gt;One piece of advice I was given early was to be consistent in how long I wait. Of course, this can vary by team, project, and other factors, but my rule of thumb is to give something half an hour before reaching out. &lt;/p&gt;

&lt;h3&gt;
  
  
  How to ask for help
&lt;/h3&gt;

&lt;p&gt;Asking for help involves bringing an outside person into the context you're in. Doing so effectively is critical to maximize the help you're about to get.&lt;/p&gt;

&lt;p&gt;This involves things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asking pointed, narrow questions&lt;/strong&gt;: If you come to someone and open with "this doesn't work, could you please take a look?" is very different from saying "I'm having some trouble logging in since updating to the latest &lt;code&gt;devise&lt;/code&gt; gem, could you please take a look?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing what I've tried&lt;/strong&gt;: To save time, it helps if I share with the person who's helping me what I've already tried, to not spend time on those.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducing the problem&lt;/strong&gt;: It's also good to have a set of steps handy so that if this is an asynchronous or remote request for help, that the other person can try it out and confirm that there's indeed an issue. In fact, we're working on tools to help you visualize your code easily and bring up those reproductions. If interested, &lt;a href="https://www.codesee.io/" rel="noopener noreferrer"&gt;do consider signing up for our free beta!&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pairing
&lt;/h3&gt;

&lt;p&gt;If possible, when reaching out for help, it's so helpful to practice &lt;a href="https://en.wikipedia.org/wiki/Pair_programming" rel="noopener noreferrer"&gt;pair programming&lt;/a&gt;. Most likely, if receiving help, you'll be &lt;em&gt;driving&lt;/em&gt;, meaning you'll be doing the coding, but you could also be &lt;em&gt;navigating&lt;/em&gt;, meaning you'd be giving tips as your helper as they drive.&lt;/p&gt;

&lt;p&gt;Having established the problem, communication is critical to ensure a successful pairing session. More on pair programming coming soon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's be clear, it's ok to get stuck
&lt;/h2&gt;

&lt;p&gt;In an instance of "do as I say, not as I do": I often panic when stuck. &lt;a href="https://en.wikipedia.org/wiki/Impostor_syndrome" rel="noopener noreferrer"&gt;Impostor syndrome&lt;/a&gt; sets in, and I start wondering if I've ever been a competent engineer. &lt;/p&gt;

&lt;p&gt;As engineers, trying to solve new problems or trying to integrate solutions into existing ones is a tricky matter!&lt;/p&gt;

&lt;p&gt;One thing that I try to keep in mind when working on a problem is that it will eventually be resolved, and that patience is key. We will eventually reach that "Aha!' moment where everything will click.&lt;/p&gt;

&lt;p&gt;What about you? How often do you get stuck? How long do you wait until reaching out for help? We'd love to hear from you! Hit us up on &lt;a href="https://twitter.com/codeseeio" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or email us &lt;code&gt;devrel[at]codesee.io&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Pre-recording conference talks</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Tue, 11 May 2021 08:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/pre-recording-conference-talks-3h99</link>
      <guid>https://dev.to/hola_soy_milk/pre-recording-conference-talks-3h99</guid>
      <description>&lt;p&gt;Most of the conference talks I’ve given this year have not only been online, but also pre-recorded. &lt;a href="https://ramonh.dev/2020/10/25/running-a-conference-online/#talks" rel="noopener noreferrer"&gt;I went into the reasons for having pre-recorded talks previously&lt;/a&gt;, as well as the pros and cons of doing so, so this post will focus on how I’ve done it in my talks so far.&lt;/p&gt;

&lt;p&gt;One thing to bear in mind is that this is how I’ve experienced pre-recording having been giving talks in person for many years.&lt;/p&gt;

&lt;h2&gt;
  
  
  The personal experience
&lt;/h2&gt;

&lt;p&gt;It’s no secret that performing a talk into your computer is completely different from doing so in person. One part I’ve struggled with is that lack of eye-contact with the audience. Being able to see their reactions to parts of my talks, or even a chuckle at my silly jokes. Talking to a computer is not quite the same.&lt;/p&gt;

&lt;p&gt;There’s still the fact that I’m talking to folks live, however! Knowing that folks are tuned in has, over time, help me stay convinced stuff is still happening as an active conversation. After trying out proper streaming recently, I’ve gotten a lot more comfortable talking to a chat. Like anything, it’s practise!&lt;/p&gt;

&lt;p&gt;Doing so to a video recording on the other hand is a whole other feeling too, and likely a matter of practising as well.&lt;/p&gt;

&lt;p&gt;That said, I have a high appreciation for the opportunity to be able to create this kind of content at home! It gives folks who wouldn’t otherwise be able to attend such events the opportunity to contribute.&lt;/p&gt;

&lt;p&gt;So let’s talk hardware! Here’s my setup:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q0ayogunxt7gvgdpn5s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q0ayogunxt7gvgdpn5s.jpg" alt="Picture of my desk top. Pictured are two monitors, a microphone, webcam, and more" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Precise models are listed in the following sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Camera
&lt;/h2&gt;

&lt;p&gt;I’ve stuck mostly to recording on my Windows 10 desktop machine, where I’ve got a &lt;a href="https://www.logitech.com/en-us/products/webcams/c270-hd-webcam.960-000694.html" rel="noopener noreferrer"&gt;720p-resolution Logitech Webcam&lt;/a&gt;. One or two conferences have asked that I provide HD 1080p resolution video, but since that includes slides and my face is normally only a part of the video feed, something with a higher resolution wasn’t necessary.&lt;/p&gt;

&lt;p&gt;Most laptops (at least MacBooks, as far as I know) nowadays should have a 720p or close camera on them, which if you’ll be recording your slides as well as your face should be more than enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microphone
&lt;/h2&gt;

&lt;p&gt;Below are some options I’ve considered for recording my speaking audio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Built-in MacBook microphone
&lt;/h3&gt;

&lt;p&gt;Given &lt;a href="https://ramonh.dev/2020/10/25/running-a-conference-online/#recording-the-talks" rel="noopener noreferrer"&gt;our experience with accepting pre-recorded talks&lt;/a&gt;, I feel that in order to deliver a decent-quality audio experience, the microphone built into a laptop can be disruptive due to factors like typing or the fans on the machine. Another issue is that the quality of the voice audio tends to depend on how close the speaker is to the microphone itself, so standing at arms’ length can really be a hindrance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Headphones (headset, pods, buds, what have you)
&lt;/h3&gt;

&lt;p&gt;I’ve found that talks delivered with a microphone close to the speaker goes a long way toward having good audio quality!&lt;/p&gt;

&lt;h3&gt;
  
  
  Desktop Microphone
&lt;/h3&gt;

&lt;p&gt;I ultimately went with a &lt;a href="http://www.rode.com/microphones/nt-usb" rel="noopener noreferrer"&gt;Rode NT-USB&lt;/a&gt; microphone, costing me about EUR 170.-&lt;/p&gt;

&lt;p&gt;It did the trick as far as audio quality went, and the included &lt;a href="https://en.wikipedia.org/wiki/Pop_filter" rel="noopener noreferrer"&gt;pop filter&lt;/a&gt; made me a lot more comfortable!&lt;/p&gt;

&lt;p&gt;It does have to be said that I’m using this microphone for &lt;a href="https://ramonh.dev/2021/01/23/recording-podcast/" rel="noopener noreferrer"&gt;podcasting&lt;/a&gt; as well, so it’s important to weigh this as a factor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lighting
&lt;/h2&gt;

&lt;p&gt;Getting plenty of balanced light on your face for your talk is pretty important for your visibility onscreen, so going for good natural light or investing in good lighting gear helps! In the past, I’ve tended more towards the former, but lately a friend of mine pointed me towards a more costly solution which is the &lt;a href="https://www.elgato.com/ring-light" rel="noopener noreferrer"&gt;Elgato Ring Light&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your mileage may vary depending on what kind of light you get and what your preference is. Here’s how the difference looks for me without the light on the left and with it on the right. Both pictures were taken at night with the room’s light on:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmqjjk6e0lunhcnsiafzx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmqjjk6e0lunhcnsiafzx.jpg" alt="Me without the light on in the left, and with it on in the right" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference might be subtle, but it makes me happy to have an even light on my face!&lt;/p&gt;

&lt;h2&gt;
  
  
  Software
&lt;/h2&gt;

&lt;p&gt;Alright! Let’s talk software.&lt;/p&gt;

&lt;p&gt;When I spoke at &lt;a href="https://futuresync.co.uk/" rel="noopener noreferrer"&gt;Future Sync&lt;/a&gt; online year, this was the first time I had to pre-record a talk! They very kindly provided a walkthrough for recording my talk using the open source software &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS&lt;/a&gt;. They recommended to use 3 sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Window capture for my slides&lt;/li&gt;
&lt;li&gt;Video capture for my webcam&lt;/li&gt;
&lt;li&gt;Audio capture for my microphone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here it is in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85t743bpohs45mnhfr2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85t743bpohs45mnhfr2i.png" alt="Screenshot of OBS in action showing my webcam in the corner and my slides at the top left" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By clicking on “Start recording”, I can immediately start recording!&lt;/p&gt;

&lt;p&gt;For more info getting into OBS, I can totally recommend &lt;a href="https://obsproject.com/wiki/OBS-Studio-Quickstart" rel="noopener noreferrer"&gt;their guides&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subtitles
&lt;/h3&gt;

&lt;p&gt;In my talks, I like to include captions by using the &lt;a href="https://support.google.com/docs/answer/9109474?hl=en" rel="noopener noreferrer"&gt;Google Slides&lt;/a&gt;’ built in functionality. Thank you to &lt;a href="https://twitter.com/codepo8/" rel="noopener noreferrer"&gt;Chris&lt;/a&gt; for showing me this functionality!&lt;/p&gt;

&lt;h2&gt;
  
  
  Slip-ups
&lt;/h2&gt;

&lt;p&gt;It’s gonna happen. It happens to us all the time! When giving a talk, I’ll say the wrong thing and have to correct myself briefly, or go to the next slide too early, or jumble my words, or pause awkwardly for a second. The temptation to cut that out of the video is strong.&lt;/p&gt;

&lt;p&gt;When I initially would deal with these slip-ups, I wasn’t well-experienced with dealing with video, and didn’t consider editing them. So what would I do if I considered a slip-up egregious enough to warrant intervening in the recoridng? Why, start over!&lt;/p&gt;

&lt;p&gt;And what if, you may ask, the talk was long? I realise this can be extremely time-consuming. Nowadays, I’ve been using some open source video-editing software like &lt;a href="https://www.openshot.org/" rel="noopener noreferrer"&gt;OpenShot&lt;/a&gt; for editing our podcast episodes and have gotten comfortable with having a minor edit here and there to make the video experience a little smoother.&lt;/p&gt;

&lt;p&gt;Over time, however, I’ve grown more comfortable with leaving these minor slip-ups in the talk recording. Like I said at the beginning of this section, these are natural in live conference talks, and can totally happen while recording! After all, you’re kinda recording “live”, in a way 😅.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;The thing to definitely bear in mind is that our experiences pre-recording talks is unique to us.&lt;/p&gt;

&lt;p&gt;I’ve seen folks try out some wonderful things, given that they have the opportunity to pre-record. I’ve seen folks give talks &lt;a href="https://fosdem.org/2021/schedule/event/codemirror/" rel="noopener noreferrer"&gt;while hiking&lt;/a&gt;, or &lt;a href="https://www.youtube.com/watch?v=Qcn0GgDlLfk" rel="noopener noreferrer"&gt;make fun use of editing&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I’ve been using OBS more for streaming lately, and getting quite comfortable with it. I could try using this to have more of an opportunity to have distinct cuts in my talks as well as different screen layouts! I don’t necessarily need to be in the corner, I can be next to my slides, or around them!&lt;/p&gt;

&lt;p&gt;I’d love to hear what you’re trying when pre-recording talks, too!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>career</category>
      <category>publicspeaking</category>
    </item>
    <item>
      <title>The Value of Reading Code</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Wed, 28 Apr 2021 03:58:34 +0000</pubDate>
      <link>https://dev.to/codesee/the-value-of-reading-code-2eef</link>
      <guid>https://dev.to/codesee/the-value-of-reading-code-2eef</guid>
      <description>&lt;p&gt;It’s not just you: Writing code is way more fun than reading it! Taking the time to read, process and understand a piece of code let alone a codebase can take heaps of work.  &lt;/p&gt;

&lt;p&gt;That said, as codebases grow in size and complexity, as dependencies increase and adapt over a project’s lifetime, it becomes significantly more cumbersome to effectively read them, but at the same time all the more important to keep track of where critical pieces of functionality lie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why read code?
&lt;/h2&gt;

&lt;p&gt;Seeing the ways different folks go about solving different problems helps add perspective to our problem-solving approaches.&lt;/p&gt;

&lt;p&gt;What cemented this for me was my experience as a kids’ coding coach. The way they have fewer assumptions of how code should work really helped me appreciate different folks’ experiences and try out new thought processes.&lt;/p&gt;

&lt;p&gt;Building with our knowledge being exposed to that of others is one of the fundamentals behind the theory of elementary learning called &lt;a href="https://en.wikipedia.org/wiki/Constructionism_(learning_theory)" rel="noopener noreferrer"&gt;constructionism&lt;/a&gt;, which is that of using the context of our understanding to build mental models and building upon them with others. It argues that the media through which we learn is just as important as the learning itself. By being exposed to the code of others, it influences the code that we write.  &lt;/p&gt;

&lt;p&gt;Here are some techniques I’ve picked up over the years to effectively read code:  &lt;/p&gt;

&lt;h2&gt;
  
  
  Go through the dependencies
&lt;/h2&gt;

&lt;p&gt;Is your codebase a JavaScript one? Let’s open up the package.json file. See some dependencies you recognize? React, Vue, Svelte, perhaps? It also helps to see what scripts are available. What does the build process look like, seeing that we’re using, say, Babel or ESBuild?  &lt;/p&gt;

&lt;p&gt;Looking at this information can tell us a lot about what to expect when understanding a codebase. For example, some things I’ll look at include, say if it’s a web app, what version of Webpack is being used? Is Webpack being used at all instead of, say, Rollup? What version of Node.js is required? Is it running React version 16 or 17?  &lt;/p&gt;

&lt;p&gt;We can try the same for the Gemfile if it’s a Ruby codebase, or the Cargo.toml one if written in Rust. This is a great entry point for seeing what makes a codebase tick!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Run the code
&lt;/h2&gt;

&lt;p&gt;This might seem counterintuitive if we’re trying to read the code, but in my experience I find that just doing the work to get the code up and running, debug any issues that might come up with trying to get it running locally for me helps loads with understanding what the code is doing.  &lt;/p&gt;

&lt;p&gt;It’s possible that trying to run the code will throw up an error. Maybe it’s because we’re trying to run the code on an unexpected setup, or a less-supported web browser. This could even lead to finding unintended issues. Focussing in on these areas helps to build a mental model of what’s going on in a codebase.  &lt;/p&gt;

&lt;p&gt;It’s also possible that the code will run on the first try, and we can jump right in and start testing specific parts of it. Here, we can use our debugging system, be it the browser’s devtools (as seen on &lt;a href="https://developer.mozilla.org/en-US/docs/Tools" rel="noopener noreferrer"&gt;Firefox&lt;/a&gt; or &lt;a href="https://developers.google.com/web/tools/chrome-devtools" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt;), LLVM for native apps, or using breakpoints in our IDE (I still do plenty of print statement debugging, myself!) to navigate calls made by the codebase during running and see how it all fits together. Stepping through the code by trying out functionality and debugging helps us understand how these pieces fit together, too!  &lt;/p&gt;

&lt;p&gt;This is an angle of understanding we’re aiming to tackle at CodeSee, letting you record which sections of your code get called up.  ‍  &lt;/p&gt;

&lt;h2&gt;
  
  
  Checking out the test suite
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://martinfowler.com/testing/" rel="noopener noreferrer"&gt;well written&lt;/a&gt; test suite should give you a bird’s eye view of what a specific module or functionality set is meant to do. The test author is essentially telling us what they expect the implementation being tested to do. We can use this as a basis for building an understanding of that module.  &lt;/p&gt;

&lt;p&gt;I find it helps to first take a look at any feature/system tests and then narrow down into individual modules’ unit tests, depending on whether these are available of course. Your mileage may vary, of course. I tend to opt for an &lt;a href="https://martinfowler.com/articles/mocksArentStubs.html" rel="noopener noreferrer"&gt;outside-in approach&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;It does happen that some parts of a codebase will be missing testing coverage. This is a good opportunity to try writing some. Let’s say, for example, we have a module called NumberToHex that converts decimal numbers to hexadecimal. It is, however, untested. This is an opportunity for us to write some tests, understanding what we expect this converter to do, to test that 5 will be converted to 5, that 10 will be converted to 16, and so on.  &lt;/p&gt;

&lt;p&gt;This can motivate us to try and look at, say, a module, and how we can unit test it effectively, building that understanding. And hey, this also can be a handy contribution to that codebase!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Piecemeal refactoring
&lt;/h2&gt;

&lt;p&gt;To be clear, this is by no means a suggestion to rewrite an entire module, codebase, or anything like that! But if a piece of code is proving hard to read for you, maybe doing a quick refactor can help with understanding it. If there are tests to support you along the way (or that you wrote, see the previous section), all the more safer the feeling!  &lt;/p&gt;

&lt;p&gt;Doing things like breaking down a large function into smaller ones can go very far toward helping understanding a piece of code much better!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Pairing
&lt;/h2&gt;

&lt;p&gt;If someone who is familiar with a particular piece of code is available, there’s no loss in asking them to walk you through it! Benefits go both ways:  &lt;/p&gt;

&lt;p&gt;As the person guiding someone through the code, articulating the decisions made towards it helps improve the understanding of the code you wrote.  &lt;/p&gt;

&lt;p&gt;As the person being guided, you have a great opportunity to ask questions, offer constructive feedback, and even work on a contribution together!  &lt;/p&gt;

&lt;h2&gt;
  
  
  And those are just some techniques!
&lt;/h2&gt;

&lt;p&gt;Regardless of your level of experience, taking the time to read others’ solutions can go a long way towards boosting your understanding of a codebase. Following are some other points of view on the same topics that helped shape some of the above ideas, from &lt;a href="https://skorks.com/2010/05/why-i-love-reading-other-peoples-code-and-you-should-too/" rel="noopener noreferrer"&gt;Alan Skorkin&lt;/a&gt; and &lt;a href="https://itnext.io/how-to-read-code-bf478c262932" rel="noopener noreferrer"&gt;Mathis Garberg&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Ultimately, being exposed to different problem-solving styles helps us grow as software builders. But we’d love to hear from you! Do you have any techniques you’ve picked up for making the code-reading process smoother? Hit us up!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>My first few months as a developer advocate</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Sat, 24 Apr 2021 08:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/my-first-few-months-as-a-developer-advocate-1hcl</link>
      <guid>https://dev.to/hola_soy_milk/my-first-few-months-as-a-developer-advocate-1hcl</guid>
      <description>&lt;p&gt;I have spent the last 10+ years freelancing and contracting as a software developer. This January, that changed when I became a developer advocate at &lt;a href="https://www.codesee.io/" rel="noopener noreferrer"&gt;CodeSee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m not gonna lie, it’s been an exhilarating opportunity to dip my toes into Developer Relations, or DevRel.&lt;/p&gt;

&lt;p&gt;Next week being the end of my fourth month at CodeSee, and having listened to an incredible &lt;a href="https://www.youtube.com/watch?v=_q_bWATVJTg" rel="noopener noreferrer"&gt;Twitter Spaces&lt;/a&gt; event where folks gave their experiences and insights into what DevRel is, I felt it was a good time to share my thoughts and experiences over the last months on this new journey. I wanted to expand on the how and why to get into DevRel by adding what it’s like a few months in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some context
&lt;/h2&gt;

&lt;p&gt;CodeSee is working on a dev tool to help folks understand and collaborate on complex code bases. My job partly consists of thinking about the kinds of solutions I can offer fellow devs, such as the types of content related to understanding code, reading code, collaborating, mentoring, etc.!&lt;/p&gt;

&lt;p&gt;Touching on the context of the story itself: CodeSee is currently in a closed Beta and up until a week ago was in stealth, meaning that instead of trying to have a broad outreach, we were going for a deliberate, 1:1 approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  On jobsharing
&lt;/h2&gt;

&lt;p&gt;My colleague and friend &lt;a href="https://twitter.com/jesslynnrose" rel="noopener noreferrer"&gt;Jessica&lt;/a&gt; approached me toward the end of 2020 with the idea of doing a job share. In short, CodeSee hired the two of us to fulfil one full-time role, splitting the compensation. I won’t go into the details of how it works or why it’s beneficial, because &lt;a href="https://www.codesee.io/blog/on-jobsharing" rel="noopener noreferrer"&gt;she’s already done that in a fantastic way&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Doing this as a part time gig has given me the benefit of not having to immediately stop doing my freelancing, and instead just taken on smaller contracts or keep existing ones on the side. Having this flexibility has allowed me to continue exploring software development and at the same time be more selective of how I spend that time. It’s a process I’m working on to better improve my work-life balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  A developer advocate… advocates for developers!
&lt;/h2&gt;

&lt;p&gt;I found the &lt;a href="https://twitter.com/dabit3/status/1383873047619276812" rel="noopener noreferrer"&gt;following tweet&lt;/a&gt; from Nader Dabit really helpful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In DevRel, if you can make developers both successful and happy then almost everything else will take care of itself.&lt;/p&gt;

&lt;p&gt;The problem is that it takes a lot of consistent &amp;amp; sometimes thankless work over a long period of time to get there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of my favourite parts of being involved in tech communities after many years has been empowering people in their tech journeys. It’s brought me great amounts of joy to be able to do things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coach at workshops like &lt;a href="http://railsgirls.com/" rel="noopener noreferrer"&gt;Rails Girls&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Give workshops for organisations like &lt;a href="https://www.refugeescode.at/" rel="noopener noreferrer"&gt;Refugees Code Vienna&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ramonh.dev/speaking/" rel="noopener noreferrer"&gt;Give talks at different conferences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Help organise and support teams at &lt;a href="https://railsgirlssummerofcode.org/" rel="noopener noreferrer"&gt;Rails Girls Summer of Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Funnily enough it wasn’t until the idea of working as a developer advocate was proposed to me that it clicked: this could be something I could be good at or at the very least already have been doing!&lt;/p&gt;

&lt;p&gt;Nevertheless…&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello impostor syndrome, my old friend
&lt;/h2&gt;

&lt;p&gt;My relationship with impostor syndrome confuses me sometimes. It’s never really gone away in the 10+ years that I’ve been building software. One of the most important things that working as a freelancer has been seeing lots of different projects, codebases and the ways that different clients work and learning to get quite comfortable in my discomfort when confronted with an unfamiliar problem. I even &lt;a href="https://www.youtube.com/watch?v=6T_6THrR5Qo" rel="noopener noreferrer"&gt;gave a talk about this&lt;/a&gt; at JSUnconf 2018. It’s a topic I feel quite comfortable in. Again, that’s not to say that it’s completely gone, mind you, just manageable.&lt;/p&gt;

&lt;p&gt;That is, until I started with this DevRel role. All of a sudden, the impostor syndrome washed over me, big time! Even though I’d been doing things in-and-out of being related to DevRel for many years this felt different.&lt;/p&gt;

&lt;p&gt;One thing that’s helped me with this has been to just talk to fellow DevRel folks! &lt;a href="https://twitter.com/jna_sh" rel="noopener noreferrer"&gt;Joe&lt;/a&gt; was kind enough on the week before my first day to sit down with me, hear me out, calm my nerves, and recommend some resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wenger-trayner.com/introduction-to-communities-of-practice/" rel="noopener noreferrer"&gt;Introduction to communities of practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gse.harvard.edu/news/uk/08/05/what-teaching-understanding" rel="noopener noreferrer"&gt;What is Teaching for Understanding?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.contentstrategy.com/content-strategy-for-the-web" rel="noopener noreferrer"&gt;Content Strategy for the Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com/Badass-Making-Awesome-Kathy-Sierra/dp/1491919019" rel="noopener noreferrer"&gt;Badass: Making Users Awesome&lt;/a&gt; by Kathy Sierra&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.stephaniemorillo.co/books" rel="noopener noreferrer"&gt;Stephanie Morillo’s books&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The shows of kindness from Jess, Joe, and so many others have meant the world to me. My intention is to pay it forward, so if you’re nervous about getting into DevRel, please feel free to reach out!&lt;/p&gt;

&lt;p&gt;Turns out there are also loads of communities and events related to DevRel! I’ve been happily helping &lt;a href="https://twitter.com/DevRelSalon" rel="noopener noreferrer"&gt;The DevRel Salon&lt;/a&gt; with note-taking, and also joined the &lt;a href="https://devrelcollective.fun/" rel="noopener noreferrer"&gt;DevRel Collective&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is all made especially easier by the fact that my fellow teammates at CodeSee have been nothing but supportive, uplifting, and overall wonderful.&lt;/p&gt;

&lt;h2&gt;
  
  
  On demoing
&lt;/h2&gt;

&lt;p&gt;One of my main tasks at CodeSee has been holding sessions with interested folks in trying out the product. As I said before, CodeSee was in stealth and in closed Beta, so we’ve been inviting folks to 1:1s with myself and/or Jess to show them the tools in action. This has been the first of a new set of skills I’ve been developing as a developer advocate, and it’s been fascinating.&lt;/p&gt;

&lt;p&gt;The closest thing I’ve been able to compare this to has been giving talks at conferences or other events. I remember how easy it became after time to develop a routine in my head for giving a talk, trying, of course, to adapt these to the audience and context.&lt;/p&gt;

&lt;p&gt;When it comes to giving demos of a devtool, however, there are some minor changes to keep in mind! Most significant is the scale and approach. Since demos tend to be 1:1, we can cater the demo experience to that one developer or team lead. One of my favourite pieces of advice was from &lt;a href="https://twitter.com/Sareh88" rel="noopener noreferrer"&gt;Sareh&lt;/a&gt; who after a demo advised to open the demo with a question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What do you hope to get out of this demo?&lt;/p&gt;

&lt;p&gt;What are your pain points?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What this does for me is completely change the tone of the demo to be less one-sided from me talking to demo attendee (demoee?), but opens the discussion to go both ways and allows me to really, as the job role would imply, to advocate for the developer I’m showing the tool to! How our tool can make their job easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  On following up
&lt;/h2&gt;

&lt;p&gt;Our goal as a dev tool over the Beta is to get as much feedback as we can from users and see where things can be improved and how to go about this. This will involve a lot of following up with leads.&lt;/p&gt;

&lt;p&gt;What I mean by following up in this case is, after showing someone CodeSee and giving them access to the Beta, to message them and see whether they’ve tried it, seeing if they’re stuck on the install portion, and whether we can pair with them with this.&lt;/p&gt;

&lt;p&gt;A personal struggle of mine has been figuring out how to follow up without being (or feeling!) overly pushy. Honestly, it’s been the hardest part for me, since I never want to bother anyone.&lt;/p&gt;

&lt;p&gt;I’ve been trying reframing this as an opportunity to empower instead of chasing a fellow developer and see how we can help them. We are by no means forced to enter a relationship where they use our tool unless they need it!&lt;/p&gt;

&lt;p&gt;Lastly, it’s important to bear in mind that the worst thing that’ll happen is you’ll be turned down. And that’s ok! It’s not a “never”, it’s a “not now, maybe not me”. As much better put by &lt;a href="https://flak.is" rel="noopener noreferrer"&gt;Flaki&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think to me the thing that best helped to frame this has been the understanding of ‘just because this person/team does not need what you can offer &lt;em&gt;right now&lt;/em&gt;, by being helpful and giving them a great experience you already sown a seed and you never know when something comes out of that relationship.’&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Producing content
&lt;/h2&gt;

&lt;p&gt;When coming into the role, the value that CodeSee provides to developers comes to mind: being a continuous understanding tool, our aim is to help developers understand, document and collaborate on complex codebases.&lt;/p&gt;

&lt;p&gt;Going off of this, the mind begins to wander, how can we as developer advocates communicate our value this way?&lt;/p&gt;

&lt;p&gt;When it comes to blog posts, I can think of the value I’ve had in reading codebases over the years, and how developers can benefit from doing so. So &lt;a href="https://www.codesee.io/blog/the-value-of-reading-code" rel="noopener noreferrer"&gt;I wrote the article&lt;/a&gt;, the first of hopefully many!&lt;/p&gt;

&lt;p&gt;As time goes on, we plan to expand this into other media, such as talks, videos, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming
&lt;/h2&gt;

&lt;p&gt;This last week, Jess and I held a soft launch of our streaming with CodeSee! We had a friendly chat as an introduction to open source.&lt;/p&gt;

&lt;p&gt;It was also an opportunity to try out our tech stack. Since this was a soft launch, we did it with Zoom, &lt;a href="https://tech.paulcz.net/blog/streaming-from-zoom-to-twitch/" rel="noopener noreferrer"&gt;streaming onto Twitch&lt;/a&gt;. We were adamant about having captioning on our stream, which &lt;a href="https://support.zoom.us/hc/en-us/articles/207279736-Closed-captioning-and-live-transcription" rel="noopener noreferrer"&gt;Zoom supports as a paid feature&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;We did a &lt;a href="https://twitter.com/hola_soy_milk/status/1385247029224411139" rel="noopener noreferrer"&gt;brief, last minute announcement&lt;/a&gt;  to get some friends and loved ones in and had a great time!&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source
&lt;/h2&gt;

&lt;p&gt;One task I’ve enjoyed greatly during my time at CodeSee is trying our tool on different open source projects. One advantage of doing this is trying the CodeSee tracker on multiple codebases and finding points of improvement.&lt;/p&gt;

&lt;p&gt;On the other hand, I’ve been getting to see the value that we can bring open source maintainers by aiding in the onboarding process of their projects. Heck, by trying to install CodeSee onto a codebase, I’m getting partially onboarded onto these projects! Since this is something that matters a lot to what we’re trying to do at CodeSee, getting this experience first hand has been really valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving forward
&lt;/h2&gt;

&lt;p&gt;Well now that we’re out of stealth, we can start looking into other kinds of activities, such as collaborating with other folks, giving talks, appearing on podcasts, and more!&lt;/p&gt;

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

&lt;p&gt;When talking to folks potentially interested in DevRel, I get the impression that the lucrative nature of the job can be intimidating or seem like an endgoal. My hope is that by sharing my experiences I can show that learning is definitely still involved and to invite you to give it a try!&lt;/p&gt;

&lt;p&gt;Finding the points where I feel the most comfortable, such as empowering fellow devs, trying out sticky open source projects, writing blog posts, coming up with and giving conference talks, or dealing with my impostor syndrome has helped me really work hard on those specific points.&lt;/p&gt;

&lt;p&gt;As I said at the start, working in DevRel has been an absolute joy for me. If you’ve recently started a DevRel position or are interested in doing so, please feel free to reach out!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>career</category>
      <category>community</category>
    </item>
    <item>
      <title>Hosting a Podcast from Scratch</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Sat, 23 Jan 2021 09:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/hosting-a-podcast-from-scratch-i9c</link>
      <guid>https://dev.to/hola_soy_milk/hosting-a-podcast-from-scratch-i9c</guid>
      <description>&lt;p&gt;A few months ago, &lt;a href="https://twitter.com/TimeaTurdean" rel="noopener noreferrer"&gt;Timea&lt;/a&gt; and I started hosting the &lt;a href="https://twitter.com/gendercoffee" rel="noopener noreferrer"&gt;Gender Equality over Coffee&lt;/a&gt; podcast, as part of the &lt;a href="https://www.womentechmakers.at/podcast/" rel="noopener noreferrer"&gt;Women Techmakers Vienna&lt;/a&gt; organisation. It’s been a blast!&lt;/p&gt;

&lt;p&gt;Now that we’ve been at it for a while, I wanted to share how we make this podcast happen. Huge thanks goes out to Jason C. McDonald for &lt;a href="https://dev.to/codemouse92/self-hosting-a-podcast-4b3f"&gt;this very helpful article&lt;/a&gt; and to &lt;a href="https://twitter.com/informatom" rel="noopener noreferrer"&gt;Stefan Haslinger&lt;/a&gt; for all your support!&lt;/p&gt;

&lt;h2&gt;
  
  
  Recording
&lt;/h2&gt;

&lt;p&gt;Right off the bat, Gender Equality over Coffee is a &lt;a href="https://www.youtube.com/watch?v=iCQv8ZI8SAo&amp;amp;list=PLVr4my5fwE_UF4wun_SE11EDyDbg7hmJq" rel="noopener noreferrer"&gt;video podcast&lt;/a&gt;. Recording will therefore involve not only audio, but also video.&lt;/p&gt;

&lt;p&gt;We currently record our episodes on &lt;a href="https://zoom.us/" rel="noopener noreferrer"&gt;Zoom&lt;/a&gt;. The advantages offered by Zoom are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recording of video and audio.&lt;/li&gt;
&lt;li&gt;Guests can join using their Zoom client.&lt;/li&gt;
&lt;li&gt;Zoom is used by loads of folks lately.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Editing
&lt;/h2&gt;

&lt;p&gt;Given we’re dealing with a video podcast, we’re splicing an intro and outtro as well as any tiny edits each episode needs with an open source app called &lt;a href="https://www.openshot.org/" rel="noopener noreferrer"&gt;OpenShot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A way to splice the video clips together making the transitions as seamless as possible is using fade ins and outs: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgny1p217iw8tfmnve4m6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgny1p217iw8tfmnve4m6.png" alt="Screenshot of OpenShot in action, showing how to add fade ins and outs" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting
&lt;/h2&gt;

&lt;p&gt;Using OpenShot, we then export an &lt;code&gt;mp4&lt;/code&gt; or &lt;code&gt;mov&lt;/code&gt; video in the ‘1080p 29.9fps’ format. When we tried exporting in 30fps (frames-per-second) format, the sync would break up. Not sure why this happened, but it was consistent! Switching to the 29.9 option eliminated this issue.&lt;/p&gt;

&lt;p&gt;We can then use an open source app called VLC to &lt;a href="https://www.vlchelp.com/convert-video-audio-mp3/" rel="noopener noreferrer"&gt;convert the exported video file to mp3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once all of that’s exported, we can then upload the video file to YouTube.&lt;/p&gt;

&lt;p&gt;Then comes the audio!&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio file hosting
&lt;/h2&gt;

&lt;p&gt;While we get this podcast off the ground, we’re operating on a volunteer, non-profit basis. Therefore, we’re keeping costs low. One thing I learned from the article posted above is that we can host the episodes for free on &lt;a href="https://archive.org/" rel="noopener noreferrer"&gt;Archive.org&lt;/a&gt;. This allows us to upload and host the&lt;code&gt;mp3&lt;/code&gt; files on their website and link to them from the RSS feed (more on that later 👇).&lt;/p&gt;

&lt;p&gt;After it’s processed, we’ve got access to a direct link.&lt;/p&gt;

&lt;p&gt;Quick note about uploading to Archive.org, however: &lt;strong&gt;It has to be one of CC0, Creative Commons or Public Domain&lt;/strong&gt;. We ended up going with Creative Commons.&lt;/p&gt;

&lt;h2&gt;
  
  
  RSS feed
&lt;/h2&gt;

&lt;p&gt;The great thing about RSS is its format being flexible enough to be expanded upon and dynamically generated!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.womentechmakers.at" rel="noopener noreferrer"&gt;Women Techmakers Vienna&lt;/a&gt; website is built using &lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt;, a static website generator. In our&lt;code&gt;_config.yml&lt;/code&gt; file, we define a episode collection, as well as a general set of podcast metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;collections:
  podcast_episodes:
    output: true
podcast:
  title: Gender Equality Over Coffee
  description: Let's talk intersectional gender equality from the perspective of organizations and individuals that strive for a more inclusive world.
  url: /podcast.xml
  author: Women Techmakers Vienna
  email: wtmvie@gmail.com
  logo: /img/podcast/logo_feed.JPG
  language: en
  category: Business
  subcategory: Non-Profit
  type: episodic
  explicit: false
  complete: 'no'
  block: 'no'

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

&lt;/div&gt;



&lt;p&gt;We can then define podcast episodes inside the &lt;code&gt;_podcast_episodes&lt;/code&gt; folder, write their shownotes using Markdown and metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
layout: podcast
title: 0. The what, who and why of Gender Equality over Coffee
author: Women Techmakers Vienna
isStaticPost: true
image: ../podcast/logo.JPG
episode: 0
episodeType: full
explicit: false
length: 394
date: 2020-12-29
audio: host://url_to_episode.mp3
---

# SHOW NOTES

# TRANSCRIPTION

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

&lt;/div&gt;



&lt;p&gt;You might’ve noticed we’re using a &lt;code&gt;podcast&lt;/code&gt; layout in the above markdown. Well, given that this is Markdown data, we can use it to render the show notes as well as audio player in the website!&lt;/p&gt;

&lt;p&gt;Here’s the layout:&lt;br&gt;
&lt;/p&gt;

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

&amp;lt;br&amp;gt;
&amp;lt;audio controls preload='auto' style='width: 100%;'&amp;gt;&amp;lt;source src='{{ page.audio }}'&amp;gt;&amp;lt;/audio&amp;gt;
{{ content }}

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

&lt;/div&gt;



&lt;p&gt;We use an &lt;code&gt;audio&lt;/code&gt; tag to play the mp3 file! &lt;a href="https://www.womentechmakers.at/podcast_episodes/episode_2.html" rel="noopener noreferrer"&gt;Here’s how it looks in action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Deploying this live gives us &lt;a href="https://www.womentechmakers.at/podcast.xml" rel="noopener noreferrer"&gt;a working RSS feed&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Transcribing
&lt;/h2&gt;

&lt;p&gt;Making a show as accessible as possible was a pretty important goal for us from the outset.&lt;/p&gt;

&lt;p&gt;Below is an example of how the transcripts look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- **TIMEA** : Hey Ramón!
- **RAMÓN** : Hey Timea!
- **TIMEA** : Let's talk gender equality.
- **RAMÓN** : I love the idea. Gimme a second I just gotta grab my coffee, I hope you've got yours, too!
- **TIMEA** : Yep, right here.

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

&lt;/div&gt;



&lt;p&gt;Transcribing can be a lot of work. One very helpful tip we found is, as previously mentioned, we upload our videos on YouTube. One thing I learned is that you can download the automatically generated YouTube subtitles from YouTube Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0543sbrszhi0zi9dmtx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0543sbrszhi0zi9dmtx2.png" alt="Screenshot of YouTube studio, allowing to download subtitles" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then use these as a basis to clean up the transcriptions. These then go into the show notes and the RSS feed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing
&lt;/h2&gt;

&lt;p&gt;Last part is getting the podcast out there into the world! What we can do is submit the podcast to different listings, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://podcastsconnect.apple.com/" rel="noopener noreferrer"&gt;Apple Podcasts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://panoptikum.io/pan/feed_backlogs/new" rel="noopener noreferrer"&gt;Panoptikum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://podcasters.spotify.com/gateway" rel="noopener noreferrer"&gt;Spotify for Podcasters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Up and running!
&lt;/h2&gt;

&lt;p&gt;With that, we’ve been up and going! We just gotta keep at it and let our show evolve and improve over time.&lt;/p&gt;

&lt;p&gt;I hope these tips will help you get up and running. I’d love to hear about what your thoughts and experiences are with creating podcasts. &lt;a href="https://twitter.com/hola_soy_milk" rel="noopener noreferrer"&gt;Hit me up!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>podcast</category>
      <category>jekyll</category>
    </item>
    <item>
      <title>How we did audio/video for our online conference</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Sun, 25 Oct 2020 09:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/how-we-did-audio-video-for-our-online-conference-3i6o</link>
      <guid>https://dev.to/hola_soy_milk/how-we-did-audio-video-for-our-online-conference-3i6o</guid>
      <description>

&lt;h2&gt;
  
  
  title: How we did audio/video for our online conference
&lt;/h2&gt;

&lt;p&gt;published: true&lt;br&gt;
date: 2020-10-25 09:24:00 UTC&lt;br&gt;
tags: womentechmakers, remote, audio, video&lt;br&gt;
canonical_url: &lt;a href="https://ramonh.dev/2020/10/25/running-a-conference-online/" rel="noopener noreferrer"&gt;https://ramonh.dev/2020/10/25/running-a-conference-online/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This year’s &lt;a href="https://www.womentechmakers.at/" rel="noopener noreferrer"&gt;Women Techmakers Vienna&lt;/a&gt; conference was meant to take place in March 2020, but had to be postponed. After three months of monitoring the possibility of holding it later, we as a team decided to hold it online.&lt;/p&gt;

&lt;p&gt;Near the beginning of July 2020, we decided to hold the annual Women Techmakers Vienna conference purely online on the 7th and 8th of August 2020.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doesn’t that make prep time one month?!
&lt;/h3&gt;

&lt;p&gt;One month… ish. We had already made a lot of preparations toward having the conference in March. This included having things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An already setup lineup that we could reach out to in the interest of speaking at our online event&lt;/li&gt;
&lt;li&gt;A list of sponsoring partners that we could update and see if they were interested in partnering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another thing worthy of note is that Women Techmakers Vienna is run by a group of volunteers. It is not a for-profit conference.&lt;/p&gt;

&lt;p&gt;What follows is the story of the series of decisions we made, why we made them, and how they panned out!&lt;/p&gt;

&lt;h2&gt;
  
  
  Audience interaction
&lt;/h2&gt;

&lt;p&gt;One of the critical ingredients of a conference is giving the audience the opportunity to interact with each other, ask questions to speakers, voice concerns, give feedback, chat with partners, and so on!&lt;/p&gt;

&lt;p&gt;Coming up with a plan to provide as satisyfing (not identical!) an experience as possible to in-person events for our attendees meant we looked at how other events that have been run online have been doing this: chat platforms!&lt;/p&gt;

&lt;p&gt;When it comes to giving the audience a platform to interact with one another, asking questions to speakers or approaching partners, we decided to try a centralised approach.&lt;/p&gt;

&lt;p&gt;I’ve been seeing a lot of tech communities pop up on &lt;a href="https://discord.com" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, such as that from &lt;a href="https://queerjs.com/" rel="noopener noreferrer"&gt;Queer.js&lt;/a&gt;, &lt;a href="https://chat.vuejs.org" rel="noopener noreferrer"&gt;Vue.js&lt;/a&gt; or &lt;a href="https://discord.gg/rust-lang" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While Discord might be associated with games, they’ve &lt;a href="https://blog.discord.com/discord-is-for-your-communities-3d14464d4c7b" rel="noopener noreferrer"&gt;recently&lt;/a&gt; adopted a more community-oriented approach.&lt;/p&gt;

&lt;p&gt;It does, however, require having a separate app running from the viewing platform. Say, YouTube or Twitch chat (more on those later).&lt;/p&gt;

&lt;p&gt;So why use Discord instead of…&lt;/p&gt;

&lt;h3&gt;
  
  
  Slack
&lt;/h3&gt;

&lt;p&gt;One big argument is that we already have a Slack server used for organising our activities internally!&lt;/p&gt;

&lt;p&gt;However, unlike Slack, Discord doesn’t require one account (email/password pair) per server. You can have one identity across several servers.&lt;/p&gt;

&lt;p&gt;Furthermore, in the interest of providing a safe, inclusive environment for viewers, Discord allows users to block one another if needed.&lt;/p&gt;

&lt;p&gt;We also appreciated the prominently visible use of &lt;a href="https://support.discord.com/hc/en-us/articles/214836687-Role-Management-101https://support.discord.com/hc/en-us/articles/214836687-Role-Management-101" rel="noopener noreferrer"&gt;roles&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  YouTube/Twitch chat
&lt;/h3&gt;

&lt;p&gt;I’ve lumped these both into the same space due to them having a similar functionality.&lt;/p&gt;

&lt;p&gt;Discord allows us to set up multiple channels, enabling viewers to talk about different topics. That includes being able to do so between the broadcasts.&lt;/p&gt;

&lt;p&gt;We ultimately decided to disable YouTube live chat, so we could focus and encourage people to use Discord.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not have several chat platforms?
&lt;/h3&gt;

&lt;p&gt;We believe that having a unified space for chat would make it easier to bring together the community during the talks. Having this unification meant they were easier to moderate, which is something we had to consider as well when picking Discord.&lt;/p&gt;

&lt;p&gt;We ran the risk of having fewer people join chat overall, but we went with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Won’t the Discord server become a ghost town once the event is over?
&lt;/h3&gt;

&lt;p&gt;I have seen this happen to some event-oriented platforms.&lt;/p&gt;

&lt;p&gt;However, since Women Techmakers Vienna is a yearly-run conference, accompanied by a series of meetups throughout the year, we decided to instead turn it into a community platform. We’ll continue to announce meetups and other events to encourage activity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Voice chat
&lt;/h3&gt;

&lt;p&gt;One thing we thought of leveraging was the built-in voice channels for Discord. Since our event was split over two days, we decided to have a breakfast hangout on the Saturday morning. People could just pop into the voice channel on Discord and hang out! It was a lot of fun.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Platform
&lt;/h2&gt;

&lt;p&gt;We chose to stream our conference on YouTube. Our reasons for this choice include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can embed the stream onto &lt;a href="https://www.womentechmakers.at/" rel="noopener noreferrer"&gt;our website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We can disable the chat completely (as written above, we want to encourage the chat to take place in a single space).&lt;/li&gt;
&lt;li&gt;YouTube allows people to rewind during the broadcast, even while the show is live.&lt;/li&gt;
&lt;li&gt;Once the show is over, the stream is available for viewing immediately thereafter.&lt;/li&gt;
&lt;li&gt;The stream allows us to have a URL we can stream closed captions to (more on that lower down).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Streaming Platform
&lt;/h2&gt;

&lt;p&gt;We ended up going with &lt;a href="https://streamyard.com" rel="noopener noreferrer"&gt;StreamYard&lt;/a&gt; as our streaming platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kcmog9lzuwugy91wdgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kcmog9lzuwugy91wdgs.png" alt="Screenshot of me broadcasting myself on StreamYard" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;StreamYard allows us to set up a broadcast that gets piped directly into YouTube.&lt;/p&gt;

&lt;p&gt;The main video shows what’s currently being broadcast. Below that are the scenes available to us. Scenes in this case are the layouts we can display to viewers. From left to right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single speaker&lt;/li&gt;
&lt;li&gt;Full screen speakers&lt;/li&gt;
&lt;li&gt;Small speakers with background&lt;/li&gt;
&lt;li&gt;Person speaking bigger&lt;/li&gt;
&lt;li&gt;Speaker with shared video&lt;/li&gt;
&lt;li&gt;All speakers with shared video&lt;/li&gt;
&lt;li&gt;Shared video full screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can also have banners of text that either run through or float at the bottom of the screen: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9y8on38lqwb7qgb7ubd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9y8on38lqwb7qgb7ubd.png" alt="Screenshot showing banner saying " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can share slides, screens as well as videos.&lt;/p&gt;

&lt;p&gt;One thing to note is that it’s not free. We ended up paying USD $25 for a month of the service. There are open source alternatives, such as &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS&lt;/a&gt;, but we found that StreamYard was the best choice for us at the time. We could onboard fellow organisers to use it quickly and had I not been able to run A/V for the conference, one of them would’ve taken over.&lt;/p&gt;

&lt;p&gt;Another advantage from using StreamYard is speakers can be given a link to join the stream, without the need to use something like Skype to connect.&lt;/p&gt;

&lt;p&gt;When it comes to sharing pre-recorded content, StreamYard allows us to share a browser tab with the video file loaded in it. Note that this only works on Google Chrome (at least of the time of writing). Closer to the event, StreamYard added the functionality of uploading 5-minute clips, which was helpful for things like partner video reels, but it didn’t provide things like volume control, so we opted for browser tabs for the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talks
&lt;/h2&gt;

&lt;p&gt;For this year, we decided to ask our speakers to please send us a pre-recorded video of their talk.&lt;/p&gt;

&lt;p&gt;The alternative would be to allow speakers to tune in and give their presentation live.&lt;/p&gt;

&lt;p&gt;Let’s go over some of the reasons for having pre-recorded talks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We minimise connection issues. These won’t be completely lost, as of course we still depend on the connection of the person streaming the videos as well as that of the person watching the stream. However, we won’t depend on the connection of each speaker.&lt;/li&gt;
&lt;li&gt;From an organisational standpoint, we will know immediately in advance how long each talk will be, and manage our schedule/breaks accordingly.&lt;/li&gt;
&lt;li&gt;By allowing speakers to pre-record their videos, they can (if they want) add all the post-production flair they want! One example I particularly enjoyed was Michael Jolley’s presentation on &lt;a href="https://www.youtube.com/watch?v=Qcn0GgDlLfk" rel="noopener noreferrer"&gt;living puppets&lt;/a&gt; at &lt;a href="https://halfstackconf.com/" rel="noopener noreferrer"&gt;HalfStack Online 2020&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Newcomers to public speaking have the opportunity to practise, get feedback from us, and see what they can improve (harder said than done. I can barely watch myself on video! 🙈) .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One glaring problem with pre-recorded talks is the loss of interactivity, for sure. I’ve often found myself wondering, if the conference is pre-recorded, what’s stopping me, the viewer from just watching the talks later if/when they’re uploaded? What value can we add to viewers to encourage them to tune in live?&lt;/p&gt;

&lt;p&gt;But there are ways to make it work! For example, speakers can chat with viewers, add links, or even answer questions while their talk is streaming. This is something we actively encouraged.&lt;/p&gt;

&lt;p&gt;We also added a live portion Q&amp;amp;A segment at the end of each talk, where our emcee would chat with the speaker, relay questions, or ask some of their own.&lt;/p&gt;

&lt;p&gt;Lastly, with the remote aspect of the conference, we can open up our CFP to speakers from around the world who wouldn’t normally be able to travel to Vienna to deliver a talk. If they’re in a time zone that would make it impossible for them to join live for one reason or another, they can still provide a talk!&lt;/p&gt;

&lt;p&gt;However, based on my experiences and talking with folks experienced in giving talks, pre-recording talks as a speaker is challenging. That’s a story for the next section, though.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recording the talks
&lt;/h3&gt;

&lt;p&gt;Similar to how &lt;a href="https://futuresync.co.uk/" rel="noopener noreferrer"&gt;Future Sync&lt;/a&gt; instructed their speakers, we recommended that speakers use &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS&lt;/a&gt; to record their talks.&lt;/p&gt;

&lt;p&gt;We asked them to approximate a majority portion at the top left for their slides, and their camera at the bottom right, like in the screenshot below:&lt;/p&gt;

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

&lt;p&gt;Though it worked for the most part, we did encounter some difficulties with the videos. Not all of us are experienced with recording videos, and it’s a very different environment from delivering a talk onstage, since you need to worry about things like microphone, camera, lighting and audio levels/sources on your own.&lt;/p&gt;

&lt;p&gt;Because of these new challenges, we had some issues such as dual audio sources in the videos leading to a strange echoing, as well as full screen issues causing the slides to cover the speakers’ camera feed.&lt;/p&gt;

&lt;p&gt;One thing to bear in mind is that some speakers, given they have the option, might prefer not to show their camera. Come to think of it, especially given we’re providing live captioning, maybe it’s not essential?&lt;/p&gt;

&lt;p&gt;Interestingly, one of our speakers opted for having just their video feed, without any slides. The space is there to be creative! It is, however, important to make sure that the talks are in a format that’s accessible.&lt;/p&gt;

&lt;p&gt;In the future, preparing a screencast they can use or having 1-on-1 sessions with speakers that desire it would be more helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Captions
&lt;/h3&gt;

&lt;p&gt;As soon as we decided the conference was taking place online, we immediately set out to figure out closed captioning. It’s a small step we could take toward having as inclusvive an experience as possible.&lt;/p&gt;

&lt;p&gt;The service we went with was one called &lt;a href="https://whitecoatcaptioning.com/" rel="noopener noreferrer"&gt;White Coat Captioning&lt;/a&gt;. I’ve been fortunate to catch their services at conferences I’ve spoken at or organised, like EuRuKo both in &lt;a href="https://euruko2018.org/" rel="noopener noreferrer"&gt;2018&lt;/a&gt; and &lt;a href="https://euruko2019.org/" rel="noopener noreferrer"&gt;2019&lt;/a&gt;, &lt;a href="https://2019.jsconf.us/" rel="noopener noreferrer"&gt;JSConf US 2019&lt;/a&gt;. They were a no-brainer and so I contacted them.&lt;/p&gt;

&lt;p&gt;What I found out was pretty fascinating! They provide us with a &lt;a href="https://streamtext.net/" rel="noopener noreferrer"&gt;StreamText&lt;/a&gt; URL that attendees could open and follow the captioning provided live. What I later learned though is that with StreamText, you can plug in a &lt;a href="https://support.google.com/youtube/answer/3068031?hl=en" rel="noopener noreferrer"&gt;YouTube Live Subtitle Ingestion URL&lt;/a&gt; and the StreamText content will be automatically carried over to YouTube’s closed captioning system! This gives viewers the option to follow the captions along either with StreamText or directly on YouTube! Neat!&lt;/p&gt;

&lt;h3&gt;
  
  
  Panel discussion
&lt;/h3&gt;

&lt;p&gt;We offered this as an opportunity for folks to have a live Q&amp;amp;A with speakers and/or invited guests. StreamYard allows us to have up to ten guests at a time in the stream, so we were easily able to have six participants in the discussion.&lt;/p&gt;

&lt;p&gt;We did have a technical issue where one of the panelists had the power go out in the town they were living in, but they joined a bit later with a mobile connection. Ultimately, not too stressful for them, thankfully. Phew!&lt;/p&gt;

&lt;h3&gt;
  
  
  Lightning talks
&lt;/h3&gt;

&lt;p&gt;Similar to how we held the panel discussion, we were able to leverage StreamYard and invite 6 people on to give their lightning talks. In order to make things smooth, we held these without slides (so no screensharing).&lt;/p&gt;

&lt;p&gt;Story time: We did have an issue where one speaker couldn’t get their machine to work with StreamYard, something about their browser being incompatible. Some quick thinking led me to try opening Discord on Chrome, starting a video call with them and then sharing that tab and making very sure to be muted, myself. It totally worked! Never hurts to think outside the box. ☺️&lt;/p&gt;

&lt;h2&gt;
  
  
  On the day
&lt;/h2&gt;

&lt;p&gt;Below are some of my thoughts on the day of the conference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Timing is essential! Need a cup of coffee or a trip to the bathroom? Make sure a colleague is there to keep an eye on things.&lt;/li&gt;
&lt;li&gt;Keep a separate tab with the video open so you can see how long until the emcee and speaker will do a Q&amp;amp;A.&lt;/li&gt;
&lt;li&gt;A separate voice chat on Discord with a fellow organiser helps keep you company and a check on things.&lt;/li&gt;
&lt;li&gt;Checklists help! When switching between different scenes (emcee to pre-recorded video) having a procedure for opening the tab, making sure “Share audio” is checked when sharing the tab (This is crucial!!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  After the day
&lt;/h2&gt;

&lt;p&gt;A few things we can improve:&lt;/p&gt;

&lt;h3&gt;
  
  
  Speaker support
&lt;/h3&gt;

&lt;p&gt;We usually hold speaker coaching sessions before the conference. This includes giving feedback on slides, talk structure, and the like.&lt;/p&gt;

&lt;p&gt;I think we can expand on this to provide support on how to pre-record talks, check lighting, audio, and so on!&lt;/p&gt;

&lt;p&gt;With a budget and good timing, we can also help provide equipment, like a microphone. Some speakers ended up using their laptop microphone!&lt;/p&gt;

&lt;h3&gt;
  
  
  Audio level tweaks
&lt;/h3&gt;

&lt;p&gt;When receiving the talks, it’s important that we check them as soon as possible to make sure the audio levels are consistent. Note that this doesn’t mean audio quality! I’m talking about making sure that the volume is consistent so as to make sure that switching from a talk, to the emcee, to a partner video doesn’t startle our viewers!&lt;/p&gt;

&lt;p&gt;Audio levels can be tested by having a colleague watching on a test YouTube stream! This helped us a lot figure out where our weak spots were.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audience Integration
&lt;/h3&gt;

&lt;p&gt;While being at home means that some audience members can relax with a hot drink and enjoy the talks, or have them on a separate screen while working on other stuff, having the option to chat with speakers and fellow attendees is a huge part of the conference experience!&lt;/p&gt;

&lt;p&gt;One thing I found really fun and ingenious from this year’s &lt;a href="https://roguelike.club/event2020.html" rel="noopener noreferrer"&gt;Roguelike Celebration&lt;/a&gt; was their idea to build a &lt;a href="https://dev.to/lazerwalker/using-game-design-to-make-virtual-events-more-social-24o"&gt;game into their event experience&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another thing I noticed was that, having we left our breakfast hangout voice channel open, people were beginning to use it! They’d just hang out there and chat with one another either during talks or in between them! Definitely something to consider.&lt;/p&gt;

&lt;h2&gt;
  
  
  And that was just the A/V portion of the conference!
&lt;/h2&gt;

&lt;p&gt;It goes without saying that these conferences require a lot of work in order to be successful, and I’m so lucky to have a &lt;a href="https://www.womentechmakers.at/team/" rel="noopener noreferrer"&gt;team of volunteers&lt;/a&gt; around me who put so much work into it.&lt;/p&gt;

&lt;p&gt;Hope this helps you when figuring out these aspects! If you’ve got some you wanna tell me about, &lt;a href="https://twitter.com/hola_soy_milk" rel="noopener noreferrer"&gt;let me know&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Running GUI Linux applications in WSL 2</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Wed, 30 Sep 2020 08:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/running-gui-linux-applications-in-wsl-2-3kaf</link>
      <guid>https://dev.to/hola_soy_milk/running-gui-linux-applications-in-wsl-2-3kaf</guid>
      <description>&lt;p&gt;I’ve been really enjoying my time using the Windows Subsystem for Linux, or &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/about" rel="noopener noreferrer"&gt;WSL&lt;/a&gt; for short. With it, I’ve been able to develop web software on Windows with the Linux environment familiar to me.&lt;/p&gt;

&lt;p&gt;One issue I’d been running into, particularly with WSL 2 is that I sometimes need to run GUI applications from inside Ubuntu.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why would you need to run GUI applications in WSL?
&lt;/h2&gt;

&lt;p&gt;Well, one example is running system tests on Rails apps I develop. In my client work, I run &lt;a href="https://github.com/teamcapybara/capybara" rel="noopener noreferrer"&gt;Capybara&lt;/a&gt; using Firefox in headless mode using &lt;a href="https://github.com/mozilla/geckodriver/releases" rel="noopener noreferrer"&gt;geckodriver&lt;/a&gt;, which works great on WSL!&lt;/p&gt;

&lt;p&gt;Problem is, sometimes, I need to do so with headless mode turned off. Maybe some tests are failing, or I just wanna make sure that some layout parts are working well. If I wanted to, running &lt;code&gt;firefox&lt;/code&gt; from within WSL would me the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Unable to init server: Could not connect: Connection refused
  Error: cannot open display: :0

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

&lt;/div&gt;



&lt;p&gt;What’s this display about, then?&lt;/p&gt;

&lt;h2&gt;
  
  
  Xserver
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;display&lt;/code&gt; mentioned above refers to an &lt;a href="https://www.x.org/releases/X11R7.7/doc/man/man1/Xserver.1.xhtml" rel="noopener noreferrer"&gt;Xserver&lt;/a&gt;, used by Linux to manage window, keyboard and mouse interaction with applications.&lt;/p&gt;

&lt;p&gt;I found a tool that does just this for us! I can run an Xserver on Windows called &lt;a href="https://sourceforge.net/projects/xming/" rel="noopener noreferrer"&gt;Xming&lt;/a&gt;, which comes with several utilities to run an Xserver on Windows 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Xming on Windows
&lt;/h2&gt;

&lt;p&gt;After downloading and installing the utility, we can run the Xlaunch utility with the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Multiple windows” selected, display number set to 0&lt;/li&gt;
&lt;li&gt;“Start no client” selected&lt;/li&gt;
&lt;li&gt;“Clipboard” and “No Access Control” selected&lt;/li&gt;
&lt;li&gt;Click on Finish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Xming will now be running in the background!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up WSL for interacting with Xming
&lt;/h2&gt;

&lt;p&gt;We next need to set up the &lt;code&gt;DISPLAY&lt;/code&gt; environment variable to point to our running Xming server. With WSL 1, I could set this to be &lt;code&gt;:0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export DISPLAY=:0

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

&lt;/div&gt;



&lt;p&gt;This, however, won’t work with WSL 2, due to, &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/compare-versions" rel="noopener noreferrer"&gt;among other differences&lt;/a&gt;, it running a Virtual Machine. We can, however, set the IP address to forward this to.&lt;/p&gt;

&lt;p&gt;This is where the discussion on &lt;a href="https://github.com/microsoft/WSL/issues/4106#issuecomment-501532834" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; really came in handy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How are you seeing your DISPLAY variable in your Linux environment? Currently you will need to specify the IP address of the host, you can easily find this by looking at your /etc/resolv.conf file:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@BENHILL-DELL:/mnt/c/Users/benhill# cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 192.168.110.177

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


&lt;p&gt;Then you’ll run:&lt;/p&gt;

&lt;p&gt;export DISPLAY=192.168.110.117:0&lt;/p&gt;

&lt;p&gt;You may also need to launch vcxsrv with the -ac argument.&lt;/p&gt;

&lt;p&gt;This is an area that we are working on improving in an update soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even more helpfully, a poster &lt;a href="https://github.com/microsoft/WSL/issues/4106#issuecomment-501885675" rel="noopener noreferrer"&gt;lower down&lt;/a&gt; suggested the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | \
  awk '{print $2}'):0

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

&lt;/div&gt;



&lt;p&gt;Adding this line to the shell profile (&lt;code&gt;~/.zshrc&lt;/code&gt; in my case) will set it up on every shell instance I start up! If you wanna do it in the current one, you can do so with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ source ~/.zshrc

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

&lt;/div&gt;



&lt;p&gt;Sadly, we’re not done yet. Running &lt;code&gt;firefox&lt;/code&gt; now just causes a big ol’ nothing to happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Windows Firewall
&lt;/h2&gt;

&lt;p&gt;The last step before I was able to run firefox is to allow Xming through the firewall. To do that, we’ll:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open up “Windows Security” (I usually type it into the Start menu)&lt;/li&gt;
&lt;li&gt;Click on the “Firewall &amp;amp; network protection”&lt;/li&gt;
&lt;li&gt;Click on “Allow an app through the firewall”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will show the list of apps and their connection permissions through private and public networks, as shown below:&lt;/p&gt;

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

&lt;p&gt;You need to find “Xming X Server” on this list and make sure it’s allowed (checked) for a public network!&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does Xming need to communicate on public networks?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/windows/wsl/compare-versions#accessing-a-wsl-2-distribution-from-your-local-area-network-lan" rel="noopener noreferrer"&gt;According to the docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WSL 2 has a virtualized ethernet adapter with its own unique IP address.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our WSL instance isn’t connected to the local network directly, but rather through Windows using this virtualized ethernet adapter. It’s as if there was an ethernet cable connected between Ubuntu and Windows.&lt;/p&gt;

&lt;p&gt;This is different from how WSL 1 worked. WSL 2 requires that we setup networking like we would another virtual machine. If you’re curious, &lt;a href="https://www.youtube.com/watch?v=yCK3easuYm4" rel="noopener noreferrer"&gt;this video&lt;/a&gt; offers a good in-depth look at how WSL networking works.&lt;/p&gt;

&lt;p&gt;Once we do this, back in WSL, we can just run &lt;code&gt;firefox&lt;/code&gt;, and voilà, it’s there! Heck, let’s run &lt;code&gt;gedit&lt;/code&gt; too:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folh4oavc4ipa448mscsy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folh4oavc4ipa448mscsy.jpg" alt="Firefox and GEdit running in Windows" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;Well! Shortly before I finished writing all of this down, I found this here &lt;a href="https://twitter.com/craigaloewen/status/1308452901266751488" rel="noopener noreferrer"&gt;tweet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The WSL team is working on getting this feature built in! Soon, it looks like GUI Linux apps will have not only their own taskbar icons, but proper shadowed windows and full compatibility without having to worry about Xservers, firewalls, or anything like that. Thank you so much, WSL team!&lt;/p&gt;

&lt;p&gt;I’m still happy I learned what I learned about Xservers, and until then, you can use GUI apps by doing what I did above!&lt;/p&gt;

&lt;p&gt;Big, big thanks to &lt;a href="https://www.joseforthe.win/" rel="noopener noreferrer"&gt;José&lt;/a&gt; for pairing with me to figure this out!&lt;/p&gt;

</description>
      <category>wsl</category>
      <category>linux</category>
      <category>gui</category>
      <category>xming</category>
    </item>
    <item>
      <title>Granting user read/write permissions to a USB device in Ubuntu Linux on boot</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Tue, 22 Sep 2020 08:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/granting-user-read-write-permissions-to-a-usb-device-in-ubuntu-linux-on-boot-29b2</link>
      <guid>https://dev.to/hola_soy_milk/granting-user-read-write-permissions-to-a-usb-device-in-ubuntu-linux-on-boot-29b2</guid>
      <description>&lt;p&gt;One of my recent projects involved having a cash register print receipts to a thermal printer. In order to do this, we had a &lt;a href="http://sinatrarb.com/" rel="noopener noreferrer"&gt;Sinatra&lt;/a&gt; server running on boot on the device that would, upon receiving a &lt;code&gt;POST&lt;/code&gt; request, print out the &lt;a href="https://github.com/escpos/escpos" rel="noopener noreferrer"&gt;ESC/POS&lt;/a&gt; data.&lt;/p&gt;

&lt;p&gt;The way I did this was by creating a &lt;a href="https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6" rel="noopener noreferrer"&gt;custom service&lt;/a&gt; on Ubuntu that automatically starts on boot that runs the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  $ su - &amp;lt;NON_ROOT_USER&amp;gt; -l -c \
    "cd /path/to/code &amp;amp;&amp;amp; \
    bundle exec ruby app.rb /dev/usb/lp0"

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

&lt;/div&gt;



&lt;p&gt;In this script, we’re passing the file path &lt;code&gt;/dev/usb/lp0&lt;/code&gt; to the server. This is the file descriptor for the thermal printer I wish to print to.&lt;/p&gt;

&lt;p&gt;With all this set, what happens when I power on the device and send in a &lt;code&gt;POST&lt;/code&gt; request?&lt;/p&gt;

&lt;p&gt;Sadly, I get an error saying that I don’t have permission to write to the file&lt;code&gt;/dev/usb/lp0&lt;/code&gt;. I can run the following command to fix this, though:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  $ sudo chown &amp;lt;NON_ROOT_USER&amp;gt; /dev/usb/lp0

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

&lt;/div&gt;



&lt;p&gt;Once I enter it, I can print to my heart’s (and paper capicity’s) content! However, once the device gets rebooted, the file will get re-created and not have the permissions I assigned. Well, darn.&lt;/p&gt;

&lt;p&gt;I did find a solution that could help me, though!&lt;/p&gt;

&lt;h1&gt;
  
  
  Custom udev rules
&lt;/h1&gt;

&lt;p&gt;This was when I learned about &lt;a href="https://wiki.debian.org/udev" rel="noopener noreferrer"&gt;&lt;code&gt;udev&lt;/code&gt;&lt;/a&gt;, the system for managing devices in Debian systems. With it, I can write specific rules for recognising devices:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;udev allows for rules that specify what name is given to a device, regardless of which port it is plugged into. For example, a rule to always mount a hard drive with manufacturer “iRiver” and device code “ABC” as /dev/iriver is possible. This consistent naming of devices guarantees that scripts dependent on a specific device’s existence will not be broken.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is &lt;em&gt;exactly&lt;/em&gt; what I need! I can assign all usb devices plugged into the Linux machine to be owned by &lt;code&gt;NON_ROOT_USER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By following the instructions, I created a file in the directory &lt;code&gt;/etc/udev/rules.d&lt;/code&gt; called &lt;code&gt;99-perm.rules&lt;/code&gt; with the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  SUBSYSTEM=="usb", OWNER="&amp;lt;NON_ROOT_USER&amp;gt;"

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

&lt;/div&gt;



&lt;p&gt;With this rule in place, rebooting the machine immediately made it work!&lt;/p&gt;

&lt;h1&gt;
  
  
  Making it more secure
&lt;/h1&gt;

&lt;p&gt;You might’ve been asking yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this mean all USB devices will be owned by &lt;code&gt;NON_ROOT_USER&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you would be absolutely correct. Maybe we want to only grant permissions for that one device, which we can totally do! We can base it on the serial number of the device. For example, for my thermal printer, I can find this out with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  $ udevadm -a /dev/usb/lp0

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

&lt;/div&gt;



&lt;p&gt;This’ll print out some results, including this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ATTRS{serial}=="L29955839962630040"

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

&lt;/div&gt;



&lt;p&gt;Let’s open up &lt;code&gt;/etc/udev/rules.d/99-perm.rules&lt;/code&gt; again, and replace the line we added with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  SUBSYSTEM=="usb", ATTRS{serial}=="L29955839962630040", OWNER="&amp;lt;NON_ROOT_USER&amp;gt;"

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

&lt;/div&gt;



&lt;p&gt;See with this we’re specifically telling &lt;code&gt;udev&lt;/code&gt; that we wanna own this specific thermal printer. A quick reboot and score, it works!&lt;/p&gt;

&lt;h1&gt;
  
  
  What’s next?
&lt;/h1&gt;

&lt;p&gt;A solid question! There is certainly more we can do to make sure this system works.&lt;/p&gt;

&lt;p&gt;For example, if I were to have multiple thermal printers on a device, then it wouldn’t be guaranteed to have the name &lt;code&gt;lp0&lt;/code&gt;. For this case we can use the&lt;code&gt;SYMLINK+=&lt;/code&gt; attribute to specify a filename it’ll always definitely have. So instead of &lt;code&gt;lp0&lt;/code&gt; or &lt;code&gt;lp1&lt;/code&gt; I could point my script to &lt;code&gt;thermal-printer&lt;/code&gt; or something:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  SUBSYSTEM=="usb", ATTRS{serial}=="L72010011070626380", OWNER="&amp;lt;NON_ROOT_USER&amp;gt;", SYMLINK+="usb/thermal-printer"

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

&lt;/div&gt;



&lt;p&gt;This will then create a &lt;a href="https://en.wikipedia.org/wiki/Symbolic_link" rel="noopener noreferrer"&gt;symbolic link&lt;/a&gt; called &lt;code&gt;/dev/usb/thermal-printer&lt;/code&gt; that I can point my Ruby server to!&lt;/p&gt;

&lt;p&gt;Big thank you to &lt;a href="http://reactivated.net/writing_udev_rules.html" rel="noopener noreferrer"&gt;Daniel Drake&lt;/a&gt; for this helpful guide on how to write rules for &lt;code&gt;udev&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;I’m eager to hear your thoughts or ideas for improvements, so &lt;a href="https://twitter.com/hola_soy_milk" rel="noopener noreferrer"&gt;hit me up on Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>udev</category>
      <category>linux</category>
      <category>usb</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Running a learn together coding group remotely</title>
      <dc:creator>Carmen Huidobro</dc:creator>
      <pubDate>Sat, 13 Jun 2020 08:24:00 +0000</pubDate>
      <link>https://dev.to/hola_soy_milk/running-a-learn-together-coding-group-remotely-f1m</link>
      <guid>https://dev.to/hola_soy_milk/running-a-learn-together-coding-group-remotely-f1m</guid>
      <description>&lt;p&gt;Our coding study group &lt;a href="https://study-jams.github.io" rel="noopener noreferrer"&gt;Study Jams&lt;/a&gt; needed a place online where folks could come together remotely, share and learn together, as we’ve done in person for a number of years.&lt;/p&gt;

&lt;p&gt;Here’s the story of how we managed to make it work!&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a coding study group?
&lt;/h2&gt;

&lt;p&gt;A solid question! What we call a study group has several other names, like ‘Hack and Learn’, or ‘Coffee and Code’, or ‘Learn Together’, and those are just the ones off the top of my head!&lt;/p&gt;

&lt;p&gt;The premise is similar across these, being regularly-held event where people gather, usually in the early evening and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discuss coding side projects&lt;/li&gt;
&lt;li&gt;Chat all things general about coding&lt;/li&gt;
&lt;li&gt;Work on coding side projects&lt;/li&gt;
&lt;li&gt;Get help on from others if you’re stuck on something&lt;/li&gt;
&lt;li&gt;Introduce people or get introduced to programming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At Study Jams, we strongly emphasise how important it is to have a &lt;a href="https://study-jams.github.io/#conduct" rel="noopener noreferrer"&gt;positive, welcoming&lt;/a&gt; community.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed when going remote?
&lt;/h2&gt;

&lt;p&gt;Not being able to meet face to face presented a number of challenges we had to face (sorry). This includes factors like not being able to easily move over to looking at someone’s screen without interrupting others, or having a side conversation with a person one-on-one while still being able to absorb the general flow of the conversation.&lt;/p&gt;

&lt;p&gt;Overall, attending a meetup online is fundamentally different from doing so in person. As my good buddy &lt;a href="https://flak.is/" rel="noopener noreferrer"&gt;Flaki&lt;/a&gt; put it oh-so-well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;…it’s very different not just because the environment is different — but that we ourselves are different, behaving differently!&lt;/p&gt;

&lt;p&gt;💜&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Community dynamics
&lt;/h2&gt;

&lt;p&gt;Keeping in mind that being exclusively online makes it harder for people to directly interact, we need to consider what helps people speak up and/or make the most of hacking together:&lt;/p&gt;

&lt;h3&gt;
  
  
  Catch-up or introduction round
&lt;/h3&gt;

&lt;p&gt;Given that we’re a smaller group (around 4-6 people at a time per session) not a whole lot of introduction to who we are is needed, but some time to catch up since the last session helps get things going. Greasen the wheels, if you will!&lt;/p&gt;

&lt;p&gt;If people would rather not have much to say, that’s fine, naturally! It’s important to impose no pressure.&lt;/p&gt;

&lt;p&gt;I’ve found that having these helps get the conversation and the topics going.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical issues
&lt;/h3&gt;

&lt;p&gt;As online meetings become more prominent through remote work, we all get used to the initial song and dance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Can you hear me?”&lt;/li&gt;
&lt;li&gt;“You’re muted”&lt;/li&gt;
&lt;li&gt;“And &lt;em&gt;bark bork&lt;/em&gt; to your dog, too!”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given the relaxed nature of the learn together event, we were able to push through it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long silences
&lt;/h3&gt;

&lt;p&gt;I’ll admit that I have a bit of a fear of long silences during these kinds of events. When having these in person, I was able to see people just hacking away on their projects. But in an online context, where (I had initially assumed) the primary goal is to talk, I was initially scared of the silences, and tried to keep conversations flowing.&lt;/p&gt;

&lt;p&gt;It wasn’t until I attended my first &lt;a href="http://berline.rs/" rel="noopener noreferrer"&gt;Hack and Learn&lt;/a&gt; that I noticed how similar these silences were to their in-person equivalents. It was reassuring even, to know we were all just hacking on our own thing!&lt;/p&gt;

&lt;h3&gt;
  
  
  Enforcing the Code of Conduct
&lt;/h3&gt;

&lt;p&gt;Moderation is key to enforceability during online events. Having a volunteer to help me moderate, and be outside of the core organisers helps keep us accountable.&lt;/p&gt;

&lt;p&gt;Furthermore, reminding folks of the existence of said code of conduct at the beginning of a coding session, having it be immediately visible on the website and having a popup reminding folks of its existence when joining a session are a few of the ways ways we can make it visible and more importantly make it clear that we take it seriously.&lt;/p&gt;

&lt;p&gt;If you’re wondering why it’s necessary to have a code of conduct, &lt;a href="https://www.ashedryden.com/blog/codes-of-conduct-101-faq#coc101why" rel="noopener noreferrer"&gt;here’s&lt;/a&gt; a few reasons written far better than I could have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaborative notetaking
&lt;/h2&gt;

&lt;p&gt;One big takeaway I had from visiting the online editions of the &lt;a href="http://berline.rs/" rel="noopener noreferrer"&gt;Berlin Rust community’s Hack and Learn&lt;/a&gt; events is the concept of taking notes to keep track of what was brought up and links shared during the meetup. One thing that blew me away was that they kept a link to the previous session’s notes!&lt;/p&gt;

&lt;p&gt;This serves the purpose of letting folks follow along at their own pace and keep these for later, but what I found myself doing was also going through the older note sets of previous events and seeing what was shared there too! Very handy.&lt;/p&gt;

&lt;p&gt;The following is a breakdown of the options for this that we’ve dabbled with:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://hackmd.io" rel="noopener noreferrer"&gt;HackMD&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;HackMD is a tool for collaborative markdown writing. We were able to use it to share link, code and other resources in real time as we spoke about different topics. The app is open source and can be self-hosted, but they have a free storage plan for open teams, which we are!&lt;/p&gt;

&lt;p&gt;Just because we are a tech-oriented study group, however, doesn’t mean we can assume people will be proficient or familiar with Markdown. This is where the rich text editing options come in handy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdp04ax4r074u5kojboq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdp04ax4r074u5kojboq.jpg" alt="Checkin' out HackMD" width="750" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watching the text update itself as people chime in with links to resources or projects of theirs is incredibly gratifying.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.google.com" rel="noopener noreferrer"&gt;Google Docs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Right off the bat, I’ll say we didn’t try Google Docs, but it being one of the most-used tools for this led us to consider it as an option.&lt;/p&gt;

&lt;p&gt;The familiarity of a text-processing environment coupled with the ability to do so in a collaborative way made it an interesting venue. Big concern for us was that not everyone has a Google account.&lt;/p&gt;

&lt;p&gt;Turns out, though, that you can view and edit Google Docs &lt;a href="https://support.google.com/drive/thread/12552865?hl=en&amp;amp;msgid=12639250" rel="noopener noreferrer"&gt;without an account&lt;/a&gt;, so there’s that!&lt;/p&gt;

&lt;p&gt;We ultimately settled on HackMD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voice/Video Chat
&lt;/h2&gt;

&lt;p&gt;One of the most commonly seen media used for online meetups is using video chat, in the format of each user having a camera and a microphone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswqsyrsmjoxy4hpjf1ps.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswqsyrsmjoxy4hpjf1ps.jpg" alt="Screenshot showing a test of all online platforms we toyed with running simultaneously" width="750" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ALL the platforms!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As shown in the above image, we had quite the experiment! We were jumping around a whole bunch of these, which I’ll go over now:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://meet.jit.si/" rel="noopener noreferrer"&gt;Jitsi Meet&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Real quick, we opted not to try out Zoom, due in part to security issues that come with its ubiquity (&lt;a href="https://en.wikipedia.org/wiki/Zoombombing" rel="noopener noreferrer"&gt;Zoombombing&lt;/a&gt; comes to mind as an example), and the fact that we had a local Jitsi instance available to us, thanks to &lt;a href="https://twitter.com/informatom" rel="noopener noreferrer"&gt;Stefan&lt;/a&gt;, one of our dedicated members, and his generosity!&lt;/p&gt;

&lt;p&gt;Jitsi is an alternative to Zoom, allowing us to have video chats with screensharing on the fly. A few reasons we were drawn to it include it being open source software, and having our video chats be fully encrypted!&lt;/p&gt;

&lt;p&gt;The way this works is by using a browser API called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API" rel="noopener noreferrer"&gt;WebRTC&lt;/a&gt;, short for Web Real-Time Communication. This allows a Jitsi server to set up the connection, but the actual transfer of data only takes place between the video chats, without the server acting as an intermediary.&lt;/p&gt;

&lt;p&gt;This being a WebRTC technology also affords Jitsi the feature of having any number of chat rooms. The URL of the room creates that room dynamically, meaning that room will exist provided there’s at least one user in that call. After that, poof! It’s gone. It also allows us as moderators to enable a room only once a moderator comes in. This also prevents abuse.&lt;/p&gt;

&lt;p&gt;This same advantage however becomes its caveat. There were some issues getting the implementation of WebRTC on Firefox, which is &lt;a href="https://github.com/jitsi/jitsi-meet/issues/4758" rel="noopener noreferrer"&gt;being worked on&lt;/a&gt;. At the time of writing, users on Firefox can access Jitsi meetings, but Stefan noticed some increased loads coming from those users.&lt;/p&gt;

&lt;p&gt;I haven’t experienced this myself, as our meetings tend not to exceed 10 people, but there would appear to be a &lt;a href="https://community.jitsi.org/t/maximum-number-of-participants-on-a-meeting-on-meet-jit-si-server/22273/3" rel="noopener noreferrer"&gt;limitation of 75 people per room&lt;/a&gt;, though this is on Jitsi’s server itself. Not just that, but as shown in the link here, the experience starts to suffer with 35. Something to bear in mind!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpv1l02svdzxj9s2b03i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpv1l02svdzxj9s2b03i.jpg" alt="Screenshot showing 6 people (+ dog!) chatting in Jitsi" width="750" height="433"&gt;&lt;/a&gt;&lt;em&gt;Complete with a snoozing Fionna!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Something that Zoom provides that’s been pretty successfuly during meetups however is the concept of breakout rooms, where people are randomly assigned a room during a break with a handful of folks to chat to. This can in theory be done with Jitsi, but requires some manual room assignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://hubs.mozilla.com/" rel="noopener noreferrer"&gt;Mozilla Hubs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Brought to you by Mozilla, it’s Hubs!&lt;/p&gt;

&lt;p&gt;I could go over what Hubs is, but who better to explain than &lt;a href="https://hubs.mozilla.com/docs/welcome.html" rel="noopener noreferrer"&gt;the Hubs team themselves&lt;/a&gt;! In their own words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hubs is a social VR platform that runs right in your browser. With Hubs you can create your own virtual space with a single click and invite others to join using a URL. No installation process or app store required.&lt;/p&gt;

&lt;p&gt;Watch videos with friends, give presentations, or meet with colleagues remotely. Hubs makes it easy to connect with others and share images, videos, 3D models, and more.&lt;/p&gt;

&lt;p&gt;Hubs works across platforms. Got a VR headset? Awesome! If not, you can use your desktop computer, laptop, tablet, or mobile device.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essentially, we can use Hubs to set up a room where folks can come in and hang out, but in 3D! Folks with most kinds of devices can join in and chat!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqau46wwbqt6h8sb1b1k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqau46wwbqt6h8sb1b1k.jpg" alt="4 cool cats hanging out in hubs" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having these nice avatars means we can roam with as much anonymity as we want. We can also use objects in 3D space imported from &lt;a href="https://hubs.mozilla.com/docs/spoke-adding-scene-content.html" rel="noopener noreferrer"&gt;3D modelling environments&lt;/a&gt; to enable screen sharing, or… webcam sharing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc5jxr6a1bpcar0y0w3r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc5jxr6a1bpcar0y0w3r.jpg" alt="Screenshot of hubs with my face hovering in the sky, as someone's Santa Claus avatar watches my face" width="750" height="381"&gt;&lt;/a&gt;&lt;em&gt;As you can see, Santa felt my presence.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I very much appreciated the Hubs team’s &lt;a href="https://hubs.mozilla.com/docs/intro-events.html" rel="noopener noreferrer"&gt;tips&lt;/a&gt; on running successful events, such as &lt;a href="https://discord.com/" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; (A community chat/voice/gaming platform) server integration, setting it up with your code of conduct, and more.&lt;/p&gt;

&lt;p&gt;Another factor that’s makes Hubs an extremely interesting choice is it aims to solve a big problem with most video chat services as a concept.&lt;/p&gt;

&lt;p&gt;See, at an in-person meetup if you like you can easily have side-conversations by taking folks aside to talk to them. This doesn’t work in environments like Jitsi, though, because everyone talks at the same volume, no exceptions nor possibilities for side conversations. We could perhaps set up side rooms, but the action of moving from one conversation to another naturally is kind of lost.&lt;/p&gt;

&lt;p&gt;That’s where the Hubs comes in with spatialised voice chat!&lt;/p&gt;

&lt;h4&gt;
  
  
  What is spatialised voice chat?
&lt;/h4&gt;

&lt;p&gt;Unlike video conferences, where it’s expected that only one person can talk at a time, spatialised voice chat involves making the sound come from (and be as loud as) the position of the person’s avatar is at the time. If someone is far away from you, you’ll hear their voice more faintly than you would right next to you.&lt;/p&gt;

&lt;p&gt;Hubs has this feature from the get-go making it a breeze to have this kind of voice chat.&lt;/p&gt;

&lt;p&gt;Trying this out as an experiment was so much fun! I can imagine it would have been even moreso with a VR headset, which we didn’t happen to have, so I don’t have first hand experience from within the group!&lt;/p&gt;

&lt;p&gt;When it came to using Hubs as a space to do social coding, that’s when we came upon a couple of sticking points.&lt;/p&gt;

&lt;p&gt;One thing that I hadn’t considered moving into this kind of a 3D space, especially in a laptop/desktop browser where you’re expected to navigate said 3D space, is that these controls aren’t immediately familiar to someone who’s relatively new to the concept. Don’t get me wrong, this has nothing to do with the on-screen instructions or documentation, &lt;a href="https://hubs.mozilla.com/docs/intro-hubs.html" rel="noopener noreferrer"&gt;on the contrary&lt;/a&gt;, they do a terrific job of giving you a primer to navigate the 3D space!&lt;/p&gt;

&lt;p&gt;Problem is that this requires a certain amount of time to become familiar with the concept of navigating a 3D space, from a first-person perspective, even! We spent some time trying to drive home the idea that someone could not see what their avatar looked like because they were looking at the world in Hubs through the eyes of their avatar, for example.&lt;/p&gt;

&lt;p&gt;Furthermore, maybe ironically seeing as I just mentioned the wonders of spatialised voice chat, we did find ourselves wondering many times if we could just set a general volume for everybody and disable the spatialised one. This was mostly due to the fact that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We’re a small group&lt;/li&gt;
&lt;li&gt;We wanted to play around with Hubs’ features off to the side, but found that if we were on the other side of the map spawning rubber duckies, we weren’t able to hear each other!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://theonline.town/" rel="noopener noreferrer"&gt;The Online Town&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This platform was brought up during my first attendance of &lt;a href="http://berline.rs" rel="noopener noreferrer"&gt;Berlin’s Rust Hack and Learn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When we were playing around with Hubs a few weeks later somebody said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is there a 2D version of this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That reminded me, this is exactly what Online Town aims to do!&lt;/p&gt;

&lt;p&gt;This is a free service that allows you to set up free rooms to have spatialised chats!&lt;/p&gt;

&lt;p&gt;Similar to how Hubs does it, you have an avatar (with fewer options for customisation). You then walk around a 2D world and chat with each other!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F846jlskdzhipczjrecwq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F846jlskdzhipczjrecwq.jpg" alt="Screenshot of the four of us hanging out in Online Town, showing our webcams and avatars" width="695" height="617"&gt;&lt;/a&gt;&lt;em&gt;Now with faces to match the avatars!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One strong difference you might notice with Hubs is that from Online Town right away allows folks to show their webcams. It creates a border around each avatar and the webcame to help distinguish which avatar is speaking.&lt;/p&gt;

&lt;p&gt;As previously mentioned, Online Town has spatialised chat. This extends not only to the voice chat, but also the video chat! The further you move from an avatar, the more faint the video feed becomes, like they’re fading away! Their voice becomes more distant as well.&lt;/p&gt;

&lt;p&gt;The immediate advantage here for people who are less familiar with navigating a 3D space is that the onboarding process is a lot quicker. The top-down viewing angle of the characters helps folks understand where they are relative to others.&lt;/p&gt;

&lt;p&gt;Online Town made it really easy for us to break off and have separate conversations and even keep background ones if we wanted to. Having fewer “toys” than in Mozilla Hubs kept us focused (though this is not really an issue, as we were experimenting!).&lt;/p&gt;

&lt;p&gt;The one major caveat I found in using Online Town for the purposes of shared learning is that there is currently no option for screen sharing. Given that it’s a fairly new platform however, I’m confident more will come! In a way, it already seems to be happening with &lt;a href="https://gather.town/" rel="noopener noreferrer"&gt;Gather&lt;/a&gt;, an initiative that was “spun off” from Online Town.&lt;/p&gt;

&lt;p&gt;In hindsight though, given that we were a small group (the 4 pictured above) the question then became…&lt;/p&gt;

&lt;h2&gt;
  
  
  Do we really need spatialised chat at a small group size?
&lt;/h2&gt;

&lt;p&gt;This became a sticky question.&lt;/p&gt;

&lt;p&gt;I’m not saying we didn’t, but it did start coming up when it was only around 4 people in a learn together environment. I think this’ll be different when we try learning together in a bigger group size! For the rest of our day of experimentation, we stuck to Jitsi.&lt;/p&gt;

&lt;h2&gt;
  
  
  What other options are there that came up?
&lt;/h2&gt;

&lt;p&gt;A few that we didn’t get around to:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/capnmidnight/Calla" rel="noopener noreferrer"&gt;Calla&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Calla is a plugin for Jitsi Meet servers that offer a service not unlike Online Town’s, where folks can do spatialised chat! We didn’t get around to trying it, as it would have had to be installed, but it looked promising. If it’s developed on top of Jitsi Meet, it probably supports screensharing, too! Will have to investigate.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://visualstudio.microsoft.com/services/live-share/" rel="noopener noreferrer"&gt;Visual Studio Code Live Share&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This just casually came up during the Rust Berlin “Hack and Learn” and it blew my mind. We were using Online Town and somebody brought up an issue they were having with their code. When they realised Online Town didn’t have screensharing, they just opened up a Live Share instance on their VS Code.&lt;/p&gt;

&lt;p&gt;It was amazing! We were able to connect, almost like we were screen sharing, except from the “comfort” of our code editors. Soon, you won’t even need to have VS code installed, because &lt;a href="https://docs.microsoft.com/en-us/visualstudio/liveshare/quickstart/browser-join" rel="noopener noreferrer"&gt;they’re working on a browser version!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This isn’t all that new as a concept, sure, &lt;a href="https://www.redhat.com/sysadmin/ssh-tmux-screen-sharing" rel="noopener noreferrer"&gt;it can be done with a terminal and tmux&lt;/a&gt;, which works great for my Vim key fingers, but having it built into one of the most popular text editors opens things up a whole bunch!&lt;/p&gt;

&lt;p&gt;With this kind of editor sharing, one major part of the need for screen sharing is reduced! Would it be completely gone? No. We’d still need it for sharing things like websites, reading docs, giving presentations, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;When we started out as a study group in person, a few of us preferred to spend most of the time rockin’ some headphones and being around people while they hacked on their stuff. Others wanted to relax, have a coffee, and see how they could help folks get unstuck in their coding. Or others just wanted to hang out and talk tech or community. Being around people working on their stuff can be a huge motivator!&lt;/p&gt;

&lt;p&gt;We hope replicate this experience in an online fashion. Have we figured it out and have a perfect recipe, now that we’ve been at it for a few months?&lt;/p&gt;

&lt;p&gt;Absolutely not.&lt;/p&gt;

&lt;p&gt;What I’ve learned during this time is that this tech and environment is still at a fledgling stage. There’s lots to try and learn. Some of it might stick, some of it might not. Some of it will work wonders for some groups, but not for others. It’s important to try stuff out!&lt;/p&gt;

&lt;p&gt;Yo, I’d love to hear about what your thoughts and experiences are with doing hack togethers online. &lt;a href="https://twitter.com/hola_soy_milk" rel="noopener noreferrer"&gt;Hit me up&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>remote</category>
      <category>meetups</category>
      <category>mozillahubs</category>
    </item>
  </channel>
</rss>
