<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Packt on Medium]]></title>
        <description><![CDATA[Stories by Packt on Medium]]></description>
        <link>https://medium.com/@packt?source=rss-8ef58ed680e6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*L8u32r1Pch73FDT5pfR8tg.png</url>
            <title>Stories by Packt on Medium</title>
            <link>https://medium.com/@packt?source=rss-8ef58ed680e6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 17 Jun 2026 21:09:52 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@packt/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Top 5 Tech Reads from the Packt Christmas Sale]]></title>
            <link>https://packt.medium.com/top-5-tech-reads-from-the-packt-christmas-sale-b2ec612e0df4?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/b2ec612e0df4</guid>
            <category><![CDATA[developer]]></category>
            <category><![CDATA[tech-books]]></category>
            <category><![CDATA[publishing]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Fri, 10 Dec 2021 16:39:48 GMT</pubDate>
            <atom:updated>2021-12-10T16:39:48.364Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8zgL7M7_b4qVvgRvKjIuFg.png" /></figure><p>How does a small pre-Christmas celebration sound?</p><p>This year, Packt is stepping into Santa’s shoes with our Amazon Christmas Sale running through 19th December. This comes just in time if you’re looking to build your knowledge before the year ends and enter 2022 with a completely transformed skillset.</p><p>We’ve pulled together a list of our 5 most exciting titles featured in the sale covering everything from web and game development to programming and security — written by industry experts who are the best at what they do!</p><p>Ready to learn from the best and give 2021 your best shot?</p><p>Here are our top 5 titles you should be sure to check out…</p><ol><li><strong>Adversarial Tradecraft in Cybersecurity</strong></li></ol><p>You won’t go wrong with security in your organization if you read this one!<em> Adversarial Tradecraft in Cybersecurity </em>comes packed with industry standard techniques and countermeasures to help protect your organization from live hackers, along with providing tips and tricks all along the kill chain of an attack. What makes it stand out is its unique approach to teaching. Each chapter features two subsections, which explain the concepts from the perspective of both offensive and defensive teams. In the end, you’ll be ready to confidently tackle real-time cybersecurity conflict!</p><p><a href="https://packt.link/No5Q8">https://packt.link/No5Q8</a></p><blockquote><strong>Reviewer quote </strong>— <em>“This book is an excellent primer on modern adversarial cybersecurity principles.”</em> <a href="https://www.amazon.com/gp/customer-reviews/RGMCCNN6VKQ59/ref=cm_cr_dp_d_rvw_ttl?ie=UTF8&amp;ASIN=1801076200">J. Flay, July 2021</a></blockquote><p><strong>2. Flutter Cookbook</strong></p><p>This book is a comprehensive guide to Flutter, written by bestselling authors Simone Alessandria, a trainer (MCT), speaker, and passionate software architect, and Brian Kayfitz, who has over 10 years’ mobile development experience, ranging from small start-ups to industry-leading corporations with billions in revenue. <em>Flutter Cookbook’s</em> recipes cover several key areas, from establishing concepts of state management in Flutter and animating your applications to implementing machine learning with Firebase and ML Kit and making your apps run faster using asynchronous programming. Expect to work on applications not just for mobile, but also for desktop and the web! <br> <br><a href="https://packt.link/Cm02L">https://packt.link/Cm02L</a></p><blockquote><strong>Reviewer quote </strong>— <em>“Anyone interested in developing Flutter applications for Android or iOS should have a copy of this book on their desk. It has 100s of great examples. But more importantly, the authors explain the “whys” behind each of the features they discuss”. </em>Paulsm, October 2021</blockquote><p><strong>3. Data Science Projects with Python, Second Edition</strong></p><p>Looking for more than just data science theory? Want hands-on experience of modern data science and machine learning techniques through a realistic end-to-end case study? This new and improved second edition of<em> Data Science Projects with Python </em>builds on the success of the original, with extra content, updated code, and improvements based on reader feedback! The book adopts a project-based approach that promotes problem solving and exploration. Practical exercises will walk you through key concepts, while challenging end-of-chapter activities will give you a chance to apply your new skills to solve real-world problems. It’s the ideal way to build your knowledge, skills, and confidence as an aspiring data scientist.</p><p><a href="https://packt.link/VELVr">https://packt.link/VELVr</a></p><blockquote><strong>Reviewer quote </strong>— <em>“Running through this book from front to back is like having a great co-worker who’s done it all before — it takes you through what questions you should be asking to get you to the point that you understand what to do next, then shows you the code that makes it happen”.</em> <a href="https://www.amazon.com/gp/profile/amzn1.account.AGF3RFXS3FT6UI3BMIFCZRKHDZUQ/ref=cm_cr_arp_d_gw_btm?ie=UTF8">Ken F,</a> October 2021</blockquote><p><strong>4. Transformers for Natural Language Processing</strong></p><p>Reading <em>Transformers for Natural Language Processing will</em> save you significant time and energy by combining everything you need to know about NLP &amp; transformers in one book! This transformers book goes beyond the architecture of transformers and into the world of usage, where you’ll learn how to actually build, train, fine-tune, and implement transformers. Before you know it, you’ll be applying these models to NLP tasks such as document summarization and semantic analysis like a professional.</p><p><a href="https://packt.link/o99TX">https://packt.link/o99TX</a></p><blockquote><strong>Reviewer quote</strong> —<strong> </strong><em>“This is a great book for anyone new to the subject of deep learning applied to AI. The author goes to great lengths to explain each topic in sufficient detail to understand it.”</em> <a href="https://www.amazon.com/gp/profile/amzn1.account.AGF4ZM374UMKYGENUU543CQQJRKQ/ref=cm_cr_dp_d_gw_tr?ie=UTF8">Pedro V. Marcal,</a> February 2021</blockquote><p><strong>5. Mastering Microsoft Endpoint Manager</strong></p><p><em>Mastering Microsoft Endpoint Manager</em> covers the latest on Microsoft endpoint management, deployment and security tips for Windows 11 and Windows 365 Cloud PCs. If you like challenges, this book is a great way to learn by testing your knowledge using mock questions in every chapter. You’ll be guided by authors Christiaan Brinkhoff and Per Larsen who have substantial experience managing physical endpoints and traditional virtual desktop infrastructures. This is one of the top books that every IT professional should have on their shelf!</p><p><a href="https://packt.link/vRcyr">https://packt.link/vRcyr</a></p><blockquote><strong>Reviewer quote </strong>— “<em>If you’re an IT administrator or any other industry professional with the task of managing and deploying devices (both virtual and physical) this is THE must have book!”</em> Briand Sanderson, October 2021</blockquote><p>Why wait to celebrate until Christmas? Get these top 5 titles and more at up to 25% off before 19th December exclusively on amazon.com and amazon.co.uk!</p><p><strong>Shop US Sale </strong><a href="https://packt.link/LBkz3">https://packt.link/LBkz3</a></p><p><strong>Shop UK Sale</strong> <a href="https://packt.link/nZ8aF">https://packt.link/nZ8aF</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b2ec612e0df4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use Semaphores in POSIX Concurrency Control]]></title>
            <link>https://packt.medium.com/how-to-use-semaphores-in-posix-concurrency-control-144c34549807?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/144c34549807</guid>
            <category><![CDATA[multithreading]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[object-oriented]]></category>
            <category><![CDATA[concurrency]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Wed, 09 Jun 2021 11:45:15 GMT</pubDate>
            <atom:updated>2021-07-21T12:32:19.268Z</atom:updated>
            <content:encoded><![CDATA[<h4>Concept of the semaphore and its counterpart object in the pthread library: the POSIX semaphore, with an example.</h4><p>Concurrency simply means having multiple pieces of logic within a program being executed simultaneously. Modern software systems are often concurrent, as programs need to run various pieces of logic at the same time. Concurrency can be implemented using only one of the multithreading or multi-processing approaches within a <strong>POSIX compliant system</strong>.</p><p>We are going to have a look at possible control mechanisms that are offered by the pthread library. Semaphores, mutexes, and condition variables alongside different types of locks are used in various combinations to bring determinism to multithreaded programs. This article is focused on Semaphores — the difference between Binary and General Semaphores and how it helps preserve Data Integrity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*erkReNwov76YhhaLHmQZRg.jpeg" /></figure><p><em>This article is an excerpt from the book </em><a href="https://www.amazon.com/Extreme-Taking-Concurrency-advanced-capabilities/dp/1789343623?maas=maas_adg_38A735FB3ADB930E1A3456F1AAB2B7ED_afap_abs&amp;ref_=aa_maas"><strong><em>Extreme C by Kamran Amini</em></strong></a><em>. This book is a highly comprehensive resource that guides you through the most advanced capabilities of C programming.</em></p><h3><strong>POSIX Semaphores</strong></h3><p>In most cases, mutexes (or <em>binary semaphores</em>) are enough to synchronize several threads accessing a shared resource. That is because, in order to make read and write operations sequentially, only one thread should be able to enter the critical section at a time. It is known as <em>mutual exclusion</em>, hence, <em>“mutex.”</em> In some scenarios, however, you might want to have more than one thread to enter the critical section and operate on the shared resource. This is the scenario in which you should use <em>general semaphores.</em></p><p><strong>Binary semaphores</strong></p><p>The following code is the solution made using semaphores. It involves two threads; each of them incrementing a shared integer by a different value. We want to protect the data integrity of the shared variable. Note that we won’t be using POSIX mutexes in the following code:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;</pre><pre>// The POSIX standard header for using pthread library<br>#include &lt;pthread.h&gt;</pre><pre>// The semaphores are not exposed through pthread.h<br>#include &lt;semaphore.h&gt;</pre><pre>// The main pointer addressing a semaphore object used<br>// to synchronize the access to the shared state.<br>sem_t *semaphore;</pre><pre>void* thread_body_1(void* arg) {<br>   // Obtain a pointer to the shared variable<br>   int* shared_var_ptr = (int*)arg;<br>   // Waiting for the semaphore<br>   sem_wait(semaphore);<br>   // Increment the shared variable by 1 by writing directly<br>   // to its memory address<br>  (*shared_var_ptr)++;<br>   printf(&quot;%d\n&quot;, *shared_var_ptr);<br>   // Release the semaphore<br>   sem_post(semaphore);<br>   return NULL;<br>}</pre><pre>void* thread_body_2(void* arg) {<br>   // Obtain a pointer to the shared variable<br>   int* shared_var_ptr = (int*)arg;<br>   // Waiting for the semaphore<br>   sem_wait(semaphore);<br>   // Increment the shared variable by 1 by writing directly<br>   // to its memory address<br>   (*shared_var_ptr) += 2;<br>   printf(&quot;%d\n&quot;, *shared_var_ptr);<br>   // Release the semaphore<br>   sem_post(semaphore);<br>   return NULL;<br>}<br>int main(int argc, char** argv) {<br>   // The shared variable<br>   int shared_var = 0;</pre><pre>// The thread handlers<br>   pthread_t thread1;<br>   pthread_t thread2;</pre><pre>#ifdef __APPLE__<br>   // Unnamed semaphores are not supported in OS/X. Therefore<br>   // we need to initialize the semaphore like a named one using<br>   // sem_open function.<br>   semaphore = sem_open(&quot;sem0&quot;, O_CREAT | O_EXCL, 0644, 1);<br>#else<br>   sem_t local_semaphore;<br>   semaphore = &amp;local_semaphore;<br>   // Initiliaze the semaphore as a mutex (binary semaphore)<br>   sem_init(semaphore, 0, 1);<br>#endif</pre><pre>   // Create new threads<br>   int result1 = pthread_create(&amp;thread1, NULL,<br>       thread_body_1, &amp;shared_var);<br>   int result2 = pthread_create(&amp;thread2, NULL,<br>       thread_body_2, &amp;shared_var);<br>   <br>   if (result1 || result2) {<br>       printf(&quot;The threads could not be created.\n&quot;);<br>       exit(1);<br>   }<br>   // Wait for the threads to finish<br>   result1 = pthread_join(thread1, NULL);<br>   result2 = pthread_join(thread2, NULL);<br>   <br>   if (result1 || result2) {<br>      printf(&quot;The threads could not be joined.\n&quot;);<br>      exit(2)<br>   }</pre><pre>#ifdef __APPLE__<br>   sem_close(semaphore);<br>#else<br>   sem_destroy(semaphore);<br>#endif</pre><pre>   return 0;<br>}</pre><p>The first thing you might notice in the preceding code is the different semaphore functions that we’ve used in Apple systems. In Apple operating systems (macOS, OS X, and iOS), <em>unnamed semaphores</em> are not supported. Therefore, we couldn’t just use sem_init and sem_destroy functions. Unnamed semaphores don’t have names (surprisingly enough) and they can only be used inside a process, by a number of threads. Named semaphores, on the other hand, are system-wide and can be seen and used by various processes in the system.</p><p>In Apple systems, the functions required for creating unnamed semaphores are marked as deprecated, and the semaphore object won’t get initialized by sem_init. So, we had to use sem_open and sem_close functions in order to define named semaphores instead.</p><p>In other POSIX-compliant operating systems, Linux specifically, we still can use unnamed semaphores and have them initialized and destroyed by using the sem_init and sem_destroy functions respectively.</p><p>In the preceding code, we have included an extra header file, semaphore.h. Inside the main function, and in Apple systems, we create a named semaphore sem0. In other POSIX-compliant operating systems, we initialize the semaphore using sem_init. Note that in this case, the pointer semaphore points to the variable local_sempahore allocated on top of the main thread’s Stack. The pointer semaphore won’t become a dangling pointer because the main thread doesn’t exit and waits for the threads to get complete by joining them.</p><p>The maximum number of threads that are allowed to be in the critical section is determined when initializing the semaphore object. We have passed the value 1 for the maximum number of threads as the last argument to the sem_open and sem_init functions; therefore, the semaphore is supposed to behave like a mutex.</p><p>To get a better understanding of semaphores, let’s dive a bit more into the details. Each semaphore object has an integer value. Whenever a thread waits for a semaphore by calling the sem_wait function if the semaphore’s value is greater than zero, then the value is decreased by 1 and the thread is allowed to enter the critical section. If the semaphore’s value is 0, the thread must wait until the semaphore’s value becomes positive again. Whenever a thread exits the critical section by calling the sem_post function, the semaphore’s value is incremented by 1. Therefore, by specifying the initial value 1, we will eventually get a <strong>binary semaphore.</strong></p><h4><strong>General semaphores</strong></h4><p>Here we shall consider a classic example that uses general semaphores. Here the scenario in which multiple threads are allowed to enter the critical section is interesting.</p><p>This <strong>classic example</strong> involves the creation of 50 water molecules. For 50 water molecules, you need to have 50 oxygen atoms and 100 hydrogen atoms. If we simulate each atom using a thread, we require two hydrogen threads, and one oxygen thread to enter their critical sections, in order to generate one water molecule and have it counted.</p><p>In the following code, we firstly create 50 oxygen threads and 1 00 hydrogen threads. For protecting the oxygen thread’s critical section, we use a mutex, but for the hydrogen threads’ critical sections, we use a general semaphore that allows two threads to enter the critical section simultaneously.</p><p>For signaling purposes, we use POSIX barriers, but since barriers are not implemented in Apple systems, we need to implement them using mutexes and condition variables. The following is the code:</p><pre>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;limits.h&gt;<br>#include &lt;errno.h&gt; // For errno and strerror function<br>// The POSIX standard header for using pthread library<br>#include &lt;pthread.h&gt;<br>// Semaphores are not exposed through pthread.h<br>#include &lt;semaphore.h&gt;<br>#ifdef __APPLE__<br>// In Apple systems, we have to simulate the barrier<br>functionality.<br>pthread_mutex_t barrier_mutex;<br>pthread_cond_t barrier_cv;<br>unsigned int barrier_thread_count;<br>unsigned int barrier_round;<br>unsigned int barrier_thread_limit;</pre><pre>void barrier_wait(){<br>    pthread_mutex_lock(&amp;barrier_mutex);<br>    barrier_thread_count++;<br>    if (barrier_thread_count &gt;= barrier_thread_limit) {<br>       barrier_thread_count = 0;<br>       barrier_round++;<br>       pthread_cond_broadcast(&amp;barrier_cv);<br>    } else {<br>       unsigned int my_round = barrier_round;<br>       do {<br>           pthread_cond_wait(&amp;barrier_cv, &amp;barrier_mutex);<br>       } while (my_round == barrier_round);<br>    }<br>    pthread_mutex_unlock(&amp;barrier_mutex);<br>}<br>#else<br>// A barrier to make hydrogen and oxygen threads synchronized<br>pthread_barrier_t water_barrier;<br>#endif</pre><pre>// A mutex in order to synchronize oxygen threads<br>pthread_mutex_t    oxygen_mutex;<br>// A general semaphore to make hydrogen threads synchronized<br>sem_t*             hydrogen_sem;<br>// A shared integer counting the number of made water molecules<br>unsigned int       num_of_water_molecules;<br>void* hydrogen_thread_body(void* arg) {<br>    // Two hydrogen threads can enter this critical section<br>    sem_wait(hydrogen_sem);<br>    // Wait for the other hydrogen thread to join<br>#ifdef __APPLE__<br>    barrier_wait();<br>#else<br>    pthread_barrier_wait(&amp;water_barrier);<br>#endif<br>    sem_post(hydrogen_sem);<br>    return NULL;<br>}</pre><pre>void* oxygen_thread_body(void* arg) {<br>    pthread_mutex_lock(&amp;oxygen_mutex);  <br>    // Wait for the hydrogen threads to join<br>#ifdef __APPLE__<br>    barrier_wait();<br>#else<br>    pthread_barrier_wait(&amp;water_barrier);<br>#endif<br>    num_of_water_molecules++;<br>    pthread_mutex_unlock(&amp;oxygen_mutex);<br>    return NULL;<br>}<br>int main(int argc, char** argv) {</pre><pre>    num_of_water_molecules = 0;</pre><pre>    // Initialize oxygen mutex<br>    pthread_mutex_init(&amp;oxygen_mutex, NULL);<br>    // Initialize hydrogen semaphore<br>#ifdef __APPLE__<br>    hydrogen_sem = sem_open(“hydrogen_sem”,<br>             O_CREAT | O_EXCL, 0644, 2);<br>#else<br>    sem_t local_sem;<br>    hydrogen_sem = &amp;local_sem;<br>    sem_init(hydrogen_sem, 0, 2);<br>#endif</pre><pre>    // Initialize water barrier<br>#ifdef __APPLE__<br>    pthread_mutex_init(&amp;barrier_mutex, NULL);<br>    pthread_cond_init(&amp;barrier_cv, NULL);<br>    barrier_thread_count = 0;<br>    barrier_thread_limit = 0;<br>    barrier_round = 0;<br>#else<br>    pthread_barrier_init(&amp;water_barrier, NULL, 3);<br>#endif</pre><pre>    // For creating 50 water molecules, we need 50 oxygen atoms and<br>    // 100 hydrogen atoms<br>    pthread_t thread[150];<br>    // Create oxygen threads<br>    for (int i = 0; i &lt; 50; i++) {<br>        if (pthread_create(thread + i, NULL,<br>            oxygen_thread_body, NULL)) {<br>        printf(“Couldn’t create an oxygen thread.\n”);<br>        exit(1);<br>        }<br>    }<br>    // Create hydrogen threads<br>    for (int i = 50; i &lt; 150; i++) {<br>        if (pthread_create(thread + i, NULL,<br>            hydrogen_thread_body, NULL)) {<br>        printf(“Couldn’t create an hydrogen thread.\n”);<br>        exit(2);<br>        }<br>    }<br>    printf(“Waiting for hydrogen and oxygen atoms to react …\n”);<br>    // Wait for all threads to finish<br>    for (int i = 0; i &lt; 150; i++) {<br>        if (pthread_join(thread[i], NULL)) {<br>            printf(“The thread could not be joined.\n”);<br>            exit(3);<br>        }<br>    }<br>    printf(“Number of made water molecules: %d\n”,<br>        num_of_water_molecules);<br>#ifdef __APPLE__<br>    sem_close(hydrogen_sem);<br>#else<br>    sem_destroy(hydrogen_sem);<br>#endif</pre><pre>    return 0;<br>}<br></pre><p>At the beginning of the code, there are several lines that are surrounded by #ifdef __APPLE__ and #endif. These lines are only compiled in Apple systems. These lines are mainly the implementation and variables required for simulating POSIX barrier behavior. In other POSIX-compliant systems other than Apple, we use an ordinary POSIX barrier.</p><p>As part of several global variables defined in the preceding code, we have declared the mutex oxygen_mutex which is supposed to protect the oxygen threads’ critical sections. At each time, only one oxygen thread (or oxygen atom) can enter the critical section.</p><p>Then in its critical section, an oxygen thread waits for two other hydrogen threads to join and then it continues to increment the water molecule counter. The increment happens within the oxygen’s critical section.</p><p>To elaborate more on the things that happen inside the critical sections, we need to explain the role of the general semaphore. In the preceding code, we have also declared the general semaphore, hydrogen_sem which is supposed to protect hydrogen threads’ critical sections. At each time, only a maximum of two hydrogen threads can enter their critical sections, and they wait on the barrier object shared between the oxygen and hydrogen threads.</p><p>When the number of waiting threads on the shared barrier object reaches two, it means that we have got one oxygen and two hydrogens, and then voilà: a water molecule is made, and all waiting threads can continue. Hydrogen threads exit immediately, but the oxygen thread exists only after incrementing the water molecules counter.</p><p>We close this section with this last note. In this example, we used the pthread_cond_broadcast function when implementing the barriers for Apple systems. It signals all threads, waiting on the barrier’s condition variable, that are supposed to continue after having other threads joining them.</p><h3><strong>Summary:</strong></h3><p>Concurrency is an important aspect of programming and maintaining data integrity is the key. In this article, we explored the general semaphore as a part of thread synchronization in multi-threaded programming. Further, we explored POSIX condition variables to wait for a specific condition, various types of locks together with mutexes and condition variables, the memory structure of a thread and how this structure can affect memory visibility in a multi-core system and much more…</p><h3><strong>About the author:</strong></h3><p><strong>Kamran Amini </strong>is a senior professional specialized in embedded and kernel development. He has worked for numerous Iranian well-known companies. In 2017, he moved to Europe to work as a senior architect and engineer for highly reputable companies such as Jeppesen, Adecco, TomTom, and ActiveVideo Networks. While residing in Amsterdam, he worked on his first book, <a href="https://github.com/PacktPublishing/Extreme-C">Extreme C</a>, published by PacktPub. His main areas of interest are computation theory, distributed systems, machine learning, information theory, and quantum computation. Parallel to his professional career, he is studying Astronomy and Planetary sciences.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=144c34549807" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Role of Declaration Files in the Implementation of TypeScript]]></title>
            <link>https://medium.com/javarevisited/role-of-declaration-files-in-the-implementation-of-typescript-3a0108633c10?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/3a0108633c10</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[tutorial]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Thu, 20 May 2021 10:56:31 GMT</pubDate>
            <atom:updated>2021-05-20T11:40:17.664Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this article, we will look at how we can enhance a JavaScript library and add syntactic sugar through declaration files.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Gd7CqojdkuCTEpqSWjv7oQ.jpeg" /></figure><p>One of the most appealing facets of <strong>JavaScript</strong> development is the wealth of external JavaScript libraries that have already been published, are tried and tested, and are available for re-use.</p><blockquote>This article is an excerpt from the book, <a href="https://www.amazon.com/Mastering-TypeScript-enterprise-ready-applications-frameworks/dp/1800564732?tag=javamysqlanta-20"><strong>Mastering TypeScript, 4th Edition</strong></a> by Nathan Rozentals — A comprehensive guide to understand TypeScript language and its latest features.</blockquote><h3>Declaration files</h3><p>A declaration file is a special type of file used by the TypeScript compiler. It is only used during the compilation step and is used as a sort of reference file to describe JavaScript. Declaration files are similar to the header files used in <a href="https://medium.com/javarevisited/10-best-c-programming-courses-for-beginners-2c2c1f6bcb12">C</a> or <a href="https://medium.com/javarevisited/top-10-courses-to-learn-c-for-beginners-best-and-free-4afc262a544e">C++</a> or the interfaces used in <a href="https://medium.com/javarevisited/top-5-java-online-courses-for-beginners-best-of-lot-1e1e240a758">Java</a>. They simply describe the structure of available functions and properties but do not provide an implementation. In this section of the chapter, we will take a look at these declaration files, what they are, and how to write them.</p><h3>Declaration file typing</h3><p>As we know, declaration files use the <em>declare </em>and <em>module </em>keywords to define objects and namespaces. We have also seen that we can use interfaces in the same way that we do within <a href="https://medium.com/javarevisited/top-10-free-typescript-courses-to-learn-online-best-of-lot-44bce9da41d1">TypeScript</a>, in order to define custom types for variables. Declaration files allow us to use the same syntax that we would in TypeScript to describe types. These types can be used everywhere types are used in normal TypeScript, including function overloading, type unions, classes, and optional properties. Let’s take a quick look at these techniques, with a few simple code samples, to illustrate this feature further. This section will cover:</p><ul><li>Function overloading</li><li>Nested namespaces</li><li>Classes</li><li>Static properties and functions</li><li>Abstract classes</li><li>Generics</li><li>Conditional types and inference</li></ul><p>We’ll begin by taking a look at function overloading.</p><h3>Function overloading</h3><p>Declaration files allow for function overloads, where the same function can be declared with different arguments, as follows:</p><pre>declare function trace(arg: string | number | boolean);<br>declare function trace(arg: { id: number; name: string });</pre><p>Here, we have a function named trace that is declared twice: once with a single parameter named arg, of type string or number or boolean, and once with the same arg parameter, which is a custom type. This overloaded declaration allows for all of the following valid code:</p><pre>trace(“trace with string”);<br>trace(true);<br>trace(1);<br>trace({ id: 1, name: “test” });</pre><p>Here, we have exercised the various combinations of arguments that are allowed by our function overrides.</p><h3>Nested namespaces</h3><p>Declaration files allow for module names to be nested. This in turn translates to nested namespaces, as follows:</p><pre>declare module FirstNamespace {<br>   module SecondNamespace {<br>      module ThirdNamespace {<br>          function log(msg: string);<br>      }<br>   }<br>}</pre><p>Here, we have declared a module named FirstNamespace that exposes a module named SecondNamespace, which in turn exposes a third module named ThirdNamespace. The ThirdNamespace module defines a function named log. This declaration will result in all three namespaces needing to referenced in order to call the log function, as follows:</p><pre>FirstNamespace.SecondNamespace.ThirdNamespace.log(“test”);</pre><p>Here, we are explicitly referencing each named namespace in order to call the log function within the ThirdNamespace module.</p><h3>Classes</h3><p>Class definitions are specified in module definitions using the class keyword, as it would be in normal TypeScript files, as follows:</p><pre>declare class MyModuleClass {<br>   public print(): void;<br>}</pre><p>Here, we have declared a class named MyModuleClass that has a public print function that returns void. This class definition can then be used as follows:</p><pre>let myClass = new MyModuleClass();<br>myClass.print();</pre><p>Here, we are creating an instance of the MyModuleClass class that has been declared in our declaration file. We then are calling the print function of the class instance named myClass.</p><p>Declaring a class in a declaration file is very similar to defining an interface for it. We do not provide any implementations of the functions, we are only declaring to the TypeScript compiler that the class exists and what properties and functions are available to it.</p><h3>Static properties and functions</h3><p>In the same manner that we can mark a property or function as static in <a href="https://medium.com/javarevisited/7-best-courses-to-learn-typescript-in-depth-58439e1ce729">TypeScript</a>, we can use the same syntax in a declaration file, as follows:</p><pre>declare class MyModuleStatic {<br>    static print(): void;<br>    static id: number;<br>}</pre><p>Here, we have declared a class named MyModuleStatic that has a static print function and a static id property. We can use these static properties and functions as follows:</p><pre>MyModuleStatic.id = 10;<br>MyModuleStatic.print();</pre><p>Here, we can see that the declaration of a static function or property follows the same usage rules as if we had defined it in <a href="https://javarevisited.blogspot.com/2018/07/top-5-courses-to-learn-typescript.html#axzz5QyVwWVg3">TypeScript</a>.</p><h3>Abstract classes</h3><p>Declaration files can define <a href="https://javarevisited.blogspot.com/2013/05/difference-between-abstract-class-vs-interface-java-when-prefer-over-design-oops.html">abstract classes</a> and functions as follows:</p><pre>declare abstract class MyModuleAbstract {<br>    abstract print(): void<br>}</pre><p>Here, we have defined an abstract class named MyModuleAbstract that has a single function named print that has also been marked as abstract. We can use this abstract class declaration in a TypeScript file as follows:</p><pre>class DerivedFromAbstract extends MyModuleAbstract {<br>    print() { }<br>}</pre><p>Here, we have defined a class named DerivedFromAbstract that extends the MyModuleAbstract class from our declaration file.</p><blockquote>Note that we will also need to provide an implementation of the print function within this class definition, as the print function has been marked as an abstract function in the class declaration.</blockquote><h3>Generics</h3><p>Declaration files allow generic syntax to be used, as follows:</p><pre>declare function sort&lt;T extends number | string&gt;<br>    (input: Array&lt;T&gt;): Array&lt;T&gt; { }</pre><p>Here, we are declaring a function named sort that is using generic syntax to specify the type of T to be either a number or a string, or both. This sort function has a single parameter named input that is an array of type T and returns an array of type T. This declaration will allow the following usage:</p><pre>let sortedStringArray = sort([“first”, “second”]);<br>let sortedNumericArray = sort([1, 2, 3]);</pre><p>Here, we have defined a variable named sortedStringArray to hold the return value of a call to the sort function, where we pass in an array of strings as the only argument. The type of the sortedStringArray variable will be Array&lt;string&gt;. Next, we define a variable named sortedNumericArray to hold the return value of another call to the sort function, where we pass in an array of numbers as the only argument. The sortedNumericArray variable will be of type Array&lt;number&gt;.</p><h3>Conditional types</h3><p>Declaration files can also define conditional types and distributed conditional types, as follows:</p><pre>declare type stringOrNumberOrBoolean&lt;T&gt; =<br>    T extends string ? string :<br>    T extends number ? number :<br>    T extends boolean ? boolean : never;</pre><p>Here, we have declared a type named stringOrNumberOrBoolean that is using generic syntax to define a type of T. If T extends string, then the type will be string. If T extends number, then the type will be number. If the type of T extends boolean, then the type will be boolean. If T does not extend any of these types, then the type will be never.</p><p>We can now use this distributed conditional type as follows:</p><pre>type myNever = stringOrNumberOrBoolean&lt;[string,number]&gt;;</pre><p>Here, we have defined a type named myNever that is the result of the distributed conditional type named stringOrNumberOrBoolean, and has defined a type of T as a tuple of string and number. As this tuple does not match any of the types we are checking for, the type of the myNever variable will be never.</p><h3>Conditional type inference</h3><p>Declaration files allow for conditional type inference, as can be seen from the following example:</p><pre>declare type inferFromPropertyType&lt;T&gt; =<br>    T extends { id: infer U } ? U : never;</pre><p>Here, we have a type named inferFromPropertyType that will infer the type named U from the property named id of the type T. If the id property does not exist, then the type will be never. We can now use this type as follows:</p><pre>type myString = inferFromPropertyType&lt;{ id: string }&gt;;<br>type myNumber = inferFromPropertyType&lt;{ id: number }&gt;;</pre><p>Here, we have defined two types, named myString and myNumber, that are using the inferred conditional type named inferFromPropertyType. As the type of the id property is a string in the first line, then myString will be of type string. The type of the id property in the second line of code is number, and therefore myNumber will be of type number.</p><h3>Declaration file summary</h3><p>What we have seen in this article is that the type rules and typing techniques that TypeScript provides can all be used within declaration files. The purpose of a declaration file is to tell the TypeScript compiler ahead of time what the structure of a JavaScript library looks like. We have seen that we can use all of the TypeScript keywords and language features within a declaration file.</p><h3>About the author</h3><p><strong>Nathan Rozentals</strong> has been writing commercial software for over 30 years, in <a href="https://medium.com/javarevisited/9-free-c-programming-courses-for-beginners-2486dff74065">C</a>, <a href="https://medium.com/javarevisited/10-best-c-and-c-programming-books-for-beginners-and-experienced-programmers-eb5ee8dbdc5a">C++</a>, <a href="https://medium.com/javarevisited/10-free-courses-to-learn-java-in-2019-22d1f33a3915">Java</a>, and <a href="https://medium.com/javarevisited/9-free-c-c-sharp-courses-and-tutorials-for-beginners-and-intermediate-programmers-best-of-lot-dc8c793aab31?source=---------16------------------">C#</a>. He picked up TypeScript within a week after its initial release in October 2012 and realized how much TypeScript could help when writing JavaScript.</p><p>Nathan’s TypeScript solutions now control User Interfaces in IoT devices, run as stand-alone applications for Point-of-Sale solutions, provide complex application configuration websites, and are used for mission-critical server APIs.</p><blockquote>This article is an excerpt from the book, <a href="https://www.amazon.com/Mastering-TypeScript-enterprise-ready-applications-frameworks/dp/1800564732?tag=javamysqlanta-20"><strong>Mastering TypeScript, 4th Edition</strong></a> by Nathan Rozentals — A comprehensive guide to understand TypeScript language and its latest features. If you like the article then you will love the book too.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3a0108633c10" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/role-of-declaration-files-in-the-implementation-of-typescript-3a0108633c10">Role of Declaration Files in the Implementation of TypeScript</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Essential Statistics for Data Assessment]]></title>
            <link>https://packt.medium.com/essential-statistics-for-data-assessment-4f47d9cf03e9?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/4f47d9cf03e9</guid>
            <category><![CDATA[statistics]]></category>
            <category><![CDATA[data-analysis]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Tue, 11 May 2021 14:35:35 GMT</pubDate>
            <atom:updated>2021-05-22T01:20:21.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*afxbCjegWYvjRJandFAbAg.png" /></figure><p>In this article we are going to learn about <strong>essential statistics </strong>for data assessment, also often referred to as <strong>descriptive statistics</strong>. Descriptive statistics provide simple, quantitative summaries of datasets, usually combined with graphics. As we shall shortly see, they can demonstrate the tendency to centralization, provide measures of the variability of features, and much more besides.</p><p>Note that there is another kind of statistics, known as <strong>inferential statistics</strong>, which tries to learn information from the distribution of the population that the dataset was generated or sampled from. Here, we assume the data covers a whole population rather than a subset sampled from a distribution.</p><p>The topics we shall cover include:</p><ul><li>Classifying numerical and categorical variables</li><li>Understanding mean, median, and mode</li><li>Learning about variance, standard deviation, percentiles, and skewness</li><li>Knowing how to handle categorical variables and mixed data types</li><li>Using bivariate and multivariate descriptive statistics.</li></ul><p>Practical examples are provided using Python, which is probably the most popular programming language for data science.</p><h3><strong>Classifying numerical and categorical variables</strong></h3><p>Descriptive statistics are all about <strong>variables</strong>. You must know what you are describing to define corresponding descriptive statistics.</p><p>A variable is sometimes referred to as a <strong>feature </strong>or <strong>attribute </strong>in other literature. They all mean the same thing: a single column in a tabulated dataset.</p><p>In this section, you will examine the two most important variable types, <strong>numerical </strong>and <strong>categorical</strong>, and learn to distinguish between them. Categorical variables are <em>discrete </em>and usually represent a classification property of an item. Numerical variables are <em>continuous </em>and are descriptive quantitatively. Descriptive statistics that can be applied to one kind of variable may not be applicable to the other kind, and hence distinguishing between them precedes analytics.</p><h4><strong>Distinguishing between numerical and categorical variables</strong></h4><p>To understand the differences between the two types of variables, I will use the example of the population estimates dataset released by the United States Department of Agriculture. It contains the estimated population data at county level for the United States from 2010 to 2018. You can obtain the data from the official website, <a href="https://www.ers.usda.gov/data-products/county-level-data-sets/download-data/">https://www.ers.usda.gov/data-products/county-level-data-sets/download-data/</a>.</p><p>The following Python code snippet loads the data and examines the first several rows:</p><pre>import pandas as pd<br>df = pd.read_excel(&quot;PopulationEstimates.xls&quot;,skiprows=2)<br>df.head(8)</pre><p>The output is a table with more than 140 columns. Here is a screenshot showing the beginning columns:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/598/1*UcYYymtrREITJ2lgq_GVDg.png" /><figcaption><strong>Figure 1 - First 6 columns of the dfad() output</strong></figcaption></figure><p>In the dataset there is a variable called <em>Rural-urban_Continuum Code_2013</em>. It takes integer values. This leads to pandas auto-interpreting this variable; pandas auto-interprets it as numerical. Instead, however, the variable is actually categorical.</p><blockquote><strong>Should you always trust libraries?</strong></blockquote><blockquote>Don’t always trust the functions that Python libraries give you. They may be wrong, and the developer, who is you, has to make the final decision.</blockquote><p>After some research, we found the variable description on this page: <a href="https://www.ers.usda.gov/data-products/rural-urban-continuum-codes/">https://www.ers.usda.gov/data-products/rural-urban-continuum-codes/</a>.</p><p>According to the code standard published in 2013, the <em>Rural-urban_Continuum_Code_2013 </em>variable indicates how urbanized an area is.</p><p>The meaning of Rural-urban_Continuum Code_2013 is shown in Figure 2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/1*doRk9A6w20Cvb7RsXZdhdA.png" /><figcaption><strong>Figure 2 - Interpretation of Rural-urban_Continuum Code_2013</strong></figcaption></figure><blockquote><strong>Note</strong></blockquote><blockquote>Pandas makes intelligent auto-interpretations of variable types, but oftentimes it is wrong. It is up to the data scientist to investigate the exact meaning of the variable type and then change it.</blockquote><p>Many datasets use integers to represent categorical variables. Treating them as numerical values may result in serious consequences in terms of downstream tasks such as machine learning, mainly because artificial <em>distances </em>between numerical values will be introduced.</p><p>On the other hand, numerical variables often have a <em>direct </em>quantitative meaning. For example, R_NET_MIG_2013 means the rate of net immigration in 2013 for a specific area. A histogram plot of this numerical variable gives a more descriptive summary of immigration trends in the States, but it makes little sense plotting the code beyond simple counting.</p><p>Let’s check the net immigration rate for the year 2013 with the following code snippet:</p><pre>plt.figure(figsize=(8,6))<br>plt.rcParams.update({&#39;font.size&#39;: 22})<br>plt.hist(df[&quot;R_NET_MIG_2013&quot;],bins=np.linspace(np.nanmin(df[&quot;R_<br>NET_MIG_2013&quot;]),np.nanmax(df[&quot;R_NET_MIG_2013&quot;]),num=100))<br>plt.title(&quot;Rate of Net Immigration Distribution for All<br>Records, 2013&quot;);</pre><p>The result appears as follows.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/1*xHeqMHkkyyfgmdMrnwjgTw.png" /><figcaption><strong>Figure 3 - Distribution of the immigration rate for all records in datasets</strong></figcaption></figure><p>Here are the observations drawn from <em>Figure 3</em>:</p><ul><li>With both categorical and numerical variables, structures can be introduced to construct special cases. A typical example is <em>date </em>or <em>time</em>. Depending on the scenario, date and time can be treated as either a categorical variable or as a numerical variable with a semi-continuous structure.</li><li>It is common to convert numerical variables to categorical variables on the basis of a number of rules. The rural-urban code is a typical example. Such a conversion is easy for conveying a first impression.</li></ul><p>Now that we have learned how to distinguish between numerical and categorical variables, let’s move on to understanding a few essential concepts of statistics, namely mean, median, and mode.</p><h3>Understanding mean, median, and mode</h3><p>Mean, median, and mode describe aspects of the <em>central tendency</em>. Mean and median are only applicable to numerical variables, whereas mode is applicable to both categorical and numerical variables. In this section, we will focus on mean, median, and mode for numerical variables, as their numerical interactions usually convey interesting information.</p><h4>Mean</h4><p>Mean, or arithmetical mean measures the <em>weighted center </em>of a variable. Let’s use <em>n </em>to denote the total number of entries and as the index. The mean is given by the following expression:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/97/1*5vPdyNST4vejShMjOFVGCQ.png" /></figure><p>Mean is influenced by the value of every entry in the population.</p><p>Let me give an example. The following code generates 1,000 random numbers from 0 to 1 uniformly, plots them, and calculates their mean:</p><pre>import random<br>random.seed(2019)<br>plt.figure(figsize=(8,6))<br>rvs = [random.random() for _ in range(1000)]<br>plt.hist(rvs, bins=50)<br>plt.title(&quot;Histogram of Uniformly Distributed RV&quot;);</pre><p>The resulting histogram plot appears as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/467/1*GlNZ97uaYaIklVEIq0pKxA.png" /><figcaption><strong>Figure 4 - Histogram distribution of uniformly distributed variables between 0 and 1</strong></figcaption></figure><p>The mean is around 0.505477, pretty close to what we’d expect.</p><h4><strong>Median</strong></h4><p>Median measures the <em>unweighted center </em>of a variable. If there is an odd number of entries, the median takes the value of the central one. If there is an even number of entries, the median takes the value of the mean of the central two entries. The median may not be influenced by every entry’s value. On account of this property, the median is more <em>robust </em>or <em>representative </em>than the mean value. I will use the same set of entries as in previous sections as an example.</p><p>The following code calculates the median:</p><pre>np.median(rvs)</pre><p>The result is 0.5136755026003803. Now, I will be changing one entry to 1,000, which is 1,000 times larger than the maximal possible value in the dataset, and repeat the calculation:</p><pre>rvs[-1]=1000<br>print(np.mean(rvs))<br>print(np.median(rvs))</pre><p>The results are 1.5054701085937803 and 0.5150437661964872. The mean increased by roughly 1, but the median is robust.</p><p>The relationship between mean and median is usually interesting and worth investigating. Usually, the combination of a larger median and smaller mean indicates that there are more points on the bigger value side, but that an extremely small value also exists. The reverse is true when the median is smaller than the mean. We will demonstrate this with some examples later.</p><p><strong>Mode</strong></p><p>The mode of a set of values is the most frequent element in a set. It is evident in a histogram plot such that it represents the peak(s). If the distribution has only one mode, we call it unimodal. Distributions with two peaks that don’t have to have equal heights are referred to as bimodal.</p><blockquote><strong>Bimodals and bimodal distribution</strong></blockquote><blockquote>Sometimes, the definition of bimodal is corrupted. The property of being <strong>bimodal </strong>usually refers to the property of having two modes, which, according to the definition of mode, requires the same height of peaks. However, the term <strong>bimodal distribution </strong>often refers to a distribution with two local maxima. Double-check your distribution and state the modes clearly.</blockquote><p>The following code snippet demonstrates two distributions with unimodal and bimodal shapes respectively:</p><pre>r1 = [random.normalvariate(0.5,0.2) for _ in range(10000)]<br>r2 = [random.normalvariate(0.2,0.1) for _ in range(5000)]<br>r3 = [random.normalvariate(0.8,0.2) for _ in range(5000)]</pre><pre>fig, axes = plt.subplots(1,2,figsize=(12,5))<br>axes[0].hist(r1,bins=100)<br>axes[0].set_title(&quot;Unimodal&quot;)<br>axes[1].hist(r2+r3,bins=100)<br>axes[1].set_title(&quot;Bimodal&quot;);</pre><p>The resulting two subplots look as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/1*NysItW7lBFdEi9HHhlyF0w.png" /><figcaption><strong>Figure 5 - Histogram of unimodal and bimodal datasets with one mode and two modes</strong></figcaption></figure><p>So far, we have talked about mean, median, and mode, which are the first three statistics of a dataset. They are the start of almost all exploratory data analysis.</p><h3><strong>Learning about variance, standard deviation, quartiles, percentiles, and skewness</strong></h3><p>In the previous section, we studied the mean, median, and mode. They all describe, to a certain degree, the properties of the central part of the dataset. In this section, we will learn how to describe the <em>spreading </em>behavior of data.</p><p><strong>Variance</strong></p><p>Using the same notation, variance for the population is defined as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/144/1*rjB6BQpGCT-AWjEM34rhjg.png" /></figure><p>Intuitively, the further away the elements are from the mean, the larger the variance. Here, I’ve plotted the histogram of two datasets with different variances. The one in the left sub-plot has a variance of 0.09 and the one in the right sub-plot has a variance of 0.009, i.e. 10 times smaller.</p><p>The following code snippet generates samples from the two distributions and plots them:</p><pre>r1 = [random.normalvariate(0.5,0.3) for _ in range(10000)]<br>r2 = [random.normalvariate(0.5,0.1) for _ in range(10000)]</pre><pre>fig, axes = plt.subplots(1,2,figsize=(12,5))<br>axes[0].hist(r1,bins=100)<br>axes[0].set_xlim([-1,2])<br>axes[0].set_title(&quot;Big Variance&quot;)<br>axes[1].hist(r2,bins=100)<br>axes[1].set_title(&quot;Small Variance&quot;)<br>axes[1].set_xlim([-1,2]);</pre><p>The results are as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/565/1*mkGpShJm-VkCpAwwEdOoDQ.png" /><figcaption><strong>Figure 6 - Big and small variances with the same mean at 0.5</strong></figcaption></figure><p>The following code snippet generates a scatter plot that will demonstrate the difference more clearly. The variable on the <em>x </em>axis spreads more widely:</p><pre>plt.figure(figsize=(8,8))<br>plt.scatter(r1,r2,alpha=0.2)<br>plt.xlim(-1,2)<br>plt.ylim(-1,2)<br>plt.xlabel(&quot;Big Variance Variable&quot;)<br>plt.ylabel(&quot;Small Variance Variable&quot;)<br>plt.title(&quot;Variables With Different Variances&quot;);</pre><p>The result looks as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/457/1*RbwndTzyn93H9zWcrpyhqA.png" /><figcaption><strong>Figure 7 - Scatter plot of large-variance and small-variance variables</strong></figcaption></figure><p>The spread in the <em>x </em>axis is significantly larger than the spread in the <em>y </em>axis, which indicates the differences in variance magnitude. A common mistake is not getting the range correct. Matplotlib will, by default, try to determine the ranges. You need to use a code such as plt.xlim() to force it, otherwise the result can be misleading.</p><h4><strong>Standard deviation</strong></h4><p>Standard deviation is the square root of the variance. It is used more commonly to measure the level of dispersion since it has the same unit as the original data. The formula for the standard deviation of a population is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/172/1*8FpiFqP6yTHgdb1aGSbo2g.png" /></figure><p>Standard deviation is extremely important in scientific graphing. A standard deviation is often plotted together with the data, and represents an estimate of variability.</p><p>For this article, I will be using the net immigration rate for Texas from 2011 to 2018 as an example. In the following code snippet, I will first extract the county-level data, append the means and standard deviations to a list, and then plot them at the end. The standard deviation is obtained using numpy.std() and the error bar is plotted using matplotlib.pyplot.errorbar():</p><pre>dfTX = df[df[&quot;State&quot;]==&quot;TX&quot;].tail(-1)</pre><pre>YEARS = [year for year in range(2011,2019)]<br>MEANS = []<br>STDS = []<br>for i in range(2011,2019):<br>    year = &quot;R_NET_MIG_&quot;+str(i)<br>    MEANS.append(np.mean(dfTX[year]))<br>    STDS.append(np.std(dfTX[year]))</pre><pre>plt.figure(figsize=(10,8))<br>plt.errorbar(YEARS,MEANS,yerr=STDS)<br>plt.xlabel(&quot;Year&quot;)<br>plt.ylabel(&quot;Net Immigration Rate&quot;);</pre><p>The output appears as shown in the following figure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/485/1*7pnCLreyudgAhqxW7cqWVQ.png" /><figcaption><strong>Figure 8 - Net immigration rate across counties in Texas from 2011 to 2018</strong></figcaption></figure><p>We can see in <em>Figure 8 </em>that although the net immigration in Texas is only slightly positive, the standard deviation is huge. Some counties may have a big positive net rate, while others may potentially suffer from the loss of human resources.</p><h4><strong>Quartiles</strong></h4><p>Quartiles are a special kind of quantile that divides data into a number of equal portions. For example, quartiles divide data into four equal parts with the 1/2 quartile as the median. Deciles and percentiles divide data into 10 and 100 equal parts, respectively.</p><p>The first quartile, also known as the lower quartile <em>Q</em>1 takes the value such that 25% of all the data lies below it. The second quartile is the median. The third quartile, <em>Q</em>3, is also known as the upper quartile and 25% of all values lie above it.</p><p>Quartiles are probably the most commonly used <strong>quantiles </strong>because they are associated with a statistical graph called a <strong>boxplot</strong>. Let’s use the same set of Texas net immigration data to study it.</p><p>The function in NumPy is quantile() and we specify a list of quantiles as an argument for the quantiles we want to calculate, as in the following single-line code snippet:</p><pre>np.quantile(dfTX[&quot;R_NET_MIG_2013&quot;],[0.25,0.5,0.75])</pre><p>The output reads as follows:</p><pre>plt.figure(figsize=(12,5))<br>plt.hist(dfTX[&quot;R_NET_MIG_2013&quot;],bins=50,alpha=0.6)<br>for quartile in np.quantile(dfTX[&quot;R_NET_<br>MIG_2013&quot;],[0.25,0.5,0.75]):<br>    plt.axvline(quartile,linestyle=&#39;:&#39;,linewidth=4)</pre><p>As you can see from the following output, the vertical dotted lines indicate the three quartiles:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/556/1*OC26pd83Ply93NWodtOfvA.png" /><figcaption><strong>Figure 9 - Quartiles of the net immigration data in 2013</strong></figcaption></figure><p>The lower and upper quartiles keep exactly 50% of the data values in between. <em>Q</em>3 — <em>Q</em>1 is referred to as the interquartile range called <strong>Interquartile Range </strong>(<strong>IQR</strong>) and it plays an important role in outlier detection. We will see more about this shortly.</p><h4><strong>Skewness</strong></h4><p>Skewness differs from the three measures of variability discussed in the previous subsections. It measures the direction the data takes and the extent to which the data distribution tilts. Skewness is given by the following equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/133/1*8U8A4-EL3iPmeIWyFFzybg.png" /></figure><blockquote><strong>Various definitions of skewness</strong></blockquote><blockquote>The skewness we defined earlier is precisely referred to as Pearson’s first skewness coefficient. It is defined through the mode, but there are other definitions of skewness. For example, skewness can be defined through the median.</blockquote><p>Skewness is unit-less. If the mean is larger than the mode, skewness is positive, and we say the data is skewed to the right. Otherwise, the data is skewed to the left.</p><p>Here is a code snippet that generates two sets of skewed data and plots them:</p><pre>r1 = [random.normalvariate(0.5,0.4) for _ in range(10000)]<br>r2 = [random.normalvariate(0.1,0.2) for _ in range(10000)]<br>r3 = [random.normalvariate(1.1,0.2) for _ in range(10000)]</pre><pre>fig, axes = plt.subplots(1,2,figsize=(12,5))<br>axes[0].hist(r1+r2,bins=100,alpha=0.5)<br>axes[0].axvline(np.mean(r1+r2), linestyle=&#39;:&#39;,linewidth=4)<br>axes[0].set_title(&quot;Skewed To Right&quot;)<br>axes[1].hist(r1+r3,bins=100,alpha=0.5)<br>axes[1].axvline(np.mean(r1+r3),linestyle=&#39;:&#39;,linewidth=4)<br>axes[1].set_title(&quot;Skewed to Left&quot;);</pre><p>The vertical dotted line indicates the position of the mean as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*Gg2yVZcQYW09wJ8SXZQx8w.png" /><figcaption><strong>Figure 10 - Skewness demonstration</strong></figcaption></figure><p>Think about the problem of income inequality. Let’s say you have a plot of the histogram of the population with different amounts of wealth. A larger value just like where the <em>x</em> axis value indicates the amount of wealth and the <em>y </em>axis value indicates the portion of the population that falls into a certain wealth amount range. A larger <em>x </em>value means more wealth. A larger <em>y </em>value means a greater percentage of the population falls into that range of wealth possession. Positive skewness (the left subplot in <em>Figure 10</em>) means that even though the average income looks good, this may be driven up by a very small number of super-rich individuals when the majority of people earn a relatively small income. Negative skewness (the right subplot in <em>Figure 10</em>) indicates that the majority may have an income above the mean value, so there might be some very poor people who may need help.</p><h4><strong>Revisiting outlier detection</strong></h4><p>Now let’s use what we have learned to revisit the outlier detection problem.</p><p>The <strong>z-score</strong>, also known as the <strong>standard score</strong>, is a good criterion for detecting outliers. It measures the distance between an entry and the population mean, taking the population variance into consideration:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/99/1*QEma-hbNe3dCviAPYtvqWQ.png" /></figure><p>If the underlying distribution is normal, a situation where a z-score is greater than 3 or less than 0 only has a probability of roughly 0.27%. Even if the underlying distribution is not normal, Chebyshev’s theorem guarantees a strong claim such that at most 1/(<em>k^</em>2), where <em>k </em>is an integer, of the total population can fall outside <em>k </em>standard deviations.</p><p>As an example, the following code snippet generates 10,000 data points that follow a normal distribution:</p><pre>random.seed(2020)<br>x = [random.normalvariate(1, 0.5) for _ in range(10000)]<br>plt.figure(figsize=(10,8))<br>plt.hist(x,bins=100,alpha=0.5);<br>styles = [&quot;:&quot;,&quot;--&quot;,&quot;-.&quot;]<br>for i in range(3):<br>    plt.axvline(np.mean(x) + (i+1)*np.std(x),<br>        linestyle=styles[i],<br>        linewidth=4)<br>    plt.axvline(np.mean(x) - (i+1)*np.std(x),<br>        linestyle=styles[i],<br>        linewidth=4)<br>plt.title(&quot;Integer Z values for symmetric distributions&quot;);</pre><p>In the generated histogram plot, the dotted line indicates the location where <em>z</em> = ±1 . The dashed line indicates the location of <em>z</em> = ±2 . The dashed-dotted line indicates the location of <em>z</em> = ±3:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/415/1*lKCdx5LW5tWbu6Yb9Wn-OA.png" /><figcaption><strong>Figure 11 - Integer z value boundaries for normally distributed symmetric data</strong></figcaption></figure><p>If we change the data points, the distribution will change, but the z-score criteria will remain valid. As you can see in the following code snippet, an asymmetric distribution is generated rather than a normal distribution:</p><pre>x = [random.normalvariate(1, 0.5) + random.expovariate(2) for _<br>in range(10000)]</pre><p>This produces the following output:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/406/1*Bo_iDy9fU-MWkjd79bgg6Q.png" /><figcaption><strong>Figure 12 - Integer z value boundaries for asymmetric data</strong></figcaption></figure><blockquote><strong>Note on the influence of extreme outliers</strong></blockquote><blockquote>A drawback of the z-score is that the mean itself is also influenced by extreme outliers. The median can replace a mean to remove this effect.</blockquote><p>We have covered several of the most important statistics to model variances in a dataset. In the next section, let’s work on the data types of features.</p><h3><strong>Knowing how to handle categorical variables and mixed data types</strong></h3><p>Categorical variables usually have simpler structures or descriptive statistics than continuous variables. Here, we introduce frequencies and proportions and talk about some interesting descriptive statistics examples when converting continuous variables to categorical ones.</p><p>We have covered several of the most important statistics to model variances in a dataset. In the next section, let’s work on the data types of features.</p><h3><strong>Knowing how to handle categorical variables and mixed data types</strong></h3><p>Categorical variables usually have simpler structures or descriptive statistics than continuous variables. Here, we introduce frequencies and proportions and talk about some interesting descriptive statistics examples when converting continuous variables to categorical ones.</p><h4><strong>Frequencies and proportions</strong></h4><p>When we discussed the mode for categorical variables, we introduced Counter, which outputs a dictionary structure whose key-value pair is the element-counting pair. The following is an example of a counter:</p><pre>Counter({2.0: 394, 3.0: 369, 6.0: 597, 1.0: 472, 9.0: 425, 7.0:<br>434, 8.0: 220, 4.0: 217, 5.0: 92})</pre><p>The following code snippet illustrates frequency as a bar plot where the absolute values of counting become intuitive:</p><pre>counter = Counter(df[&quot;Rural-urban_Continuum Code_2013&quot;].<br>dropna())<br>labels = []<br>x = []<br>for key, val in counter.items():<br>    labels.append(str(key))<br>    x.append(val)<br>plt.figure(figsize=(10,8))<br>plt.bar(labels,x)<br>plt.title(&quot;Bar plot of frequency&quot;);</pre><p>This produces a bar plot like the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/472/1*dYdRzzxoIFo5fEzE1QIXwA.png" /><figcaption><strong>Figure 13 - Bar plot of rural-urban continuum code</strong></figcaption></figure><p>For proportionality, simply divide each count by the summation of counting, as shown in the following code snippet:</p><pre>x = np.array(x)/sum(x)</pre><p>The shape of the bar plot remains the same, but the <em>y </em>axis ticks change. To better check the relative size of components, I have plotted a pie plot with the help of the following code snippet:</p><pre>plt.figure(figsize=(10,10))<br>plt.pie(x=x,labels=labels,)<br>plt.title(&quot;Pie plot for rural-urban continuum code&quot;);</pre><p>This creates a nice pie chart as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/412/1*NJQYooLQuhD8UR4zkfzLgA.png" /><figcaption><strong>Figure 14 - Pie plot of rural-urban continuum code</strong></figcaption></figure><p>It becomes evident that code 2.0 contains about twice as many samples as code 8.0 does.</p><p>Unlike the mean and median, categorical data does have a mode. We are going to reuse the same data:</p><pre>Counter(df[&quot;Rural-urban_Continuum Code_2013&quot;].dropna())</pre><p>The output reads as follows:</p><pre>Counter({2.0: 394, 3.0: 369, 6.0: 597, 1.0: 472, 9.0: 425, 7.0:<br>434, 8.0: 220, 4.0: 217, 5.0: 92})</pre><p>The mode is 6.0.</p><blockquote><strong>Note</strong></blockquote><blockquote>The mode means that the counties with urban populations of 2,500 to 19,999 adjacent to a metro area are most prevalent in the United States, and not the number 6.0.</blockquote><h4><strong>Transforming a continuous variable to a categorical one</strong></h4><p>Occasionally, we may need to convert a continuous variable to a categorical one. Let’s take lifespan as an example. The 80+ age group is supposed to be very small. Each of them will represent a negligible data point in classification tasks. If they can be grouped together, the noise introduced by the sparsity of this age group’s individual points will be reduced.</p><p>A common way to perform categorization is to use quantiles. For example, quartiles will divide the datasets into four parts with an equal number of entries. This avoids issues such as data imbalance.</p><p>For example, the following code indicates the cut-offs for the categorization of net immigration rate, a continuous variable:</p><pre>series = df[&quot;R_NET_MIG_2013&quot;].dropna()<br>quantiles = np.quantile(series,[0.2*i for i in range(1,5)])<br>plt.figure(figsize=(10,8))<br>plt.hist(series,bins=100,alpha=0.5)<br>plt.xlim(-50,50)<br>for i in range(len(quantiles)):<br>    plt.axvline(quantiles[i],linestyle=&quot;:&quot;, linewidth=4)<br>plt.title(&quot;Quantiles for net immigration data&quot;);</pre><p>As you can see in the following output, the dotted vertical lines split the data into 5 equal sets, which are hard to spot with the naked eye. I truncated the <em>x </em>axis to select the part between -50 and 50. The result looks as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/472/1*cDuvTkG6axMmWgFOo83PiQ.png" /><figcaption><strong>Figure 15 - Quantiles for the net immigration rate</strong></figcaption></figure><blockquote><strong>Note on the loss of information</strong></blockquote><blockquote>Categorization destroys the rich structure in continuous variables. Only use it when you absolutely need to.</blockquote><h3><strong>Using bivariate and multivariate descriptive statistics</strong></h3><p>In this section, we briefly talk about bivariate descriptive statistics. Bivariate descriptive statistics apply two variables rather than one. We are going to focus on correlation for continuous variables and cross-tabulation for categorical variables.</p><h4><strong>Covariance</strong></h4><p>The word <em>covariance </em>is often incorrectly used as <em>correlation</em>. However, there are a number of fundamental differences. Covariance usually measures the joint variability of two variables, while correlation focuses more on the strength of variability. Correlation coefficients have several definitions in different use cases. The most common descriptive statistic is the Pearson correlation coefficient. We will also be using it to describe the covariance of two variables. The correlation coefficient for variables <em>x </em>and <em>y </em>from a population is defined as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/309/1*-5Nm65vzeEEwW3LAbUz5mw.png" /></figure><p>Let’s first examine the expression’s sign. The coefficient becomes positive when <em>x </em>is greater than its mean and <em>y </em>is also greater than its own mean.</p><p>Another case is when <em>x</em> and <em>y</em> are both smaller than their means, respectively. The products sum together and then get <em>normalized</em> by the standard deviation of each variable. So, a positive coefficient indicates that <em>x</em> and <em>y</em> vary jointly in the same direction. You can make a similar argument about negative coefficients.</p><p>In the following code snippet, we select the net immigration rates for counties in Texas as our datasets and use the corr() function to inspect the correlation coefficient across years:</p><pre>corrs = dfTX[[&#39;R_NET_MIG_2011&#39;,&#39;R_NET_MIG_2012&#39;, &#39;R_NET_<br>MIG_2013&#39;, &#39;R_NET_MIG_2014&#39;, &#39;R_NET_MIG_2015&#39;,&#39;R_NET_MIG_2016&#39;,<br>&#39;R_NET_MIG_2017&#39;, &#39;R_NET_MIG_2018&#39;]].corr()</pre><p>The output is a so-called <em>correlation matrix </em>whose diagonal elements are the self- correlation coefficients, which are just 1:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*qgDpa4i3iQYAicsljqpbzA.png" /><figcaption><strong>Figure 16 - Correlation matrix for the net immigration rate</strong></figcaption></figure><p>A good way to visualize this matrix is to use the heatmap() function from the Seaborn library. The following code snippet generates a nice heatmap:</p><pre>import seaborn as sns<br>plt.figure(figsize=(10,8))<br>plt.rcParams.update({&#39;font.size&#39;: 12})<br>sns.heatmap(corrs,cmap=&quot;YlGnBu&quot;);</pre><p>The result is as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/499/1*AuAKOX7_5epWMo1enFZyqw.png" /><figcaption><strong>Figure 17 - Heatmap of a correlation matrix for net immigration rates in Texas</strong></figcaption></figure><p>We do see an interesting pattern that odd years correlate with one another more strongly, and even years correlate with each other more strongly, too. However, that is not the case between even- and odd-numbered years. Perhaps there is a 2-year cyclic pattern and the heatmap of the correlation matrix just helped us discover it.</p><h4><strong>Cross-tabulation</strong></h4><p>Cross-tabulation can be treated as a discrete version of correlation detection for categorical variables. It helps derive innumerable insights and sheds light on downstream task designs.</p><p>Here is an example. I am creating a list of weather information and another list of a golfer’s decisions on whether to go golfing. The crosstab() function generates the following table:</p><pre>weather = [&quot;rainy&quot;,&quot;sunny&quot;,&quot;rainy&quot;,&quot;windy&quot;,&quot;windy&quot;,<br>           &quot;sunny&quot;,&quot;rainy&quot;,&quot;windy&quot;,&quot;sunny&quot;,&quot;rainy&quot;,<br>           &quot;sunny&quot;,&quot;windy&quot;,&quot;windy&quot;]<br>golfing = [&quot;Yes&quot;,&quot;Yes&quot;,&quot;No&quot;,&quot;No&quot;,&quot;Yes&quot;,&quot;Yes&quot;,&quot;No&quot;,&quot;No&quot;,<br>           &quot;Yes&quot;,&quot;No&quot;,&quot;Yes&quot;,&quot;No&quot;,&quot;No&quot;]<br>dfGolf = pd.DataFrame({&quot;weather&quot;:weather,&quot;golfing&quot;:golfing})<br>pd.crosstab(dfGolf.weather, dfGolf.golfing, margins=True)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/121/1*rSMzv2TE63MHHQv1Pfmg_A.png" /><figcaption><strong>Figure 18 - Cross-tabulation for golfing decisions</strong></figcaption></figure><p>As you can see, the columns and rows give the exact counts, which are identified by the column name and row name. For a dataset with a limited number of features, this is a handy way to inspect imbalance or bias.</p><p>We can tell that the golfer goes golfing if the weather is sunny, and that they seldom go golfing on rainy or windy days.</p><h3><strong>In conclusion</strong></h3><p>In this article, we’ve explained what descriptive statistics are and what they can tell you. You have seen how to extract information from your datasets and use descriptive statistics to make quantitative judgments. Hopefully, it is now clear that an understanding of the different descriptive statistics, knowledge of when to use them, and the practical ability to derive them from your data, are indispensable items in the data scientist’s toolkit.</p><p>Equipped with this knowledge, you can reinforce your understanding of data science and data analysis from a statistical perspective and extract meaningful insights from your data using Python programming. Find out how with Rongpeng Li’s book <a href="https://packt.live/3dTBde4">Essential Statistics for Non-STEM Data Analysts</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4f47d9cf03e9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementing Terminal I/O in Rust]]></title>
            <link>https://packt.medium.com/implementing-terminal-i-o-in-rust-4a44652b0f11?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a44652b0f11</guid>
            <category><![CDATA[high-performance]]></category>
            <category><![CDATA[rust-language]]></category>
            <category><![CDATA[rustlang]]></category>
            <category><![CDATA[systems-engineering]]></category>
            <category><![CDATA[systems-programming]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Wed, 05 May 2021 16:23:21 GMT</pubDate>
            <atom:updated>2021-05-05T16:23:21.874Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mF7SXF06H2DJSB_N50s08w.png" /></figure><p>Rust is a modern, open source system programming language that promises the best of three worlds: the type safety of Java; the speed, expressiveness, and efficiency of C++; and memory safety without a garbage collector. In this article, we look at building terminal-based applications in Rust.</p><p><strong>Terminal applications</strong> are an integral part of many software programs, including games, text editors, and terminal emulators. For developing these types of programs, it helps to understand how to build customized terminal interface-based applications. We will review the basics of how terminals work, and then look at how to perform various types of actions on a terminal, such as setting colors and styles, performing cursor operations (such as clearing and positioning), and working with keyboard and mouse inputs.</p><p>We will cover the following topics:</p><ul><li>Introducing terminal I/O fundamentals</li><li>Working with the terminal UI (size, color, styles) and cursors</li><li>Processing keyboard inputs and scrolling</li><li>Processing mouse inputs</li></ul><p>The bulk of the article will be dedicated to explaining these concepts through a practical example. We will build a mini text viewer that will demonstrate key concepts of working with terminals. The text viewer will be able to load a file from disk and display its contents on the terminal interface. It will also allow a user to scroll through the contents using the various arrow keys on the keyboard, and display information on the header and footer bar.</p><h3><strong>Technical requirements</strong></h3><p>The Git repo for the code in this article can be found at <a href="https://github.com/PacktPublishing/Practical-System-Programming-for-Rust-Developers/tree/master/Chapter07/tui">https://github.com/PacktPublishing/Practical-System-Programming-for-Rust-Developers/tree/master/Chapter07/tui</a>.</p><p>For those working on the Windows platform, a virtual machine needs to be installed, as the third-party crate used for terminal management does not support the Windows platform (at the time of writing). It is recommended to install a virtual machine such as VirtualBox or equivalent running Linux for working with the code. Instructions to install VirtualBox can be found at <a href="https://www.virtualbox.org/">https://www.virtualbox.org</a>.</p><p>For working with terminals, Rust provides several features to read keypresses and to control standard input and output for a process. When a user types characters in the command line, the bytes generated are available to the program when the user presses the <em>Enter</em> key. This is useful for several types of programs. But for some types of programs, such as games or text editors, which require more fine-grained control, the program must process each character as it is typed by the user, which is also known as raw mode. There are several third-party crates available that make raw mode processing easy. We will be using one such crate, <strong>Termion</strong>.</p><h3><strong>Introducing terminal I/O fundamentals</strong></h3><p>In this section, we’ll cover the key characteristics of terminals, see an overview of the Termion crate, and define the scope of what we will be building in this project.</p><h4><strong>Characteristics of terminals</strong></h4><p>Terminals are devices with which users can interact with a computer. Using a terminal, a user can get command-line access to interact with the computer’s operating system. A shell typically acts as the controlling program to drive the terminal on one hand and the interface with the operating system on the other hand.</p><p>Originally, UNIX systems were accessed using a terminal (also called a console) connected to a serial line. These terminals typically had a 24 x 80 row x column character-based interface, or, in some cases, had rudimentary graphics capabilities. In order to perform operations on the terminal, such as clearing the screen or moving the cursor, specific escape sequences were used.</p><p>There are two modes in which terminals can operate:</p><ul><li><strong>Canonical mode</strong>: In canonical mode, the inputs from the user are processed line by line, and the user has to press the <em>Enter </em>key for the characters to be sent to the program for processing.</li><li><strong>Non-canonical or raw mode</strong>: In raw mode, terminal input is not collected into lines, but the program can read each character as it is typed by the user.</li></ul><p>Terminals can be either physical devices or virtual devices. Most terminals today are <strong>pseudo-terminals</strong>, which are virtual devices that are connected to a terminal device on one side, and to a program that drives the terminal device on the other end. Pseudo-terminals help us write programs where a user on one host machine can execute a <em>terminal-oriented program </em>on another host machine using network communications. An example of a pseudo-terminal application is <strong>SSH </strong>(Secure Shell Protocol), which allows a user to log in to a remote host over a network.</p><p>Terminal management includes the ability to perform the following things on a terminal screen:</p><ul><li><strong>Color management</strong>: Setting various foreground and background colors on the terminal and resetting the colors to default values.</li><li><strong>Style management</strong>: Setting the style of text to <em>bold</em>, <em>italics</em>, <em>underline</em>, and so on.</li><li><strong>Cursor management</strong>: Setting the cursor at a particular position, saving the current cursor position, showing and hiding a cursor, and other special features, such as blinking cursors.</li><li><strong>Event handling</strong>: Listening and responding to keyboard and mouse events.</li><li><strong>Screen handling</strong>: Switching from main to alternate screens and clearing the screen.</li><li><strong>Raw mode</strong>: Switching a terminal to raw mode.</li></ul><p>In this article, we will use a combination of the Rust standard library and the Termion crate to develop a terminal-oriented application. Let’s begin by looking at the Termion crate.</p><h4><strong>The Termion crate</strong></h4><p>The Termion crate provides the features listed in the previous section, while also providing the user with easy-to-use command-line interfaces (CLIs).</p><blockquote><strong>Why use an external crate for terminal management?</strong></blockquote><blockquote>While it is technically possible to work at the byte level using the Rust standard library, it is cumbersome. External crates such as Termion help us group individual bytes to keypresses, and also implement many of the commonly used terminal management functions, which allows us to focus on the higher level, user-directed functionality.</blockquote><p>Let’s discuss a few terminal management features of the Termion crate. The official documentation of the crate can be found at <a href="https://docs.rs/termion/">https://docs.rs/termion/</a>.</p><p>The Termion crate has the following key modules:</p><ul><li>cursor: For moving cursors</li><li>event: For handling key and mouse events</li><li>raw: To switch the terminal to raw mode</li><li>style: To set various styles on text</li><li>clear: To clear the entire screen or individual lines</li><li>color: To set various colors to text</li><li>input: To handle advanced user input</li><li>scroll: To scroll across the screen</li></ul><p>To include the Termion crate, start a new project and add the following entry to cargo.toml:</p><pre>[dependencies]<br>termion = &quot;1.5.5&quot;</pre><p>A few examples of Termion usage are shown through code snippets here:</p><ul><li>To get the terminal size, use the following:</li></ul><pre>termion::terminal_size()</pre><ul><li>To set the foreground color, use the following:</li></ul><pre>println!(“{}”, color::Fg(color::Blue));</pre><ul><li>To set the background color and then reset the background color to the original state, use the following:</li></ul><pre>println!(<br>    “{}Background{} “,<br>    color::Bg(color::Cyan),<br>    color::Bg(color::Reset)<br>);</pre><ul><li>To set bold style, use the following:</li></ul><pre>println!(<br>    “{}You can see me in bold?”,<br>    style::Bold<br>);</pre><ul><li>To set the cursor to a particular position, use the following:</li></ul><pre>termion::cursor::Goto(5, 10)</pre><ul><li>To clear the screen, use the following:</li></ul><pre>print!(“{}”, termion::clear::All);</pre><p>We will use these terminal management features in a practical example in the upcoming sections. Let’s now define what we are going to build.</p><h4><strong>What will we build?</strong></h4><p>We will develop a mini text viewer application. This application provides a terminal text interface to load a document from a directory location and view the document. The user can scroll through the document using keyboard keys. We’ll build this project progressively over multiple iterations of code.</p><p><em>Figure 1 </em>shows the screen layout of what we will build:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*BSHpmHM6f5at_2MyuMvLIg.png" /><figcaption><strong>Figure 1 - Text viewer screen layout</strong></figcaption></figure><p>There are three components in the terminal interface of the text viewer:</p><ul><li><strong>Header bar</strong>: This contains the title of the text editor.</li><li><strong>Text area</strong>: This contains the lines of text to be displayed.</li><li><strong>Footer bar</strong>: This displays the position of the cursor, the number of lines of text in the file, and the name of the file being displayed.</li></ul><p>The text viewer will allow the user to perform the following actions:</p><ul><li>Users can provide a filename as a command-line argument to display. This should be a valid filename that already exists. If the file does not exist, the program will display an error message and exit.</li><li>The text viewer will load the file contents and display them on the terminal. If the number of lines in a file is more than the terminal height, the program will allow the user to scroll through the document, and repaint the next set of lines.</li><li>Users can use the up, down, left, and right keys to scroll through the terminal.</li><li>Users can press <em>Ctrl </em>+ <em>Q </em>to exit the text viewer.</li></ul><p>A popular text viewer would have a lot more features, but this core scope provides an adequate opportunity for us to learn about developing a terminal-oriented application in Rust.</p><p>In this section, we’ve learned what terminals are and what kinds of features they support. We also saw an overview of how to work with the Termion crate and defined what we will be building as part of the project. In the next section, we’ll develop the first iteration of the text viewer.</p><h3><strong>Working with the terminal UI (size, color, styles) and cursors</strong></h3><p>In this section, we will build the first iteration of the text viewer. At the end of this section, we will have a program that will accept a filename from the command line, display its contents, and display a header and footer bar. We will use a Termion crate to set the color and style, get the terminal size, position the cursor at specific coordinates, and clear the screen.</p><p>The code in this section is organized as follows:</p><ul><li>Writing data structures and the main() function</li><li>Initializing the text viewer and getting the terminal size</li><li>Displaying a document and styling the terminal color, styles, and cursor position</li><li>Exiting the text viewer</li></ul><p>Let&#39;s start with data structures and the main() function of the text viewer.</p><h4><strong>Writing data structures and the main() function</strong></h4><p>In this section, we’ll define the data structures needed to represent the text viewer in memory. We’ll also write the main() function, which coordinates and invokes various other functions:</p><p>1. Create a new project and switch to the directory with the following command:</p><pre><strong>cargo new tui &amp;&amp; cd tui</strong></pre><p>Here, tui stands for <strong>terminal user interface</strong>. Create a new file called textviewer1.rs under src/bin.</p><p>2. Add the following to cargo.toml:</p><pre>[dependencies]<br>termion = “1.5.5”</pre><p>3. Let’s first import the required modules from the standard library and the Termion crate:</p><pre>use std::env::args;<br>use std::fs;<br>use std::io::{stdin, stdout, Write};<br>use termion::event::Key;<br>use termion::input::TermRead;<br>use termion::raw::IntoRawMode;<br>use termion::{color, style};</pre><p>4. Let’s next define the data structures to represent a text viewer:</p><pre>struct Doc {<br>    lines: Vec&lt;String&gt;,<br>}<br>#[derive(Debug)]<br>struct Coordinates {<br>    pub x: usize,<br>    pub y: usize,<br>}<br>struct TextViewer {<br>    doc: Doc,<br>    doc_length: usize,<br>    cur_pos: Coordinates,<br>    terminal_size: Coordinates,<br>    file_name: String,<br>}</pre><p>This code shows three data structures defined for the text viewer:</p><ul><li>The document that will be displayed in the viewer is defined as a Doc struct, which is a vector of strings.</li><li>To store cursor position <em>x </em>and <em>y </em>coordinates and to record the current size of the terminal (the total number of rows and columns of characters), we have defined a Coordinates struct.</li><li>The TextViewer struct is the main data structure representing the text viewer. The number of lines contained in the file being viewed is captured in the doc_length field. The name of the file to be shown in the viewer is recorded in the file_name field.</li></ul><p>5. Let’s now define the main() function, which is the entry point for the text viewer application:</p><pre>fn main() {<br>    //Get arguments from command line<br>    let args: Vec&lt;String&gt; = args().collect();<br>    if args.len() &lt; 2 {<br>        println!(“Please provide file name<br>            as argument”);<br>        std::process::exit(0);<br>    }<br>    //Check if file exists. If not, print error<br>    // message and exit process<br>    if !std::path::Path::new(&amp;args[1]).exists() {<br>        println!(“File does not exist”);<br>        std::process::exit(0);<br>    }<br>    // Open file &amp; load into struct<br>    println!(“{}”, termion::cursor::Show);<br>    // Initialize viewer<br>    let mut viewer = TextViewer::init(&amp;args[1]);<br>    viewer.show_document();<br>    viewer.run();<br>}</pre><p>The main() function accepts a filename as a command-line parameter and exits the program if the file does not exist. Furthermore, if a filename is not provided as a command-line parameter, it displays an error message and exits the program.</p><p>6. If the file is found, the main() function does the following:</p><p>It first calls the init() method on the TextViewer struct to initialize the variables.</p><p>Then, it invokes the show_document() method to display the contents of the file on the terminal screen.</p><p>Lastly, the run() method is called, which waits for user inputs to the process. If the user presses <em>Ctrl </em>+ <em>Q</em>, the program exits.</p><p>7. We will now write three method signatures — init(), show_document(), and run(). These three methods should be added to the impl block of the TextViewer struct, as shown:</p><pre>impl TextViewer {<br>    fn init(file_name: &amp;str) -&gt; Self {<br>        //...<br>    }<br>    fn show_document(&amp;mut self) {<br>        // ...<br>    }<br>    fn run(&amp;mut self) {<br>        // ...<br>    }<br>}</pre><p>So far, we’ve defined the data structures and written the main() function with placeholders for the other functions. In the next section, let’s write the function to initialize the text viewer.</p><h4><strong>Initializing the text viewer and getting the terminal size</strong></h4><p>When a user starts the text viewer with a document name, we have to initialize the text viewer with some information and perform startup tasks. This is the purpose of the init() method.</p><p>Here is the complete code for the init() method:</p><pre>fn init(file_name: &amp;str) -&gt; Self {<br>    let mut doc_file = Doc { lines: vec![] };                   <strong>&lt;1&gt;    <br>    </strong>let file_handle = fs::read_to_string(file_name)<br>        .unwrap();                                              <strong>&lt;2&gt;<br>    </strong>for doc_line in file_handle.lines() {                       <strong>&lt;3&gt;<br>        </strong>doc_file.lines.push(doc_line.to_string());<br>    }<br>    let mut doc_length = file_handle.lines().count();           <strong>&lt;4&gt;</strong></pre><pre><strong>    </strong>let size = termion::terminal_size().unwrap();               <strong>&lt;5&gt;<br>    </strong>Self {                                                      <strong>&lt;6&gt;<br>        </strong>doc: doc_file,<br>        cur_pos: Coordinates {<br>            x: 1,<br>            y: doc_length,<br>        },<br>        doc_length: doc_length,<br>        terminal_size: Coordinates {<br>            x: size.0 as usize,<br>            y: size.1 as usize,<br>        },<br>        file_name: file_name.into(),<br>    }<br>}</pre><p>The code annotations in the init() method are described here:</p><ol><li>Initialize the buffer that is used to store the file contents.</li><li>Read the file contents as a string.</li><li>Read each line from the file and store it in the Doc buffer.</li><li>Initialize the doc_length variable with the number of lines in the file.</li><li>Use the termion crate to get the terminal size.</li><li>Create a new struct of the TextViewer type and return it from the init() method.</li></ol><p>We’ve written the initialization code for the text viewer. Next, we’ll write the code to display the document contents on the terminal screen, and also display the header and footer.</p><h4><strong>Displaying a document and styling the terminal color, styles, and cursor position</strong></h4><p>We saw earlier the layout of the text viewer that we would like to build. There are three main parts of the text viewer screen layout — the header, the document area, and the footer. In this section, we’ll write the primary function and supporting function to display the contents as per the defined screen layout.</p><p>Let’s look at the show_document() method:</p><p><strong>src/bin/text-viewer1.rs</strong></p><pre>fn show_document(&amp;mut self) {<br>    let pos = &amp;self.cur_pos;<br>    let (old_x, old_y) = (pos.x, pos.y);<br>    print!(&quot;{}{}&quot;, termion::clear::All,<br>        termion::cursor::Goto(1, 1));<br>    println!(<br>        &quot;{}{}Welcome to Super text viewer\r{}&quot;,<br>        color::Bg(color::Black),<br>        color::Fg(color::White),<br>        style::Reset<br>    );<br>    for line in 0..self.doc_length {<br>        println!(&quot;{}\r&quot;, self.doc.lines[line as usize]);<br>    }</pre><pre>    println!(<br>        &quot;{}&quot;,<br>        termion::cursor::Goto(0, (self.terminal_size.y - 2) as<br>            u16),<br>    );<br>    println!(<br>        &quot;{}{} line-count={} Filename: {}{}&quot;,<br>        color::Fg(color::Red),<br>        style::Bold,<br>        self.doc_length,<br>        self.file_name,<br>        style::Reset<br>    );<br>self.set_pos(old_x, old_y);<br>}</pre><p>The code annotations for the show_document() method are described here:</p><ol><li>Store the current positions of the cursor <em>x </em>and <em>y </em>coordinates in temp variables. This will be used to restore the cursor position in a later step.</li><li>Using the Termion crate, clear the entire screen and move the cursor to row 1 and column 1 on the screen.</li><li>Print the header bar of the text viewer. A background color of black and a foreground color of white is used to print text.</li><li>Display each line from the internal document buffer to the terminal screen.</li><li>Move the cursor to the bottom of the screen (using the terminal size <em>y </em>coordinate) to print the footer.</li><li>Print the footer text in red and with bold style. Print the number of lines in the document and filename to the footer.</li><li>Reset the cursor to the original position (which was saved to temporary variable in <em>step 1</em>).</li></ol><p>Let’s look at the set_pos() helper method used by the show_document() method:</p><p><strong>src/bin/text-viewer1.rs</strong></p><pre>fn set_pos(&amp;mut self, x: usize, y: usize) {<br>    self.cur_pos.x = x;<br>    self.cur_pos.y = y;<br>    println!(<br>        &quot;{}&quot;,<br>        termion::cursor::Goto(self.cur_pos.x as u16,<br>            (self.cur_pos.y) as u16)<br>    );<br>}</pre><p>This helper method synchronizes the internal cursor tracking field (the cur_pos field of the TextViewer struct) and the on-screen cursor position.</p><p>We now have the code to initialize the text viewer and to display the document on the screen. With this, a user can open a document in the text viewer and view its contents. But how does the user exit the text viewer? We’ll find out in the next section.</p><h4><strong>Exiting the text viewer</strong></h4><p>Let’s say that a key combination of <em>Ctrl </em>+ <em>Q </em>will let the user exit the text viewer program. How can we implement this code?</p><p>To achieve this, we need a way to listen for user key strokes, and when a particular key combination is pressed, we should exit the program. As discussed earlier, we need to get the terminal into raw mode of operation, where each character is available for the program to evaluate, rather than wait for the user to press the <em>Enter </em>key. Once we get the raw characters, the rest of it becomes fairly straightforward. Let’s write the code to do this in the run() method, within the impl TextViewer block, as shown:</p><p><strong>src/bin/text-viewer1.rs</strong></p><pre>fn run(&amp;mut self) {<br>    let mut stdout = stdout().into_raw_mode().unwrap();<br>    let stdin = stdin();<br>    for c in stdin.keys() {<br>        match c.unwrap() {<br>            Key::Ctrl(‘q’) =&gt; {<br>                break;<br>          }<br>          _=&gt; {}<br>        }<br>        stdout.flush().unwrap();<br>    }<br>}</pre><p>In the code shown, we use the stdin.keys() method to listen for user inputs in a loop. stdout() is used to display text to the terminal. When <em>Ctrl </em>+ <em>Q </em>is pressed, the program exits.</p><p>We can now run the program with the following:</p><pre>cargo run --bin text-viewer1 &lt;file-name-with-full-path&gt;</pre><p>Since we have not implemented scrolling yet, pass a filename to the program that has 24 lines or less of content (this is typically the default height of a standard terminal in terms of the number of rows). You will see the text viewer <em>open up </em>and the <em>header bar</em>, <em>footer</em> <em>bar</em>, and <em>file contents </em>printed to the terminal. Type <em>Ctrl </em>+ <em>Q </em>to exit. Note that you have to specify the filename with the full file path as a command-line argument.</p><p>In this section, we learned how to get the terminal size, set the foreground and background colors, and apply bold style using the Termion crate. We also learned how to position the cursor onscreen at specified coordinates, and how to clear the screen.</p><p>In the next section, we will look at processing keystrokes for user navigation within the document displayed in the text editor and how to implement scrolling.</p><h3><strong>Processing keyboard inputs and scrolling</strong></h3><p>In the previous section, we built the first iteration of our text viewer terminal-oriented application. We were able to display a file with fewer than 24 lines and see the header and footer bar containing some information. Finally, we were able to exit the program with <em>Ctrl </em>+ <em>Q</em>.</p><p>In this section, we will add the following features to the text viewer:</p><ul><li>Provide the ability to display files of any size.</li><li>Provide the ability for the user to scroll through the document using arrow keys.</li><li>Add cursor position coordinates to the footer bar.</li></ul><p>Let’s begin by creating a new version of the code.</p><p>Copy the original code to a new file, as shown:</p><pre>cp src/bin/text-viewer1.rs src/bin/text-viewer2.rs</pre><p>This section is organized into three parts. First, we’ll implement the logic to respond to the following keystrokes from a user: up, down, left, right, and backspace. Next, we’ll implement the functionality to update the cursor position in internal data structures, and simultaneously update the cursor position onscreen. Lastly, we’ll allow scrolling through a multi-page document.</p><p>We’ll begin with handling user keystrokes.</p><h4><strong>Listening to keystrokes from the user</strong></h4><p>Let’s modify the run() method to act on user inputs and scroll through the document. We also want to record and display the current cursor position in the footer bar. The code is shown here:</p><p><strong>src/bin/text-viewer2.rs</strong></p><pre>fn run(&amp;mut self) {<br>    let mut stdout = stdout().into_raw_mode().unwrap();<br>    let stdin = stdin();<br>    for c in stdin.keys() {<br>        match c.unwrap() {<br>            Key::Ctrl(&#39;q&#39;) =&gt; {<br>                break;<br>            }<br>            <strong>Key::Left =&gt; {<br>                self.dec_x();<br>                self.show_document();<br>            }<br>            Key::Right =&gt; {<br>                self.inc_x();<br>                self.show_document();<br>            }<br>            Key::Up =&gt; {<br>                self.dec_y();<br>                self.show_document();<br>            }<br>            Key::Down =&gt; {<br>                self.inc_y();<br>                self.show_document();<br>            }<br>            Key::Backspace =&gt; {<br>                self.dec_x();<br>            }<br>            </strong>_ =&gt; {}<br>        }<br>        stdout.flush().unwrap();<br>    }<br>}</pre><p>Lines in bold show the changes to the run() method from the earlier version. In this code, we are listening for up, down, left, right, and backspace keys. For any of these keypresses, we are incrementing the <em>x </em>or <em>y </em>coordinate appropriately using one of the following methods: inc_x(), inc_y(), dec_x(), or dec_y(). For example, if the right arrow is pressed, the <em>x </em>coordinate of the cursor position is incremented using the inc_x() method, and if the down arrow is pressed, only the <em>y </em>coordinate is incremented using the inc_y() method. The changes to coordinates are recorded in the internal data structure (the cur_pos field of the TextViewer struct). Also, the cursor is repositioned on the screen. All these are achieved by the inc_x(), inc_y(), dec_x(), and dec_y() methods.</p><p>After updating the cursor position, the screen is refreshed fully and repainted.</p><p>Let’s look at implementing the four methods to update cursor coordinates, and reposition the cursor on the screen.</p><h4><strong>Positioning the terminal cursor</strong></h4><p>Let’s write the code for the inc_x(), inc_y(), dec_x(), and dec_y() methods. These should be added as a part of the impl TextViewer block of code like the other methods:</p><p><strong>src/bin/text-viewer2.rs</strong></p><pre>fn <strong>inc_x</strong>(&amp;mut self) {<br>    if self.cur_pos.x &lt; self.terminal_size.x {<br>        self.cur_pos.x += 1;<br>    }<br>    println!(<br>        &quot;{}&quot;,<br>        termion::cursor::Goto(self.cur_pos.x as u16,<br>            self.cur_pos.y as u16)<br>    );<br>}<br>fn <strong>dec_x</strong>(&amp;mut self) {<br>    if self.cur_pos.x &gt; 1 {<br>        self.cur_pos.x -= 1;<br>    }<br>    println!(<br>        &quot;{}&quot;,<br>        termion::cursor::Goto(self.cur_pos.x as u16,<br>            self.cur_pos.y as u16)<br>    );<br>}<br>fn <strong>inc_y</strong>(&amp;mut self) {<br>     if self.cur_pos.y &lt; self.doc_length {<br>         self.cur_pos.y += 1;<br>     }<br>     println!(<br>         &quot;{}&quot;,<br>         termion::cursor::Goto(self.cur_pos.x as u16,<br>             self.cur_pos.y as u16)<br>     );<br>}<br>fn <strong>dec_y</strong>(&amp;mut self) {<br>    if self.cur_pos.y &gt; 1 {<br>        self.cur_pos.y -= 1;<br>    }<br>    println!(<br>        &quot;{}&quot;,<br>        termion::cursor::Goto(self.cur_pos.x as u16,<br>            self.cur_pos.y as u16)<br>    );<br>}</pre><p>The structure of all these four methods is similar and each performs only two steps:</p><ol><li>Depending on the keypress, the corresponding coordinate (<em>x </em>or <em>y</em>) is incremented or decremented and recorded in the cur_pos internal variable.</li><li>The cursor is repositioned on the screen at the new coordinates.</li></ol><p>We now have a mechanism to update the cursor coordinates whenever the user presses the up, down, left, right, or backspace keys. But that’s not enough. The cursor should be repositioned on the screen to the latest cursor coordinates. For this, we will have to update the show_document() method, which we will do in the next section.</p><h4><strong>Enabling scrolling on the terminal</strong></h4><p>We have so far implemented the code to listen for user keystrokes and reposition the cursor onscreen. Now, let’s turn our attention to another major issue in the code. If we load a document that has fewer lines than the terminal height, then the code works fine. But consider a situation where the terminal has the capacity to display 24 rows of characters, and there are 50 lines in the document to be displayed on text viewer. Our code cannot handle it. We’re going to fix it in this section.</p><p>To display more lines than is possible for the screen size, it is not enough to reposition the cursor. We will have to repaint the screen to fit a portion of the document in the terminal screen depending on the cursor location. Let’s see the modifications needed to the show_document() method to enable scrolling. Look for the following lines of code in the show_document() method:</p><pre>for line in 0..self.doc_length {<br>      println!(&quot;{}\r&quot;, self.doc.lines[line as<br>          usize]);<br>      }</pre><p>Replace the preceding with the following code:</p><p><strong>src/bin/text-viewer2.rs</strong></p><pre>if self.doc_length &lt; self.terminal_size.y {                     <strong>&lt;1&gt;       <br>    </strong>for line in 0..self.doc_length {<br>        println!(&quot;{}\r&quot;, self.doc.lines[line as<br>            usize]);<br>    }<br>} else {</pre><pre>    if pos.y &lt;= self.terminal_size.y {                          <strong>&lt;2&gt;    <br>        </strong>for line in 0..self.terminal_size.y - 3 {<br>            println!(&quot;{}\r&quot;, self.doc.lines[line as<br>                usize]);<br>        }<br>    } else {<br>        for line in pos.y - (self.terminal_size.y –<br>            3)..pos.y {<br>            println!(&quot;{}\r&quot;, self.doc.lines[line as<br>                usize]);<br>        }<br>    }<br>}</pre><p>The code annotations in the show_document() method snippet are described here:</p><ol><li>First, check whether the number of lines in the input document is less than the terminal height. If so, display all lines from the input document on the terminal screen.</li><li>If the number of lines in the input document is greater than the terminal height, we have to display the document in parts. Initially, the first set of lines from the document are displayed onscreen corresponding to the number of rows that will fit into the terminal height. For example, if we allocate 21 lines to the text display area, then as long as the cursor is within these lines, the original set of lines is displayed. If the user scrolls down further, then the next set of lines is displayed onscreen.</li></ol><p>Let’s run the program with the following:</p><pre><strong>cargo run –-bin text-viewer2 &lt;file-name-with-full-path&gt;</strong></pre><p>You can try two kinds of file inputs:</p><ul><li>A file where the number of lines is less than the terminal height</li><li>A file where the number of lines is more than the terminal height</li></ul><p>You can use the up, down, left, and right arrows to scroll through the document and see the contents. You will also see the current cursor position (both <em>x </em>and <em>y </em>coordinates) displayed on the footer bar. Type <em>Ctrl </em>+ <em>Q </em>to exit.</p><p>This concludes the text viewer project. You have built a functional text viewer that can display files of any size, and can scroll through its contents using the arrow keys. You can also view the current position of the cursor along with the filename and number of lines in the footer bar.</p><blockquote><strong>Note on the text viewer</strong></blockquote><blockquote>Note that what we have implemented is a mini version of a text viewer in under 200 lines of code. While it demonstrates the key functionality, additional features and edge cases can be implemented by you to enhance the application and improve its usability. Furthermore, this viewer can also be converted into a full-fledged text editor. These are left to you, the reader, as an exercise.</blockquote><p>We’ve completed the implementation of the text viewer project in this section. The text viewer is a classic command-line application, lacking a graphical user interface (GUI) where mouse inputs are needed. But it is important to learn how to handle mouse events, for developing GUI-based terminal interfaces. We’ll learn how to do that in the next section.</p><h3><strong>Processing mouse inputs</strong></h3><p>Like keyboard events, the Termion crate also supports the ability to listen for mouse events, track the mouse cursor location, and react to it in code. Let’s see how to do this here.</p><p>Create a new source file called mouse-events.rs under src/bin.</p><p>Here is the code logic:</p><ol><li>Import the needed modules.</li><li>Enable mouse support in the terminal.</li><li>Clear the screen.</li><li>Create an iterator over incoming events.</li><li>Listen to mouse presses, release and hold events, and display the mouse cursor location on the terminal screen.</li></ol><p>The code is explained in snippets corresponding to each of these points.</p><p>Let’s first look at module imports:</p><ol><li>We’re importing the termion crate modules for switching to raw mode, detecting the cursor position, and listening to mouse events:</li></ol><pre>use std::io::{self, Write};<br>use termion::cursor::{self, DetectCursorPos};<br>use termion::event::*;<br>use termion::input::{MouseTerminal, TermRead};<br>use termion::raw::IntoRawMode;</pre><p>In the main() function, let’s enable mouse support as shown:</p><pre>fn main() {<br>    let stdin = io::stdin();<br>    let mut stdout = MouseTerminal::from(io::stdout().<br>        into_raw_mode().unwrap());<br>    // ...Other code not shown<br>}</pre><p>To ensure that previous text on the terminal screen does not interfere with this program, let’s clear the screen, as shown here:</p><pre>writeln!(<br>    stdout,<br>    &quot;{}{} Type q to exit.&quot;,<br>    termion::clear::All,<br>    termion::cursor::Goto(1, 1)<br>)<br>.unwrap();</pre><p>2. Next, let’s create an iterator over incoming events and listen to mouse events. Display the location of the mouse cursor on the terminal:</p><pre>for c in stdin.events() {<br>    let evt = c.unwrap();<br>    match evt {<br>        Event::Key(Key::Char(&#39;q&#39;)) =&gt; break,<br>        Event::Mouse(m) =&gt; match m {<br>            MouseEvent::Press(_, a, b) |<br>                MouseEvent::Release(a, b) |<br>                MouseEvent::Hold(a, b) =&gt; {<br>                    write!(stdout, &quot;{}&quot;,<br>                    cursor::Goto(a, b))<br>                    .unwrap();<br>                    let (x, y) = stdout.cursor_pos<br>                        ().unwrap();<br>                    write!(<br>                        stdout,<br>                        &quot;{}{}Cursor is at:<br>                        ({},{}){}&quot;,<br>                        cursor::Goto(5, 5),<br>                        termion::clear::<br>                            UntilNewline,<br>                        x,<br>                        y,<br>                        cursor::Goto(a, b)<br>                    )<br>                    .unwrap();<br>            }<br>        },<br>        _ =&gt; {}<br>    }<br>    <br>    stdout.flush().unwrap();<br>}</pre><p>In the code shown, we are listening to both keyboard events and mouse events. In keyboard events, we are specifically looking for the <em>Q </em>key, which exits the program. We are also listening to mouse events — press, release, and hold. In this case, we position the cursor at the specified coordinates and also print out the coordinates to the terminal screen.</p><p>3. Run the program with the following command:</p><pre><strong>cargo run --bin mouse-events</strong></pre><p>4. Click around the screen with the mouse, and you will see the cursor position coordinates displayed on the terminal screen. Press q to exit.</p><p>With that, we conclude the section on working with mouse events on the terminal, and also this introduction to terminal I/O management using Rust.</p><h3><strong>Summary</strong></h3><p>In this article, we learned the basics of terminal management by writing a mini text viewer. We saw how to use the Termion library to get the terminal size, set the foreground and background colors, and set styles. After this, we looked at how to work with cursors on the terminal, including clearing the screen, positioning the cursor at a particular set of coordinates, and keeping track of the current cursor position.</p><p>You’ve learned how to listen to user inputs and track the keyboard arrow keys for scrolling operations, including left, right, up, and down. We wrote code to display document contents dynamically as the user scrolls through it, keeping the constraints of the terminal size in mind. As an exercise, you could refine the text viewer, and also add functionality to convert the text viewer into a full-fledged editor.</p><p>Learning about these features is important for writing applications such as terminal-based games, editing and viewing applications and terminal graphical interfaces, and for developing terminal-based dashboards.</p><p>To read more about building fast and secure software for Linux/UNIX systems, check out Prabhu Eshwarla’s book <a href="https://packt.live/3aq8J9S">Practical System Programming for Rust Developers</a>. Explore Rust features, data structures, libraries, and toolchain to build modern systems software with the help of hands-on examples.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a44652b0f11" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Upgrading Existing .NET Apps to .NET 5]]></title>
            <link>https://packt.medium.com/upgrading-existing-net-apps-to-net-5-e3768052ec44?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/e3768052ec44</guid>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[webdev]]></category>
            <category><![CDATA[dotnet-core]]></category>
            <category><![CDATA[aspnet]]></category>
            <category><![CDATA[csharp]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Fri, 30 Apr 2021 12:53:00 GMT</pubDate>
            <atom:updated>2021-04-30T12:53:00.216Z</atom:updated>
            <content:encoded><![CDATA[<h3>Upgrading Existing .NET Apps to .NET 5</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*REkFiSQqPrsWDZGpcqtV9Q.png" /></figure><p>Upgrading an app to its latest platform version, just for the sake of upgrading, is usually not a fun exercise, especially if there is no new and exciting feature to be added. Fortunately, Microsoft has provided solid inter-compatibility between libraries developed for earlier versions of .NET and .NET 5 to make the migration process much smoother. The cherry on top is the underlying performance enhancement that will make the existing code run faster without any significant transformation by the app developer.</p><p>There are some technologies that Microsoft has decided not to port to the .NET 5 platform, such as <strong>Windows Communication Foundation </strong>(<strong>WCF</strong>) Server, <strong>Windows</strong> <strong>Workflow</strong>, and <strong>ASP.NET web forms</strong>. We will discuss the options to replace these technologies where it is feasible to do so.</p><p>In this article, you will learn about the following topics:</p><ul><li>Choosing the migration approach</li><li>Points to ponder regarding an as-is upgrade</li></ul><p>We’ll assume that you are already familiar with .NET Framework and Entity Framework as we are upgrading these to the latest platform. We will focus on the core aspects of these technologies that require transformation during migration to .NET 5.</p><h3><strong>Choosing the migration approach</strong></h3><p>Before starting the app migration process there are some big decisions that need to be made upfront.</p><p>If you are upgrading from any previous version of .NET Core, the implications are less severe simply because .NET 5 is a continuation of the same platform and the upgrade process is much simpler.</p><p>Migrating from .NET Framework, however, requires a bit more thought. There are a number of factors that will impact the approach, including the following:</p><ul><li>The size and footprint of the solution</li><li>The number of different technologies that comprise the solution (for example, desktop apps, web apps, and REST APIs)</li><li>Whether an unsupported technology (such as WCF Server) or .NET runtime feature (such as .NET Remoting) is used</li></ul><p>These factors can influence the .NET migration approach and in particular the decision about whether to migrate the whole solution at once or try to do it in different stages. Let’s review the pros and cons of both approaches.</p><p><strong>Big bang approach</strong></p><p>For small- and medium-sized solutions, it makes sense to upgrade the entire solution stack at once from .NET Framework to .NET 5. For large solutions, it might not be too practical due to time constraints. You would need to maintain two separate codebases, one each for .NET Framework and .NET 5, during the migration process, and if any new feature needs to be implemented, it could become hard to keep the two code bases in sync.</p><p>The benefit of this approach is its <em>simplicity</em>. Instead of worrying about compatibility issues between intermediate phases of the upgrade, we just have to ensure that the final version of all the solution pieces is compatible with .NET 5.</p><p><strong>Gradual upgrade</strong></p><p>An alternative approach is to identify the least-dependent libraries first. These are the projects that do not depend on other projects in the codebase. A common example of such projects is a library containing model definitions or shared helper functions. Once these libraries have been upgraded to .NET 5, we look for the next set of libraries that are only dependent on previously upgraded components. We then gradually move up the dependency ladder to migrate the components with all their dependencies previously migrated.</p><p>The .NET team has made it easier by making it possible to multi-target an assembly for multiple platforms. So, you can write code once and target it for both .NET Framework and .NET 5 platforms. This will obviously work for scenarios where feature sets across both platforms are the same, or similar. Once the shared libraries have been migrated, the executing app (desktop or web app) can be migrated to the latest platform to take advantage of .NET 5’s specific features. The complexity arises with this approach when a particular API is not supported on .NET 5. We would have to write a conditional compilation code so that unsupported API is only used when code is compiled for the .NET Framework platform.</p><p>Once the choice between the gradual versus big bang approach has been made, the next decision is whether to introduce any changes in the solution architecture.</p><h4><strong>Lift and shift versus architectural transformation</strong></h4><p>In the lift and shift approach, we try to minimize any fundamental changes to code and its constituent components. Once the application is up and running on the latest platform, architectural changes are taken aboard as a separate project. This is a simpler approach and there is less risk of upgrade failure, but the new platform must support the components from the previous platform.</p><p>For example, if you have built a WCF Server instance or have implemented inter-process communication using .NET Remoting, it is simply not possible to upgrade these technologies on an as-is basis on .NET 5 as .NET 5 does not support them.</p><p>Architectural transformation makes sense when new features are expected to be implemented as part of an upgrade exercise or in the near future. It is best to leverage the latest platform features and technologies to reduce the technical debt on an older platform.</p><p>The final decision that we need to make is about whether and how we upgrade third-party libraries.</p><h4><strong>Replacing third-party libraries with platform-provided features</strong></h4><p>A similar concern to the architectural changes that are discussed in the previous section is about making code improvements. This is especially tempting for third-party libraries when a newer alternative is provided by the framework itself.</p><p>In .NET Core and .NET 5, Microsoft provides a system API for JSON parsing and serialization named System.Text.Json. Similarly, libraries for <strong>dependency</strong> <strong>injection </strong>(<strong>DI</strong>), Microsoft.Extensions.DependencyInjection, and logging, Microsoft.Extensions.Logging, eliminate the need to use corresponding third-party libraries, especially for basic use cases. If you are using advanced features of existing libraries, then it is best to consult the documentation of the newer alternative to understand whether every feature is available as a drop-in replacement or whether significant development is required.</p><p>Also, sometimes it takes less effort to transform the feature than to keep trying to use the existing code or library in a backward-compatible fashion. For example, in .NET 5, it is easier to read application configuration from JSON files instead of *.config XML files, so it may be worthwhile upgrading the configuration reading code unless it is significantly customized in the existing codebase.</p><p>We will now review the points that would generally be applicable to most .NET like-for-like migration projects.</p><h3><strong>Points to ponder regarding an as-is upgrade</strong></h3><p>A transformation project can easily get quite large and complex, but sometimes it is possible to score some worthwhile technical improvements in the solution, where comparatively little effort brings good rewards in terms of code maintenance and performance.</p><p>With that in mind, the following subsections make some general points that will be applicable to most upgrade projects.</p><h4><strong>Unsupported technologies</strong></h4><p>While most of the .NET Framework technologies can be migrated relatively easily to the .NET 5 platform, some features and technologies do not have a direct replacement and will require redesign or, at a minimum, replacing code from a different library. In addition, due to the fast-paced nature of .NET Core/.NET 5 development, many features in libraries such as <strong>Entity Framework Core or ASP.NET Core </strong>get marked as obsolete or deprecated in newer versions. So, it is best to review release notes when migrating to newer versions of these libraries.</p><p>In this section, we will review what major .NET Framework features are not available and the possible approaches to replace these features.</p><p><strong>WCF Server</strong></p><p>WCF was originally released in November 2006. Since then, it has been a very popular inter-service communication mechanism for .NET developers. It has vastly improved technology compared to ASMX web services. Its major strength is the support for various communication protocols, inter-server communication, and intra-server communication with minimal coding changes.</p><p>While still used in many legacy applications, Microsoft has decided to not support WCF Server on the .NET Core/.NET 5 platform in favor of modern technologies such as REST APIs over HTTP or Google RPC (commonly known as gRPC) for contract-based RPCs. Both alternatives are cross-platform and support the most popular programming languages and cloud platforms.</p><blockquote><strong>Tip</strong></blockquote><blockquote>If you still want to continue development with WCF Server, one option is to consider the CoreWCF project, which is an open-source port of WCF to the .NET Core platform: <a href="https://github.com/CoreWCF/CoreWCF11">https://github.com/CoreWCF/CoreWCF11</a>.</blockquote><blockquote>At the time of writing, this project is still under development and not production-ready.</blockquote><p>The recommended approach is to use the REST APIs or gRPC for new features. Alternatively, you can upgrade the WCF client to .NET 5 and continue to use the WCF Server on .NET Framework until you have the time resources available to do the migration.</p><p><strong>ASP.NET Web Forms</strong></p><p>ASP.NET Web Forms is another technology that is being axed in .NET 5. Microsoft recommends migrating to Blazor WebAssembly for modern web UX development. Blazor supports C# and is quite scalable. The transformation from Web Forms to Blazor is not a simple task and requires considerable planning.</p><p>The following Microsoft article has guidance on transforming ASP.NET Web Forms apps to Blazor WebAssembly: <a href="https://docs.microsoft.com/en-us/dotnet/architecture/blazor-for-web-forms-developers/migration">https://docs.microsoft.com/en-us/dotnet/architecture/blazor-for-web-forms-developers/migration</a>.</p><p>ASP.NET Web Forms was introduced in 2002 and now (if not before) is a good time to port the code to newer technologies. If you could consider using a non-C# technology, modern JavaScript-based UI frameworks such as Angular and React provide a robust feature set to build a sleek UX.</p><p><strong>Windows Workflow Foundation (WWF or WF)</strong></p><p>WWF’s primary feature set is to reduce coding for developing and automating repeatable business processes. It does so by providing an API, an in-process workflow engine that supports long-running processes, and a visual designer.</p><p>Compared to WCF Server and Web Forms, WWF’s market footprint is somewhat reduced. There is no direct alternative to this technology on .NET 5, but most of its functionality can be redesigned using a combination of gRPC, REST APIs, Azure Logic Apps, and Power Automate.</p><p>Like CoreWCF, there is an open-source fork of WWF available that is still in the experimental phase: <a href="https://github.com/UiPath-Open/corewf">https://github.com/UiPath-Open/corewf</a>.</p><p>We will now review some Windows platform-specific features that cannot be used from code when targeting .NET 5.</p><h4><strong>Unsupported Windows OS-specific features</strong></h4><p>Aside from the technologies mentioned in the preceding section, some platform-specific features for Windows OS are not available in .NET 5 platform libraries. These features should generally be of concern to Windows desktop developers when migrating to .NET 5.</p><p><strong>AppDomains</strong></p><p>AppDomains were primarily used to <em>isolate </em>application processes from each other. For modern applications, a better alternative for process isolation is to use containers, which are more versatile and flexible. There is also the AssemblyLoadContext class, which supports dynamically loading assemblies at runtime.</p><p>For ease of migration, .NET 5 provides some of AppDomains’ APIs; however, not all methods are guaranteed to behave in the same way. Some will throw PlatformNotSupportedException, some will do nothing, and others will continue to function as per previous behavior.</p><p><strong>Remoting</strong></p><p>A related feature to AppDomains is remoting, where processes living in different app domains can communicate with each other. This is no longer supported.</p><p>For communications across the network, REST and gRPC are recommended. For interprocess communication on the same machine, MemoryMappedFile or System.IO.Pipes can be used.</p><p><strong>Code Access Security (CAS)</strong></p><p>Sandboxing applications on the Windows platform allowed applications to execute in a constrained environment with restricted access to resources. This feature has been retired from .NET Framework itself, and so has not been ported to .NET Core or .NET 5.</p><p>The cross-platform alternative is to restrict process privileges by using containers and/or constrained user accounts.</p><p><strong>Security transparency</strong></p><p>Security transparency was used in sandboxed applications to declaratively specify access privileges required by code. This is generally used in Silverlight applications. As CAS is not supported, the related feature of security transparency is also not supported. The alternative is also the same as CAS, which is to use virtualization, containers, and user accounts to control the process privileges.</p><h4><strong>Transforming application configuration</strong></h4><p>In .NET Framework, application configuration is typically specified in app.config or web.config files in XML format.</p><p>An example appSettings section appears as follows:</p><pre>&lt;appSettings&gt;<br>     &lt;add key=”MaximumRowsPerPage” value=”10&quot; /&gt;<br>&lt;/appSettings&gt;</pre><p>.NET Framework implemented a hierarchy of configuration files, where a parent file’s settings can be inherited or overridden by a more specific file. For example, machine-specific settings can be specified in machine.config and then a web application can inherit or override these settings for its process in a web.config file.</p><p>These settings are accessed by developers using the System.Configuration namespace. This namespace is still available in the .NET Core world, but a more flexible approach with usually minor code changes is to use the Microsoft.Extensions.Configuration namespace, which offers considerable improvements.</p><p>The benefits of using the Microsoft.Extensions.Configuration namespace includes:</p><ul><li>Support for hierarchical <strong>plain old CLR object </strong>(<strong>POCO</strong>)-based settings</li><li>Built-in binding and validation for non-string values, such as int, bool, and decimal</li><li>Uniform handling and choices of configuration store, such as JSON files, XML files, in-memory objects, command-line arguments, and environment variables</li><li>Support for encrypted and cloud-specific stores, such as Azure Key Vault or Azure App Configuration</li></ul><h4><strong>Choosing the Entity Framework version</strong></h4><p>The majority of applications need to access databases for one use case or another. Entity Framework is a very popular choice for .NET developers as an <strong>object-relation mapping</strong> (<strong>ORM</strong>) tool to access the data layer in .NET Code.</p><p>The most recent major version of Entity Framework is Entity Framework 6. It is fully supported by Microsoft on the .NET Core platform, but all new development should be done on Entity Framework Core. EF Core supports .NET Framework (up to EF Core v3.1) and .NET 5 (all EF Core versions).</p><p>EF Core and Entity Framework do not have 100% feature parity; there are many new features in EF Core and some that will never be ported from Entity Framework to EF Core (due to low usage or radical design change), while some features are slated to be ported in future EF Core versions.</p><p>Refer to the official documentation for a detailed overview of the features that are not available on either platform: <a href="https://docs.microsoft.com/en-us/ef/efcore-and-ef6/">https://docs.microsoft.com/en-us/ef/efcore-and-ef6/</a>.</p><h4><strong>Using .NET Framework compatibility</strong></h4><p>A common migration approach is to port your libraries to .NET Standard first. .NET Standard libraries can be referenced from both .NET Framework and .NET 5 assemblies, which works great as an interim solution until both frameworks are in use in the organization.</p><p>With .NET Framework compatibility mode, .NET Standard projects can make references to .NET Framework libraries as if they were compiled for the .NET Standard platform. This helps remove a major migration blocker where migrating dependent libraries to newer platforms is not feasible in a short time frame.</p><p>Of course, having a compatibility layer does not automatically guarantee that all .NET Framework APIs will work on the .NET 5 platform. The APIs that are not supported will either throw PlatformNotSupportedException or might do nothing in some cases.</p><p>The vast majority of APIs are now ported on the .NET 5 platform, so using .NET Standard is a useful way to reference third-party NuGet packages that have not been updated by their developers despite having full API available on the new platform.</p><p>During our example migration exercise, we will learn about using the .NET Portability Analyzer tool, which can detect and inform about potential API incompatibility on the new platform.</p><h4><strong>Upgrading third-party NuGet packages</strong></h4><p>When using third-party NuGet packages, you can use one of the following approaches:</p><ul><li>If the current NuGet package version is .NET 5- or .NET Standard 2.1-compatible, then use that version.</li><li>If the current version does not support .NET 5/.NET Standard 2.1, but the later NuGet package version does, it’s likely a good candidate to be used. We need to review any breaking changes in the new version to assess the code refactoring effort required to use the new version.</li><li>The vast majority of active and popular NuGet packages fall under the first two cases. However, if there is no compatible version, then it is possible to use the .NET Framework library from .NET Standard code using the compatibility mode as described in the preceding section.</li><li>Another option is to use an alternative library, but this could potentially take significant time and cost to implement.</li></ul><p>We have now covered enough theoretical ground to understand the considerations and pitfalls of migration.</p><h3><strong>Summary</strong></h3><p>In this article, we’ve learned about different migration approaches and the pros and cons of each. There is no one-size-fits-all solution. The preferred approach depends on the compatibility of the technologies involved, the size of the existing code base, and the extent of dependence on the third-party NuGet libraries.</p><p>Sometimes it’s not possible to use the legacy technology, as we saw in the case of WCF Server, WWF, and Web Forms. Other technologies, such as gRPC, Blazor, and REST, can usually be used to replace the existing solutions in such cases.</p><p><em>Discover practical examples of upgrading .NET apps to .NET 5 and get ready to make the most of .NET 5’s features with Hammad Arif and Habib Qureshi’s book </em><a href="https://packt.live/30OPAsW"><em>Adopting .NET 5</em></a><em>.</em></p><h3><strong>Further reading</strong></h3><p>We have covered the most common migration scenarios of migrating WPF-, ASP.NET-, and Entity Framework-based applications from .NET Framework to .NET 5 while largely keeping the feature set as-is. You may also find the following resources helpful when migrating from other versions of .NET Core or upgrading a WinForms application to Blazor:</p><ul><li>There is a video titled <em>Porting Projects to .NET 5 </em>from the .NET 5 launch event on YouTube. It discusses the migration approaches from .NET Framework and .NET Core to .NET 5 with live demos: <a href="https://www.youtube.com/watch?v=bvmd2F11jpA">https://www.youtube.com/watch?v=bvmd2F11jpA</a>.</li><li>If you’re looking to replace Window Forms applications with Blazor, this YouTube video titled <em>Migrating a Windows Forms App to Blazor </em>from the .NET 5 launch event could be a good starting point: <a href="https://www.youtube.com/watch?v=bvmd2F11jpA">https://www.youtube.com/watch?v=bvmd2F11jpA</a>.</li><li>Every version of ASP.NET Core has breaking changes compared with the previous major version. You can review the official documentation for breaking changes and the migration guide for each version at the following Microsoft article: <a href="https://docs.microsoft.com/en-us/aspnet/core/migration/31-to-50?view=aspnetcore-5.0&amp;tabs=visual-studio">https://docs.microsoft.com/en-us/aspnet/core/migration/31-to-50?view=aspnetcore-5.0&amp;tabs=visual-studio</a>.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e3768052ec44" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exploring SharePoint Migration]]></title>
            <link>https://packt.medium.com/exploring-sharepoint-migration-14acfc937288?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/14acfc937288</guid>
            <category><![CDATA[microsoft-365]]></category>
            <category><![CDATA[sharepointserver]]></category>
            <category><![CDATA[sharepointybrid]]></category>
            <category><![CDATA[sharepointarchitercts]]></category>
            <category><![CDATA[sharepoint-2019]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Tue, 27 Apr 2021 08:18:59 GMT</pubDate>
            <atom:updated>2021-04-27T08:18:59.590Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lJ_vWcUhG_q6w1oLmiE4yg.png" /></figure><p>Migrating data is a tough role in any organization. Getting all the data from source to destination is a challenging task, especially with Microsoft SharePoint, mapped drives, and other storage resources. Users will complain about data being missing, even if it is irrelevant. In some cases, they will be irritated or even combative, because they are afraid of change. This overview will give you valuable insights to help you master these challenges to deliver a painless migration.</p><h3><strong>Getting ready: know your content</strong></h3><p>When contemplating a SharePoint migration, the first piece of advice is to plan and make sure you understand your users’ data, some of their processes, and the content they are using. You will also need to find out what data is relevant and what data may not be relevant before moving to the new environment. You will find this to be a daunting task when dealing with mapped drives because people do not know what the latest versions of files are in most cases; for example, some may be named FinalFinal. To make sure you’re using the correct files, you must work with the customer to clean up any irrelevant files before going forward. You have lots of choices when it comes to storage locations due to SharePoint and OneDrive being available. Don’t go back to mapped drives if you can avoid it, but if you do, clean up those files before moving them.</p><p>When looking at content, you must be prepared to classify and reclassify files as needed and tag them within the new environment correctly. The use of managed metadata and/or columns to describe the content is key for search results. Securing the data based on those classifications comes into play so that once they’ve been migrated to a document library, they can be secured. Files within the libraries can also be secured individually if needed. Breaking inheritance is also a concern at this point when you’re talking to your customer because you do not want to do this a lot when you’re setting up content. So, be mindful of how you set up new libraries in the new environment.</p><p>Here is a list of areas to pay attention to before migration:</p><ul><li>File size</li><li>Individual permissions</li><li>URLs (file paths) and file names</li><li>File sizes</li><li>Character limitations</li><li>Custom solutions</li><li>Branding</li><li>InfoPath</li><li>Workflow state and history</li><li>Permissions (do you have access to all the files?)</li><li>Folders with more than 5000 items</li><li>Unsupported site templates</li><li>Orphaned users</li><li>Checked out files</li><li>Unsupported list templates</li><li>File extensions</li></ul><p>We must also remember that even with mapped drives, we can also migrate to OneDrive. Security and various options for folder organization will help the customer manage those files. It’s not like SharePoint, but if a customer wants to implement this type of storage location, be ready to answer questions. This is contingent on you being in a hybrid environment where you already have Microsoft 365 set up.</p><p>If you’re working with MS SharePoint, you will also need to look at versioning settings, column types, and any updated aspects that are moving from one version of SharePoint to another. Help them understand that moving to this new location will give them more control over the data from a security aspect; waiting for an admin to update security for new and existing users within mapped drives is also possible.</p><p>This sometimes gets them excited about moving and helps them relax, which will make your users feel as though everything is going to be OK. Show them that you have investigated everything and build confidence in the migration by having meetings about this migration. You can even suggest the use of retention libraries for holding documents online either with OneDrive or SharePoint so that the customer understands there are choices when it comes to how old documents can be handled. Processes can be put in place for handling new files that need to be moved to a separate location for safekeeping as well.</p><p>As we mentioned previously, this is not an easy task. You are in the hot seat to figure out how to get 100% of your identified content from one version to the other. We will talk about some of the areas to focus on and which migration method will work for your migration scenario. We have also identified some migration tools within the method to give you a breakdown of my experiences with those tools.</p><p>We will also talk about creating schedules for your departments and testing with users as we also want to break down the use of preliminary migrations and final migration testing. If you have not, and we will say this again, create new dev and test environments to make sure you can provide areas within the environment where users can test their content and have new ways of accessing it.</p><p>As part of our environment, we should have dev, test, and production environments, which gives us a complete, functional SharePoint environment. This means we have a place we can test out migrations and have the user test them too. The last thing you want to do is a test in your test and production environments; always do this during the development phase. If you have these environments set up, then we can move on and find out what we need to do in order to start moving content from our old farm to the new one. Make sure all your farms have been configured correctly and are the same so that the results of the tests will be the same across the board. Configuration management is important!</p><p>During migrations, you also want to make sure you put source content in read-only mode when doing final migrations so that nothing is changed during this process. There are many things you need to make sure are in place before we start this migration. Take full backups of content before the migration, as well as once you have got the content over to the new farm. This backup should be taken once you have settled all issues and confirmed that all the errors have been fixed with the customer. This helps create a baseline that acts as a safeguard from the migration of both the source and target farms.</p><h3><strong>Know your customers</strong></h3><p>Identify all the departments that are being migrated and create a list of departments and users (if possible). If you have departments that are ready to move and eager to take advantage of new technology, then work with those customers first. These departments are the ones that will be successful and will give you a chance to build a good story going forward. Make sure to interview all departments before picking and choosing a schedule as well.</p><p>The following are some example questions you should ask when performing department interviews:</p><ul><li>What are you currently using SharePoint for?</li><li>How big are some of the larger files that you will be migrating?</li><li>Is there anything you want to change on your current site?</li><li>Do you have any automated processes?</li><li>Do you have any custom applications?</li><li>Are there any file shares that will be migrated?</li><li>What do you do day-to-day with SharePoint?</li><li>Do you have any staff that can be contacted and can help drive the migration process?</li><li>When would you like to move?</li><li>Do you have any immediate or future goals for the product?</li></ul><p>It is crucial that the migration is successful. When you fail in front of IT staff, it is OK; you can recover since it’s a small subset of the project. However, when you get to the migration stage, this affects the company because everyone is watching. This also brings a spotlight on why some users do not like SharePoint. Do not give them any ammunition to criticize SharePoint because it can cause issues and it’s something you will have to live with for a while. Believe us, success is the goal here.</p><p>Some of the things you can do to be more in tune with your customers or department include understanding what they do. Knowing what they do and how they use SharePoint can go a long way in supporting the department during the migration process. If possible and if you have time, find out who used to work in those departments that might have data that is still valid in the source content. Knowing some of those user accounts that may not be in Active Directory now will help to troubleshoot errors going forward. Some tools that are used when migrating lists and libraries do not work well when versioning items that could have a user account specified in a people and group column because, when the item is migrated, it will fail. Use the tool mapping component to map users and groups if needed. By doing this, accounts that are not there can be masked with the admin account or another account so that the item does not fail during the migration.</p><p>Find out what your customer or department needs from you. Whether it is hand-holding or more information for them to feel comfortable, make sure you provide it. There might be multiple questions you wish to ask, including:</p><ul><li>Are you migrating a file share or SharePoint site?</li><li>Do you have access to the file share or SharePoint site?</li><li>How large are the files that are being migrated?</li></ul><p>Reduce the likelihood of any scheduling hold-ups by interviewing all departments before you finalize your schedule. If there is a person on the staff that would like to help or be that go-to person, find that out now so that they can be your liaison with the rest of the team.</p><p>Find out the immediate or future goals of the department. This is crucial so that you can get an understanding of where they would like to go with SharePoint. This also gives you the opportunity to discuss how SharePoint can help them manage data more efficiently. Having a demo ready for some of the new features within SharePoint can show you are prepared and that these features are working as they should in the new version. This gives the business analyst some information on what could be done to help them in the future. This is the time to start being proactive and not reactive with your customers. Start fresh and make this transition useful for everyone.</p><h3><strong>Migration — choosing your weapon of choice</strong></h3><p>When choosing how we migrate, we must look at the content and versions of SharePoint we are working with. Some questions that you should be asking yourself are as follows:</p><ul><li>What method should I use to get this task completed?</li><li>Should I purchase a tool to perform migration?</li><li>What are some other methods we can use to migrate content from the source to the destination?</li></ul><p>There are a few ways to migrate content in SharePoint:</p><ul><li>Content database migration</li><li>Using a migration tool</li><li>PowerShell migration</li><li>Manually using Windows Explorer</li></ul><p>Let’s take a look at these in more detail.</p><h4><strong>Content database migration</strong></h4><p>This is the out-of-the-box task of moving content from one farm to another. This supports migration from version to version and cross-web applications for on-premises environments. There are technical points that need to be addressed as part of both migration paths when using this method. This provides a better capture of the site from a bigger standpoint, but it does not give you some of the capabilities you may need in order to clean up content beforehand. This is best used when custom solutions are not involved, and the content is mostly out of the box.</p><h4><strong>Using a migration tool</strong></h4><p>This depends on whether you’re using an external application to move content from one SharePoint site to another site. These tools can be used for either on-premises or cloud migrations. This also means we can migrate from one version of a SharePoint farm to another SharePoint farm. Using a migration tool provides us with flexibility for scheduling, picking specific content, using mapping capabilities to map columns in lists, and updating permissions on items that may be held by users who no longer work at the company, to name a few. Governance tools also come into play with tools you select, as many companies provide those to help you understand your environment before migration.</p><p>One thing we do to speed up the migration process is to create as many server-named sites as possible to extend our web applications. This will give you many URL points of entry for content migrations so that you can use separate servers to push the content through, instead of using a DNS name where all traffic will hit one or two servers. The server resources are then separate from one another and you can have different admins pointing different tool installations to different servers. You will see no bottlenecks pushing content through as long as your SQL server can keep up with the influx of data.</p><p>Tools also allow you to make choices for other Microsoft cloud services and third-party solutions such as Google, Dropbox, and OneDrive. If you have a tool that can connect to those types of services and you want to migrate content from those repositories, this is the way to do it. A migration tool provides such integrations and can be helpful in moving these documents over to a new platform. It will also leave behind database errors found in the content, such as errors with solutions that were left behind from other versions, plus other content that may have faced errors due to database issues.</p><p>You can also use the tool in combination with content database migration and migrate your databases first, before using the tool on the weekend to push incremental changes to the content. This cuts down how long it will take you to move content and save you money since with most tools you must pay per GB. Unfortunately, you cannot use this method when moving to the cloud.</p><blockquote><strong>Important note</strong></blockquote><blockquote>Remember: your logging files will grow while you’re completing this process, and large amounts of logging data will be created on your SQL and SharePoint servers. Make sure that all your logging services for IIS and SharePoint are pointed to the Data or Log drive on your machine and that it has a lot of space during this process!</blockquote><h4><strong>PowerShell migration</strong></h4><p>PowerShell migration is another way we can migrate content. It is more tedious and requires you to be skilled in PowerShell. We do not recommend this method for newbies or admins who do not have this skill set already. The chances of errors occurring are high, and you do not want that when you are on a schedule. It is not the time to practice PowerShell at this point.</p><blockquote><strong>Tip</strong></blockquote><blockquote>Some examples of PowerShell being used as a migration tool can be found on Microsoft’s website at <a href="https://docs.microsoft.com/en-us/sharepointmigration/overview-spmt-ps-cmdlets">https://docs.microsoft.com/en-us/sharepointmigration/overview-spmt-ps-cmdlets</a>.</blockquote><h4><strong>Manual migrations</strong></h4><p>As an example, let’s say we have a folder on a server that is being used as a shared folder. This folder contains documents that need to be migrated to a SharePoint library. We can take these files from the shared folder and copy them directly into the library using the Windows Explorer functionality within the SharePoint library. This is an easy way to migrate documents from desktops, but the limitation is that you can only copy up to 100 documents at a time. You also do not have the opportunity to add column information or metadata to these documents as they are being uploaded.</p><blockquote><strong>Important Note</strong></blockquote><blockquote>Beware! Do not make the mistake of having a live site on a destination farm where you have not finished configuring your services. Make sure you have completed all configurations before you put any new ‘live’ sites in your new production environment. If you need to work with some of the departments and have sites that are live while migrating, ensure your dev and test environments are set up so that you can test any migrated content before it’s put into production as a live site. You can then make configuration changes there and not in production to test the farm.</blockquote><p>There are other ways we can use manual processes to move data as well. Microsoft Office tools such as Microsoft Access and Microsoft Excel allow us to move content from one list to another or one farm to another. All lists are basically Excel and Access databases.</p><p>So, capturing columns and pulling data back into another list is fairly straightforward using PowerShell and even just Access itself. Look around and see what you can find. In some instances, this may work when you are just moving small items or concentrating on one document library and don’t want to purchase something, or you don’t want users bothering the admin when it comes to moving the list through Central Administration.</p><p>The Central Administration tool, which can be used to export lists and libraries, can be seen in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*3CaMY6hQn0L0nr2UexbpSw.png" /><figcaption><strong>Figure 1 - Exporting a site or list</strong></figcaption></figure><p>As you can see, there are many ways to migrate content from SharePoint. Using the tools that work for your situation is the name of the game. Do not just take someone else’s word for it. Some tools work better for some people than others. It’s all about what you want to achieve, not how expensive or popular a solution is. Even within SharePoint, we can pull content from top-level areas and import them. In some cases, this would not work, while in others, it could be the best solution to use. Just make sure it works for you and your requirements.</p><p>Now that we have talked about the different ways we can perform migrations, next we will learn about the types of migrations that can be achieved.</p><h3><strong>Types of migration</strong></h3><p>In this section, we will cover different types of migration. This will provide you with a use case to follow once you start the migration process. The types of migration that can be achieved are as follows:</p><ul><li>Version to version</li><li>Server to server</li><li>Service to service</li><li>Cross-web applications</li><li>Cloud migrations from on-premises</li><li>Third-party to on-premises and cloud</li><li>Files shares</li></ul><p><strong>Version to version</strong>: A version-to-version migration is when you migrate from a SharePoint 2013 farm to a SharePoint 2019 farm. However, as part of that migration, you need to validate your content through the in-between version of SharePoint — in this case, SharePoint 2016. This also needs to be a content database migration method.</p><p><strong>Server to server</strong>: Server-to-server migrations can be easy or may become very complex, depending on the way the content was structured in SharePoint. Server-to-server migrations could be when you migrate from one cloud to another cloud where you have the same version of SharePoint, or it could be when you need to upgrade the server platform from Windows Server 2012 R2 to Windows 2016 Server. This could be for licensing or supportability reasons, or just to keep your servers up to date with the latest and greatest server technology. If you are migrating from SharePoint 2007 to SharePoint 2019 using the content database migration method, this could be considered a server-to-server migration as well because when lifting content from 2007, you have to take it through the different versions of SharePoint to get the content to 2019.</p><p>When moving through 2010, 2013, and 2016, each server would have to be set up and configured to support the migration. There is also a step in the 2010 migration that will upgrade your workflows and InfoPath forms during the process, and there’s a tool to migrate you to 2019 from that point. You would have to manually migrate the business data catalog (BCS in 2019) from 2007 to 2010, for which you can refer to <a href="https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ff817559(v=office.14)">https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ff817559(v=office.14)</a>. After that, the services database could be moved through this process as well to keep those services intact as you move through the migration. You will also need to migrate classic users to claims, which occurs during the migration from 2007 to 2010. For more information on migrating from classic-mode to claims-based authentication in SharePoint 2013, refer to <a href="https://docs.microsoft.com/en-us/sharepoint/upgrade-and-update/migrate-from-classic-mode-to-claims-based-authentication-insharepoint-2013">https://docs.microsoft.com/en-us/sharepoint/upgrade-and-update/migrate-from-classic-mode-to-claims-based-authentication-in-sharepoint-2013</a>.</p><p><strong>Service to service</strong>: These migrations can be complex. We were recently on a migration from Rackspace to AWS and it was challenging due to the size of the content databases that we had to work with. Getting such databases transferred to a new service is tough, especially when you have small maintenance windows. The one thing to watch out for is the size, but also what type of web application configuration you choose.</p><p>Say, for instance, you chose Path-Based Web Applications as your standard application. Now, in terms of migration, all content needs to be migrated all at once, regardless of how many databases you have in that web application. If you do not move all the content databases at once, your users will have no way of getting to the content because there is no way to split the URL so that it talks to two separate farms.</p><p>However, you can migrate Host Named Site Collections one at a time or all at once. This is because the Host Name is the key to getting to the content, and it is associated with the site collection and not the web application. This is great when it comes to these types of situations, where content can be very hard to move to another service or farm. Plan accordingly so that you do not get caught in a situation like this, especially when you’re managing the sizes of your content databases.</p><p><strong>Cross-web applications (internal farm)</strong>: These migrations also happen during the production use of a SharePoint farm. You need to understand how or why you need to use any other migration methods mentioned at the beginning of this section. The approach you should use for list and library migrations would be to use a tool or use the area within Central Administration to extract the site, list, or library and then move the content from one site to another. Some tweaks may be involved here, but this is something you should explore, depending on your requirements.</p><p><strong>Migration to the cloud</strong>: This can only be achieved using a tool or a very time-consuming manual method. Of course, a tool is preferred in this scenario due to the amount of time you would have to spend going through files and uploading them to SharePoint Online. The manual process would be to download all files to a local system and then upload them back into the new farm libraries. This would mean reapplying all permissions, as well as losing version history. We can see why a tool is very important when migrating to the cloud. Most tools charge you per GB, so please budget for this!</p><p>We remember migrating from DocuShare a few years ago and the only tool available was the command line. During that process, you could export all the files, but a lot of information was lost. At the time of writing, there are lots of command-line tools, such as JSOM, that can help define these files and permissions. They are exported in a flat-file structure to help pull that information into SharePoint and apply some metadata from the old system, which in some cases is not SharePoint.</p><p>You can also migrate many different types of information using tools to SharePoint or OneDrive. Some tools give you different capabilities with different applications. Some connect to Google Docs, Dropbox, and even some other applications. We have seen some tools, such as Saketa, offer Microsoft Teams migrations as part of their toolset.</p><p>Microsoft also has a free tool that can be used to perform migrations from an on-premises environment to the cloud. We have only used this tool once and it works as it should. However, at the time, it didn’t have a lot of bells and whistles compared to what other tools offer. We believe they have made updates to this tool, so if you are looking for one, try it and see if it will work for your project.</p><blockquote><strong>Important note</strong></blockquote><blockquote>Microsoft has its own migration tool that only migrates to the cloud. You can find more information at <a href="https://docs.microsoft.com/en-us/sharepointmigration/introducing-the-sharepoint-migration-tool">https://docs.microsoft.com/en-us/sharepointmigration/introducing-the-sharepoint-migration-tool</a>.</blockquote><p><strong>File shares</strong>: File shares are always forgotten, but the return on investment in migrating these files to SharePoint is huge. When we leave these files shared on servers, you are requiring these files to be hosted by one or many servers with extended storage space. These servers cost you money to run and always require disk space upgrades. Instead, pull these files into SharePoint and use the databases for sharing and managing these files.</p><p>OneDrive can also be used to hold personal files and get rid of MySites and the storage comes for free with your plan. The SharePoint 2019 Server must be set up to use a hybrid connection to the cloud.</p><p>The users win as well because they gain functionality when using SharePoint, and your help desk will love you for it. With this, you have the benefit of versioning and much more control over your files. You can also place the files into segregated site collections/document libraries so that there will be no slips in data security, unlike file shares. They will also not be calling the help desk to add users to certain folders, which will cut down administration use as well. Users can also use files for workflow processes, versioning, and other collaborative means. They can include these files in links throughout sites in order to share information using the latest version of the file via Manage Copies.</p><h3><strong>Migration tools</strong></h3><p>Most tools run on any OS platform and provide a lot of options when it comes to migrating using mappings, PowerShell, and scheduling. Our experience with ShareGate has been great, but it does not offer an array of solutions as it seems to concentrate on the migration and governance space. As far as the tool goes, it is great and provides everything you need to prepare for a smooth migration process. We have not had many issues using the product, and we would say that it is first class!</p><p>ShareGate has been the tool of choice for our migrations. We really like both ShareGate and Saketa. Unlike other tools in this space, ShareGate gives you a great desktop and many functionalities you will not see in other tools. The tool is inexpensive and runs on any Windows platform. Again, pricing is tiered, so you can find a comfortable spot that fits your budget based on your data requirements.</p><blockquote><strong>Important note</strong></blockquote><blockquote>If you are performing an on-premises migration, make sure to try out content database migrations first. This will save you money in the long run. You can then use ShareGate to push the deltas needed to finalize the updates to the user’s content when performing on-premises migrations.</blockquote><p>Some of the features of ShareGate are as follows:</p><ul><li>Auto-generates PowerShell scripts for all types of migrations with copy options</li><li>You can pre-test your migration to figure out errors before performing a real-time migration</li><li>Governance reporting features for pinpointing issues with governance</li><li>Gives you the option to import user and group mappings from Excel files</li><li>ShareGate Shell can be used to migrate on schedules and allows you to use PowerShell within the tool</li><li>Advanced options for managing more complex migration strategies</li><li>Provides a connection manager for performing SharePoint and OneDrive migrations</li><li>Performance improves when using Insane Mode for migrations</li><li>General bug fixes and updates are provided regularly</li><li>Easy to use.</li></ul><p>The following is a list of some of the tools that can be used for SharePoint migration:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*r_sdrxS4DhoR_90yGMMRjw.png" /><figcaption><strong>Figure 2 - Tools that can be used for SharePoint migration</strong></figcaption></figure><p>AvePoint also has a new migration tool called Fly that does not require any server resources. This really changed the game for the company’s migration offering from our perspective. It can be installed free of charge from the AvePoints enterprise application interface and is similar to portable applications such as ShareGate. The product is great! We have tested it, but not with a lot of data. Please check this tool out for your next migration and tell them we sent you!</p><p>Metalogix has been a key player in SharePoint since we can remember. We wrote up some of this information a while back with the first release of the product, and you definitely need to try this product. Although we had a bad experience with it, we have heard good things about the tool now and the features are very impressive. The downside to it is that is not very user-friendly, so there is a learning curve. Also this tool, despite its improvement, does not support PowerShell integration. We just wanted to update you on this tool to make it clear that you should try it.</p><p>Microsoft also has a free migration tool that allows you to migrate to Microsoft 365 from SharePoint On-Premises platforms, including 2016, 2013 including Foundation, and 2010 including Foundation. It also includes hooks for connecting to the network and local file shares. To find out more about this tool, please go to <a href="https://docs.microsoft.com/en-us/sharepointmigration/introducing-the-sharepoint-migration-tool">https://docs.microsoft.com/en-us/sharepointmigration/introducing-the-sharepoint-migration-tool</a>.</p><p>If you are looking for a planning and assessment tool, Microsoft provides the <strong>SharePoint Migration Assessment Tool </strong>(<strong>SMAT</strong>), a command-line tool that scans SharePoint farms<strong> </strong>to identify issues before you migrate. This will give you a report so that you can go back<strong> </strong>and fix any issues before migration. This tool can also be found in the preceding link.</p><p><strong>Managed metadata</strong>: This is a more complex migration. Some of the migration tools that are available allow you to migrate metadata using the methods provided by the tool. The issue with managed metadata is that there is a GUID for each term set, and the term within the service will not change if you migrate the data. So, if you are doing a service and content database migration, this method of migrating the databases works because there is no GUID change. If you cannot get these methods working and you must do a new installation, you will have to recreate the service and the terms within it.</p><p>When performing a content database migration, these details for the managed metadata can be brought over by backing up and restoring the managed metadata service database. When you’re creating your managed metadata service, you will use that restored backup to create the new service on the new farm. If you are using a content type hub, update that link using the following PowerShell script:</p><pre>Set-SPMetadataServiceApplication -Identity &quot;Managed metadata<br>Service Application&quot; -HubURI &quot;http://sitename/contenttypehub&quot;</pre><p>If this is not the method you would like to use to restore the service database, you can use the export-import method. When you migrate the service in this way, you will have to create the service first and then import the information using Excel. You can do that using the following PowerShell script:</p><pre>Add-PSSnapin Microsoft.SharePoint.Powershell $metadataApp= Get-<br>SpServiceApplication | ? {$_.TypeName -eq &quot;Managed metadata<br>Service&quot;} $mmsAppId = $metadataApp.Id $mmsproxy = Get-SPServiceApplicationProxy | ?{$_.TypeName -eq &quot;Managed metadata<br>Service Connection&quot;} Export-SPMetadataWebServicePartitionData<br>-Identity $mmsAppId -ServiceProxy $mmsproxy -Path &quot;C:\MMD.cab&quot;</pre><blockquote><strong>Important note</strong></blockquote><blockquote>Make sure you do not have any duplicates in your file before moving forward. If you have duplicates, the process will error on import.</blockquote><p>The script for importing is as follows:</p><pre>Add-PSSnapin Microsoft.SharePoint.Powershell $metadataApp=<br>Get-SpServiceApplication | ? {$_.TypeName -eq &quot;Managed<br>metadata Service&quot;} $mmsAppId = $metadataApp.Id $mmsproxy =<br>Get-SPServiceApplicationProxy | ?{$_.TypeName -eq &quot;Managed<br>metadata Service Connection&quot;} Import-SPMetadataWebServicePartitionData -Identity $mmsAppId -ServiceProxy $mmsproxy -Path &quot;//<br>SharedPath/MMD.cab&quot;</pre><p>Remember that if you were using managed metadata previously in your farm, then you need to migrate this service database and create a service application first before migrating any content. The content, when migrated, will find out whether this data is available so that it can populate the data in the fields that use metadata columns. In some cases, it may give you the functionality to migrate this metadata, depending on the tool you are using. When performing content database migrations, you will have to move the metadata first.</p><p>You also need to check that there is a Content Type Hub in your past farm. If so, you will want to make sure you configure that in the new SharePoint 2019 farm. You can do this by setting up a new site collection solely for this purpose and adding the URL to the Content Type Hub form field when editing your Managed Metadata Service application. You can also update the Content Type Hub using PowerShell, as shown in the preceding script, to create the service application. If you have already created it without it, use this script:</p><pre>Set-SPMetadataServiceApplication -Identity &lt;MMSAppName&gt; -HubURI<br>&lt;ContentTypeHub&gt;</pre><p>As you can see, there is a sequence you must follow when performing migrations, and scheduling is a big part of this process. Next, we will learn how and when to schedule migrations.</p><h3><strong>Scheduling migrations</strong></h3><p>At this point, everyone knows they are moving to the new SharePoint environment. Everyone is on edge to do this because, at the end of the day, most are afraid of change. So, how do we schedule migrations? Our take on this is that you start with the departments that are most eager to jump in. The reason you want to do this is that you will get the most help with the process from resources within the department. This creates a team effort that you might not get from another department, which could defeat the migration before it starts.</p><p>If you don’t have any eager departments, which we doubt you will, take one department that you have some camaraderie with or one of the hardest you will have to move due to complexity, and test their migration first. You can at least test migration with this first department and have the users test the migrated content and compare it between the source and the destination. You should be able to give them an error report from any migration type and work with them on how you will mitigate the errors when performing the final migration of the content.</p><p>In the <em>Types of migration </em>section, we discussed that migration tools have some scheduling automation capabilities that you can use to configure a migration and create a scheduled task when a particular content migration should run. You can also migrate using PowerShell by scheduling a command to execute on the server at a certain time, but most tools have this integrated with the product.</p><p>When running scheduled migrations, you do not have to be present. You could migrate several departments at a time if the content size is reasonable. This also depends on what your time frame is because you want to make sure your users have access to the content you’re migrating, maybe the next morning or after the weekend on Monday morning.</p><p>You will need to support the migration from time to time to monitor the progress of the migrations you are scheduling. Believe us, there are always errors. To help with such errors, you may need to assign tasks to people in your department to help monitor their progress. If you have tested your migrations and are pretty sure you have done the testing well, or if you know there is not much complexity in the site you’re migrating, then you may be able to let the scheduled migration run on its own.</p><p>If you were testing and used the most difficult customer based on the complexity of the content, then this would have given you a realistic look at the tool and any errors that come up, based on this content. Always take this on with all resources on the ground. If it is just you, get support from Microsoft, a third-party company, or from the company that owns the tools you purchased. This can be done successfully if you plan out the migration properly and identify any errors and mitigate them prior to a test migration.</p><p>Again, this may take a couple of test migrations, but the mitigation of errors that surface is the key to success and how quickly you can turn them around. Make sure you always take account of the time you may have to spend on the backend recreating content in a site. Again, if the solution is not available in the next version of the farm, you have to make sure you recreate it using a new tool and communicate the difficulty and/or discontinuation of the product to the customer.</p><blockquote><strong>Important note</strong></blockquote><blockquote>If you have a couple or even a few web applications, NEVER EVER migrate one web application if the services on the new farm are not stable. If you are still in configuration mode and making updates to services, DO NOT migrate anyone to that unstable farm. Once you have a stable service platform and you have tested those services, you can migrate your first set of user content.</blockquote><h3><strong>Concluding remarks</strong></h3><p>Success is the best way to build confidence in the company as you undertake migrations. Choose the right department to work with and test your migration. Review your errors and figure out how to fix them before the final migrations. This may take another test migration, but do not let the first migration fail. Do your best to be successful and have the department using the new environment brag about how easy it was to migrate so that others will be at ease and want to move immediately.</p><p>To find out how to bring on-premise and cloud collaboration features to life with Microsoft’s SharePoint Server, check out the book <a href="https://packt.live/3daPEcg">Implementing Microsoft SharePoint 2019</a> by Lewin Wanzer and Angel Wood.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=14acfc937288" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is Moodle Workplace?]]></title>
            <link>https://packt.medium.com/what-is-moodle-workplace-266bca65f42f?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/266bca65f42f</guid>
            <category><![CDATA[enterprise-lms]]></category>
            <category><![CDATA[employee-onboarding]]></category>
            <category><![CDATA[learningmanagementsystem]]></category>
            <category><![CDATA[remote-working]]></category>
            <category><![CDATA[moodlecore]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Fri, 23 Apr 2021 10:02:23 GMT</pubDate>
            <atom:updated>2021-05-17T14:20:02.385Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N_EfzkiJnx-uJgswNOTo0A.png" /></figure><p>Moodle is the most-used <strong>Learning Management Systems </strong>(<strong>LMS</strong>) there is, and now it’s joined by <strong>Moodle Workplace</strong>. In this overview, we introduce Moodle Workplace and describe its various new key features. We then compare this newly updated software with standard Moodle, its little sibling, and with Totara, the other popular Moodle distribution for learning in organizations and businesses. Finally, we explore Moodle Workplace’s business model and its versioning policy.</p><h3><strong>Introducing Moodle Workplace</strong></h3><p>An open-source LMS that has been developed by Moodle Pty Ltd, Moodle Workplace is based on standard Moodle and has extra features specially designed for corporate and organizational training, resulting in a powerful and flexible platform for workplace learning (<a href="https://moodle.com/workplace">https://moodle.com/workplace</a>).</p><p>The main targets for Workplace are companies — from small to medium enterprises, all the way to global corporations and governments (regional and national), as well as public-sector and non-governmental organizations such as charities, foundations, and healthcare providers. However, Moodle Workplace is not limited to these organizations: a university might make use of Moodle Workplace for the training and development of its employees while using standard Moodle as their LMS for students.</p><p>The key features of Moodle Workplace are as follows:</p><ul><li><strong>Multi-tenancy</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*f0VLIdTwltYl4otoIah2Zw.png" /></figure><p>Allows you to create different tenants in the same Workplace installation. These are completely isolated from each other with their own look and feel, structure, users, and learning entities.</p><p>There might be multiple hospitals belonging to the same trust, but each with their individual corporate identity and their own employees organized in their local department structure. There is likely to be learning content unique to the hospital’s specialism, but also courses that are shared across hospitals.</p><ul><li><strong>Organization Structure</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*bUk_9GyejzEwrr4OeE8OQA.png" /></figure><p>Allows you to model your organization with multiple hierarchical department and position frameworks, and define reporting lines assigning jobs to your staff, giving managers visibility on learning progress.</p><p>The departments of a heart clinic might be Cardiac Imaging and Testing, General Cardiology, Heart Rhythm/Electrophysiology, Interventional Cardiology, and Peripheral Vascular Disease Treatment. Typical positions are Cardiologist, Electrophysiologist, and Cardiac Nurse. A job assignment would assign user Joe Flutter to the position of Cardiac Nurse in the Department of Electrophysiology, which is managed by user Joanne Ticker.</p><ul><li><strong>Report Builder</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*nfRQighIS5_rrOxeFJ7ebQ.png" /></figure><p>Allows you to build and customize your own reports with drag’n’drop, instant preview, inline column editing, groupings, aggregation, and restriction to specific audiences from various data sources, including the internal Workplace datastore.</p><p>A typical report would display all staff who have completed the course <em>Clinical Documentation</em> and can be filtered by department and position.</p><ul><li><strong>Dynamic Rules</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*RaXQAY4B1iTBp6vDBDM7tA.png" /></figure><p>Allows you to define and execute centralized and automated rules using an ‘if this then that’ conditional approach to trigger actions when certain conditions are met.</p><p>A sample rule might stipulate that upon course completion of <em>Clinical Documentation</em>, a message is sent to his/her manager and a certificate of completion is issued alongside a badge.</p><ul><li><strong>Programs</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*CauT_zWLFm41vj75lX3KWw.png" /></figure><p>Allows you to establish learning pathways for your employees by adding a combination of courses or a hierarchical sequence of courses. You have the tools to control what learners need to complete to progress and ensure depth understanding of subjects by defining different completion criteria at the program and set levels.</p><p>A typical program comprises a number of courses that make up an onboarding program for a particular audience, for instance, nursing apprentices. The assignment to a program can take place via dynamic rules, and reporting shows the progress of all recent hires.</p><ul><li><strong>Certifications</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*kp8Z9E0yGcj3y2KDdl1C7g.png" /></figure><p>Allows you to validate learning paths by offering certifications for recurring programs. Ensure your staff is compliant, enabling certification expiry and re-certification pathways.</p><p>Certifications are used for compliance training. Typical compulsory training with a validity period in the hospital context are health &amp; safety and hygiene sessions.</p><ul><li><strong>Certificates</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*M1RtuTtUtgvI5Gyl1ZMIMQ.png" /></figure><p>Allows you to issue certificates to learners or teams in any context: side-wide, per tenant, by category or course. The creation of diplomas takes place in a built-in certificate designer supporting digital signatures.</p><p>Certificates can either be used as incentives for hospital employees, or they become part of the staff’s employment record, in particular when there is a legal requirement to complete a course, program, or certification.</p><ul><li><strong>Appointment Bookings</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/76/1*KHvLVn-x4D5fBKrWc-u_fg.png" /></figure><p>Allows you to create one-to-one meetings or seminars with multiple sessions through its internal booking system. Session management supports bulk events creation, attendance handling, and wait-listing features.</p><p>A ward manager might schedule regular 1:1 sessions with all nurses to discuss any issues in the facility. Both scheduling and attendance recording takes place via the Appointment bookings module.</p><ul><li><strong>Mobile App</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/72/1*-aWfZptHGRVfjkMK1KsHnA.png" /></figure><p>Allows you to provide your employees with a seamless e-learning experience across devices and allow your learners to fit learning around their life. A fully branded Workplace App supports your corporate identity for a fully customized experience.</p><p>Now that you are familiar with the key features of Moodle Workplace, let’s compare it with its little brother, standard Moodle.</p><h3><strong>Comparing Moodle Workplace and standard Moodle</strong></h3><p>Use of the term Moodle — both as a noun and a verb — has been synonymous with the leading open source LMS. However, there are multiple components in the Moodle product family, and the one almost everyone refers to as <em>Moodle </em>is technically called <strong>Moodle Core</strong>. The high-level components can be seen in the following diagram:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/309/1*P1c98XfjctvoX-8o0vIdNw.png" /><figcaption><strong>Figure 1 - Moodle Core versus Moodle Workplace</strong></figcaption></figure><p>Let’s have a closer look at each of the components in the preceding diagram.</p><h4><strong>Moodle Core or standard Moodle</strong></h4><p>The original open-source LMS, Moodle has become the de facto standard worldwide in educational settings, particularly in schools, colleges, and universities. Since its inaugural launch in 2002, Moodle Core has become the benchmark that every LMS is measured against. It has won a wide range of international accolades and established itself as an ecosystem for numerous educational tools and services.</p><blockquote><strong>Important note</strong></blockquote><blockquote>We are going to refer to Moodle Core as <strong>standard Moodle </strong>for simplicity and better readability.</blockquote><p>Standard Moodle contains facilities for formative and informal assessment, synchronous and asynchronous communication and collaboration, grading, competencies, and much more. Various standards, such as SCORM, LTI, and IMS, have been adopted, and integration via numerous standard protocols is available, including SOAP and REST web services, Active Directory, and SAML.</p><p>A key ingredient to the success story of Moodle is its flexibility and customizability. In addition to hundreds of application configuration options, various elements can be tailored to your needs, including the look and feel of the LMS to represent the corporate identity of your organization. Think of Moodle as a massive box of Lego bricks, where you can either follow pre-built sets or build your own individual system. A major contribution to the latter is Moodle plugins.</p><h4><strong>Moodle plugins and Moodle LMS</strong></h4><p>While standard Moodle is a powerful and comprehensive LMS, very few sites solely rely on the base system. Instead, add-on modules are used to supplement the feature set of standard Moodle to customize the platform to individual requirements. These add-ons are called Moodle plugins<strong> </strong>and are mostly community-contributed additions to standard Moodle, extending its functionality for a specific use case. At the time of writing, there are over 1,750 (!) entries in the official Moodle plugins database at <a href="https://moodle.org/plugins">https://moodle.org/plugins</a>.</p><p>There exist a plethora of third-party Moodle plugins that add new functionalities, fix problems, or integrate Moodle with external systems and cloud services. This also covers add-ons for commercial software popular in workplace settings, such as the following, for example:</p><ul><li><strong>Office systems</strong>: Microsoft has developed a suite of plugins to allow Microsoft Office 365 usage within Moodle. This includes logging in via OpenID, access to OneDrive, integration with Office resources, and Outlook calendar synchronization.</li><li><strong>Web conferencing</strong>: Various commercial web conferencing suppliers provide plugins for their system to be used from within a Moodle course. Examples are WebEx, Zoom, and BigBlueButton.</li><li><strong>Video platforms</strong>: Streaming is a highly effective way to transport video content, which is already supported via basic integrations with YouTube and Vimeo. The Moodle functionality for the latter can be nicely enhanced using the popular Video Time plugin. Additionally, dedicated video platforms such as Kaltura also provide suites of plugins for smooth integration with Moodle.</li></ul><p><strong>Moodle LMS </strong>is effectively standard Moodle plus — optionally — one or many Moodle plugins.</p><h4><strong>Workplace plugins</strong></h4><p>Moodle has developed a set of Workplace plugins<strong> </strong>that contain the key features of Moodle Workplace that sit on top of Moodle LMS.<strong> </strong>All Moodle plugins still work in Moodle<strong> </strong>Workplace, with the rare exception of features that conflict with Workplace functionality.</p><p>Some of the Moodle Workplace plugins will make their way into standard Moodle over time, so Moodle LMS users can benefit from the investment that has gone into the Enterprise Edition of Moodle. The priority and timing will be determined through a collaborative approach with the Moodle community and Moodle Partners.</p><p>This section has given you a brief overview of the delta between standard Moodle and Moodle Workplace. Since Workplace is an extension of Moodle LMS, the differences are clear cut. This is different when it comes to Totara Learn, which we will cover in the next section.</p><h3><strong>Comparing Moodle Workplace and Totara Learn</strong></h3><p>Totara LMS is a subscription-based Moodle distribution that was launched in 2010 by Totara Learning (<a href="https://totaralearning.com/">https://totaralearning.com</a>). Initially, it was an extension to standard Moodle, plus some plugins, that was kept in lockstep with Moodle’s releases until version 2.9. Moodle introduced competencies and learning plans in version 3.1, which conflicted with their counterparts in Totara. Totara LMS was renamed Totara Learn; the latest version is Totara Learn 13.</p><p>Totara Learn is now part of a product family — <strong>Totara Experience Platform </strong>(<strong>TXP</strong>) — that comprises the following three interlinked components:</p><ul><li><strong>Totara Learn</strong>: An LMS for training and development</li></ul><p>Totara Learn is Totara’s flagship product and has been the only serious contender among the open-source Moodle LMS distributions for the commercial sector until Moodle Workplace arrived on the scene. Totara Learn is the product in the Totara suite that is used for comparison with Moodle Workplace in this article.</p><p>Key features include online learning design and delivery, offline seminar management, assessment and certification, learning plans, program management, adaptive learning, and reporting.</p><ul><li><strong>Totara Engage</strong>: A Learning Experience System (LXP) focused on social learning</li></ul><p>Totara Engage provides a secure social space powered by people, where learning comes recommended and self-directed, and not just mandated by the organization. Totara Engage is an LXP that supports day-to-day workplace communication, knowledge sharing, and discovery.</p><p>Key features include peer-to-peer content creation and sharing, collaborative workspaces, integration with Microsoft Teams and Slack, informal learning, messaging, discussion, recognition, pulse surveys, and action lists.</p><ul><li><strong>Totara Perform</strong>: A performance management tool supporting various HR activities</li></ul><p>Totara Perform is a flexible performance platform that allows organizations to proactively manage staff performance in order to operate more effectively and achieve their goals.</p><p>Key features include appraisals, check-ins, goals, OKRs, 360° feedback, competencies, evidence banks, and reporting dashboards.</p><p>Additional products might be added to the mix in the future, but for now, these are the available components. All three products make use of the same underlying core business logic represented in a shared services layer.</p><p>Totara Learn and Moodle Workplace target the same audiences and are effectively competing for products. You may ask what the differences are between the two available offerings. Generally, the dissimilarities can be grouped into three categories:</p><ul><li>Features unique to Moodle Workplace</li><li>Features unique to Totara Learn</li><li>Features that exist in both products but are implemented differently</li></ul><p>Let’s take a look at these in more detail.</p><h4><strong>Features unique to Moodle Workplace</strong></h4><p>There are several features that only exist in Moodle Workplace that are not offered by Totara Learn. An example is dynamic rules, where automation can be achieved via ‘if this, then that’ rules to trigger actions when certain conditions are met. For instance, when a course has been completed, a certificate will be issued, and a notification will be sent to the user and also to the responsible manager.</p><p>Totara Learn comes with so-called dynamic audiences, which support similar workflows, but are nowhere near as comprehensive or flexible as Workplace’s dynamic rules.</p><p>Another example is the migration tool, which supports the export and import of various Workplace elements into other Workplace instances.</p><h4><strong>Features unique to Totara Learn</strong></h4><p>Equally, some features are unique to Totara Learn. For instance, seminar management is a component covering room and equipment management, manager approval, sign-ups to the course catalog, and much more.</p><p>Moodle Workplace contains the appointments feature mentioned earlier, which covers some of the same use cases, but to date, it is no match for Totara’s seminar management functionality.</p><p>Another example is the highly customizable course catalog offered by Totara Learn. It allows users to browse, search, and filter courses, programs, and certifications. Moodle Workplace currently doesn’t have a catalog feature.</p><h4><strong>Features that exist differently in both products</strong></h4><p>Competencies and learning plans have already been mentioned as two features that exist in both products but have been modeled and implemented very differently.</p><p>Another good example is the way managers are modeled. In Totara Learn, a manager has a 1:1 relationship with a user; that is, one user is the manager of another user. Both users belong to one or many organizations. In Moodle Workplace, a user belongs to a department, and a manager is responsible for this organizational entity. Every user that belongs to the same department reports to the manager in charge. The result — one user is superior to one or many other users — is the same in both systems, but their implications when implementing user-profiles and synchronizing HR data are significant.</p><p>There are plenty of features that belong to this category but a full comparison is beyond the scope of this overview. Instead, we offer some pointers on how to decide which is the better product for your setup.</p><h4><strong>So, which is the better product?</strong></h4><p>The only way to answer this question is that <em>it depends on the project at hand and its requirements</em>. For instance, if your organization only provides sporadic face-to-face<em> </em>training, Moodle Workplace is likely to suffice. However, if you require full-blown seminar<em> </em>management, Totara Learn might be the better option. A thorough evaluation of each<em> </em>element and how it responds to your requirements is highly recommended to make an<em> </em>informed decision.</p><p>It must be noted that both systems continue to grow organically at a breakneck pace. Also, both product architects look sideways to see what the other side is doing, and we all know that competition is good for business!</p><p>Both Moodle and Totara offer their services through global partner networks. While the principles behind the partner models are similar, the business models are very different.</p><h3><strong>The Moodle Workplace business model</strong></h3><p>60% of Moodle’s revenue comes from the sectors targeted by Moodle Workplace, that is, commercial, not-for-profit, and government. Well-known examples of organizations that run Moodle include global enterprises such as Google, Cisco, Coca-Cola, Shell, Intel, and Bridgestone, but also large organizations such as the United Nations, which relies on Moodle as its LMS.</p><p>Most of Moodle’s revenue comes from Moodle Partners<strong> </strong>(Standard, Premium, and Integration), who pay royalties<strong> </strong>on all Moodle work. Customers<strong> </strong>who (hopefully) engage with a Moodle Partner pay fees<strong> </strong>for the services<strong> </strong>provided, such as consultancy, hosting, support, custom development, theme creation, and integration work. These high-level revenue streams are displayed in the following diagram, showing the overall Moodle business model:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/440/1*jgJo7gyJ0HohoEaKqhgAsg.png" /><figcaption><strong>Figure 2 - Moodle business model</strong></figcaption></figure><p>Moodle HQ employs a global team of staff who develop and maintain a range of offerings, comprising the following six products (see <a href="https://moodle.com/products">https://moodle.com/products</a> for more details):</p><ul><li><strong>Moodle LMS</strong>: Standard Moodle plus Moodle plugins (as covered previously).</li><li><strong>Moodle App</strong>: This includes the Moodle app, the Moodle Workplace app, and related chargeable branding services.</li><li><strong>MoodleCloud</strong>: A Moodle Software-as-a-Service (SaaS) offering of Moodle LMS and Moodle Workplace. There is a free basic plan for small Moodle LMS projects; all other packages are paid-for offerings.</li><li><strong>Moodle Workplace</strong>: Well, you know what this is…</li><li><strong>MoodleNet</strong>: An open-source social media platform for educators, integrated with Moodle and focused on collaboratively curating collections of open content.</li><li><strong>Moodle Education</strong>: The Moodle Educator Certification (MEC) program is a comprehensive teaching and learning curriculum designed to help you develop transferable knowledge and skills to be effective educators in today’s growing digital workplace.</li></ul><p>Both standard Moodle and Moodle Workplace are open source under the GNU Public License 3.0. However, unlike standard Moodle, which is available from the download section of <a href="https://moodle.org/">https://moodle.org</a>, Moodle Workplace is currently only available through Premium Moodle Partners (<a href="https://moodle.com/partners">https://moodle.com/partners</a>). Workplace can either be hosted in the data center facilities of a Moodle Partner or on-premises. The latter requires you to sign a three-way agreement between Moodle HQ, your Moodle (Premium) Partner, and your company. You need to agree to the Moodle Workplace License, which outlines your responsibilities as the customer.</p><p>The purpose of the aforementioned arrangement is to protect Moodle’s significant investment in Moodle Workplace and to ensure that the Workplace source code is not distributed to any third parties.</p><p>The other option for utilizing Moodle Workplace in your business is via <strong>Workplace on MoodleCloud</strong>, a SaaS offering from Moodle HQ. It is a turnkey solution for sites of up to<strong> </strong>1,000 users that includes a video conferencing tool (BigBlueButton) as well as access to<strong> </strong>content from GO1. However, Workplace on MoodleCloud does not allow you to install<strong> </strong>plugins or themes, and certain features and configuration settings cannot be changed.<strong> </strong>Depending on the chosen package, different Workplace features are limited, for instance,<strong> </strong>the number of tenants allowed or the number of custom reports that can be created. For<strong> </strong>more details and pricing, contact your Moodle Partner.</p><p>Now that you are familiar with Moodle’s business model and its primary revenue streams, let’s have a look at the Moodle Workplace versions, which differ slightly from the release schedule of standard Moodle.</p><h3><strong>Understanding Moodle Workplace versions</strong></h3><p>Moodle Workplace versions are based on the releases of standard Moodle, so Moodle Workplace 3.9.2 is based on standard Moodle 3.9.2. <strong>Minor versions </strong>of Workplace are released the day after their standard Moodle counterparts, which typically takes place on the second Monday of odd months (January, March, May, July, September, and November). The same applies to unscheduled releases in the case of a severe security issue or serious regression being fixed. <strong>Major versions </strong>of Workplace are released 1–2 weeks after the respective major version of standard Moodle. The release frequency is twice a year (the second Mondays of May and November).</p><blockquote><strong>Important note</strong></blockquote><blockquote>Moodle Workplace is always based on the official update (minor version) that does not have a ‘+’ sign.</blockquote><p>Currently, backporting to older releases is not supported by Workplace, even if the standard Moodle counterpart is still under support. However, this is likely to change in the future. The following timeline diagram demonstrates the interdependence between standard Moodle and Moodle Workplace releases:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*veG2yZ9uySz7XOGKZ1IO_A.png" /><figcaption><strong>Figure 3 - Release timeline for standard Moodle versus Moodle Workplace</strong></figcaption></figure><p>Version 3.7 was the first (mostly internal) version of Moodle Workplace. Version 3.9.2 is the most up-to-date release at the time of writing. Standard Moodle 3.5 and 3.9 are Long-Term Support (LTS) releases that will be supported for 3 and 5 years respectively. The next major release of standard Moodle will be version 4.0, to be released in November 2021.</p><p>For more information on standard Moodle releases, check out <a href="https://docs.moodle.org/dev/Releases">https://docs.moodle.org/dev/Releases</a>. You can find the release notes of Moodle Workplace at <a href="https://docs.moodle.org/en/Moodle_Workplace_Release_notes">https://docs.moodle.org/en/Moodle_Workplace_Release_notes</a>.</p><p>Each Moodle Workplace release is a full distribution that contains standard Moodle, all Workplace plugins including the Workplace theme, and several core modifications that can be either future core fixes or Workplace-only patches that allow Workplace plugins to hook into the Core functionality. That is, when installing Moodle Workplace, you do not have to install standard Moodle first and then add plugins or apply Core patches.</p><p>This section has provided you with an overview of the Moodle Workplace release schedule and its relationship with the standard Moodle releases. This timetable should be taken into account when planning updates and upgrades, as this is likely to involve maintenance work as well as some downtime.</p><h3><strong>Summary</strong></h3><p>In this article, you have learned about the key features of Moodle Workplace, such as multi-tenancy, dynamic rules, reports, and many more. You have also learned about the divergence between standard Moodle and Moodle Workplace, which is a powerful extension of the base product. The design and development of this delta between the two products is quite a technical masterpiece, maintaining 100% compatibility with standard Moodle while adding a plethora of features that can be used consistently throughout the system.</p><p>We looked at the popular Totara product suite and saw that important differences exist between Moodle Workplace and Totara Learn, both in terms of functionality and commercials. This led to a discussion of Workplace’s business model, showing its main revenue streams and stressing the importance of Moodle Partners. Finally, you gained some insight into the Workplace versioning policy and its dependencies on standard Moodle.</p><p>The depth and breadth of Moodle Workplace give it real clout as a learning solution for training and development. Yes, Moodle was a bit late to the party, but when it finally turned up, it brought a superstar of a guest along.</p><p><em>To learn more about what Moodle has to offer in the fast-growing online learning space and how to adopt Moodle Workplace in your organization, check out Alex Büchner’s book </em><a href="https://packt.live/312TrTt"><em>Corporate Learning with Moodle Workplace</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=266bca65f42f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What Is Cyber Threat Intelligence?]]></title>
            <link>https://packt.medium.com/what-is-cyber-threat-intelligence-7f369e5d773b?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/7f369e5d773b</guid>
            <category><![CDATA[security-analysts]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[threat-hunting]]></category>
            <category><![CDATA[threat-intelligence]]></category>
            <category><![CDATA[cyber-intelligence]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Tue, 20 Apr 2021 08:43:27 GMT</pubDate>
            <atom:updated>2021-04-20T08:43:27.029Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FuiPnXs_HBxK_qcvGGPliQ.png" /></figure><p>The objective of this overview is to help you become familiar with some of the main concepts and terminology used in the field of cyber threat intelligence (CTI). We shall cover the following topics:</p><ul><li>Cyber threat intelligence</li><li>The intelligence cycle</li><li>Defining your intelligence requirements</li><li>The collection process</li><li>Processing and exploitation</li><li>Bias and analysis</li></ul><p>With no further ado, let’s get started!</p><h3>Cyber threat intelligence</h3><p>If we want to discuss the roots of intelligence discipline, we could probably go back as far as the 19th century, when the first military intelligence departments were founded. We could even argue that the practice of intelligence is as old as warfare itself and that the history of humanity is full of espionage stories as a result of needing to have the upper hand over the enemy.</p><p>It has been stated over and over that in order to have a military advantage, we must be capable not only of understanding ourselves but also the enemy: how do they think? How many resources do they have? What forces do they have? What is their ultimate goal?</p><p>This military need, especially during the two World Wars, led to the growth and evolution of the intelligence field as we know it. Several books and papers have been written about the craft of intelligence, and I sincerely encourage anyone interested in the matter to explore the resources available on the CIA website (<a href="https://www.cia.gov/">https://www.cia.gov/</a>).</p><p>The definition of intelligence has been under academic discussion among people better-versed in the matter than me for more than two decades. Unfortunately, there is no consensus over the definition of intelligence practice. We shall use the definition proposed by Allan Breakspear in his paper <em>A New Definition of Intelligence</em> (2012) as a reference:</p><blockquote>Intelligence is a corporate capability to forecast change in time to do something about it. The capability involves foresight and insight, and is intended to identify impending change, which may be positive, representing opportunity, or negative, representing threat.</blockquote><p>Based on this, we are going to define CTI as a cybersecurity discipline that attempts to be a proactive measure of computer and network security, which nourishes itself from the traditional intelligence theory.</p><p>CTI focuses on data collection and information analysis so that we can gain a better understanding of the security threats facing an organization. This helps us protect its assets. The objective of any CTI analyst is to produce and deliver <em>relevant</em>, <em>accurate</em>, and <em>timely</em> curated information — that is, intelligence — so that the recipient organization can learn how to protect itself from a potential threat.</p><p>The sum of related data generates information that, through analysis, is transformed into intelligence. However, as we stated previously, intelligence only has value if it is relevant, accurate, and, most importantly, if it is <em>delivered on time</em>. The purpose of intelligence is to serve those responsible for making decisions so they can do so in an informed way. There is no use for this if it is not delivered before the decision must be made.</p><p>This means that when we talk about intelligence, we are not only referring to the product itself, but also to all the processes that make the product possible. We will cover this in considerable detail.</p><p>Finally, we can classify intelligence according to the time that’s been dedicated to studying a specific subject, either by distinguishing between <strong>long-term </strong>and <strong>short-term intelligence</strong>, or according to its form; that is, <strong>strategic</strong>, <strong>tactical</strong>, or <strong>operational intelligence</strong>. In this case, the intelligence that’s delivered will vary, depending on which recipients are going to receive it.</p><h4>Strategic level</h4><p>Strategic intelligence informs the top decision-makers — usually called the C-suite: CEO, CFO, COO, CIO, CSO, CISO — and any other chief executive to whom the information could be relevant. The intelligence that’s delivered at this level must help the decision-makers understand the threat they are up against. The decision-makers should get a proper sense of what the main threat capabilities and motivations are (disruption, theft of proprietary information, financial gain, and so on), their probability of being a target, and the possible consequences of this.</p><h4>Operational level</h4><p>Operational intelligence is given to those making day-to-day decisions; that is, those who are in charge of defining priorities and allocating resources. To complete these tasks more efficiently, the intelligence team should provide them with information regarding which groups may target the organization and which ones have been the most recently active.</p><p>The deliverable might include <strong>CVEs</strong> (common vulnerabilities and exposures) and information regarding the tactic used by, as well as the techniques of, the possible threat. For example, this could be used to assess the urgency to patch certain systems or to add new security layers that will hinder access to them, among other things.</p><h4>Tactical level</h4><p>Tactical intelligence should be delivered to those in need of instantaneous information. The recipients should have a complete understanding of what adversary behaviors they should be paying attention to in order to identify the threats that could target the organization.</p><p>In this case, the deliverable may include IP addresses, domains and URLs, hashes, registry keys, email artifacts, and more. For example, these could be used to provide context to an alert and evaluate if it is worth involving the <strong>incident response </strong>(<strong>IR</strong>) team.</p><p>So far, we have defined the concepts surrounding intelligence, CTI, and intelligence levels, but what do we understand by the term <em>threat </em>in the cyber realm?</p><p>We define a <strong>threat </strong>as any circumstance or event that has the potential to exploit vulnerabilities and negatively impact operations, assets (including information and information systems), individuals, and other organizations or societies of an entity.</p><p>We could say that the main areas of interest for cyber threat intelligence are <strong>cybercrime</strong>, <strong>cyberterrorism</strong>, <strong>hacktivism</strong>, and <strong>cyberespionage</strong>. All of these can be roughly defined as organized groups that use technology to infiltrate public and private organizations and governments to steal proprietary information or cause damage to their assets. However, this doesn’t mean that other types of threats, such as criminals or insiders, are outside the scope of interest.</p><p>Sometimes, the terms <strong>threat actor </strong>and <strong>advanced persistent threat </strong>(<strong>APT</strong>) are used interchangeably, but the truth is that although we can say that every APT is a threat actor, not every threat actor is advanced or persistent. What distinguishes an APT from a threat actor is its high level of <strong>operational security </strong>(<strong>OPSEC</strong>), combined with a low detection rate and a high level of success. Keep in mind that this might not apply perfectly to all APT groups. For example, there are some groups that feed on the propaganda from the attack, so they put a lower effort into not being identified.</p><p>In order to generate valuable intelligence, it is important to work with clear and defined concepts so that you can structure the data and generate information. It is not mandatory to choose an existing terminology, but the MITRE Corporation has developed the <strong>Structured Threat Information Expression </strong>(<strong>STIX</strong>) (<a href="https://oasis-open.github.io/cti-documentation/">https://oasis-open.github.io/cti-documentation/</a>) in order to facilitate the standardization and sharing of threat intelligence.</p><p>So, if we follow the STIX definition (<a href="https://stixproject.github.io/data-model/">https://stixproject.github.io/data-model/</a>), threat actors are “<em>actual individuals, groups, or organizations believed to be</em> <em>operating with malicious intent</em>.” Any threat actor can be defined by any of the following:</p><ul><li>Its <strong>type </strong>(<a href="https://stixproject.github.io/data-model/1.1/stixVocabs/ThreatActorTypeVocab-1.0/">https://stixproject.github.io/data-model/1.1/stixVocabs/ThreatActorTypeVocab-1.0/</a>)</li><li>Its <strong>motivations </strong>(<a href="https://stixproject.github.io/data-model/1.1/stixVocabs/MotivationVocab-1.1/">https://stixproject.github.io/data-model/1.1/stixVocabs/MotivationVocab-1.1/</a>)</li><li>Its <strong>sophistication level </strong>(<a href="https://stixproject.github.io/data-model/1.1/stixVocabs/ThreatActorSophisticationVocab-1.0/">https://stixproject.github.io/data-model/1.1/stixVocabs/ThreatActorSophisticationVocab-1.0/</a>)</li><li>Its <strong>intended effect </strong>(<a href="https://stixproject.github.io/data-model/1.1/stixVocabs/IntendedEffectVocab-1.0/">https://stixproject.github.io/data-model/1.1/stixVocabs/IntendedEffectVocab-1.0/</a>)</li><li>The <strong>campaigns </strong>it was involved in</li><li>Its <strong>Tactics, Techniques, and Procedures </strong>(<strong>TTPs</strong>) (<a href="https://stixproject.github.io/data-model/1.2/ttp/TTPType/">https://stixproject.github.io/data-model/1.2/ttp/TTPType/</a>)</li></ul><p>In summary, cyber threat intelligence is a tool that should be used to gain better insight into a threat actor’s interests and capabilities. It should be used to inform all the teams involved in securing and directing the organization.</p><p>To generate good cyber intelligence, it is necessary to define the right set of requirements for understanding the needs of the organization. Once this first step has been accomplished, we can prioritize the threats the team should be focusing on and start monitoring those threat actors that might have the organization among its desired targets. Avoiding the collection of unnecessary data will help us allocate more time and resources, as well as set our primary focus on the threats that are more imminent to the organization.</p><p>As <em>Katie Nickels </em>stated in her talk <em>The Cycle of Cyber Threat Intelligence </em>(2019, <a href="https://www.youtube.com/watch?v=J7e74QLVxCk">https://www.youtube.com/watch?v=J7e74QLVxCk</a>), the CTI team is going to be influenced by where they’ve been placed, so having them at a central position in the structure of the organization will help the team actually support different functions. This can be visualized as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/368/1*YnzaZIwMWsHVoXnMogJkhA.png" /><figcaption><strong>Figure 1 - CTI team center role</strong></figcaption></figure><p>We will now look at the intelligence cycle.</p><h3>The intelligence cycle</h3><p>Before we dive into the theory of the intelligence cycle, I believe it is worth showing the relationship between data, knowledge, and intelligence practice through what is known as a knowledge pyramid. In it, we can see how the facts, through measurement, are transformed into data that we can extract information from when processing it. When analyzed together, it can be transformed into knowledge. This knowledge interacts with our own experience and forms the basis of what we call wisdom. It is this ultimate wisdom that we rely on for decision-making.</p><p>As shown in the following pyramid, we can intertwine this knowledge pyramid with the processes that are part of what is widely known as the intelligence cycle:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/479/1*ZGr3GENgqDED8fRvvm1nlw.png" /><figcaption><strong>Figure 2 - DIKW pyramid</strong></figcaption></figure><p>In short, we can deduce that an intelligence analyst must process data to transform it into wisdom (intelligence), which in the last instance will lead to an action (decision).</p><p>Traditionally, the intelligence process is understood as a six-phase cycle: planning and targeting, preparation and collection, processing and exploitation, analysis and production, dissemination and integration, and evaluation and feedback. Each of these phases presents its own particularities and challenges:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/335/1*ii_5kSZ0yzthr_Be0-EvCg.png" /><figcaption><strong>Figure 3 - The intelligence cycle</strong></figcaption></figure><p>We will now look at each of these phases in detail.</p><h4>Planning and targeting</h4><p>The first step is to identify the <strong>intelligence requirements </strong>(<strong>IRs</strong>). Any information that the decision-makers need and don’t know enough about falls under this category.</p><p>In this stage of the process, it is important to identify the key assets of the organization, why the organization might be an interesting target, and what the security concerns of those in charge of making decisions are.</p><p>It’s also important to identify the potential threats that exist and what mitigations can be prioritized (through a process known as <strong>threat modeling</strong>), as well as establishing a collection framework and collection priorities.</p><h4>Preparation and collection</h4><p>This stage refers to defining and developing collection methods to obtain information regarding the requirements that were established in the previous phase.</p><p>It is important to keep in mind that it’s impossible to answer all the questions we may have and meet all our intelligence requirements.</p><h4>Processing and exploitation</h4><p>Once the planned data has been collected, the next step is to process it to generate information. The processing method is usually not perfect, and the amount of data that the intelligence team is able to process is always lower than the amount of data that has been gathered. All data that does not get processed is the same as data not collected at all. It’s lost intelligence.</p><h4>Analysis and production</h4><p>The information that’s been gathered so far must be analyzed in order to generate intelligence. There are several techniques that are used for intelligence analysis and to prevent the analyst’s bias. The cyber threat intelligence analyst must learn how to filter their personal views and opinions to carry out the analysis.</p><h4>Dissemination and integration</h4><p>In this stage, the intelligence that’s been produced is distributed to the necessary sectors. Before distribution, the analysts have to consider a variety of things, such as what the most pressing issues are among the intelligence that’s been collected, who should receive the report, how urgent the intelligence is or how much detail the recipient needs if the report should include preventive recommendations, and so on. Sometimes, different reports may need to be created and directed to different audiences.</p><h4>Evaluation and feedback</h4><p>This is the final stage of the process and probably the most difficult to achieve, mainly due to the usual lack of feedback from intelligence recipients. Establishing good mechanisms to get feedback helps intelligence producers evaluate the effectiveness of the intelligence that’s been generated before they repeat the process over and over, without making the necessary adjustments that will make the intelligence that’s produced more relevant to the recipients. As intelligence producers, we want our intelligence to be relevant — we want our intelligence to help the decision-makers to make informed decisions. Without gathering the appropriate feedback, we won’t know if we are achieving our goal, and we won’t know which steps to take to improve our product.</p><p>This model has been widely accepted and adopted, especially in the United States of America and among those who follow their academic discussions in an attempt to replicate its methods. Despite this wide acceptance, there have been some vocal criticisms against this model.</p><p>Some have pointed out that the current model depends excessively on the data that’s been collected, and also that technological advances have allowed us to collect massive amounts of it. This endless harvesting process and the capacity to better represent the data that’s been collected leads us to believe that this process is enough for us to understand what is happening.</p><p>There have been alternative proposals for the intelligence cycle. For anyone interested in studying more on this, a particularly interesting contribution has been published by <em>Davies, Gustafson, and Ridgen </em>(2013) titled <em>The Intelligence Cycle is Dead,</em> <em>Long Live the Intelligence Cycle: Rethinking Intelligence Fundamentals for a New Intelligence</em> <em>Doctrine </em>(<a href="https://bura.brunel.ac.uk/bitstream/2438/11901/3/Fulltext.pdf">https://bura.brunel.ac.uk/bitstream/2438/11901/3/Fulltext.pdf</a>), in which what has been labeled <em>the UK Intelligence Cycle </em>is described in detail:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/391/1*_hlEWvOvs0Olw7qwqerfnw.png" /><figcaption><strong>Figure 4 - The Core Functions of Intelligence (JDP 2–00) (3rd Edition)</strong></figcaption></figure><p>Now, let’s learn how to define and identify our intelligence requirements.</p><h3>Defining your intelligence requirements</h3><p>As defined by the United States Department of Defense, an <strong>intelligence requirement </strong>(<strong>IR</strong>) is as follows:</p><blockquote><em>1. Any subject, general or specific, upon which there is a need for the collection of information, or the production of intelligence.</em></blockquote><blockquote><em>2. A requirement for intelligence to fill a gap in the command´s knowledge or understanding of the battlespace or threat forces.</em></blockquote><p>The first stage in the intelligence cycle is to identify the information that the decision-maker needs. These requirements should be the driving factor in the intelligence team’s collection, processing, and analysis phases.</p><p>The main problem that occurs when identifying these IRs is that, usually, the decision-makers do not know what information they want until they need it. Moreover, other issues, such as resource and budget shortcuts or sociopolitical events, may arise, as well as difficult the task of identifying and satisfying the IRs.</p><p>Posing and trying to answer a series of questions, not only the ones stated here as examples, could be a good starting point when you’re trying to identify the PIRs (P for <em>priority</em>, referring to those that are more critical) and the IRs of an organization.</p><blockquote><strong>Important note</strong></blockquote><blockquote><strong>Identifying Intelligence Requirements</strong></blockquote><blockquote><em>When working out your intelligence requirements, ask yourself the following questions:</em></blockquote><blockquote><em>What’s the mission of my organization?</em></blockquote><blockquote><em>What threat actors are interested in my organization’s industry?</em></blockquote><blockquote><em>What threat actors are known for targeting my area of operation?</em></blockquote><blockquote><em>What threat actors could target my organization in order to reach another company I supply a service for?</em></blockquote><blockquote><em>Had my organization been targeted previously? If so, what type of threat actor did it? What were its motivations?</em></blockquote><blockquote><em>What asset does my organization need to protect?</em></blockquote><blockquote><em>What type of exploits should my organization be looking out for?</em></blockquote><p>There are four criteria to keep in mind when validating a PIR: the <strong>specificity </strong>and the <strong>necessity </strong>of the question, the <strong>feasibility </strong>of the collection, and the <strong>timeliness </strong>of the intelligence that would be generated from it. If the requirement meets all these criteria, we can start the collection process around it. In the next section, we will cover this in detail.</p><h3>The collection process</h3><p>Once the intelligence requirements have been defined, we can proceed with collecting the raw data we need to fulfill them. For this process, we can consult two types of sources: <strong>internal sources </strong>(such as networks and endpoints) and <strong>external sources </strong>(such as blogs, threat intelligence feeds, threat reports, public databases, forums, and so on).</p><p>The most effective way to carry on the collection process is to use a <strong>collection management framework </strong>(<strong>CMF</strong>). Using CMF allows you to identify data sources and<strong> </strong>easily track the type of information you are gathering for each. It can also be of use to<strong> </strong>rate the data that’s been obtained from the source, including how long that data has been<strong> </strong>stored, and to track how trustworthy and complete the source is. It is advised that you<strong> </strong>use the CMF to track not only the external sources but also the internal ones. Here’s an<strong> </strong>example of what one would look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/506/1*zbzG0NaSzFbrgNuNb5Q2Vg.png" /><figcaption><strong>Figure 5 - Simple CMF example</strong></figcaption></figure><p>Dragos analysts Lee, Miller, and Stacey wrote an interesting paper (<a href="https://dragos.com/wp-content/uploads/CMF_For_ICS.pdf?hsCtaTracking=1b2b0c29-2196-4ebd-a68c-5099dea41ff6|27c19e1c-0374-490d-92f9-b9dcf071f9b5">https://dragos.com/wp-content/uploads/CMF_For_ICS.pdf?hsCtaTracking=1b2b0c29-2196-4ebd-a68c-5099dea41ff6|27c19e1c-0374-490d-92f9-b9dcf071f9b5</a>) about using CMF to explore different methodologies and examples.</p><p>Another great resource available that can be used to design an advanced collection process is the Collection Management Implementation Framework (<a href="https://studylib.net/doc/13115770/collection-management-implementationframework-what-does-...">https://studylib.net/doc/13115770/collection-management-implementationframework-what-does-...</a>), designed by the Software Engineering Institute.</p><h4>Indicators of compromise</h4><p>So far, we’ve talked about finding the intelligence requirements and how to use the CMF. But what data are we are going to collect?</p><p>An <strong>indicator of compromise </strong>(<strong>IOC</strong>), as the name suggests, is an artifact that’s been observed in a network or in an operating system that, with high confidence, indicates that it has been compromised. This forensic data is used to understand what happened, but if collected properly, it can also be used to prevent or detect ongoing breaches.</p><p>Typical IOCs may include hashes of malicious files, URLs, domains, IPS, paths, filenames, Registry Keys, and malware files themselves.</p><p>It is important to remember that, in order to be really useful, it is necessary to provide context for the IOCs that have been collected. Here, we can follow the mantra <em>quality over</em> <em>quantity </em>— a huge number of IOCs does not always mean better data.</p><h4>Understanding malware</h4><p><strong>Malware</strong>, short for <strong>malicious software</strong>, is not everything, but it can be an incredibly valuable source of information. Before we look at the different types of malware, it is important for us to understand how the malware typically works. Here, we need to introduce two concepts: the <strong>dropper </strong>and the <strong>Command and Control (C2 or C2C)</strong>.</p><p>A <strong>dropper </strong>is a special type of software designed to install a piece of malware. We will sometimes talk about <strong>single-stage </strong>and <strong>two-stage </strong>droppers, depending on whether or not the malware code is contained in the dropper. When the malicious code is not contained within the dropper, it will be downloaded to the victim’s device from an external source. Some security researchers may call this two-stage type of dropper a <strong>downloader</strong> while referring to a two-stage dropper as the one that requires further steps to put different pieces of code together (by decompressing or executing different pieces of code) to build a final piece of malware.</p><p>The <strong>Command and Control </strong>(<strong>C2</strong>) is an attacker-controlled computer server that’s used to send commands to the malware running in the victim’s systems. It’s the way the malware <strong>communicates </strong>with its “owner.” There are multiple ways that a C2 can be established and, depending on the malware’s capabilities, the complexity of the commands and the communication that can be established may vary. For example, threat actors have been seen using cloud-based services, emails, blog comments, GitHub repositories, and DNS queries, among other things, for C2 communication.</p><p>There are different types of malware according to their capabilities, and sometimes, one malware piece can be classified as more than one type. The following is a list of the most common ones:</p><ul><li><strong>Worm</strong>: An autonomous program capable of replicating and propagating itself through the network.</li><li><strong>Trojan</strong>: A program that appears to serve a designated purpose, but also has a hidden malicious capability to bypass security mechanisms, thus abusing the authorization that’s been given to it.</li><li><strong>Rootkit</strong>: A set of software tools with administrator privileges, designed to hide the presence of other tools and hide their activities.</li><li><strong>Ransomware</strong>: A computer program designed to deny access to a system or its information until a ransom has been paid.</li><li><strong>Keylogger</strong>: Software or hardware that records keyboard events without the user’s knowledge.</li><li><strong>Adware</strong>: Malware that offers user-specific advertising.</li><li><strong>Spyware</strong>: Software that has been installed onto a system without the knowledge of the owner or the user, with the intention of gathering information about him/her and monitoring his/her activity.</li><li><strong>Scareware</strong>: Malware that tricks computer users into visiting compromised websites.</li><li><strong>Backdoor</strong>: The method by which someone can obtain administrator user access in a computer system, a network, or a software application.</li><li><strong>Wiper</strong>: Malware that erases the hard drive of the computer it infects.</li><li><strong>Exploit kit</strong>: A package that’s used to manage a collection of exploits that could use malware as a payload. When a victim visits a compromised website, it evaluates the vulnerabilities in the victim’s system in order to exploit certain vulnerabilities.</li></ul><p>A <strong>malware family </strong>references a group of malicious software with common characteristics and, most likely, the same author. Sometimes, a malware family can be directly related to a specific threat actor. Sometimes, malware (or tool) is shared among different groups. This happens a lot with open source malware tools that are publicly available. Leveraging them helps the adversary disguise its identity.</p><p>Now let’s take a quick look at how we can collect data around malware pieces.</p><h4>Using public sources for collection — OSINT</h4><p><strong>Open Source Intelligence </strong>(<strong>OSINT</strong>) is the process of collecting publicly available data. The most common sources that come to mind when talking about OSINT are social media, blogs, news, and the dark web. Essentially, any data that’s made publicly available can be used for OSINT purposes.</p><blockquote><strong>Important note</strong></blockquote><blockquote>There are many great resources for someone looking to start collecting information: VirusTotal (<a href="https://www.virustotal.com/">https://www.virustotal.com/</a>), CCSS Forum (<a href="https://www.ccssforum.org/">https://www.ccssforum.org/</a>), and URLHaus (<a href="https://urlhaus.abuse.ch/">https://urlhaus.abuse.ch/</a>) are great places to get started with the collection process.</blockquote><blockquote>Also, take a look at OSINTCurio.us (<a href="https://osintcurio.us/">https://osintcurio.us/</a>) to learn more about OSINT resources and techniques.</blockquote><h4>Honeypots</h4><p>A <strong>honeypot </strong>is a decoy system that imitates possible targets of attacks. A honeypot can be set up to detect, deflect, or counteract an attacker. All traffic that’s received is considered malicious and every interaction with the honeypot can be used to study the attacker’s techniques.</p><p>There are many types of honeypots (an interesting list can be found here: <a href="https://hack2interesting.com/honeypots-lets-collect-it-all/),">https://hack2interesting.com/honeypots-lets-collect-it-all/),</a> but they are mostly divided into three categories: low interaction, medium interaction, and high interaction.</p><p>Low interaction honeypots simulate the transport layer and provide very limited access to the operating system. Medium interaction honeypots simulate the application layer in order to lure the attacker into sending the payload. Finally, high interaction honeypots usually involve real operating systems and applications. These ones are better for uncovering the abuse of unknown vulnerabilities.</p><h4>Malware analysis and sandboxing</h4><p><strong>Malware analysis </strong>is the process of studying the functionality of malicious software. Typically, we can distinguish between two types of malware analysis: <strong>dynamic </strong>and <strong>static</strong>.</p><p>Static malware analysis refers to analyzing the software that’s used without executing it. <strong>Reverse engineering </strong>or <strong>reversing </strong>is a form of static malware analysis and is performed using a disassembler such as IDA or the more recent NSA tool, Ghidra, among others.</p><p>Dynamic malware analysis is performed by observing the behavior of the malware piece once it’s been executed. This type of analysis is usually performed in a controlled environment to avoid infecting production systems.</p><p>In the context of malware analysis, a <strong>sandbox </strong>is an isolated and controlled environment used to dynamically analyze malware pieces automatically. In a sandbox, the suspected malware piece is executed and its behavior is recorded.</p><p>Of course, things are not always this simple, and malware developers implement techniques to prevent the malware from being sandboxed. At the same time, security researchers develop their own techniques to bypass the threat actor’s anti-sandbox techniques. Despite this chase of cat and mouse, sandboxing systems are still a crucial part of the malware analysis process.</p><blockquote><strong>Tip</strong></blockquote><blockquote>There are some great online sandboxing solutions, such as Any Run (<a href="https://any.run">https://any.run</a>) and Hybrid Analysis (<a href="https://www.hybrid-analysis.com/">https://www.hybrid-analysis.com/</a>). Cuckoo Sandbox (<a href="https://cuckoosandbox.org/">https://cuckoosandbox.org/</a>) is an open source and offline sandboxing system for Windows, Linux, macOS, and Android.</blockquote><h3>Processing and exploitation</h3><p>Once the data has been collected, it must be processed and exploited so that it can be converted into intelligence. The IOCs must be provided with context, and their relevance and reliability must be assessed.</p><p>One way to approach this is to break data into buckets and take advantage of the available frameworks in order to look for patterns.</p><p>We are going to quickly review three of the most commonly used intelligence frameworks: The Cyber Kill Chain®, The Diamond Model, and The MITRE ATT&amp;CK™ Framework.</p><h4>The Cyber Kill Chain®</h4><p>Developed by Lockheed Martin, the Cyber Kill Chain® is a means to identify the steps the threat actor should follow in order to achieve their objective.</p><p>There are seven different steps:</p><p>1. <strong>Reconnaissance: </strong>Getting to know the victim using non-invasive techniques.</p><p>2. <strong>Weaponization</strong>: Generating the malicious payload that is going to be delivered.</p><p>3.<strong> Delivery</strong>: Delivering the weaponized artifact.</p><p>4.<strong> Exploitation</strong>: Achieving code execution on the victim’s system through the exploitation of a vulnerability.</p><p>5. <strong>Installation</strong>: Installing the final malware piece.</p><p>6. <strong>Command and Control </strong>(<strong>C2</strong>): Establishing a channel to communicate with the malware on the victim’s system.</p><p>7. <strong>Actions on objectives</strong>: With full access and communication, the attacker achieves their goal.</p><p>This model has been criticized for not being good enough to describe the way some modern attacks work, but at the same time, it has been praised for delimiting the points in which an attack can be stopped:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*vVBtkEY7vQwXf6yTZ_wPpg.png" /><figcaption><strong>Figure 6 - Lockheed’s Martin Cyber Kill Chain®</strong></figcaption></figure><h4>The Diamond Model</h4><p><strong>The Diamond Model </strong>provides us with a simple way to track breach intrusions since it helps us establish the atomic elements involved in them. It comprises four main features: adversary, infrastructure, capability, and victim. These features are connected by the sociopolitical and technical axes:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/490/1*eW9hS-x8nQyrro0qDlgDVA.png" /><figcaption><strong>Figure 7 - The Diamond Model</strong></figcaption></figure><p>We will now have a look at the MITRE ATT&amp;CK™ Framework.</p><h4>MITRE ATT&amp;CK™ Framework</h4><p>The MITRE <strong>ATT&amp;CK™ Framework </strong>is a descriptive model used to label and study the activities that a threat actor is capable of carrying out in order to get a foothold and operate inside an enterprise environment, a cloud environment, smartphones, or even industrial control systems.</p><p>The magic behind the ATT&amp;CK™ Framework is that it provides a common taxonomy for the cybersecurity community to describe the adversary’s behavior. It works as a common language that both offensive and defensive researchers can use to better understand each other and to better communicate with people not specialized in the field.</p><p>On top of that, you not only can use it as you see fit, but you can also build on top of it, creating your own set of <strong>tactics, techniques, and procedures </strong>(<strong>TTPs</strong>).</p><p>12 tactics are used to encompass different sets of techniques. Each tactic represents a tactical goal; that is, the reason why the threat actor is showing a specific behavior. Each of these tactics is composed of a set of techniques and <strong>sub-techniques </strong>that describe specific threat actor behaviors.</p><p>The <strong>procedure </strong>is the specific way in which a threat actor implements a specific technique or sub-technique. One procedure can be expanded into multiple techniques and sub-techniques:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*IcpmqbIromENq-tafVFZwA.png" /><figcaption><strong>Figure 8 - The Enterprise Matrix</strong></figcaption></figure><p>We will now have a look at bias and analysis.</p><h3>Bias and analysis</h3><p>Once all the necessary information has been processed, it is time to make sense of it; that is, search for the security issues and deliver this intelligence to the different strategic levels meeting the intelligence requirements that were identified during the planning step.</p><p>A lot has been written about how intelligence analysis should be done, especially in excellent books such as <em>Structured Analytic Techniques for Intelligence Analysis </em>(Heuer and Pherson, 2014), <em>Critical Thinking for Strategic Intelligence </em>(Pherson and Pherson, 2016), and <em>Psychology of Intelligence Analysis </em>(Heuer, 1999), among many others. These books employ many metaphors to describe the process of intelligence analysis.</p><p>My personal favorite is the one that compares the art of intelligence analysis with the art of mosaics: intelligence analysis is like trying to put the pieces of a mosaic together in which the pattern is not clear and the pieces continue to change in size, shape, and color.</p><p>One thing that an intelligence analyst cannot forget is that part of the practice is to challenge their own preconceptions and prejudices ceaselessly. Avoid confirmation bias, not to merely transmit the collected data, but to not fall for mirror imaging, clientelism, layering, and linear thinking. You should never influence the analysis so that it suits your needs or views. There are many techniques that can be used to mitigate analyst bias.</p><p>Some common traits are used to define a good intelligence analyst: he or she must have specific knowledge in more than one field; he or she must have a good spoken and written expression; and, most important of all, he or she must have the ability to synthesize the background of a situation almost intuitively.</p><p>In conclusion, we can close with the asseveration that in order to generate effective and relevant intelligence, there has to be a continuous intelligence process in place, with information from both internal and external sources being continually collected, processed, and analyzed.</p><p>This analysis must be tackled from different angles and by people with different perspectives and backgrounds in order to minimize the risk of falling into our own cognitive biases.</p><p>In addition, establishing good mechanisms for both disseminating quality and relevant intelligence reports, as well as getting feedback from the recipients, is key to enriching and improving this process.</p><h3>Summary</h3><p>In this overview, we’ve covered the definitions of cyber threat intelligence (CTI) and advanced persistent threats (APTs). We reviewed each of the steps involved in the intelligence cycle and provided an overview of how to carry out data collection and processing. Finally, we examined one of the main challenges that intelligence analysts face: analyst bias.</p><p>This introduction to cyber threat intelligence is part of Valentina Palacin’s <a href="https://packt.live/3sszbGN">Practical Threat Intelligence and Data-Drive Threat Hunting</a> book. If you want to start out in the cyber intelligence and threat hunting domains, this guide will help you explore the ATT&amp;CK™ Framework and open source tools to implement a threat hunting program from scratch.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7f369e5d773b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Configuring the Salesforce Mobile App]]></title>
            <link>https://packt.medium.com/configuring-the-salesforce-mobile-app-7dbf65487cf5?source=rss-8ef58ed680e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/7dbf65487cf5</guid>
            <category><![CDATA[user-interface]]></category>
            <category><![CDATA[salesforce]]></category>
            <category><![CDATA[mobile-apps]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[data-model]]></category>
            <dc:creator><![CDATA[Packt]]></dc:creator>
            <pubDate>Tue, 13 Apr 2021 10:56:41 GMT</pubDate>
            <atom:updated>2021-04-27T16:37:38.197Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/927/0*wCad5jRpbSloamLN" /></figure><p>This guide will show you how to configure the Salesforce Mobile App using declarative customization and actions in the Salesforce Lightning platform. You will learn about the features available to customize the Salesforce mobile application user interface, and you will learn how to configure actions and action layouts and optimize the Salesforce Mobile App user experience for users accessing the Lightning Platform on the go.</p><p>We will cover the following topics:</p><ul><li>Exam objectives — Mobile apps</li><li>Installing the Salesforce Mobile App</li><li>Configuring the Salesforce mobile application user interface</li><li>Building global and object-specific actions and action layouts</li></ul><h3><strong>Exam objectives — Mobile apps</strong></h3><p>To complete the Mobile section of the Certified Platform App Builder exam, app builders are expected to be able to carry out the following tasks:</p><ul><li>Describe the declarative customization options available for the Salesforce mobile application user interface.</li><li>Given a set of requirements, determine the appropriate global and object-specific actions and action layouts to optimize the Salesforce mobile application UX (user experience).</li></ul><blockquote><strong>Reference - Salesforce Certified Platform App Builder Exam Guide</strong></blockquote><blockquote>This guide is published by Salesforce and can be referenced at <a href="https://trailhead.salesforce.com/help?article=Salesforce-Certified-Platform-App-Builder-Exam-Guide">https://trailhead.salesforce.com/help?article=Salesforce-Certified-Platform-App-Builder-Exam-Guide</a>.</blockquote><p>In the Salesforce Certified Platform App Builder Exam Guide, the total number of questions is given, along with a percentage breakdown for each of the objectives, and an indication of the number of features/functions that can be expected in each of the objectives.</p><p>By analyzing these objectives, percentages, and question counts, we can determine the likely number of questions that will appear in the exam. For the Mobile objective, there are likely to be <strong>three questions</strong> in total (5% of 60 total exam questions).</p><p>To help reinforce the skills and knowledge required to create reports and build dashboards, there is some practical work for you to do in Salesforce, so if you do not have a Salesforce environment in which to carry this out, first create a free developer org.</p><p>The options and capabilities of the mobile features will be covered in this guide, and you will learn how mobile features enable you to design an appropriate user interface on the mobile platform and optimize the user experience.</p><p>Let’s now look at the Salesforce Mobile App and learn how to set up the app on mobile devices.</p><h3><strong>Installing the Salesforce Mobile App</strong></h3><p>Mobile phones and devices are ubiquitous within both our private lives and the business environment. In the current climate of mixing work from the office, the home, remotely, and on the move, organizations of all sizes have realized the benefits of using mobile devices to access business applications in today’s mobile-first world.</p><p>Mobile application development, however, is not always cost-effective, as the final product can be expensive to build or fails to meet user requirements. Not all mobile apps developed pass the test for usability, with apps built for mobile devices often lacking functionality and providing a poor user experience. New mobile apps or migrations of desktop apps to mobile sometimes fail as they are simply mobile screen overlays that are not fit for purpose. This can result in poor user adoption.</p><p>The Salesforce Mobile App differs in its approach as it is built within the Lightning Platform and configurations carried in the desktop are fully integrated and reflected in the mobile app. The mobile offering provided with the Lightning Platform provides a common security model and a common set of configuration features that provide an innovative, responsive, and easy-to-use mobile experience for users.</p><blockquote><strong>The Salesforce mobile web browser is no longer available</strong></blockquote><blockquote>Prior to the Summer 2020 release, there were two options for accessing Salesforce mobile features using a mobile device. The first was the downloadable Salesforce Mobile App and then there was a second option, the Salesforce mobile web browser app, which did not require any software installation and used the web browser on mobile devices.</blockquote><blockquote>Starting from the Summer 2020 release, the Salesforce mobile web browser app is no longer available. Users must use the downloadable Salesforce Mobile App to access the mobile features on mobile devices, as detailed in the following article: <a href="https://help.salesforce.com/articleView?id=000349471&amp;language=en_US&amp;type=1&amp;mode=1">https://help.salesforce.com/articleView?id=000349471&amp;language=en_US&amp;type=1&amp;mode=1</a></blockquote><p>The Salesforce Mobile App includes many of the customizations that have been configured within the desktop version of your organization and are therefore already partly tailored out of the box to deliver your mobile application requirements.</p><p>Let’s now look at which mobile devices are supported for use with the Salesforce Mobile App.</p><h3><strong>Supported mobile devices for the Salesforce Mobile App</strong></h3><p>The Salesforce Mobile App is accessible from most Salesforce editions and types of user licenses and is supported for use with the following two operating systems and versions: Apple iOS version 12.0 or later, and Android version 7.0 or later.</p><p>Salesforce conducts ongoing tests using various mobile phones and tablets to verify that the Salesforce Mobile App operates correctly with the stated platform.</p><p>At the time of writing, Salesforce has identified the following mobile phones as supported for use with the Apple iOS platform:</p><ul><li>iPhone 11 Pro and Pro Max</li><li>iPhone 11</li><li>iPhone XR</li><li>iPhone XS and XS Max</li><li>iPhone X</li><li>iPhone 8 and 8 Plus</li><li>iPhone 7 and 7 Plus</li><li>iPhone SE</li><li>iPhone 6S</li><li>iPhone 6</li></ul><p>Salesforce has identified the following tablets as being supported for use with the Apple iOS platform:</p><ul><li>iPad Pro 10.5 inch</li><li>iPad Air 2</li><li>iPad Mini 4</li></ul><p>At the time of writing, Salesforce has identified the following mobile phones as being supported for use with the Android platform:</p><ul><li>Google Pixel 4 XL</li><li>Google Pixel 3</li><li>Samsung Galaxy S10 and S10+</li><li>Samsung Galaxy S9 and S9+</li><li>Samsung Galaxy S8 and S8+</li><li>Samsung Galaxy S7</li><li>Samsung Galaxy Note 10+</li><li>Samsung Galaxy Note 9</li><li>Samsung Galaxy Note 8</li></ul><blockquote><strong>Salesforce Mobile App-supported devices and minimum platform requirements</strong></blockquote><blockquote>Salesforce may, at any time, change the list of supported devices and minimum platform requirements for the Salesforce Mobile App. The latest set of supported devices and minimum platform requirements can be accessed from the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=salesforce_app_requirements.htm&amp;type=5">https://help.salesforce.com/articleView?id=salesforce_app_requirements.htm&amp;type=5</a></blockquote><p>We will now look at how to set up the Salesforce Mobile App on a supported mobile device.</p><h4><strong>Setting up the Salesforce Mobile App</strong></h4><p>The Salesforce Mobile App is available from the App Store for mobile devices that are running on the iOS platform and from Google Play for mobile devices that are running on the Android platform.</p><p>We will step through the process of setting up the Salesforce Mobile App on an iOS device. The set-up process is similar for an Android device, although there may be some minor variations.</p><p>To access the installation links for the Salesforce Mobile App on an iOS device, perform the following steps:</p><ol><li>Navigate to the <strong>Getting started with the Salesforce Mobile App </strong>page by browsing to the web URL located at <a href="https://www.salesforce.com/solutions/mobile/getting-started/">https://www.salesforce.com/solutions/mobile/getting-started/</a>, as shown in the following screenshot:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/224/1*itNat2c9KZ8XzvGHae4g8Q.png" /><figcaption><strong>Figure 1 - Getting Started</strong></figcaption></figure><p>In this setup, we will install the Salesforce Mobile App on an Apple iPhone that runs under the iOS platform, so here we’ll select the App Store option.</p><p>2. Click on <strong>Download on the App Store</strong> within the <strong>Getting Started</strong> screen to navigate to the Salesforce App Store menu, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/243/1*2aPSpjmtYylH5u4PHSsA-g.png" /><figcaption><strong>Figure 2 - Salesforce on the App Store</strong></figcaption></figure><p>3. Click on <strong>Install </strong>in the <strong>App Store</strong>.</p><p>4. Wait for a few moments for the installation to complete and the screen will then change to present an option to open the Salesforce Mobile App, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/222/1*xkjlwmOmbrrnXimmMPLmZQ.png" /><figcaption><strong>Figure 3 - Salesforce Mobile App open</strong></figcaption></figure><p>5. Click on <strong>Open </strong>in the Salesforce Mobile App and this action will (upon navigation to the Salesforce Mobile App for the first time) present the <strong>Allow Access </strong>screen, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/219/1*v8z7GbeVvl1GhoYIQal_MA.png" /><figcaption><strong>Figure 4 - Salesforce Mobile App access permissions</strong></figcaption></figure><p>6. Click on <strong>Allow </strong>to permit the Salesforce Mobile App to gain access to your Salesforce organization, whereby the screen will then change to the <strong>Welcome to the Salesforce Mobile App </strong>screen, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/212/1*7wFHKtWvYPA56JziFCx4zQ.png" /><figcaption><strong>Figure 5 - The Salesforce Mobile App welcome screen</strong></figcaption></figure><p>7. Finally, click on <strong>Get Started </strong>to navigate to the Salesforce Mobile App menu, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/232/1*q6D9yuyYmNnBhUf2eitZWg.png" /><figcaption><strong>Figure 6 - The Salesforce Mobile App menu</strong></figcaption></figure><blockquote><strong>More information about setting up the Salesforce Mobile App</strong></blockquote><blockquote>To find out more information about setting up the Salesforce Mobile App, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=salesforce_app_set_up.htm&amp;type=5">https://help.salesforce.com/articleView?id=salesforce_app_set_up.htm&amp;type=5</a></blockquote><p>This will set up the mobile app. Now let’s look at the mobile app UI (user interface) options in the Lightning Platform.</p><h3><strong>Configuring the Salesforce mobile application user interface</strong></h3><p>The options and capabilities of the Salesforce Mobile App are not the same as the full Lightning Platform application, and there are many differences within the Salesforce Mobile App, in particular, concerning the ways in which data is entered, screens are presented, and navigation is carried out between screens.</p><p>Salesforce has built mobile-friendly alternatives to the way information is captured, and navigation takes place accordingly to cater for the much smaller screen real estate and the reduced capability of a mobile device to display functions and features to a user.</p><blockquote><strong>Differences between the full Lightning Experience app and the Salesforce Mobile App</strong></blockquote><blockquote>For more detailed information about the features that are not available in the Salesforce Mobile App when compared to the full Lightning Experience app, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=limits_mobile_sf1_parent.htm&amp;type=5">https://help.salesforce.com/articleView?id=limits_mobile_sf1_parent.htm&amp;type=5</a></blockquote><p>The features and capabilities that are available for configuring the Salesforce Mobile App user interface are as follows:</p><ul><li><strong>Lightning </strong>App Navigation Menu: The Lightning app navigation menu can be changed by users who have permission to personalize the desktop navigation bar. This also allows a user who has permission to edit the desktop navigation bar, for a given app, to reorder items in the navigation menu within the Salesforce Mobile App, for that particular app.</li><li><strong>Mobile Only </strong>Default Navigation Menu: The Mobile Only app allows you to create navigation items that become the default set of items within the Salesforce Mobile App.</li><li><strong>Mobile </strong>App Branding: This provides the facilities to configure the way in which the app appears.</li><li><strong>Global Quick Actions</strong>: These actions in the Lightning Platform can be thought of as shortcuts that appear within the user interface. A given global quick action is available in both the desktop and mobile apps and can be used to create records, log calls, and so on.</li><li><strong>Object-specific Quick Actions</strong>: In the same way as global quick actions, object-specific quick actions can be thought of as shortcuts that appear within the user interface. They are also available in both the desktop and mobile apps, but are associated with a specific Lightning Platform object type and can be used to update as well as create records, log calls, and so on.</li></ul><blockquote><strong>Customization options in the Salesforce Mobile App</strong></blockquote><blockquote>For more information about customizing the Salesforce Mobile App, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=salesforce_app_customize.htm&amp;type=5">https://help.salesforce.com/articleView?id=salesforce_app_customize.htm&amp;type=5</a></blockquote><p>Having looked at options for configuring the user interface, let’s now look at how the changes are reflected when personalizing the Lightning app menu in the Salesforce Mobile App.</p><h4><strong>Customizing a Lightning app navigation menu in the Salesforce mobile app</strong></h4><p>The Lightning app navigation menu can be personalized by any user who has permission to modify the navigation bar whereby they are able to add, remove (only for items that they have added), rename, and reorder items.</p><p>The modifications to the navigation bar are also applied to the navigation menu and navigation bar for the specific Lightning app within the Salesforce Mobile App, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*2yDSNQ7IKEqI3O6yYPaZEw.png" /><figcaption><strong>Figure 7 - The Lightning app navigation menu</strong></figcaption></figure><p>The preceding screenshot demonstrates reordering by placing the <strong>Leads </strong>tab to appear as the first item that is reflected in the Salesforce mobile app, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/211/1*37UHir_mA0UPHjtkB0bPYw.png" /><figcaption><strong>Figure 8 - The Lightning app navigation menu in mobile</strong></figcaption></figure><p>Having identified how the Lightning app navigation menu can be personalized, let’s now look at the Mobile Only default navigation menu in the Salesforce mobile app.</p><h4><strong>Customizing the Mobile Only default navigation menu in the Salesforce Mobile App</strong></h4><p>The Mobile Only default navigation menu can only be configured by users with system administrator permissions and is used to create navigation items that become the default set of items within the Salesforce mobile app.</p><p>By configuring the items that are presented to users, you can include Lightning pages, Visualforce pages, Lightning components, and so on in the default navigation menu and navigation bar of the Salesforce mobile app.</p><p>Modification of the navigation bar for the Mobile Only default navigation menu can be carried out by performing the following steps:</p><ol><li>Navigate to <strong>SETUP </strong>and then search for Salesforce Navigation in the <strong>Quick Find </strong>search box located at the top of the <strong>Setup </strong>menu on the left sidebar.</li><li>Click on <strong>Salesforce Navigation </strong>in the <strong>SETUP </strong>menu.</li><li>In the <strong>Salesforce Navigation </strong>setup screen, choose the items from the <strong>Available </strong>list and move them to the <strong>Selected </strong>list, as shown in the following screenshot:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*OFqQIa9Q-bO5hqJFohdCaQ.png" /><figcaption><strong>Figure 9 - The Mobile Only default navigation menu</strong></figcaption></figure><p>4. Finally, click on <strong>Save</strong>.</p><p>The <strong>Mobile Only </strong>default option shows the selected items in the Salesforce mobile app, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/231/1*3TEwB0qged7ZyQX0tLWq6A.png" /><figcaption><strong>Figure 10 - The Mobile Only default navigation menu in mobile</strong></figcaption></figure><blockquote><strong>Customization options in the Mobile Only default navigation menu</strong></blockquote><blockquote>For more information about customizing the Mobile Only default navigation menu, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=salesforce_app_customize.htm&amp;type=5">https://help.salesforce.com/articleView?id=salesforce_app_customize.htm&amp;type=5</a></blockquote><p>We will now look at the mechanism for setting branding for the Salesforce mobile app.</p><h4><strong>Mobile app branding</strong></h4><p>Mobile app branding provides the facilities to configure the way in which the app appears. Here, the features that can be configured are the loading page logo, the loading background color, and the header background color.</p><p>Mobile app branding modifications can be carried out by performing the following steps:</p><ol><li>Navigate to <strong>SETUP </strong>and then search for Branding in the <strong>Quick Find </strong>search box located at the top of the <strong>SETUP </strong>menu on the left sidebar.</li><li>Click on <strong>Salesforce Branding </strong>in the <strong>SETUP </strong>menu.</li><li>In the <strong>Salesforce Branding </strong>setup screen, click on <strong>Edit</strong>.</li><li>In the <strong>Salesforce Branding </strong>edit page, choose the colors for <strong>Brand Color </strong>and <strong>Loading Page Color</strong>, and then choose a <strong>Loading Page Logo</strong>, as shown in the following screenshot:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*SZOJmAf37DL2ssAOqQ0W-A.png" /><figcaption><strong>Figure 11 - Mobile app branding</strong></figcaption></figure><p>The loading page color and loading page logo appear within the Salesforce mobile app, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/222/1*GEupEEuIO-BW0rimaid1nw.png" /><figcaption><strong>Figure 12 - Mobile app branding on a mobile device</strong></figcaption></figure><p>The brand color appears within the Salesforce mobile app, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/236/1*aZKdFhHJqmCWrycawaS2Dg.png" /><figcaption><strong>Figure 13 - Mobile app branding in a mobile device</strong></figcaption></figure><p>Next, we’ll look at the mechanism for building global and object-specific actions and action layouts in the Lightning Platform.</p><h3><strong>Building global and object-specific actions and action layouts</strong></h3><p>Global and object-specific quick actions in the Lightning Platform can be thought of as shortcuts that appear within the user interface. They are two forms of what is known as a quick action, which is available in both desktop and mobile apps and can be used to create records, update records, log calls, and so on.</p><p>In the Salesforce mobile app, global and object-specific quick actions offer a quick way to access functions that launch a specific action or custom process automation that exists in the Lightning Platform.</p><p>In addition to the custom actions that are tailored to your business processes, the Salesforce Mobile App comes with standard pre-built actions. The quick actions are located within the action bar and the action menu that appears at the top of the screen of the mobile device.</p><p>Quick actions that are used to capture data input have their own type of page layout called an <strong>action layout </strong>and allow you to reduce the number of fields to ensure that only those that are absolutely essential are presented to the mobile user.</p><p>In addition to presenting a limited set of fields for data capture, you can also set fields with given values, which are shown on the page layout, to save the user time when there are records that have common values that are to be entered. This feature is called <strong>prepopulate</strong> <strong>fields </strong>and is available in both the desktop and the Salesforce Mobile Apps.</p><p>As an app builder, you will need to understand how to build global and object-specific actions and action layouts in the Lightning Platform and understand the following key differences.</p><p>Global quick actions can be used to create records that are not associated with any other record (that is, there is no option to set an object relationship field). They are called global quick actions because they can be placed anywhere within the Lightning Platform where actions are supported such as the <strong>Home </strong>page, the <strong>Chatter </strong>tab, object pages, and custom Lightning app pages.</p><blockquote><strong>Global quick actions</strong></blockquote><blockquote>For more information about the actions that can be carried out using global quick actions, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=actions_overview_global.htm&amp;type=5">https://help.salesforce.com/articleView?id=actions_overview_global.htm&amp;type=5</a></blockquote><p>Object-specific actions, on the other hand, can be used to create and also update records as they operate in the context of a given Lightning Platform object type. Within the Salesforce mobile app, object-specific quick actions can be placed on record detail pages. So, for example, an action associated with the lead object is only available when viewing a lead record.</p><blockquote><strong>Object-specific actions</strong></blockquote><blockquote>For more information about the actions that can be carried out using object-specific actions, refer to the following article:</blockquote><blockquote><a href="https://help.salesforce.com/articleView?id=actions_overview_object_specific.htm&amp;type=5">https://help.salesforce.com/articleView?id=actions_overview_object_specific.htm&amp;type=5</a></blockquote><p>Let’s look at how to create global quick actions in the Lightning Platform.</p><h4><strong>Creating global quick actions</strong></h4><p>In this example, we will add a <strong>New Lead </strong>action to global layouts that will allow mobile users to create lead record details from within a <strong>Chatter </strong>thread. Let’s go ahead and configure a global quick action by performing the following steps:</p><ol><li>Navigate to <strong>SETUP </strong>and then search for Actions in the <strong>Quick Find </strong>search box located at the top of the <strong>SETUP </strong>menu on the left sidebar.</li><li>Click on <strong>Global Actions </strong>in the <strong>SETUP </strong>menu.</li><li>Click on <strong>New Action </strong>on the <strong>Global Actions </strong>setup page.</li><li>In the <strong>Enter Action Information </strong>dialog screen, enter the following:</li></ol><ul><li><strong>Action Type</strong>: Create a Record</li><li><strong>Target Object</strong>: Lead</li><li><strong>Standard Label Type</strong>: — None —</li><li><strong>Label</strong>: New Lead (Global Action)</li><li><strong>Name</strong>: New_Lead_Global_Action</li><li><strong>Description</strong>: Platform App Builder Certification Guide, Custom Lead Assignment Scenario, Global Action New Lead</li><li><strong>Create Feed Item</strong>: Enabled (when enabled, a feed item is created along with the action. The compact layout for the target object sets the fields for the feed item.)</li><li><strong>Success Message</strong>: Lead Created</li><li><strong>Icon</strong>: Accept the default lead icon for the Lead (icons change according to the target object.)</li></ul><p>5. Finally, click on the <strong>Save </strong>button to save the global action, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/447/1*CD_WmuuvM5M3kWG6DvyBtw.png" /><figcaption><strong>Figure 14 - Global actions</strong></figcaption></figure><p>The options for the action types are as follows:</p><ul><li>Create a Record</li><li>Send Email</li><li>Log a Call</li><li>Custom Visualforce</li><li>Custom Canvas</li><li>Lightning Component</li></ul><p>Upon saving the global action, the layout setup screen appears as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*zP23Y8rOW5UNDudlHsa78A.png" /><figcaption><strong>Figure 15 - Global actions layout</strong></figcaption></figure><p>The following fields are added as default: <strong>Name</strong>, <strong>Email</strong>, <strong>Phone</strong>, <strong>Company</strong>, <strong>Title</strong>, and <strong>Lead Status</strong>. The <strong>Name</strong>, <strong>Company</strong> and <strong>Lead Status </strong>fields marked with a red asterisk are mandatory fields and cannot be removed from the page layout.</p><p>6. Remove the following fields, <strong>Phone, </strong>and <strong>Title</strong>, by clicking on the <strong>Remove </strong>icon, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*S-MlaUfSIaush54WyPNq5Q.png" /><figcaption><strong>Figure 16 - Global actions - removing layout</strong></figcaption></figure><p>7. Add the following fields by dragging and dropping the field section, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*vk6RO7DbPF-Yjo3SrLPyKA.png" /><figcaption><strong>Figure 17 - Global actions - adding layout</strong></figcaption></figure><p>8. Finally, click on the <strong>Save </strong>button to save the global action layout.</p><blockquote><strong>Limiting the number of fields on an action layout</strong></blockquote><blockquote>Salesforce recommends including fewer than five and observing a maximum number of eight fields on an action layout, as referenced in the following article:</blockquote><blockquote><a href="https://trailhead.salesforce.com/en/content/learn/modules/salesforce1_mobile_app/salesforce1_mobile_app_actions_global">https://trailhead.salesforce.com/en/content/learn/modules/salesforce1_mobile_app/salesforce1_mobile_app_actions_global</a></blockquote><p>To present the <strong>New Lead </strong>global action as an option in the user interface, we now need to add the global action to a publisher layout. We can create custom publisher layouts. However, there is a standard layout that we will use called the <strong>Global Publisher </strong>layout. You may need to check that this layout is included within the profiles within the <strong>Publisher</strong> <strong>Layout Assignment </strong>if you have already made any changes to the <strong>Global Publisher </strong>layout.</p><p>Let’s now go ahead and add the global action to the global publisher layout by performing the following steps:</p><ol><li>Navigate to <strong>SETUP </strong>and then search for Publisher in the <strong>Quick Find </strong>search box located at the top of the <strong>SETUP </strong>menu on the left sidebar.</li><li>Click on <strong>Publisher Layouts </strong>in the <strong>SETUP </strong>menu.</li><li>Click on <strong>Edit </strong>for the standard <strong>Global Publisher </strong>layout.</li><li>If you are editing <strong>Global Publisher </strong>for mobile actions for the first time, you will need to click the <strong>override the predefined actions </strong>link, as shown in the following screenshot:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*7vScWXpQGPv3AFAQRgbWvw.png" /><figcaption><strong>Figure 18 - Global Publisher override</strong></figcaption></figure><p>5. Optionally, click on <strong>override the predefined actions</strong> in the Global Publisher layout.</p><p>6. Ensure that New Lead (Global Action) is included within Salesforce Mobile and Lightning Experience Actions, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*kA87tPer7ryFXI-5IyMkng.png" /><figcaption><strong>Figure 19 - Global Publisher layout</strong></figcaption></figure><p>7. Finally, click on the <strong>Save </strong>button to save the publisher layout.</p><p>Let’s now see how this looks in the Salesforce Mobile App by navigating to the <strong>Chatter </strong>item (this can be found in the <strong>Mobile Only </strong>app). <strong>The New Lead (Global Action) </strong>option<strong> </strong>will be presented, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/223/1*ReKRoVuzunB53IDU8gBaWg.png" /><figcaption><strong>Figure 20 - Global Publisher layout mobile</strong></figcaption></figure><p>Next, we’ll turn to the practicalities of building reports that satisfy a specific business requirement by implementing a report with the use of the Lightning report builder.</p><h4><strong>Configuring object-specific actions</strong></h4><p>In this example, we will add a <strong>Deactivate </strong>action to the location records that will allow mobile users to easily mark the location as inactive from within a location record.</p><p>Let’s go ahead and configure an object-specific quick action by performing the following steps:</p><ol><li>Navigate to <strong>SETUP </strong>and then search for Object Manager in the <strong>Quick Find </strong>search box located at the top of the <strong>SETUP </strong>menu on the left sidebar.</li><li>Click on <strong>Object Manager </strong>in the <strong>SETUP </strong>menu.</li><li>In the <strong>Object Manager </strong>setup screen, search for the <strong>Location </strong>object.</li><li>Click on <strong>Location </strong>in <strong>Object Manager </strong>in the <strong>SETUP </strong>menu.</li><li>In the <strong>Location </strong>object manager setup screen, click on <strong>Buttons, Links, and Actions </strong>from within the <strong>Location </strong>object setup menu on the left sidebar.</li><li>In the <strong>Buttons, Links, and Actions </strong>section, click on <strong>New Action</strong>.</li><li>In the <strong>Enter Action Information </strong>dialog screen, enter the following information:</li></ol><ul><li><strong>Action Type</strong>: Update a Record</li><li><strong>Standard Label Type</strong>: — None —</li><li><strong>Label</strong>: Deactivate Location</li><li><strong>Name</strong>: Deactivate_Location</li><li><strong>Description</strong>: Platform App Builder Certification Guide, Custom Lead Assignment Scenario, Object-specific Action Deactivate Location</li><li><strong>Success Message</strong>: Location Deactivated</li><li><strong>Icon</strong>: Accept the default icon</li></ul><p>8. Finally, click on the <strong>Save </strong>button to save the global action, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*-_i4zgmmAmsxGJjACYkefA.png" /><figcaption><strong>Figure 21 - Object-specific actions</strong></figcaption></figure><p>The options for <strong>Action Types </strong>are as follows:</p><ul><li>Create a Record</li><li>Send Email</li><li>Log a Call</li><li>Custom Visualforce</li><li>Update a Record</li><li>Lightning Component</li><li>Flow</li></ul><p>Upon saving the global action, the layout setup screen appears as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*WPnlqiMBlu_7FXXd_IJw1Q.png" /><figcaption><strong>Figure 22 - Object-specific actions layout</strong></figcaption></figure><p>The following field, <strong>Location Name</strong>, is added by default and is marked with a red asterisk to show it is a mandatory field and cannot be removed from the page layout.</p><ol><li>Add the <strong>Active </strong>field to the action layout.</li><li>Click on the <strong>Save </strong>button to save the action layout.</li><li>Upon saving the action layout, click on <strong>New </strong>in the <strong>Predefined Field Values </strong>section, as shown in the following screenshot:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*1HKlOV3VYIiswA7CCLKFMg.png" /><figcaption><strong>Figure 23 - Object-specific action predefined</strong></figcaption></figure><p>4. In the <strong>Enter Action Information </strong>dialog screen, enter the following information:</p><ul><li><strong>Field Name</strong>: <strong>Active</strong></li><li><strong>Specify New Field Value: Formula Value (Checkbox)</strong>: <strong>FALSE</strong></li></ul><p>5. Click on the <strong>Save </strong>button to save the <strong>Predefined Field Value</strong>, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*mQq_ahn2GEuHaoIuTOZ1aA.png" /><figcaption><strong>Figure 24 - Object-specific predefined action saved</strong></figcaption></figure><p>Let’s now add the object-specific action to the <strong>Location </strong>page layout by performing the following steps:</p><p>6. In the <strong>Location </strong>object manager setup screen, click on <strong>Page Layout </strong>from within the <strong>Location </strong>object setup menu on the left sidebar.</p><p>7. Click on the <strong>Location Layout </strong>page layout.</p><p>8. Drag the <strong>Deactivate Location </strong>action to the <strong>Salesforce Mobile and Lightning Experience Actions </strong>section of the page layout, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*U1gGOW2naOT5oFqkJ_1EHQ.png" /><figcaption><strong>Figure 25 - Object-specific action page layout</strong></figcaption></figure><p>9. Finally, click on the <strong>Save </strong>button to save the page layout.</p><p>Let’s now see how this looks in the Salesforce Mobile App by navigating to the <strong>Chatter </strong>item (this can be found in the <strong>Mobile Only </strong>app). The <strong>New Lead (Global Action) </strong>option<strong> </strong>will be presented, as shown in the following screenshot:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/207/1*hRb2wmxIi1UIEJqXEbGIpA.png" /><figcaption><strong>Figure 26 - Object-specific action - mobile</strong></figcaption></figure><h3>Summary</h3><p>In this guide for Salesforce developers, we have looked at the options for configuring mobile using declarative customization and actions in the Salesforce Lightning Platform.</p><p>You have learned about the setup and installation of the Salesforce Mobile App and about options for customizing the Salesforce Mobile App user interface.</p><p>You have learned how to configure quick actions within the Salesforce Mobile App that can be used to implement global quick actions, object-specific actions, and action layouts to optimize the Salesforce mobile application user experience.</p><p>With this knowledge, you are now well-equipped to tackle the Mobile section of the Salesforce Certified Platform App Builder exam.</p><p>This article is part of the Salesforce Platform App Builder Certification Guide by Paul Goodey. To learn how to build apps on the Salesforce Platform and pass the Salesforce Platform App Builder certification exam, check out the complete book <a href="https://packt.live/3sBAkLh">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7dbf65487cf5" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>