<?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: Rose Day </title>
    <description>The latest articles on DEV Community by Rose Day  (@rosejcday).</description>
    <link>https://dev.to/rosejcday</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%2F61286%2F21442a05-c9a1-414e-b46a-16b364aadb15.jpeg</url>
      <title>DEV Community: Rose Day </title>
      <link>https://dev.to/rosejcday</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rosejcday"/>
    <language>en</language>
    <item>
      <title>What advice would you give someone who wants to mentor younger developers? What are good attributes to focus on as a mentor? </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 09 Jul 2020 19:59:39 +0000</pubDate>
      <link>https://dev.to/rosejcday/what-advice-would-you-give-someone-who-wants-to-mentor-younger-developers-what-are-good-attributes-to-focus-on-as-a-mentor-3gm9</link>
      <guid>https://dev.to/rosejcday/what-advice-would-you-give-someone-who-wants-to-mentor-younger-developers-what-are-good-attributes-to-focus-on-as-a-mentor-3gm9</guid>
      <description>

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Log SMS Data in Google Sheets using Twilio and Flask</title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 30 Apr 2020 01:38:52 +0000</pubDate>
      <link>https://dev.to/rosejcday/log-sms-data-in-google-sheets-using-twilio-and-flask-7he</link>
      <guid>https://dev.to/rosejcday/log-sms-data-in-google-sheets-using-twilio-and-flask-7he</guid>
      <description>&lt;p&gt;Happy Wednesday evening and last day of the Twilio x Dev Hackathon! I hope you are all doing well. It has been great to spend the month of April working with Twilio and Google sheets on this project in order to capture SMS data from a survey.&lt;/p&gt;

&lt;p&gt;For those who may not have seen the other posts in this series, you can view them above. The first post began as the initial start of the project in &lt;a href="https://dev.to/rosejcday/tracking-migraines-with-sms-4hhl"&gt;Tracking Migraines with SMS&lt;/a&gt; which is just an introductory post.&lt;/p&gt;

&lt;p&gt;The setup of Google Sheets is discussed in &lt;a href="https://dev.to/rosejcday/setting-up-python-to-connect-to-google-sheets-2ak7"&gt;Setting up Python to Connect to Google Sheets&lt;/a&gt; where I talked about API Errors due to scope along with path issues with PyTest. &lt;/p&gt;

&lt;p&gt;My first experience with Flask is talked about in the post &lt;a href="https://dev.to/rosejcday/setting-up-twilio-with-flask-and-testing-surveys-3e9k"&gt;What I Learned using Flask for the First Time&lt;/a&gt; in which I discussed port issues, data types, casting data types, and Flask sessions. This section also details issues with getting to the next question in the survey. &lt;/p&gt;

&lt;p&gt;The final integration of Google Sheets and Twilio is discussed in &lt;a href="https://dev.to/rosejcday/integrating-twilio-with-google-sheets-7p6"&gt;Integrating Twilio with Google Sheets&lt;/a&gt;. This post discusses clearing results in a list, and data import issues with Google Sheets appending single quotes at the start of numbers and dates. &lt;/p&gt;

&lt;p&gt;With all of that said, todays post will focus on the wrap up of the Twilio x Dev Hackathon, along with a walk through and discussion of the application flow through the functions in &lt;code&gt;app.py&lt;/code&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;For a quick recap on the project concept, I spend time logging migraines for the doctors office but don't remember the format she wanted, or the details she found important. This application was created as a way to request a survey for a migraine, quickly fill out the details, and log the data for later use at the doctors appointment. &lt;/p&gt;

&lt;h3&gt;
  
  
  Commonly Asked Questions for Migraines
&lt;/h3&gt;

&lt;p&gt;Below is a list of commonly asked questions relating to migraines: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In a scale of 1-10, how would you rate your migraine?&lt;/li&gt;
&lt;li&gt;Where is your migraine located today?&lt;/li&gt;
&lt;li&gt;How long did your migraine last (in hours)?&lt;/li&gt;
&lt;li&gt;What medication did you take to treat the migraine?&lt;/li&gt;
&lt;li&gt;Has anything changed? Is anything out of the ordinary? Do you have any other notes to add?
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Category - Engaging Engagements and Interesting Integrations
&lt;/h3&gt;

&lt;p&gt;During this hackathon, I focused on two categories: Engaging Engagements and Interesting Integrations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engaging Engagements&lt;/strong&gt; looked at developing applications that a company could implement to better engage with their customers or to manage their business. An application of this type could be utilized by doctors offices in order to collect data commonly needed during patient visits or to have patients collect their own data for use in their visits. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interesting Integrations&lt;/strong&gt; focused on the integration of the Twilio API with at least one other API. This application integrated Twilio with the Google Sheets API in order to log data in an easy to access format.  &lt;/p&gt;




&lt;p&gt;Filled out Twilio CodeExchange Agreement: ✔️&lt;br&gt;
Agreed to the Competition's Terms: ✔️&lt;/p&gt;




&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;To clone the code, please visit the GitHub project &lt;a href="https://github.com/rosejcday/migraine_tracking" rel="noopener noreferrer"&gt;Migraine Tracking&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Demo Link
&lt;/h3&gt;

&lt;p&gt;In the repository is also a GIF showing a brief &lt;a href="https://github.com/rosejcday/migraine_tracking/blob/master/static/demo_2.gif" rel="noopener noreferrer"&gt;demo&lt;/a&gt; of the code. There is also a &lt;a href="https://github.com/rosejcday/migraine_tracking/blob/master/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt; available for those who would like to run the code locally and try it out. &lt;/p&gt;

&lt;h2&gt;
  
  
  Application Flow
&lt;/h2&gt;

&lt;p&gt;The first route that is reached when the application receives an SMS is the &lt;code&gt;/sms&lt;/code&gt; route that calls the function &lt;code&gt;sms_survey()&lt;/code&gt;. This function looks to see if a question ID comes in and in the session, the function will redirect to the &lt;code&gt;/answer&lt;/code&gt; route. &lt;/p&gt;

&lt;p&gt;Before a question ID will come in, the function will first default to collecting the Twilio number, the users number, and the date. &lt;em&gt;Note: These were hidden in the demo data output in Google Sheets.&lt;/em&gt; These values are appended to the collected data list and then the a welcome message will be displayed to the user through the &lt;code&gt;welcome_user()&lt;/code&gt; function. After displaying the welcome message, the user is redirected to the first question in the survey. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6nqu4h4c72sy73tncobp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6nqu4h4c72sy73tncobp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;welcome_user()&lt;/code&gt;, seen below, will return a brief message to the user. Then the user is directed to the &lt;code&gt;/question/&amp;lt;question_id&amp;gt;&lt;/code&gt; route. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F06j4kn85gr3jvmz6d4mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F06j4kn85gr3jvmz6d4mh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/question/&amp;lt;question_id&amp;gt;&lt;/code&gt; route takes in the question ID and tells the application which question it should respond back to the user with. Using the question ID, we pass the ID into the &lt;code&gt;parseJson&lt;/code&gt; pulls out the first question and its type. The question ID is stored into a session variable called &lt;code&gt;question_id&lt;/code&gt; to be used as the application looks for the next question or the end of the survey. Once that has been captured, the &lt;code&gt;sms_twiml()&lt;/code&gt; function is called with question and type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0xmupm48ly9moqaueimv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0xmupm48ly9moqaueimv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function responds with the message and type of data to ask the user for. The three types of data asked for in this survey are text, hours, or a numeric number from 1 to 10. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjz5d0cbub4iqhcs9n3cv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjz5d0cbub4iqhcs9n3cv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the user has answered the question, the application will redirect to the &lt;code&gt;/answer/&amp;lt;question_id&amp;gt;&lt;/code&gt; route. This route first iterates to the next question ID which is used to grab data collected from the &lt;code&gt;parseJson&lt;/code&gt; object. Then, the user entered data for the previous question is extracted and appended to the &lt;code&gt;data_collected&lt;/code&gt; list. &lt;code&gt;extract_content()&lt;/code&gt; returns either text for text elements or numeric digits for hours and numeric answers. If data is available for the next question, the survey will continue by redirecting to the &lt;code&gt;/question/&amp;lt;question_id&amp;gt;&lt;/code&gt; route, otherwise the survey will end and display a goodbye message through the use of the &lt;code&gt;goodbye_twiml()&lt;/code&gt; function.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fptrsf7tz5j7veq3qivsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fptrsf7tz5j7veq3qivsq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;redirect_twiml()&lt;/code&gt; redirects the survey to the &lt;code&gt;/question/&amp;lt;question_id&amp;gt;&lt;/code&gt; route to allow the user to view and answer the next question, repeating the process until all questions have been answered. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9oosea7pasl3ql8cw5gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9oosea7pasl3ql8cw5gd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;goodbye_twiml()&lt;/code&gt; function ends the survey, appending all the data collected into the Google Sheet using the &lt;code&gt;spreadsheet&lt;/code&gt; object. After a goodbye message is displayed to the user, the data collected is cleared from the &lt;code&gt;data_collected&lt;/code&gt; list and the session variable for &lt;code&gt;question_id&lt;/code&gt; is cleared. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4iuhbfg80grifducgb4v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4iuhbfg80grifducgb4v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is the overall flow of the code from first question to last. &lt;/p&gt;

&lt;h3&gt;
  
  
  Development Stack
&lt;/h3&gt;

&lt;p&gt;Thank you for following along this past month as all of the pieces have come together to log the data into the Google sheet from the SMS survey. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fla7zchv71vf9rdwe5em7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fla7zchv71vf9rdwe5em7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you to all those who put together this hackathon and participated in it. Have a Happy May!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reference Links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/docs/usage/api" rel="noopener noreferrer"&gt;Twilio's Rest API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.twilio.com/docs/voice/tutorials/automated-survey-python-flask" rel="noopener noreferrer"&gt;Automated Survey - Python Flask App&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/TwilioDevEd/automated-survey-flask" rel="noopener noreferrer"&gt;GitHub Sample Automated Survey&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=vISRn5qFrkM&amp;amp;list=PLqrz4nXepkz60FNw4ORm1iLTn_R5o9fBb" rel="noopener noreferrer"&gt;Google Sheets and Python Example&lt;/a&gt;&lt;br&gt;
&lt;a href="https://towardsdatascience.com/accessing-google-spreadsheet-data-using-python-90a5bc214fd2" rel="noopener noreferrer"&gt;Accessing Google Spreadsheets with Python&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>twilio</category>
      <category>python</category>
      <category>flask</category>
    </item>
    <item>
      <title>Integrating Twilio with Google Sheets</title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Fri, 24 Apr 2020 00:03:29 +0000</pubDate>
      <link>https://dev.to/rosejcday/integrating-twilio-with-google-sheets-7p6</link>
      <guid>https://dev.to/rosejcday/integrating-twilio-with-google-sheets-7p6</guid>
      <description>&lt;p&gt;Happy Thursday! I hope you are all doing well. It has been interesting to continue working with Twilio and Google sheets on this project for the hackathon. This week I focus on the issues and learnings I had with using Google Sheets with Twilio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;I spend time logging migraines for the doctors office but don't remember the format she wanted, or the details she found important. This application was created as a way to request a survey for a migraine, quickly fill out the details, and log the data for later use at the doctors appointment.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;To clone the code, please visit the GitHub project &lt;a href="https://github.com/rosejcday/migraine_tracking" rel="noopener noreferrer"&gt;Migraine Tracking&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Issues and Learnings
&lt;/h2&gt;

&lt;p&gt;After creating functions to work with the Twilio API and Google Sheets, it came time to integrate the two together. This process did not go smoothly at first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clearing Results from a List
&lt;/h3&gt;

&lt;p&gt;While running the Flask app, I append the data collected to a list called &lt;code&gt;data_collected&lt;/code&gt; and after answering one survey question and starting onto the next, the results would keep appending to the list. This behavior was expected, as, in the end, I wanted to take the answers to all questions and upload to Google sheets. What I did not realize would start to happen was that once a survey ended and the next started, the list continued to append the data. &lt;/p&gt;

&lt;p&gt;Having not worked with Flask before, I found this to be an interesting issue that I did not expect to have. I had assumed the data from one survey would be cleared after the survey ended, allowing for the data from the next to start getting added. After realizing this was not the case, I searched on different ways to clear a list of data. &lt;/p&gt;

&lt;p&gt;The first thing I had tried was to assign &lt;code&gt;data_collected&lt;/code&gt; an empty list after the data was inserted into Google Sheets.&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_collected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Put data into Google sheet
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Thank you for filling out todays migraine... Feel better soon! :)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data_collected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing so gave me the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;UnboundLocalError: &lt;span class="nb"&gt;local &lt;/span&gt;variable &lt;span class="s1"&gt;'data_collected'&lt;/span&gt; referenced before assignment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After looking into this issue further, I found other ways to clear a list in Python that allowed me to remove old survey data once it had been stored in Google Sheets. The &lt;code&gt;clear()&lt;/code&gt; method can be used with lists to remove all the elements from a list.&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;data_collected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Clear the list after it has been saved
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizing this method worked as expected and allowed the data to be removed after a survey has completed. &lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;What did I learn here? The variable &lt;code&gt;data_collected&lt;/code&gt; would continue to collect data as new surveys came in until the variable data was cleared. Using &lt;code&gt;clear()&lt;/code&gt; on a list allows you to remove the data from the list and start fresh, &lt;strong&gt;meaning each survey would only collect the data needed for that survey, store it in Google Sheets, and clear the data before beginning the next survey.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Data Import has Single Quotes Appended to Numbers / Dates
&lt;/h3&gt;

&lt;p&gt;The other main issue I had when integrating the two pieces was an interesting issue. When inserting data into Google Sheets, the numbers would be appended with one single quote. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'2415434
'3.0834536
'1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found this problem to be interesting due to the fact that when I originally worked with the Google Sheets API and was able to pass data using the functions I made, I did not see this problem surface with any data that was passed. &lt;/p&gt;

&lt;p&gt;With this, I spent more time looking into how data was being passed to a sheet and what could cause the extra character to be appended to the beginning of a number. When using Google Sheet's API there is an option to specify the &lt;code&gt;value_input_option&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Looking into this option, I found that this issue could be solved by changing the function I was using to enter data into a sheet. I was utilizing &lt;code&gt;insert_row()&lt;/code&gt; to add data into the sheet but the other option &lt;code&gt;append_row()&lt;/code&gt; allowed for the insertion of the of the &lt;code&gt;value_input_option&lt;/code&gt;.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Insert data provided into the sheet.

        :param data: List of data elements to insert into the sheet.
        :param index: Index to insert data into. Defaults to index 2, assuming the first index has headers.
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value_input_option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER_ENTERED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&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;Cannot append data to sheet.&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;After making the quick switch to the new function, I read further into what value to pass with this parameter. When looking more at the documentation for this option, I selected &lt;code&gt;USER_ENTERED&lt;/code&gt; as it allows for the data to be parsed as if it were typed into a sheet, meaning numbers will stay as numbers and strings will be interpreted as either string, numbers, dates, etc. &lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;What did I learn here? The issue of a single quote appending to the front of numbers was not coming from the code I had developed to collect the data but the way in which I was utilizing the functions(s) to append new data into the sheet. &lt;strong&gt;A simple switch to &lt;code&gt;append_row()&lt;/code&gt; allowed the data to be considered as &lt;code&gt;USER_ENTERED&lt;/code&gt; meaning when entering numbers or dates, that they would be interpreted as such in the sheet when uploaded.&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Development Stack
&lt;/h3&gt;

&lt;p&gt;Thank you for following along! We have all the pieces together to be able to collect data with a SMS survey using Twilio and append the data into a Google Sheet. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fla7zchv71vf9rdwe5em7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fla7zchv71vf9rdwe5em7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for next weeks post where I discuss the application as a whole and how I tied all the pieces together. I look forward to sharing with you  the final issues and learnings I have encountered while participating in this hackathon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reference Links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/docs/usage/api" rel="noopener noreferrer"&gt;Twilio's Rest API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.twilio.com/docs/voice/tutorials/automated-survey-python-flask" rel="noopener noreferrer"&gt;Automated Survey - Python Flask App&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/TwilioDevEd/automated-survey-flask" rel="noopener noreferrer"&gt;GitHub Sample Automated Survey&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=vISRn5qFrkM&amp;amp;list=PLqrz4nXepkz60FNw4ORm1iLTn_R5o9fBb" rel="noopener noreferrer"&gt;Google Sheets and Python Example&lt;/a&gt;&lt;br&gt;
&lt;a href="https://towardsdatascience.com/accessing-google-spreadsheet-data-using-python-90a5bc214fd2" rel="noopener noreferrer"&gt;Accessing Google Spreadsheets with Python&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.geeksforgeeks.org/different-ways-to-clear-a-list-in-python/" rel="noopener noreferrer"&gt;Clearing Lists&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developers.google.com/sheets/api/reference/rest/v4/ValueInputOption" rel="noopener noreferrer"&gt;Google Sheets Value Input Option&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>twilio</category>
      <category>python</category>
      <category>flask</category>
    </item>
    <item>
      <title>What I Learned using Flask for the First Time </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 16 Apr 2020 18:18:17 +0000</pubDate>
      <link>https://dev.to/rosejcday/setting-up-twilio-with-flask-and-testing-surveys-3e9k</link>
      <guid>https://dev.to/rosejcday/setting-up-twilio-with-flask-and-testing-surveys-3e9k</guid>
      <description>&lt;p&gt;Happy Thursday! I hope things are going well. I have enjoyed working through some (ha, many) issues while learning Flask to integrate Python with Twilio's API. This week I will focus on the issues and learnings I had with using both Flask and Twilio for the first time. &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;At the moment, I spend time logging migraines for the doctors office but don't remember the format she wanted, or the details she found important. This application is being created as a way to request a survey for a migraine through SMS, quickly fill out the details, and log the data for later use at the doctors appointment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;To clone the code, please visit the GitHub project &lt;a href="https://github.com/rosejcday/migraine_tracking" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This project is a current work in progress and is not fully functional at this time, the app will walk through a survey but data is not currently saved anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues and Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Port Issues
&lt;/h3&gt;

&lt;p&gt;The first issue I ran into was connecting to a port when starting my application using &lt;code&gt;python3 -m app run&lt;/code&gt;. I have run into this issue in the past when I use to work on servers and would get similar messages to the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket.error: &lt;span class="o"&gt;[&lt;/span&gt;Errno 48] Address already &lt;span class="k"&gt;in &lt;/span&gt;use 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This just means a process is bound to the port I am trying to use. This is caused by the same Python app being called before and that process still being bound to the port. To fix this, I looked at what Python processes were still running using &lt;code&gt;ps -fA | grep python&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Using this, you can spot the running Python process that is still active. You may want to test if &lt;code&gt;http://localhost:&amp;lt;port&amp;gt;/&lt;/code&gt; still shows a directory listing for local files. The second number is the process number that you will need to stop. This can be done using the command &lt;code&gt;kill&lt;/code&gt; as in the example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-fA&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;python

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;  501 39548 16817   0  9:50PM ttys001    0:00.20 Python &lt;span class="nt"&gt;-m&lt;/span&gt; app run

&lt;span class="nb"&gt;kill &lt;/span&gt;39548

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;1]+  Terminated: 15          python3 &lt;span class="nt"&gt;-m&lt;/span&gt; app run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;blockquote&gt;
&lt;p&gt;What did I learn here? &lt;strong&gt;This is caused by the same Python app being called before and that process still being bound to the port.&lt;/strong&gt; This has only happened twice so far, and it is a simple and quick fix to just kill the process.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Type and Casting
&lt;/h3&gt;

&lt;p&gt;The next issue was one I didn't realize was happening until I ran into it. When running the application, I would answer the first question sent by the survey and received the response below:&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="k"&gt;*&lt;/span&gt; Running on http://127.0.0.1:5000/ &lt;span class="o"&gt;(&lt;/span&gt;Press CTRL+C to quit&lt;span class="o"&gt;)&lt;/span&gt;
127.0.0.1 - - &lt;span class="o"&gt;[&lt;/span&gt;08/Apr/2020 18:09:20] &lt;span class="s2"&gt;"POST /sms HTTP/1.1"&lt;/span&gt; 200 -
&lt;span class="o"&gt;[&lt;/span&gt;2020-04-08 18:09:20,296] ERROR &lt;span class="k"&gt;in &lt;/span&gt;app: Exception on /question/1 &lt;span class="o"&gt;[&lt;/span&gt;GET]

TypeError: cannot unpack non-iterable NoneType object
127.0.0.1 - - &lt;span class="o"&gt;[&lt;/span&gt;08/Apr/2020 18:09:20] &lt;span class="s2"&gt;"GET /question/1?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After an initial search into this issue, it was clear that results were all over the place. With that, I looked into the first question and coded up what I expected to be happening. I set the &lt;code&gt;question_id&lt;/code&gt; to 1, read in the JSON for the survey, and passed the question ID into the survey to grab the question information for it. After returning the first question and its type, I printed the information.&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;parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parseJson&lt;/span&gt;

&lt;span class="n"&gt;question_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;surv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../survey.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;surv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;question_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&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="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running this code, it produced the expected results, therefore something was wrong with the way the &lt;code&gt;question_id&lt;/code&gt; was being passed. To recreated the problem outside of the Flask application, I changed the &lt;code&gt;question_id&lt;/code&gt; to a string instead of int. Rerunning that code, reproduced the expected error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TypeError: cannot unpack non-iterable NoneType object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;blockquote&gt;
&lt;p&gt;What did I learn here? Therefore, the issue had been resolved. It was a type issue in which I was expecting an integer and receiving a string instead. &lt;strong&gt;Don't assume the type of the value being passed in, make it explicit.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Flask Session Secrets
&lt;/h3&gt;

&lt;p&gt;As I had mentioned, I have not used Flask before, so I expected to end up with issues learning how to use it. The main issue I had when learning Flask was how to use session secrets. After resolving the above issues, the next that came up was the about not having a session secret setup.&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="s2"&gt;"The session is unavailable because no secret "&lt;/span&gt;
RuntimeError: The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sessions allow you to store user data from one request to the next. This was needed in the survey in order to store and track the question that the user was on and iterate to the next question. &lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;What did I learn here? When researching sessions, &lt;strong&gt;I learned that the secret key is used in a session to implement on top of the cookies and is used so that the data cannot be modified without the key used for signing.&lt;/strong&gt; Here is more information on &lt;a href="https://flask.palletsprojects.com/en/1.1.x/quickstart/#sessions" rel="noopener noreferrer"&gt;Sessions&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Getting to the Next Question
&lt;/h3&gt;

&lt;p&gt;The last issue I had came about when I was interacting with the code I developed previously to grab the JSON survey and read it. When implementing this code and trying to get to the next question in the survey, I ran into two main problems I had when working with the survey questions: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to find out if there was another question in the JSON or not based on the currently stored &lt;code&gt;question_id&lt;/code&gt;?
&lt;/li&gt;
&lt;li&gt;What does the app do if there is another question? What does the app do if there is not another question?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With that, let's take a look at question 1, how do you use &lt;code&gt;question_id&lt;/code&gt; to determine if another question exists. To start, I looked back at the function I created in &lt;code&gt;parse.py&lt;/code&gt; to see how I was gathering the data and was using a filter object which grabbed out the question whose ID matched and would return the body and type of the data.&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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;survey_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_json_to_dict&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;questions&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;question_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;survey_dict&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;except&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;The index povided for the question does not appear to exist.&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;After some further reading into this section of the code, I changed the line that filters to a way that will return a list instead of filter object. The line &lt;code&gt;filter(function, iterable)&lt;/code&gt; is equivalent to &lt;code&gt;[item for item in iterable if function(item)]&lt;/code&gt; which means I can change the code to substitute:&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;survey_dict&lt;/span&gt; &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;question_id&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a more Pythonic way to find the next question in the JSON that we read in. &lt;/p&gt;

&lt;p&gt;With that, we can get onto question 2, what does the app do now that it has the data for the next question? The data returned for the next question is either &lt;code&gt;None&lt;/code&gt; or the next question's information. Using the &lt;code&gt;question_id&lt;/code&gt;, the &lt;code&gt;answer()&lt;/code&gt; function reads in the question ID given, (example: question 1 returns 1) and then iterates to the next questions ID by 1. Therefore, when question 1 is provided, the next ID would be 2. We use that ID, 2, and feed it into the &lt;code&gt;surv.question_metadata()&lt;/code&gt; function which looks to see if the data returned is None or another question. &lt;/p&gt;

&lt;p&gt;Before proceeding with that data collected, the &lt;code&gt;answer()&lt;/code&gt; function extracts out the content from the previous question and stores it, which will be discussed more next week. After storing the data, the function looks to see if the data for the next question is None, which will end the survey, OR the if the data contains the next question, it will then pass the ID of the question and pass the ID to &lt;code&gt;redirect_twiml()&lt;/code&gt; which will handle the response to the user.&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/answer/&amp;lt;question_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# Cast to an int, comes in as a string
&lt;/span&gt;    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;surv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;question_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Return first question
&lt;/span&gt;    &lt;span class="n"&gt;data_collected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;extract_content&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="c1"&gt;# Append the data collected
&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect_twiml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;goodbye_twiml&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;What did I learn here? After working through these two problems, I gained a better understanding in how Flask operates to redirect from one function to the next and how I needed to setup the survey to redirect correctly as the user answered each question. During this time, I began to understand more about &lt;code&gt;Sessions&lt;/code&gt; as well, which I talked about earlier. &lt;strong&gt;The smallest tidbit of info I took away from this issue was that the line &lt;code&gt;filter(function, iterable)&lt;/code&gt; is equivalent to &lt;code&gt;[item for item in iterable if function(item)]&lt;/code&gt; which is a more Pythonic way to work with the data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Development Stack
&lt;/h3&gt;

&lt;p&gt;So far, I have worked on the code needed to interact with Google Sheets API and Twilio API in a Flask application... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy77x1q2oufbxi3yw5buj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy77x1q2oufbxi3yw5buj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for next weeks post where I discuss how I integrate the two API's together in the Python Flask app that generates a survey for migraines. I look forward to sharing with you the issues and learnings I have encountered while learning to use Flask with these API's!&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reference Links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/docs/usage/api" rel="noopener noreferrer"&gt;Twilio's Rest API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.twilio.com/docs/voice/tutorials/automated-survey-python-flask" rel="noopener noreferrer"&gt;Automated Survey - Python Flask App&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/TwilioDevEd/automated-survey-flask" rel="noopener noreferrer"&gt;GitHub Sample Automated Survey&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ngrok.com/docs" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=cZeCz_QOoXw&amp;amp;list=PLqrz4nXepkz63z1y4-oHfZHWy11gSoAn0&amp;amp;index=17" rel="noopener noreferrer"&gt;How to Receive an SMS in Python with Twilio&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.twilio.com/blog/2014/07/the-definitive-guide-to-sms-conversation-tracking.html" rel="noopener noreferrer"&gt;SMS Conversation Tracking&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>python</category>
      <category>flask</category>
      <category>twilio</category>
    </item>
    <item>
      <title>Setting up Python to Connect to Google Sheets </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 09 Apr 2020 23:29:33 +0000</pubDate>
      <link>https://dev.to/rosejcday/setting-up-python-to-connect-to-google-sheets-2ak7</link>
      <guid>https://dev.to/rosejcday/setting-up-python-to-connect-to-google-sheets-2ak7</guid>
      <description>&lt;p&gt;Happy Thursday! I hope you are all doing well. It has been exciting to continue working with Twilio and Google sheets on this project. This week I will focus on the issues and learnings I had with using Google's APIs for the first time. &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;p&gt;At the moment, I spend time logging migraines for the doctors office but don't remember the format she wanted, or the details she found important. This application is being created as a way to request a survey for a migraine through SMS, quickly fill out the details, and log the data for later use at the doctors appointment.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;To clone or view the code, please visit my GitHub project &lt;a href="https://github.com/rosejcday/migraine_tracking" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This project is a current work in progress and is not fully functional at this time.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Issues and Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  API Errors due to Scope
&lt;/h3&gt;

&lt;p&gt;The first issue I ran into when trying to implement code to interact with Google Sheets through API was related to scope issues. I first assumed I had setup the configuration file wrong but later realized it was due to version changes on the API and referencing older tutorials. The issue I was seeing was as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gspread.exceptions.APIError: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'errors'&lt;/span&gt;: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'domain'&lt;/span&gt;: &lt;span class="s1"&gt;'global'&lt;/span&gt;, &lt;span class="s1"&gt;'reason'&lt;/span&gt;: &lt;span class="s1"&gt;'insufficientPermissions'&lt;/span&gt;, &lt;span class="s1"&gt;'message'&lt;/span&gt;: &lt;span class="s1"&gt;'Insufficient Permission: Request had insufficient authentication scopes.'&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;, &lt;span class="s1"&gt;'code'&lt;/span&gt;: 403, &lt;span class="s1"&gt;'message'&lt;/span&gt;: &lt;span class="s1"&gt;'Insufficient Permission: Request had insufficient authentication scopes.'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After spending time researching this error, I came across a post that showed the scopes needed were the two shown below:&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="c1"&gt;# Create a spread client authorizing it using those credentials.
&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://spreadsheets.google.com/feeds&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.googleapis.com/auth/drive&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;What did I learn here? The reason this issue was occurring was due to an API update. &lt;strong&gt;gspread was upgraded and is based on API v4.&lt;/strong&gt; The change allowed the API to be faster than previous versions but also required scopes to be updated in order to work properly. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Path Issues with PyTest
&lt;/h3&gt;

&lt;p&gt;The next issue I ran across was when working with PyTest. The constructor of the class I setup to work with spreadsheets requires two inputs (1) filename of the JSON containing the credentials for the API which includes the path in the input, and (2) the name of the sheet to connect to. &lt;/p&gt;

&lt;p&gt;When working with this constructor in the &lt;code&gt;executor.py&lt;/code&gt; file, I provided the path seen below, which worked as expected. (&lt;strong&gt;Note&lt;/strong&gt;: This code will later move to the app.py file when the Twilio API is introduced.)&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;sheet1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../client_secret.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;migraine_tracker&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;Utilizing the same line, I placed the code into a test file and came back with the warning &lt;code&gt;WARNING: Failed to generate report: No data to report.&lt;/code&gt; meaning that no data could be read. &lt;/p&gt;

&lt;p&gt;After seeing this, I installed pytest-cov to analyze the test coverage and see what lines were being hit and what lines were being missed. At this point, I realized the test coverage was stopping at an important line in the constructor:&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;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ServiceAccountCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_json_keyfile_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, the credentials were not being created due to this line failing and the sheet was not able to be called. &lt;/p&gt;

&lt;p&gt;When looking back at the test for the line that provides the JSON file, I worked to determine why the path was not working correctly. To look further at the path issue, I created a small test that would assert if the path existed. I ran this test with both paths &lt;code&gt;../client_secret.json&lt;/code&gt; and &lt;code&gt;client_secret.json&lt;/code&gt;, at which point I found out the path needed to be the latter to work properly in the test file.&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;import&lt;/span&gt; &lt;span class="n"&gt;os.path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pprint&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_path&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Determine if the path specified is correct.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;client_secret.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Produces True and pass 
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../client_secret.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Produces False and fail 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, I changed the input into the constructor which in turn fixed my issue and made it so I could run my tests successfully.&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;sheet1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;client_secret.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;migraine_tracker&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;What did I learn here? &lt;strong&gt;Check the root directory&lt;/strong&gt;. Pytest was running from &lt;code&gt;rootdir: /../../../twilio_application&lt;/code&gt; and not the folder I was expecting it to run from. Seems like a trivial mistake when looking back at it, but it is something that can easily be overlooked.  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Development Stack
&lt;/h3&gt;

&lt;p&gt;So far, I have worked on the code needed to interact with Google Sheets API... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvbt2d6fnj0typ6v203xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvbt2d6fnj0typ6v203xf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for next weeks post where I discuss how I utilize the Twilio API to develop a Python Flask app that generates a survey for migraines. I look forward to sharing with you the issues and learnings I have encountered while learning to use Flask!&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reference Links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=vISRn5qFrkM&amp;amp;list=PLqrz4nXepkz60FNw4ORm1iLTn_R5o9fBb" rel="noopener noreferrer"&gt;Google Sheets and Python Example&lt;/a&gt;&lt;br&gt;
&lt;a href="https://towardsdatascience.com/accessing-google-spreadsheet-data-using-python-90a5bc214fd2" rel="noopener noreferrer"&gt;Accessing Google Spreadsheets with Python&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.guru99.com/python-check-if-file-exists.html" rel="noopener noreferrer"&gt;Python Check if File or Directory Exists&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.pytest.org/en/latest/" rel="noopener noreferrer"&gt;pytest&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pypi.org/project/pytest-cov/" rel="noopener noreferrer"&gt;pytest-cov&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>python</category>
      <category>api</category>
      <category>learning</category>
    </item>
    <item>
      <title>Tracking Migraines with SMS</title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Fri, 03 Apr 2020 20:00:31 +0000</pubDate>
      <link>https://dev.to/rosejcday/tracking-migraines-with-sms-4hhl</link>
      <guid>https://dev.to/rosejcday/tracking-migraines-with-sms-4hhl</guid>
      <description>&lt;p&gt;Happy Friday! I am excited to try something new and begin working with Twilio's APIs. &lt;/p&gt;

&lt;h2&gt;
  
  
  Category - Engaging Engagements and Interesting Integrations
&lt;/h2&gt;

&lt;p&gt;I am focusing on two categories during this hackathon: Engaging Engagements and Interesting Integrations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engaging Engagements&lt;/strong&gt; looks at developing applications that a company could implement to better engage with their customers or to manage their business and &lt;strong&gt;Interesting Integrations&lt;/strong&gt; focus on the integration of Twilio with at least one other API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;During this hackathon, I am looking for a simple method to collect data using SMS and Google Sheets. Every month I spend time logging migraines for the doctors office but don't remember the questions she commonly asks, or the details she found important from my last appointment. This application is being created as a way to log migraines in Google Sheets by quickly filling out the details of a survey sent through SMS. The user can then print off the sheet that has been populated and bring it with them to their next doctor's appointment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commonly Asked Questions for Migraines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In a scale of 1-10, how would you rate your migraine?&lt;/li&gt;
&lt;li&gt;Where is your migraine located today?&lt;/li&gt;
&lt;li&gt;How long did your migraine last (in hours)?&lt;/li&gt;
&lt;li&gt;What medication did you take to treat the migraine?&lt;/li&gt;
&lt;li&gt;Has anything changed? Is anything out of the ordinary? &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Development Stack
&lt;/h3&gt;

&lt;p&gt;I am working with the Twilio API to develop a Python Flask app that generates a survey for migraines and saves the data in a Google Sheet. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---1cWXpRD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la7zchv71vf9rdwe5em7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---1cWXpRD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la7zchv71vf9rdwe5em7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I look forward to posting each week my progress and learnings as I tackle this problem. Stay tuned for next weeks post as I begin to utilize Googles API to read and write data to a sheet!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reference Links
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/docs/usage/api"&gt;Twilio's Rest API&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>Software Engineering to Data Science </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Sat, 28 Mar 2020 02:15:50 +0000</pubDate>
      <link>https://dev.to/rosejcday/software-engineering-to-data-science-2f5f</link>
      <guid>https://dev.to/rosejcday/software-engineering-to-data-science-2f5f</guid>
      <description>&lt;p&gt;The other day I saw a question from &lt;a class="comment-mentioned-user" href="https://dev.to/yadlra"&gt;@yadlra&lt;/a&gt;
 posted: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dev.to/yadlra/swapping-to-data-science-8pi"&gt;Hey guys, what skills do I need to be a data scientist? Do the same skills apply as being a software developer?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I posted a lengthy response but felt others would also benefit from a post on the topic. &lt;/p&gt;

&lt;p&gt;In 2017, I graduated college as a computer engineer and began working full time before making the transition into data science. I have found the skills learned from software to be greatly transferrable to data science, especially when you are looking to build tools to work with big data. &lt;/p&gt;

&lt;p&gt;Currently, I work on a team that focuses on tools and machine learning application, but there are many areas of data science that one could consider. Below, I outline some of the areas, skills, and resources that I looked into during my transition into the field. &lt;/p&gt;

&lt;h2&gt;
  
  
  Areas of Data Science
&lt;/h2&gt;

&lt;p&gt;There are many fields in which data science can be applied. Recently, I have spoken at two colleges for talks on data science and was asked a series of questions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is there a field in which you cannot utilize data science?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer to this question was no. I believe that every field could utilize data science if the data is available, or in turn, be able to use it in the future, if the data is made available. I have even seen artists utilize data to create sculptures. Once you have picked a field of interest, you can find data related jobs in data science, data engineering, and more. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did you study data science in your undergraduate or is it okay to have a Bachelors degree in another field first? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like mentioned earlier, I did not study data science initially but transitioned to it when I went back for a masters. I have found that with most data scientists I have worked with, they have studied something else first before moving into data science. These individuals specialized in computer science, different areas of engineering, mathematics, and more. It is perfectly fine to specialize in one area and then use the knowledge gained there to further your data science education. You will bring different aspects to data science that others may not see due to your background. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How did you go about searching for jobs? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One thing I have learned while job searching in the field is that not all titles mean the same thing. Titles ranged from data scientist, data analyst, business analyst, data engineer, and more. I stopped searching by title and started searching by keywords as it helped me narrow down job descriptions that fit with what I was looking for. Keywords I used when searching focused on the languages I wanted to program in (Python), the tools I wanted to get exposure to or keep using (Tableau, Spark, Git), and the type of work I was looking for (IoT, Connected Systems, Sensors). &lt;/p&gt;

&lt;p&gt;Another method of job searching that can be a valuable tool is networking, both virtually and attending meetups. For example, I have found LinkedIn to be a wonderful tool to network virtually with colleagues in my field, and to connect with them on what their companies are doing and the types of conferences or events they are attending. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What skills have helped you in your career and what tools have you used? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once I found a field to specialize in, I began focusing on the skills I wanted to learn. The first job I had in data science was a co-op as a data engineer. During this time I worked to learn more about Docker for containerization of data applications, databases, and ETL processes. After this job, I began working as an engineer in applied data science. At this point, I began focusing my skills more on statistics / math, data cleaning, big data handling, data storytelling and visualizations, and tool development. Of these two jobs, tool development and application development was where I was able to leverage more of my software background, while more data analysis and visualizations were where I was able to use more of my data science background. During both jobs, I have found programming to be a valuable skill, especially object oriented programming and writing clean code. Skills can vary job by job but finding out what you enjoy doing will aid you not just in finding a job but in enjoying it too!    &lt;/p&gt;

&lt;p&gt;If you are looking for tools and frameworks to learn, here are just a few to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jupyter Notebooks for prototyping code &lt;/li&gt;
&lt;li&gt;Git for version controlling notebooks and other code &lt;/li&gt;
&lt;li&gt;Spark and Hadoop for big data processing&lt;/li&gt;
&lt;li&gt;Databases and data storage for different types of data, understanding when to use what type of data store will be helpful &lt;/li&gt;
&lt;li&gt;Tableau and other BI tools for dashboarding and visualizations &lt;/li&gt;
&lt;li&gt;Python visualization libraries: Bokeh, Matplotlib, etc.&lt;/li&gt;
&lt;li&gt;R and its respective libraries / R Shiny
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;What resources have you found helpful to continue learning outside of going to college? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A good book to look at when starting in data science is &lt;strong&gt;An Introduction to Statistical Learning: With Applications in R&lt;/strong&gt;. This was a great read and very helpful when I was starting out. I still keep a copy at work as a reference for when I am working on something. &lt;/p&gt;

&lt;p&gt;If you are looking for another good read that is more software focused, &lt;strong&gt;Clean Code&lt;/strong&gt; by Robert Cecil Martin is a great book focused on how to write well structured code that is easy to read. The book focuses on Java to teach the skills but I apply the same concepts to Python. &lt;/p&gt;

&lt;p&gt;Another good resource for books is the publisher O'Rielly. They have tons of good books on data science and Python. I have found their books to be helpful and keep some of them as reference at work as well. &lt;/p&gt;

&lt;p&gt;I also recommend looking into open source data sets available to see what flavors of data exists and to determine your preference on what kind of data you want to work with. Some types of data include spacial data, image processing, structured or unstructured documents, etc. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;There is so much you can look into with data science, just pick somewhere to start and run with it!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>development</category>
    </item>
    <item>
      <title>From Interviewee to Interviewer to Interviewee </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 11 Jul 2019 17:57:36 +0000</pubDate>
      <link>https://dev.to/rosejcday/from-interviewee-to-interviewer-to-interviewee-320a</link>
      <guid>https://dev.to/rosejcday/from-interviewee-to-interviewer-to-interviewee-320a</guid>
      <description>&lt;p&gt;Back when I began interviewing for internships, it seemed like questions were asked at random with no real goal in mind. Some questions would be more open ended, some looking for a specific answer, and others technical in nature. As I have continued in my career, I have not only had many interviews but I have now been on the other side of the table interviewing people for open positions, and it brings a whole new light into how and why certain questions are asked. Over the past two years or so I have had many opportunities to interview and be interviewed. Through which, I have accumulated notes on how people interview, what types of questions they ask and why. So, here is my experience with it:  &lt;/p&gt;

&lt;h2&gt;
  
  
  Behavioral Questions
&lt;/h2&gt;

&lt;p&gt;The questions that I have always found interesting are the behavioral questions. In asking different people why they ask these types of questions during interviews, most have told me it was to evaluate how I would react in different situations and to determine if I would be a good cultural fit for the team. Here are a ew behavioral questions that I have always loved to be asked and to ask: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;If you had to be a fruit/dessert, what would you be and why?&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Explain a time when you had to be a leader on a project or at work. How did you take on this role? What did you learn?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Explain a time when you had to educate others on a technical topic? How did you approach this? How did it go?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Discuss your experience with public speaking.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Favorite type of music / instrument / band and why?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;You are on a sky lift that has a tight turn radius and 24 seats. You are at the bottom getting on the chair. There is a chair at the top coming down. How many chairs do you pass on the way up to the top?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Explain your volunteer work. What do you do outside of work?&lt;/em&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Technical Questions
&lt;/h2&gt;

&lt;p&gt;The next set of questions come from the technical side but range in what is asked and how. From my experience, these are the types of technical interviews I have had and what I learned from each: &lt;/p&gt;

&lt;h4&gt;
  
  
  Online Code Test
&lt;/h4&gt;

&lt;p&gt;(&lt;em&gt;Time&lt;/em&gt;: 1-2 hours, &lt;em&gt;Questions&lt;/em&gt;: 3-4) &lt;/p&gt;

&lt;p&gt;The online code tests I have taken are the standard tests that ask a handful of questions (typically 3 to 4) in a coding language. Depending on the company, some require a specific language to be used while other don't. Most of these resemble the algorithmic questions you would get in a college coding class. They expect a specific answer to a problem. Some companies will send out the code test to be completed while others will have you complete the code test while being monitored. I have found that the tests in which I am monitored, it is best to take many notes and have an open dialog during the process to show how you're thinking through the problem.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Take-home Code Test
&lt;/h4&gt;

&lt;p&gt;(&lt;em&gt;Time&lt;/em&gt;: 1 week, &lt;em&gt;Questions&lt;/em&gt;: 1 mini project) &lt;/p&gt;

&lt;p&gt;Code tests that I have taken in this format are much more open ended. They provide a problem and desired output, and it is up to the coder to develop a function or set of functions to complete the task. When I take these types of code tests, I read through everything carefully and build up a set of questions / assumptions I have about the problem and verify that what is expected on their end is the same as what I expect. I find it is best to have good communication in these types of code tests, to clear up any misconceptions that could occur while developing the code.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Open Ended Questions
&lt;/h4&gt;

&lt;p&gt;(&lt;em&gt;Time&lt;/em&gt;: depends on interview length)  &lt;/p&gt;

&lt;p&gt;The next type of questions I have seen in an interview is more open ended questions during a 30 minute talk with a team member. These questions have ranged anywhere from basic problems and how you would solve them, to explaining key features in an application. I have found these problems to be the most interesting of the coding questions as it allows for an open dialog with both the interviewer and interviewee. You can bounce ideas off of one another, openly discuss solutions, and explain your thinking as you go. These can also lead into more questions or further discussion.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Discussion on Experience
&lt;/h4&gt;

&lt;p&gt;(&lt;em&gt;Time&lt;/em&gt;: depends on interview length) &lt;/p&gt;

&lt;p&gt;The last type of technical interview I have been in was very open and more focused on my own experience. When placed in these situations, I have had one or more team members in a room asking about personal experiences, basing questions off the discussion, and diving deeper into the projects or work discussed. I have found that an interviewer may push further into specifics on a project or work experience if they want to test your knowledge or understanding of it. I try to include as much detail as I can on these discussions and allow room for further discussion and ideas to flourish. Sometimes many technical minds in a room can give light to new ideas as you discuss projects you are tackling! &lt;/p&gt;

&lt;h2&gt;
  
  
  Questions for the Company
&lt;/h2&gt;

&lt;p&gt;After all of their questions have been answered, it is time to begin to ask your own. I find this is a good place to have researched the company and the product(s) that they specialize in, in order to go in with a good set of questions to ask. If it is a multistep interviewing process, I make sure to review all notes and previous questions asked in order to make a new list of questions for each person or interview I walk into.  &lt;/p&gt;

&lt;p&gt;A few questions I love to ask no matter the place include: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Why do you love to work at you job? What keeps you motivated to stay here?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;What do you believe to be a key feature or asset of the product / company that sets you apart on the market?&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Ask in-depth questions on the product, how it operates, and what functionality may benefit the company moving forward.&lt;/em&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I love to ask the first question of almost everyone I interview with. I began asking this question this past year or so because I wanted to find a place people enjoyed working for and a team that enjoys each other. Making people think about their team and company can tell you a lot about the environment they work in. This has helped me filter out companies that I feel do not have a great culture fit with what I am looking for. &lt;/p&gt;

&lt;p&gt;The next question helps me determine what a company is really striving for and where they are headed in the future. I ask this question of different people to get a better understanding of how they view the company versus what is posted online about the company or on the company site. If it is a startup, I also like to ask what began the company? What was the motivation behind building this product in the first place? Sometimes the answers may surprise you. &lt;/p&gt;

&lt;p&gt;Lastly, I like to dive deeper into the product itself to understand where the company is now, where they are looking to head, and how the position I am applying for helps reach those goals. If there is not a clear understanding of where the role fits into this development, I take that as a warning. I look for positions that offer growth, learning, and development, not only as an individual but as a company.  &lt;/p&gt;

&lt;h3&gt;
  
  
  What types of questions do you face? What has been your experience with technical interviews? And lastly, what are your favorite questions to ask?
&lt;/h3&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is your one piece of advice or best tip for getting better in Python programming? </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Wed, 24 Apr 2019 14:23:00 +0000</pubDate>
      <link>https://dev.to/rosejcday/what-is-your-one-piece-of-advice-or-best-tip-for-getting-better-in-python-programming-1dih</link>
      <guid>https://dev.to/rosejcday/what-is-your-one-piece-of-advice-or-best-tip-for-getting-better-in-python-programming-1dih</guid>
      <description>

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Learning the Differences between Softmax and Sigmoid for Image Classification</title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Thu, 22 Nov 2018 04:04:36 +0000</pubDate>
      <link>https://dev.to/rosejcday/learning-the-differences-between-softmax-and-sigmoid-for-image-classification--59c</link>
      <guid>https://dev.to/rosejcday/learning-the-differences-between-softmax-and-sigmoid-for-image-classification--59c</guid>
      <description>&lt;p&gt;Liquid syntax error: Unknown tag '20'&lt;/p&gt;
</description>
      <category>python</category>
      <category>ai</category>
      <category>deeplearning</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Parsing CSV Rows into Separate Text Files </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Tue, 13 Nov 2018 03:42:24 +0000</pubDate>
      <link>https://dev.to/rosejcday/parsing-csv-rows-into-separate-text-files--29lk</link>
      <guid>https://dev.to/rosejcday/parsing-csv-rows-into-separate-text-files--29lk</guid>
      <description>&lt;p&gt;The #100DaysofCode challenge is an initiative by Alexander Kallaway designed to help people learning how to code to be more consistent. The goal of this challenge was to code for at least an hour everyday for 100 days. &lt;/p&gt;

&lt;p&gt;Going off this premise, I decided to work at least an hour every day on just research and coding for image classification. Today marks the end of the first week, in which I researched and worked on the project &lt;a href="https://devmesh.intel.com/projects/analyzing-deforestation-and-urbanization-using-intel-ai-technologies"&gt;Analyzing Deforestation and Urbanization Using Intel AI Technologies&lt;/a&gt;. During this project, I have been working with Intel Optimized TensorFlow for image classification of satellite imagery. In this first week I have learned many interesting things about image classification and labeling. The one I found most interesting to share would be how to parse labels from a CSV file and transform the labels into the format that I wanted. &lt;/p&gt;

&lt;p&gt;For this challenge I faced, let's look at the following example CSV file. This table has two columns, the first column being image name, and the second column consisting of an array of labels. This was the design of the original CSV file that I was working with. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Image Name&lt;/th&gt;
&lt;th&gt;Labels&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Image_001&lt;/td&gt;
&lt;td&gt;haze city farm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image_002&lt;/td&gt;
&lt;td&gt;city&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image_003&lt;/td&gt;
&lt;td&gt;water farm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The desired format I needed for labels was to take the image name and create a text file based on that name. For the first row, the file would be called &lt;code&gt;Image_001.jpg.txt&lt;/code&gt; and contain all the labels for that image with each label on a separate line. Coding in Python 3, I worked to create a function that would transform the original CSV into the desired text files. As can be seen below, the file &lt;code&gt;Image_001.jpg.txt&lt;/code&gt; would be populated with data like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;haze&lt;/span&gt; 
&lt;span class="n"&gt;city&lt;/span&gt; 
&lt;span class="n"&gt;farm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function created to make this transformation first reads in the data path and filename. Data path refers to the path in which the original CSV is stored and filename refers to the name of the CSV file. This data is stored in a dataframe that can be then traversed to gather data. Each row in the CSV is read as the variable row. Once in row, the first column &lt;code&gt;row[0]&lt;/code&gt; is used to create the name of the new text file. Then, the second column, &lt;code&gt;row[1]&lt;/code&gt; is split based on spaces. This list of labels, called splitrow, is then iterated over to append each label on a new line of the text file. Once completed, the file is closed and a new file can be created for the next image. This will create one label text file for each image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_parse_labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;df_train_tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data_path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df_train_tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iterrows&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df_train_tags&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: Cannot read images, file length too short..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing: Reading image "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;labels_path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'.jpg.txt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'w'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;splitrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;splitrow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Completed: Finished reading labels dataset..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An interesting note to make here that I didn't realize at first was why the index was required in the for loop. When thinking of a for loop, I refer to &lt;code&gt;for each item in dataset then loop&lt;/code&gt; where each item is a row of the dataframe. This logic makes sense but what is happening here is iterrows gives a tuple value rather than just the rows. This means we have to call (index, row) for the tuple in order to access the columns. &lt;/p&gt;

&lt;p&gt;After working this past week on research and coding, this was one of the more interesting problems I faced as it involved splitting and transforming one singular column into a text file of many lines. This function also helped give a good overview of basic dataframe and array manipulation in Python. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;What interesting problems have you faced this week?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References:
&lt;/h3&gt;

&lt;p&gt;Cover image sourced from &lt;a href="https://images6.alphacoders.com/368/368992.jpg"&gt;Alpha Coders&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ai.intel.com/tensorflow/"&gt;Intel Optimized TensorFlow&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/tensorflow/tensorboard"&gt;TensorBoard&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/guide/"&gt;TensorFlow Guide&lt;/a&gt;&lt;br&gt;
&lt;a href="https://devmesh.intel.com/users/rose-day"&gt;Intel DevMesh&lt;/a&gt;&lt;br&gt;
&lt;a href="https://software.intel.com/en-us/ai-academy"&gt;Intel AI Academy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.iterrows.html"&gt;pandas.DataFrame.iterrows&lt;/a&gt;&lt;/p&gt;

</description>
      <category>100daysofcode</category>
      <category>python</category>
      <category>ai</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Data Cleaning and Mapping Functions - Learning AI with Intel AI Technology </title>
      <dc:creator>Rose Day </dc:creator>
      <pubDate>Fri, 02 Nov 2018 21:12:22 +0000</pubDate>
      <link>https://dev.to/rosejcday/data-cleaning-and-mapping-functions---learning-ai-with-intel-ai-technology--24g8</link>
      <guid>https://dev.to/rosejcday/data-cleaning-and-mapping-functions---learning-ai-with-intel-ai-technology--24g8</guid>
      <description>&lt;p&gt;I started on my journey to learn more about data science and AI a little over a year ago as I began my masters and then quit my job. I enrolled full time as a data science student and have enjoyed the decision ever since. When I began my data science classes, most focused on the fundamentals of data storage, management, and analysis. So in my spare time, I have been trying to learn more about AI. One particular thing I find of interest in AI is image recognition and classification. Through this, I have dabbled in different projects to look at live image recognition for movement and person detection. Moving on from this, I have found an interesting in analyzing satellite imagry to gather information from those images. One particular project I have been working on is my proposal for &lt;a href="https://devmesh.intel.com/projects/analyzing-deforestation-and-urbanization-using-intel-ai-technologies"&gt;Analyzing Deforestation and Urbanization Using Intel AI Technologies&lt;/a&gt;. Through these projects, I have learned new things in data import, setup and pipelines that I thought would be of interest to share. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cleaning Images
&lt;/h3&gt;

&lt;p&gt;One of the first things I have been learning while working with images for AI was that image import and setup was not as simple as sending an image to a model. When working with Intel Optimized TensorFlow to train a neural network to recognize images, an image dataset is needed with categories. The first thing I read that struck me as odd at first was that all images should be of the same size, for example (28 by 28 pixels). This is common on real-world image datasets that are being used to train neural networks as the images often come in different sizes. Based on this information, they should be batched into a fixed size. This information was well explained in the TensorFlow Guide for &lt;a href="https://www.tensorflow.org/guide/datasets#decoding_image_data_and_resizing_it"&gt;Importing Data&lt;/a&gt;, as seen below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Reads an image from a file, decodes it into a dense tensor, and resizes it&lt;/span&gt;
&lt;span class="c"&gt;# to a fixed shape.&lt;/span&gt;
def _parse_function&lt;span class="o"&gt;(&lt;/span&gt;filename, label&lt;span class="o"&gt;)&lt;/span&gt;:
  image_string &lt;span class="o"&gt;=&lt;/span&gt; tf.read_file&lt;span class="o"&gt;(&lt;/span&gt;filename&lt;span class="o"&gt;)&lt;/span&gt;
  image_decoded &lt;span class="o"&gt;=&lt;/span&gt; tf.image.decode_jpeg&lt;span class="o"&gt;(&lt;/span&gt;image_string&lt;span class="o"&gt;)&lt;/span&gt;
  image_resized &lt;span class="o"&gt;=&lt;/span&gt; tf.image.resize_images&lt;span class="o"&gt;(&lt;/span&gt;image_decoded, &lt;span class="o"&gt;[&lt;/span&gt;28, 28]&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;image_resized, label
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;From this, I was able to understand just how images were preprocessed before placing them into the model. As I continued to research just how images were processed, I also found it interesting to reexamine pixel format. The most common pixel format is a byte image which means each pixel in the 28 by 28 pixels image would range from 0 to 255 where 0 is black and 255 is white, and all values in between range in gray. This means that all images processed are analyzed in grayscale instead of color. More on image transformation can be seen at TensorFlow &lt;a href="https://www.tensorflow.org/api_guides/python/image"&gt;Images&lt;/a&gt; documentation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Data Pipelines and Decoding Images
&lt;/h3&gt;

&lt;p&gt;After understanding the image cleaning, I looked into data pipelines and decoding images. Moving from the code snippet above, it can be seen that the function reads an image from a file, then decodes that image into a dense tensor before resizing it into the determined 28 by 28 pixels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# A vector of filenames.&lt;/span&gt;
filenames &lt;span class="o"&gt;=&lt;/span&gt; tf.constant&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"/var/data/image1.jpg"&lt;/span&gt;, &lt;span class="s2"&gt;"/var/data/image2.jpg"&lt;/span&gt;, ...]&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# `labels[i]` is the label for the image in `filenames[i].&lt;/span&gt;
labels &lt;span class="o"&gt;=&lt;/span&gt; tf.constant&lt;span class="o"&gt;([&lt;/span&gt;0, 37, ...]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function, as can be seen, takes in a set of images and labels. These images and labels can be saved in tf.constants as below. At first this seemed odd, but through further reading I realized this action of tf.constant(value) was saving both the images and the labels into two constant tensors called filenames and labels.  &lt;/p&gt;

&lt;h3&gt;
  
  
  TensorFlow Mapping Functions
&lt;/h3&gt;

&lt;p&gt;Through all of the data cleaning, decoding, and pipelining it finally came down to the last two steps of the code which create the TensorFlow dataset from the filenames and labels before mapping the final function. I found this line, &lt;code&gt;tf.data.Dataset.from_tensor_slices&lt;/code&gt;, to be particularly confusing at first glance. Through research, I was able to discern that this line refers to the making of a TensorFlow dataset from the input constant vectors created above. This allows for the division of image files and labels in the dataset once created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;dataset &lt;span class="o"&gt;=&lt;/span&gt; tf.data.Dataset.from_tensor_slices&lt;span class="o"&gt;((&lt;/span&gt;filenames, labels&lt;span class="o"&gt;))&lt;/span&gt;
dataset &lt;span class="o"&gt;=&lt;/span&gt; dataset.map&lt;span class="o"&gt;(&lt;/span&gt;_parse_function&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once created, the &lt;code&gt;dataset.map&lt;/code&gt; function can be called with the parse function created earlier as a parameter. Map allows a transformation across all elements of the dataset and then returns a new dataset containing all transformed items. These items will appear in the same order at the original input. Therefore, when this map function is called, it calls upon the parse function created originally. This parse function was what had done all the image transformation and cleaning for us earlier. &lt;/p&gt;

&lt;p&gt;Writing my proposal for &lt;a href="https://devmesh.intel.com/projects/analyzing-deforestation-and-urbanization-using-intel-ai-technologies"&gt;Analyzing Deforestation and Urbanization Using Intel AI Technologies&lt;/a&gt; many months ago seemed like a small task, but now it has allowed me to push further into AI and image classification. I hope what I have learned thus far has helped you as well! &lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;p&gt;Cover image sourced from &lt;a href="https://www.vexels.com/blog/illustrator-tutorial-abstract-waves/"&gt;Vexel's Blog&lt;/a&gt;&lt;br&gt;
&lt;a href="https://devmesh.intel.com/projects/analyzing-deforestation-and-urbanization-using-intel-ai-technologies"&gt;Analyzing Deforestation and Urbanization Using Intel AI Technologies DevMesh &lt;/a&gt;&lt;br&gt;
&lt;a href="https://software.intel.com/en-us/articles/intel-optimization-for-tensorflow-installation-guide"&gt;Intel Optimized TensorFlow&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/guide/datasets#decoding_image_data_and_resizing_it"&gt;TensorFlow Importing Data&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/tutorials/keras/basic_classification"&gt;TensorFlow Basic Classification&lt;/a&gt; &lt;br&gt;
&lt;a href="https://cs230-stanford.github.io/tensorflow-input-data.html#building-an-image-data-pipeline"&gt;Building an Image Data Pipeline&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/api_docs/python/tf/constant"&gt;tf.constant&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/api_guides/python/image"&gt;TensorFlow Images&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map"&gt;TensorFlow Dataset Map&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tensorflow</category>
      <category>ai</category>
      <category>intel</category>
      <category>imageclassification</category>
    </item>
  </channel>
</rss>
