<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emily Cain</title>
    <description>The latest articles on DEV Community by Emily Cain (@emcain).</description>
    <link>https://dev.to/emcain</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F19115%2F0b314a67-e0b5-4cfe-beea-515ef16c5202.png</url>
      <title>DEV Community: Emily Cain</title>
      <link>https://dev.to/emcain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emcain"/>
    <language>en</language>
    <item>
      <title>maintaining your mental health after a layoff</title>
      <dc:creator>Emily Cain</dc:creator>
      <pubDate>Fri, 30 Jun 2023 18:22:52 +0000</pubDate>
      <link>https://dev.to/emcain/maintaining-your-mental-health-after-a-layoff-25i3</link>
      <guid>https://dev.to/emcain/maintaining-your-mental-health-after-a-layoff-25i3</guid>
      <description>&lt;p&gt;If you’re reading this, you may have lost your job recently or know someone who has. That’s a stressful situation that can challenge the mental health of anyone, regardless of whether you’ve struggled with it in the past. Here are some tips for taking care of yourself in the wake of a layoff; it doesn’t erase the pain of losing your job suddenly or the stress of trying to find a new one, but it’s a good starting point to help you stay well enough for whatever you need to do next. &lt;/p&gt;

&lt;p&gt;Note: I am not a medical professional and this is not medical advice. Please talk to a doctor or therapist if you feel you need help or advice specific to your situation. &lt;/p&gt;

&lt;p&gt;Ok, here are my tips:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep routine and structure. Try to wake up at the same time (doesn’t have to be the same time you did while working but it should be the same every day) and have breakfast and get dressed just like you were going to a job. Consider going for a walk every morning.&lt;/li&gt;
&lt;li&gt;In all the below items, focus on concrete goals you can control (I will apply to x jobs per week, spend y minutes cleaning a day, put my phone away by 9pm) rather than outcomes you can’t (I will get a job by x date, I will have a clean house, I will always fall asleep by 11pm). &lt;/li&gt;
&lt;li&gt;Keep work/life boundaries with job searching. There is a diminishing return on investment in terms of time spent and it definitely is less than 40 hours a week. If you have a work desk or area you would sit in to work from home, use that for job searching; try not to do things like scroll LinkedIn on your phone outside that area. Don’t job search evenings and weekends (or declare some other time off-limits if your schedule makes that easier).&lt;/li&gt;
&lt;li&gt;Take care of your health generally. Maintain good sleep hygiene (tips below). Try to exercise at least a little every day—consistency &amp;gt; intensity, and if you can, find something you enjoy and/or with other people. Now may be a good time to schedule doctor/dentist/etc appointments you’ve been putting off if you still have insurance. &lt;/li&gt;
&lt;li&gt;Reach out to people. Make plans to see friends. Call people you haven’t talked to in a while and catch up. Volunteer. If you have a hobby or community group or faith community you used to attend regularly, start again. &lt;a href="http://Meetup.com"&gt;http://Meetup.com&lt;/a&gt; is good for finding free or cheap events in your area. &lt;/li&gt;
&lt;li&gt;If you have a past history of needing a particular type of support—like you used to see a therapist or you have gone through substance abuse recovery—now is a good time to set up an appointment with your old therapist, call your sponsor/attend a meeting, etc. &lt;/li&gt;
&lt;li&gt;Please try not to let all this be another thing to worry about. If you fall short one day, try to forgive yourself and think “I’ll do better tomorrow,” not “I’m failing at all this mental health stuff.” This is all very hard and anything you do to care for yourself in this time is better than nothing. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sleep hygiene tips &lt;a href="https://www.healthline.com/health/sleep-hygiene#bed-and-sleep"&gt;https://www.healthline.com/health/sleep-hygiene#bed-and-sleep&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I may update this later with some more detailed resources. Feel free to share what has worked for you in the comments!&lt;/p&gt;

</description>
      <category>career</category>
      <category>layoffs</category>
      <category>personal</category>
      <category>techindustry</category>
    </item>
    <item>
      <title>How to change bash versions on Mac with Homebrew</title>
      <dc:creator>Emily Cain</dc:creator>
      <pubDate>Wed, 04 Mar 2020 00:18:24 +0000</pubDate>
      <link>https://dev.to/emcain/how-to-change-bash-versions-on-mac-with-homebrew-20o3</link>
      <guid>https://dev.to/emcain/how-to-change-bash-versions-on-mac-with-homebrew-20o3</guid>
      <description>&lt;p&gt;MacOS comes with bash 3 as the default shell program; &lt;a href="https://en.wikipedia.org/wiki/GNU_General_Public_License#Legal_barrier_to_app_stores"&gt;Apple doesn't want to upgrade to the later versions for intellectual property reasons&lt;/a&gt;. This means that some features of later versions of bash, like associative arrays, are not available with the default shell. You can always install later versions yourself, however. &lt;/p&gt;

&lt;p&gt;Setting up my Mac to run a different version of bash in the terminal was surprisingly hard for me to figure out how to do; it's a pretty straightforward process but I didn't see any one resource describing the entire thing from start to finish, so I'm doing it here. &lt;/p&gt;

&lt;p&gt;This is based on my own experience installing bash 5.0.16, using Homebrew 2.2.7, on MacOS Mojave 10.14.6. If this doesn't work for you, let me know in the comments (including the versions of bash, Homebrew, and MacOS), and what if anything did end up working. I'd love to make it applicable to more people. &lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;This tutorial assumes some basic familiarity using the terminal on Mac. &lt;/p&gt;

&lt;p&gt;You should have the Homebrew package manager installed -- see &lt;a href="https://treehouse.github.io/installation-guides/mac/homebrew"&gt;this article&lt;/a&gt; for instructions. &lt;/p&gt;

&lt;p&gt;There's some basic editing with vim -- &lt;a href="https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/"&gt;this article&lt;/a&gt; contains everything you need here, but it's basically just knowing &lt;code&gt;i&lt;/code&gt; for "insert" and &lt;code&gt;esc&lt;/code&gt;+ &lt;code&gt;:wq&lt;/code&gt; + &lt;code&gt;return&lt;/code&gt; to save changes. &lt;/p&gt;

&lt;h1&gt;
  
  
  Check your current version
&lt;/h1&gt;

&lt;p&gt;Verify that you have the old version installed currently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$BASH_VERSION&lt;/span&gt;
3.2.57&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;-release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Install the latest bash version using Homebrew
&lt;/h1&gt;

&lt;p&gt;Use &lt;code&gt;$ brew install bash&lt;/code&gt; to install the latest version (or &lt;a href="https://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula"&gt;specify a version&lt;/a&gt;). Take note of where in the filesystem the cask is located, you'll see a message like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; Pouring bash-5.0.16.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/bash/5.0.16: 150 files, 9.4MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at that folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /usr/local/Cellar/bash/5.0.16
AUTHORS         NEWS            changelog
CHANGES         NOTES           include
COPYING         README          lib
INSTALL_RECEIPT.json    bin         share
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /usr/local/Cellar/bash/5.0.16/bin
bash    bashbug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full path to the shell we want is (in this case) &lt;code&gt;/usr/local/Cellar/bash/5.0.16/bin/bash&lt;/code&gt;. Make a note of it for the next step. &lt;/p&gt;

&lt;h1&gt;
  
  
  Set the default shell
&lt;/h1&gt;

&lt;p&gt;There are two steps to changing this. First, find the "shells" file and edit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;atom /etc/shells  &lt;span class="c"&gt;# or whatever your preferred text editor is&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the full path (in this case &lt;code&gt;/usr/local/Cellar/bash/5.0.16/bin/bash&lt;/code&gt;) to the end of the list of shells, then save and quit. This will tell your computer that it is safe to use that shell (it's a safety measure to prevent people from accidentally setting random programs as their default shell and breaking everything). &lt;/p&gt;

&lt;p&gt;Back in your command line, use the "change shell" command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;chsh
Changing shell &lt;span class="k"&gt;for&lt;/span&gt; &amp;lt;user&amp;gt;.
Password &lt;span class="k"&gt;for&lt;/span&gt; &amp;lt;user&amp;gt;:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter your password. You'll then get file like this in Vim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Changing user information for &amp;lt;user&amp;gt;.
# Use "passwd" to change the password.
##
# Open Directory: /Local/Default
##
Shell: /bin/bash
Full Name: 
Office Location:
Office Phone:
Home Phone:
~
~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the entry after "shell" to the new shell path, then save and exit. &lt;/p&gt;

&lt;h1&gt;
  
  
  Check installation
&lt;/h1&gt;

&lt;p&gt;You may need to open a new terminal window or tab for this to work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo $BASH_VERSION
5.0.16(1)-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🥳 Yay! 🥳 You can now use new features from bash 4 and 5. And you can always put the default shell back using &lt;code&gt;chsh&lt;/code&gt; if you want. &lt;/p&gt;

</description>
      <category>macos</category>
      <category>bash</category>
      <category>homebrew</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Bitwise Operations on your Fingers 🙌👩🏻‍💻</title>
      <dc:creator>Emily Cain</dc:creator>
      <pubDate>Thu, 29 Nov 2018 02:06:15 +0000</pubDate>
      <link>https://dev.to/emcain/bitwise-operations-on-your-fingers-2d01</link>
      <guid>https://dev.to/emcain/bitwise-operations-on-your-fingers-2d01</guid>
      <description>&lt;p&gt;I first came across bitwise operations as part of an Advent of Code challenge in 2017. I was thoroughly confused. "How can you do AND on two numbers? That doesn't make sense!" I dutifully used the AND operator in whatever language I was using for the challenge (probably Go) and just accepted not knowing what it meant.&lt;/p&gt;

&lt;p&gt;My next encounter was in a workplace discussion group where we learned about using AND operators to &lt;a href="https://danielmiessler.com/study/tcpdump/" rel="noopener noreferrer"&gt;filter packets, using &lt;code&gt;tcpdump&lt;/code&gt;&lt;/a&gt;. I asked enough questions to actually understand what was going on with these bitwise operations, and I want to share one of the methods I came up with in this article. It involves counting on your fingers in binary and then using your hands to perform bitwise arithmetic -- no computer needed. I don't know if anyone else has done it quite like this, but I find it helpful. &lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;Any computer system you use represents information as a series of 0s and 1s, using base 2 or &lt;a href="https://en.wikipedia.org/wiki/Binary_number#Counting_in_binary" rel="noopener noreferrer"&gt;binary&lt;/a&gt; to represent numbers. Bitwise operators perform a &lt;a href="https://en.wikipedia.org/wiki/Logical_connective" rel="noopener noreferrer"&gt;Boolean operation&lt;/a&gt; on each bit to reach the final result. &lt;/p&gt;

&lt;p&gt;For example, let's say we want to find 6 AND 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0110 (6) 
0011 (3)
----
0010 (2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking this down: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the 2^0 (1's) place, the first value is 0 (false) and the second value is 1 (true). false AND true = false. &lt;/p&gt;

&lt;p&gt;In the 2^1 (2's) place, the first value is 1 (true) and the second value is 1 (true). true AND true = true. &lt;/p&gt;

&lt;p&gt;In the 2^2 (4's) place, the first value is 1 (true) and the second value is 0 (false). true AND false = false. &lt;/p&gt;

&lt;p&gt;In the 2^3 (8's) place, the first value is 0 (false) and the second value is 0 (false). false AND false = false. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To summarize: for each place or column, do the Boolean logic operation on the input values in that column to get the output for that column. &lt;/p&gt;

&lt;p&gt;You use the same process for doing other bitwise operations. &lt;/p&gt;

&lt;p&gt;OR (true if either value is true):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0110 (6) 
0011 (3) 
----
0111 (7) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/XOR_gate" rel="noopener noreferrer"&gt;XOR&lt;/a&gt; (true if the two values are different):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0110 (6) 
0011 (3) 
----
0101 (5) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOT is a unary operator, which is to say it takes only one input, and it reverses the value of each column (or bit).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0101 (5) 
----
1010 (10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can play with bitwise arithmetic using &lt;a href="https://www.miniwebtool.com/bitwise-calculator" rel="noopener noreferrer"&gt;this calculator&lt;/a&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  Finger Method
&lt;/h1&gt;

&lt;p&gt;We'll start by learning to finger-count in binary. &lt;/p&gt;

&lt;p&gt;Some finger counting systems start with the thumb, but I am going to use the index finger for 1 because then each hand represents a &lt;a href="https://en.wikipedia.org/wiki/Nibble" rel="noopener noreferrer"&gt;nibble&lt;/a&gt;, or half-byte, which can be represented by a single &lt;a href="https://en.wikipedia.org/wiki/Hexadecimal" rel="noopener noreferrer"&gt;hexadecimal&lt;/a&gt; digit. (It also means I can use my thumb to hold down any unused fingers.) The middle finger is 2, the ring finger is 4, and the pinky is 8.&lt;/p&gt;

&lt;p&gt;1, or 0001:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1izxzxrc31l4u3m63f2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1izxzxrc31l4u3m63f2.jpg" alt="index finger up, other fingers down" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2, or 0010: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyr0s90qdiu3qrkvloc6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyr0s90qdiu3qrkvloc6.jpg" alt="middle finger up, others down" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3, or 0011, or 2^1 + 2^0: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qex5wb4dir7x8t2bkr5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qex5wb4dir7x8t2bkr5.jpg" alt="middle and index fingers up, others down" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7, or 0111, or  2^2 + 2^1 + 2^0: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0yzrcze6efcy21366e3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0yzrcze6efcy21366e3.jpg" alt="ring, middle, index fingers up, pinky down" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;12, or 1100, or 2^3 + 2^2, or C in hexadecimal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl47hpuz4j7auk1uxkjhd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl47hpuz4j7auk1uxkjhd.jpg" alt="pinky and ring fingers up, middle and index down" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15, or 1111, or  2^3 + 2^2 + 2^1 + 2^0, or F in hexadecimal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciyb1y5mxnonmyrub0tg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciyb1y5mxnonmyrub0tg.jpg" alt="all fingers up" width="800" height="803"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  AND
&lt;/h1&gt;

&lt;p&gt;For the AND operation, use your left hand to make the first number and your right hand to make the second number. For each hand, the index finger should always represent 1, the pinky 8. &lt;/p&gt;

&lt;p&gt;Here's 6 on the left hand and 3 on the right. &lt;/p&gt;

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

&lt;p&gt;Now take the two hands and place them together, palms touching, fingers tented. &lt;/p&gt;

&lt;p&gt;The fingers that are touching at the top represent the answer (2).&lt;/p&gt;

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

&lt;p&gt;Some more examples: &lt;/p&gt;

&lt;p&gt;12 AND 7 = 4&lt;/p&gt;

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

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

&lt;p&gt;10 AND 5 = 0 &lt;/p&gt;

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

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

&lt;h1&gt;
  
  
  OR
&lt;/h1&gt;

&lt;p&gt;Let's use the same inputs with the OR operator. &lt;/p&gt;

&lt;p&gt;Here's 6 on the left hand and 3 on the right. &lt;/p&gt;

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

&lt;p&gt;Now take the two hands and place them together, palms touching, fingers tented. &lt;/p&gt;

&lt;p&gt;The places with at least 1 finger up represent the answer (7). &lt;/p&gt;

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

&lt;p&gt;Some more examples: &lt;/p&gt;

&lt;p&gt;12 OR 7 = 15&lt;/p&gt;

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

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

&lt;p&gt;10 OR 5 = 15 &lt;/p&gt;

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

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

&lt;p&gt;8 OR 1 = 9 &lt;/p&gt;

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

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

&lt;h1&gt;
  
  
  XOR
&lt;/h1&gt;

&lt;p&gt;Here's 6 on the left hand and 3 on the right. &lt;/p&gt;

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

&lt;p&gt;Now take the two hands and place them together, palms touching, fingers tented. &lt;/p&gt;

&lt;p&gt;The places that have exactly one finger up represent the answer (5). &lt;/p&gt;

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

&lt;p&gt;Some more examples: &lt;/p&gt;

&lt;p&gt;12 XOR 7 = 11&lt;/p&gt;

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

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

&lt;p&gt;10 XOR 5 = 15 &lt;/p&gt;

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

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

&lt;h1&gt;
  
  
  NOT
&lt;/h1&gt;

&lt;p&gt;Take all the fingers that are up and put them down; put all the fingers that are down and put them up. &lt;/p&gt;

&lt;p&gt;NOT 5 = 10 &lt;/p&gt;

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

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

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

&lt;p&gt;Now you know how to do the bitwise operators on your fingers! Hopefully this helps you understand these operations in a more intuitive way. &lt;/p&gt;

</description>
      <category>bitwise</category>
      <category>logic</category>
      <category>binary</category>
      <category>math</category>
    </item>
    <item>
      <title>How to Set up a Twitter Bot with Python and Heroku</title>
      <dc:creator>Emily Cain</dc:creator>
      <pubDate>Sun, 24 Jun 2018 01:46:30 +0000</pubDate>
      <link>https://dev.to/emcain/how-to-set-up-a-twitter-bot-with-python-and-heroku-1n39</link>
      <guid>https://dev.to/emcain/how-to-set-up-a-twitter-bot-with-python-and-heroku-1n39</guid>
      <description>&lt;p&gt;I just set up &lt;a href="https://twitter.com/AskYrDoctorABot" rel="noopener noreferrer"&gt;a Twitter bot&lt;/a&gt; to generate pharmaceutical ads and tweet them out a few times a day. (Source code &lt;a href="https://github.com/emcain/drug_names" rel="noopener noreferrer"&gt;here&lt;/a&gt;). I ended up piecing together concepts from a couple different tutorials in order to do this, and no single tutorial laid out the whole process, so I'm writing it up here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fcontainers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fcontainers.png" alt="image description: xkcd comic 1988. Transcript can be found at https://www.explainxkcd.com/wiki/index.php/1988:_Containers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The steps can be summarized as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;write a function to &lt;strong&gt;generate text strings&lt;/strong&gt; for your bot to tweet&lt;/li&gt;
&lt;li&gt;create a &lt;strong&gt;Twitter account&lt;/strong&gt;, and set up an &lt;strong&gt;application&lt;/strong&gt; under it

&lt;ul&gt;
&lt;li&gt;set up a phone number with Google Voice&lt;/li&gt;
&lt;li&gt;assign your account that phone number, allowing you to create applications&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;write a script that &lt;strong&gt;connects to your Twitter application&lt;/strong&gt;,  and sends it an API call to &lt;strong&gt;tweet the output&lt;/strong&gt; of your function from step 1&lt;/li&gt;
&lt;li&gt;set up a &lt;strong&gt;Heroku app&lt;/strong&gt; that runs the function from step 3 as a &lt;strong&gt;worker&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;set up a basic &lt;strong&gt;server&lt;/strong&gt; in your Heroku app so that Heroku won't freak out and throw an error&lt;/li&gt;
&lt;li&gt;set &lt;strong&gt;environment variables&lt;/strong&gt; in Heroku for your Twitter app's credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 4 through 6 could also be used to set up any Python script to run on Heroku.&lt;/p&gt;

&lt;p&gt;I'm using some Google features to generate a unique email and phone number for the Twitter account, but you can handle creating those with whatever service you like.&lt;/p&gt;

&lt;p&gt;This article assumes some basic background knowledge on the following concepts: Python, REST APIs, Git, environment variables.&lt;/p&gt;

&lt;p&gt;Because it uses Heroku, the app will have to be saved in a Git repository.&lt;/p&gt;

&lt;p&gt;Also, I used a virtual environment and saved the requirements in a file by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes relevant when you set up Heroku, which uses &lt;code&gt;requirements.txt&lt;/code&gt; to install the Python packages you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Generate strings
&lt;/h2&gt;

&lt;p&gt;I'd made this functionality a while back. For the pharma bot, I use Markov chains to generate drug names, and then insert them in a randomly generated template, to get advertisements like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Worried you might have twitchy ossicle? Sudate® can help!&lt;/p&gt;

&lt;p&gt;Are you plagued by restless elbow? Ask your doctor about Estron® today!&lt;/p&gt;

&lt;p&gt;You don't have to deal with pompous spleen alone. Ask your doctor about Ryzema Prenztriumetine® today!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The function that creates these is called &lt;a href="https://github.com/EMCain/drug_names/blob/master/generate_advertisement.py" rel="noopener noreferrer"&gt;&lt;code&gt;get_ad&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In your own code, replace &lt;code&gt;get_ad&lt;/code&gt; with a function that generates whatever kind of text you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create a Twitter app
&lt;/h2&gt;

&lt;p&gt;You'll probably want to give the bot its own account rather than Tweeting from an existing account, so set one up.&lt;/p&gt;

&lt;p&gt;The Twitter account will need a unique email. If you want to use an email address that already has its own Twitter account, you can take advantage of Gmail's functionality to sign up with an &lt;a href="https://fieldguide.gizmodo.com/how-to-use-the-infinite-number-of-email-addresses-gmail-1609458192" rel="noopener noreferrer"&gt;"alternate" email that goes to the same inbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You will also need to set a phone number in your app; again, you can use Google to create an alternate contact that goes to an existing number, this time using &lt;a href="https://www.wikihow.com/Get-a-Google-Voice-Phone-Number" rel="noopener noreferrer"&gt;Google Voice&lt;/a&gt;.&lt;br&gt;
Next, go to your Twitter Apps dashboard and &lt;a href="https://apps.twitter.com/app/new" rel="noopener noreferrer"&gt;create a new app&lt;/a&gt; (while logged in as the bot's account).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7tr5lr7p4gpr27qugk1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7tr5lr7p4gpr27qugk1h.png" alt="a screenshot of the Twitter application creation page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the app's website, I put the GitHub URL where the repo for this project lives.&lt;/p&gt;

&lt;p&gt;Once you create the app, make sure that it allows read and write access.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Connect to the Twitter App and send tweets
&lt;/h2&gt;

&lt;p&gt;I used this article, &lt;a href="https://dototot.com/how-to-write-a-twitter-bot-with-python-and-tweepy/" rel="noopener noreferrer"&gt;How To Write a Twitter Bot with Python and tweepy&lt;/a&gt;, as a rough guide for this part. Check it out for a guide on setting up your Twitter app and connecting to it via API. Note that you will need to add an "access key" to your Twitter application.&lt;/p&gt;

&lt;p&gt;They have their bot reading lines from a text file; instead, I had mine call &lt;code&gt;get_ad&lt;/code&gt;. The script that does this is called &lt;a href="https://github.com/EMCain/drug_names/blob/master/bot.py" rel="noopener noreferrer"&gt;bot.py&lt;/a&gt;. Here's the part that generates and sends the Tweet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;generate_advertisement&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_ad&lt;/span&gt;

&lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;  &lt;span class="c1"&gt;# tweet every 6 hours
# INTERVAL = 15  # every 15 seconds, for testing
&lt;/span&gt;
&lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tweepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OAuthHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONSUMER_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CONSUMER_SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_access_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ACCESS_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ACCESS_SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tweepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;API&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about to get ad...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_ad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INTERVAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then ran &lt;code&gt;bot.py&lt;/code&gt; in my local terminal. &lt;/p&gt;

&lt;p&gt;Success!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk2bh0dvw0fielp82ww4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk2bh0dvw0fielp82ww4t.png" alt="screenshot of initial tweets sent by bot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was able to send tweets just fine, but I don't want to leave my laptop on and my terminal open forever, so I needed to get it running on its own server somewhere. My next task was to put the bot on Heroku.&lt;/p&gt;

&lt;h3&gt;
  
  
  IMPORTANT: DON'T COMMIT YOUR SECRET KEYS
&lt;/h3&gt;

&lt;p&gt;Connecting to Twitter via the API (including via a wrapper library like &lt;code&gt;tweepy&lt;/code&gt;) requires you to use keys that identify your app and authenticate you as a user. Make sure you don't commit these keys in a Git repository--that's like publishing your password. Even if you later remove the keys from your code, they'll be in your commit history.&lt;/p&gt;

&lt;p&gt;Initially, I stored the keys in a file called &lt;code&gt;credentials.py&lt;/code&gt;, which I added to my &lt;code&gt;.gitignore&lt;/code&gt;. It looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;CONSUMER_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;consumer key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;CONSUMER_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;consumer secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;ACCESS_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;access key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;ACCESS_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;access secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then imported the keys into &lt;code&gt;bot.py&lt;/code&gt;. This didn't end up working out once I put the app on Heroku, but it was fine for testing it on my local machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Set up Heroku
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://signup.heroku.com" rel="noopener noreferrer"&gt;Sign up for a Heroku account&lt;/a&gt; if you don't already have one. Heroku allows you to push and deploy code with Git, and you can create up to 5 apps for free.&lt;/p&gt;

&lt;p&gt;Once you have the Heroku command line interface &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;installed&lt;/a&gt;, initialize your repository with Heroku. It's ok if you let it generate a random URL for your app, since nobody will be looking at it directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ heroku create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will set up a Heroku app and also give your Git repository a remote called &lt;code&gt;heroku&lt;/code&gt;. The code on that remote's &lt;code&gt;master&lt;/code&gt; branch will be run by Heroku.&lt;/p&gt;

&lt;p&gt;You'll need to set up a &lt;code&gt;Procfile&lt;/code&gt; to tell Heroku what to do once it gets your code. Put this in your &lt;code&gt;Procfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;worker: python bot.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means Heroku will do the equivalent of when you ran &lt;code&gt;python bot.py&lt;/code&gt; on your local terminal.&lt;/p&gt;

&lt;p&gt;Then commit your code and push it to Heroku.&lt;/p&gt;

&lt;p&gt;To deploy from your local &lt;code&gt;master&lt;/code&gt; branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To deploy from a different branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push heroku my_branch_name:master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can log into your Heroku dashboard and check its activity and logs to see what happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Basic Web Server
&lt;/h2&gt;

&lt;p&gt;Turns out Heroku doesn't like to just run scripts with workers, because it expects to see a web server.&lt;/p&gt;

&lt;p&gt;You can fix this by creating a simple web server. I used &lt;a href="https://stackoverflow.com/a/39170561" rel="noopener noreferrer"&gt;this StackOverflow answer&lt;/a&gt; as a guide.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code (server.py):&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Then, in your Procfile, just say: web: python server.py.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I tried this (and committed and pushed to Heroku again). I then saw the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error R10 (Boot timeout) -&amp;gt; Web process failed to bind to $PORT within 60 seconds of launch python flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I fixed this by setting the host when I ran the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Set environment variables
&lt;/h2&gt;

&lt;p&gt;Remember how I said not to commit your Twitter credentials to your Git repository? This becomes an issue when you deploy to Heroku, because it uses your Git repo to deploy, and so importing constants from an ignored file won't work.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://devcenter.heroku.com/articles/config-vars#using-the-heroku-dashboard" rel="noopener noreferrer"&gt;set environment variables in your Heroku dashboard&lt;/a&gt;, then use &lt;code&gt;os.environ&lt;/code&gt; to get them in Python. Add this to &lt;code&gt;bot.py&lt;/code&gt; before making the API call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="n"&gt;CONSUMER_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CONSUMER_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;CONSUMER_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CONSUMER_SECRET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ACCESS_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ACCESS_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ACCESS_SECRET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then your app will be able to connect to the Twitter API without ever committing your secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Now you know how to create a Twitter bot and run it on Heroku!&lt;/p&gt;

&lt;p&gt;You can adapt this project to tweet out anything you like. &lt;a href="http://www.onthelambda.com/2014/02/20/how-to-fake-a-sophisticated-knowledge-of-wine-with-markov-chains/" rel="noopener noreferrer"&gt;This article&lt;/a&gt; explains how to use Python to generate text with Markov chains. You can create a text file with each line containing a sentence you want to tweet using the method outlined in &lt;a href="https://dototot.com/how-to-write-a-twitter-bot-with-python-and-tweepy/" rel="noopener noreferrer"&gt;How To Write a Twitter Bot with Python and tweepy&lt;/a&gt;. You can tweet lines from public domain works at &lt;a href="https://www.gutenberg.org/" rel="noopener noreferrer"&gt;Project Gutenberg&lt;/a&gt;. Or do anything you want!&lt;/p&gt;

&lt;p&gt;note: an earlier version of this article was published at &lt;a href="https://emcain.github.io" rel="noopener noreferrer"&gt;emcain.github.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>heroku</category>
      <category>flask</category>
      <category>twitter</category>
    </item>
  </channel>
</rss>
