{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Scraping USPTO tables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The data for this visualization lives in 51 different HTML tables (50 states + Washington DC), each on a separate page. We could copy and paste each table into an Excel or LibreOffice spreadsheet, unpivot the tables and export to a CSV format, but that doesn’t scale well, and worse, it’s boring. Let's write a script!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Importing necessary packages"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We first import the necessary packages. For this script we use the collections, csv, requests, and Beautiful Soup to:\n",
"* Access the url where the different tables are stored,\n",
"* Parse and scrape the resulting page,\n",
"* Create a named tuple\n",
"* Write to a CSV file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from collections import namedtuple\n",
"import csv\n",
"import requests\n",
"from bs4 import BeautifulSoup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Declaring initial variables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now declare the variables that will be needed when we scrape USPTO.\n",
"1. A dictionary with the full state name to state abbreviation key-value pair,\n",
"2. the prefix and suffix url to the HTML tables,\n",
"3. the empty list to store scraped values,\n",
"4. and the named tuple function to pull the values from the scraped HTML."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# US state codes; add territory codes here if desired\n",
"REGION_CODES = {\n",
" 'Alabama' : 'AL',\n",
" 'Alaska' : 'AK',\n",
" 'Arizona' : 'AZ',\n",
" 'Arkansas' : 'AR',\n",
" 'California' : 'CA',\n",
" 'Colorado' : 'CO',\n",
" 'Connecticut' : 'CT',\n",
" 'Delaware' : 'DE',\n",
" 'District of Columbia' : 'DC',\n",
" 'Florida' : 'FL',\n",
" 'Georgia' : 'GA',\n",
" 'Hawaii' : 'HI',\n",
" 'Idaho' : 'ID',\n",
" 'Illinois' : 'IL',\n",
" 'Indiana' : 'IN',\n",
" 'Iowa' : 'IA',\n",
" 'Kansas' : 'KS',\n",
" 'Kentucky' : 'KY',\n",
" 'Louisiana' : 'LA',\n",
" 'Maine' : 'ME',\n",
" 'Maryland' : 'MD',\n",
" 'Massachusetts' : 'MA',\n",
" 'Michigan' : 'MI',\n",
" 'Minnesota' : 'MN',\n",
" 'Mississippi' : 'MS',\n",
" 'Missouri' : 'MO',\n",
" 'Montana' : 'MT',\n",
" 'Nebraska' : 'NE',\n",
" 'Nevada' : 'NV',\n",
" 'New Hampshire' : 'NH',\n",
" 'New Jersey' : 'NJ',\n",
" 'New Mexico' : 'NM',\n",
" 'New York' : 'NY',\n",
" 'North Carolina' : 'NC',\n",
" 'North Dakota' : 'ND',\n",
" 'Ohio' : 'OH',\n",
" 'Oklahoma' : 'OK',\n",
" 'Oregon' : 'OR',\n",
" 'Pennsylvania' : 'PA',\n",
" 'Rhode Island' : 'RI',\n",
" 'South Carolina' : 'SC',\n",
" 'South Dakota' : 'SD',\n",
" 'Tennessee' : 'TN',\n",
" 'Texas' : 'TX',\n",
" 'Utah' : 'UT',\n",
" 'Vermont' : 'VT',\n",
" 'Virginia' : 'VA',\n",
" 'Washington' : 'WA',\n",
" 'West Virginia' : 'WV',\n",
" 'Wisconsin' : 'WI',\n",
" 'Wyoming' : 'WY'\n",
"}\n",
"\n",
"BASE_URL_PREFIX = 'http://www.uspto.gov/web/offices/ac/ido/oeip/taf/stcteca/'\n",
"BASE_URL_SUFFIX = 'stcl_gd.htm'\n",
"\n",
"MASTER_LIST = []\n",
"StateRow = namedtuple('StateRow', 'state_name tech_code year value')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Scraping each state"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now can loop through each state abbreviation and build the actual url for each table. We then pass that url path to requests and parse through Beautiful Soup. From that parsed result, we search for a HTML table tag and pull values using our named tuple function. We store that result in our final MASTER_LIST."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# for each state code, generate the target URL and pull the data\n",
"for state in sorted(REGION_CODES):\n",
" print('Processing data for ' + state)\n",
" path = BASE_URL_PREFIX + REGION_CODES[state].lower() + BASE_URL_SUFFIX\n",
" r = requests.get(path)\n",
" soup = BeautifulSoup(r.text, \"html.parser\")\n",
"\n",
" # skip first and last rows, which are headers and totals respectively\n",
" for table_row in soup.find_all('tr')[1:-1]:\n",
" tech_code = table_row.find('td', style=' text-align: left; ').string.strip()\n",
" year = 1963\n",
" # skip the last element, which is a total; we can aggregate the data ourselves\n",
" for value in table_row.find_all('td', {'style': None})[:-1]:\n",
" row = StateRow(state, tech_code, year, value.string.strip())\n",
" MASTER_LIST.append(row)\n",
" year = year + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Scraping Tech Codes and Names"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now have to scrape the associated classifications with their code values from the USPTO site."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Declaring initial variables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We declare the following prior to scraping the site:\n",
"* URL to the Tech code table,\n",
"* final list to store the data,\n",
"* and named tuple function to pull the necessary data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"URL = 'http://www.uspto.gov/web/patents/classification/selectnumwithtitle.htm'\n",
"TECH_CODES = []\n",
"ClassRow = namedtuple('ClassRow', 'class_code class_name')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Scraping Tech Code Table"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We pass the URL we defined to requests and parse through Beautiful Soup. We now loop through HTML table tags and pull values based on our named tuple function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"REQUEST = requests.get(URL)\n",
"SOUP = BeautifulSoup(REQUEST.text, \"html.parser\")\n",
"\n",
"print('Scraping data')\n",
"for table_row in SOUP.find_all('tr'):\n",
" class_code_tag = table_row.find('td', width='27')\n",
"\n",
" # not a class_code + name row. skip\n",
" if class_code_tag is None:\n",
" continue\n",
"\n",
" class_code = class_code_tag.string\n",
" class_name = table_row.find('td', width='532').string\n",
" TECH_CODES.append(ClassRow(class_code, class_name))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exporting to CSV"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We open the file, state_tech.csv and tech_code.csv, for writing and:\n",
"1. output the column names for the CSV as the first row,\n",
"2. and write each iteration of our final list as another row."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# write out to csv\n",
"with open('./state_tech.csv', 'w', newline='') as out:\n",
" print('Writing data to ' + out.name)\n",
" CSV_FILE = csv.writer(out, delimiter=',')\n",
" CSV_FILE.writerow(['Region', 'Tech Class Code', 'Year', 'Utility Patent Count'])\n",
" CSV_FILE.writerows(MASTER_LIST)\n",
" \n",
"with open('./tech_code.csv', 'w', newline='') as out:\n",
" print('Writing data to ' + out.name)\n",
" CSV_FILE = csv.writer(out, delimiter=',')\n",
" CSV_FILE.writerow(['Class Code', 'Class Name'])\n",
" CSV_FILE.writerows(TECH_CODES)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Creating Visualizations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that we have our data in a clean, normalized format, let's make the visualization! We use [Tableau Public](https://public.tableau.com/s/), an interactive visualization platform that can publish to a public profile. Once it's published, you'll be able to browse and interact with your visualization on your Tableau Public profile web site, as well as embed that visualization in other web pages.\n",
"First, install [Tableau Public](https://public.tableau.com/s/). Tableau requires an email to obtain the app. Once that's done, sign up for a free Tableau Public profile.\n",
"Now let's load up Tableau Public.\n",
"\n",
"Below we show how to create the embedded visualizations with Tableau Public. We highlight points of interest in red for clarity. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Connecting to our CSV"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![homescreen](img/tableau-public-connect-screen.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we need to connect to our data. Select ‘Text File’ on the left side of the screen, under ‘Connect.’ In the dialog box that opens, navigate to state_tech.csv file we just created and click Open."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Data Joining"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![datascreen1](img/data-screen-1.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here, we see that Tableau has linked to the state_tech.csv file we generated. Our data sources for this visualization will be our state_tech.csv file joined to our tech_code.csv file (to supply the name for the technology class). On the left, Tableau lists available text files in the current working directory, and on the top, Tableau shows which sources are currently driving the visualization. So first, we need to join our state_tech.csv file onto our tech_code.csv file. Drag the tech_code.csv entry from the left section (under ‘Files’) onto the top section. Tableau’s Join dialog pops up:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![datajoin](img/data-screen-join.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this case, we want a Left Join, using the ‘Tech Class Code’ field in state_tech.csv and the ‘Class Code’ field in tech_code.csv. At first, this won’t work. Tableau supports some extract and load functionality, and will try to infer the data types of the loaded columns. In this case, Tableau infers that the ‘Class Code’ field in tech_code.csv is a text field, whereas the ‘Tech Class Code’ is a numeric field, which prevents our Join. In fact, there’s multiple changes we need to make. First, Tableau supports many Geographical data types, so we’ll want to change Region to Geographic Role -> State/Province. Next, change the data type of ‘Tech Class Code’ to String. (NOTE: To change data types, click the symbol above a given column header (such as ‘Abc’ or ‘#’)). Once the data types are consistent, the join should work. Click the ‘Automatically Update’ button to see the joined data."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![datafix](img/data-screen-join-fix.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looking good! Just one more fix: We currently have two columns for class code, but we only need one. Let’s hide the first one (the second column): mouseover the column header and click the arrow in the upper right corner of the header, then select Hide."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![datafinal](img/data-screen-final.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With that done, let’s start putting together our visualization. Select the orange button at the bottom of the page for Sheet 1. This brings us to the worksheet view for Sheet 1. Tableau uses worksheets to represent a single component of a dashboard, which may include many worksheets. For the purposes of this tutorial, we’re treating ‘dashboard’ as synonymous with ‘visualization.’"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![sheet11](img/sheet1-1.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First things first, let’s rename ‘Sheet 1’ to ‘treemap’. Our visualization will consist of this worksheet as well as an additional worksheet for the bar graph. Now let’s take a look at the screen. On the left side, we find our column names (as well as some extra fields in italics, which for the purposes of this tutorial we can ignore) organized into two different categories: Dimensions and Measures. Put simply, a dimension is a field that identifies a piece of data, whereas a measure is a field that tells us, quantitatively, something about that data. So, ‘Region Name’ identifies a row of data as referring to a given region (such as Alabama), whereas ‘Utility Patent Count’ gives us a quantitative value for that row of data. Tableau will attempt to infer which fields are dimensions and which are measures, but sometimes it requires some adjusting. In this case, Tableau correctly identifies the ‘Region’, ‘Year’, ‘Class Code’ and ‘Class Name’ as dimensions, and ‘Utility Patent Count’ as our only measure. That is, ‘Region’, ‘Year’, ‘Class Code’ and ‘Class Name’ identify the scope of a particular row of data (or, in the case of Class Name, provide additional data on another dimension), and ‘Utility Patent Count’ represents a value for that scope.\n",
"\n",
"Let’s make our treemap. First, drag ‘Class Name’ from the Dimensions section to the ‘Columns’ row at the top of the screen. Then, drag ‘Utility Patent Count’ from the Measures section to the ‘Rows’ row at the top of the screen. This will generate a bar graph, with a column for each class name that has at least one utility patent, and the corresponding bars are aggregated from the Utility Patent Count value for a given class across all states and years."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![sheet12](img/sheet1-2.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But we want a treemap, not a bar graph. The answer is the Show Me menu on the right. Tableau supports switching between multiple different styles of graph with a single click, as long as the number of dimensions and measures involved are compatible. In the Show Me menu, click the TreeMap square (fourth from the top, on the left)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![sheet13](img/sheet1-3.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Presto! Tableau moved the Utility Patent Count and Class Name pills from the Columns and Rows rows at the top to the left under Marks. In this case, we could have built the treemap by configuring these items ourselves, but the Show Me menu offers a convenient shortcut.\n",
"\n",
"One last thing: Tableau creates a default tooltip using the measures and dimensions involved in the worksheet, but we want to show two additional data items: The class code and the ratio of the patents for a technology class for the total. First, drag the Class Code pill onto the Tooltip square (in the Marks section). Mouseover a square in the treemap and observe that the class code was added. Next, right-click the first Utility Patent Counts pill in the Marks section (with two colorless squares to its right) and select Quick Table Calculation -> Percent of Total. The tooltip now includes the class code and percent of total for a given square. To re-order the tooltip rows to match the original visualization, click the Tooltip square in the Marks section and adjust manually."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![sheet14](img/sheet1-4.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let’s get started on the line graph. Click the button directly to the right of the treemap tab on the bottom of the page to create a new worksheet and rename it ‘line.’"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"s![sheet21](img/sheet2-1.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For this graph, drag Year to Columns and Utility Patent Count to Rows. Finally, right-click the row header on the right of the graph (labeled ‘Utility Patent Count’), select ‘Add Reference Line’ and press OK. By default, this creates a reference line based on the Average of the Utility Patent Count measure, aggregated by sum for a given year. To have the line appear dashed instead of solid, we can right-click the reference line itself and select ‘Format.’ This opens the Format menu for the reference line on the left side of the screen. Open the ‘Line’ dropdown and select the dashed line. Finally, deselect the reference line by clicking an empty space within the line graph. Your graph should look like this:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![sheet22](img/sheet2-2.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can start putting these components together into a complete visualization. Click the second button to the right of the line tab at the bottom of the page to create a new dashboard, and rename it ‘main.’"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash1](img/main-dash1.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On the top left, we see a Dashboard section, with a row for each worksheet we created. In the middle is the dashboard pane. Drag the treemap row onto the pane, then drag the line row below the treemap sheet. As you drag a component onto the pane, a gray box will show you how it will be oriented. You want the gray box to be below the treemap component, not to either side. Your dashboard should look like this:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash2](img/main-dash2.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looks good, but we’re not done yet! We want to allow the user to filter based both on State and Year, but we’re currently showing aggregations for all values, regardless of State and Year. To accomplish this, let’s return to the treemap worksheet. First, let’s create the Year filter. Right-click the Year row in the Dimensions section and select ‘Show Filter’. Tableau adds a filter control that defaults to the full range of years. If we wanted our dashboard to default to a particular range of years on load, or to exclude certain values in the final product, we can set these bounds to anything we like. Let’s leave it at the default."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash3](img/main-dash3.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Right now, this filter only applies to the treemap worksheet. To apply it to the line graph as well, click the arrow in the upper-right section of the new Year filter control and select Apply to Worksheets -> All Using This Data Source. If you return to the dashboard, you’ll find that the filter doesn’t show up yet. The simplest way to refresh the dashboard is to drag the treemap component off the pane (removing it from the dashboard), then re-add it to the top of the dashboard. The Year Filter will then pop up. Drag it around a bit and confirm that it affects both the treemap and the line graph."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash4](img/main-dash4.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now for the Region filter. Return to the treemap worksheet, right-click on Region and select Show Filter. By default, Tableau creates a multi-checkbox filter. Let’s adjust the Region filter component: click the arrow in the upper-right of the Region filter and select ‘Single Value Dropdown’. Now we can select a region and see the technology class breakdown for that particular region, or select the ‘(All)’ value in the dropdown to clear out the Region filter. For now, let’s set the default to ‘(All).’ And, as before, we need to tell Tableau that we want this filter to apply to other worksheets using the same data source: click the arrow in the upper right of the Region filter and select Apply to Worksheets -> All Using This Data Source."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash3](img/main-dash3.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let’s go back to the main dashboard and refresh the treemap component by dragging it off the dashboard pane then dragging it back on. Drag the year slider around and set the Region filter to other values to confirm that it all works."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![dash5](img/main-dash5.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looking great! There are some additional tweaks we could make, such as resizing the dashboard using the Dashboard section in the lower-left of the page, and either hiding or renaming the worksheet titles to something more meaningful than ‘treemap’ and ‘line,’ but making these changes is straightforward. When you’re ready, select File -> Save to Tableau Public to start the publication process to the Tableau Public profile you created earlier. You’ll receive a log-in prompt for Tableau Public, then an opportunity to rename your workbook. Once saved, Tableau Public will open in your browser, and you’ll find the result of your hard work! Your visualization will be publicly available at this point. If you want to share your visualization with other people, either with a direct link or embedded into your own web page, check out the Share button on the bottom-right of the visualization.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exploratory Visualization"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's create the exploratory viz we showed earlier, which allowed us to compare states by technology class. We'll use the same data that we pulled for the previous viz, so there's no need to write any more code. First, let's start up a new instance of Tableau Public (or select File -> New). Follow the join steps for the previous visualization, joining state_tech.csv to tech_code.csv. No additional data steps are needed. Once that's done, create a new worksheet and rename it to 'bar'.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![m2-dash1](img/main2-dash1.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For this vis, we want to display all regions for a selected technology class, sorted in descending order by patent count. First, drag Region to Columns and Utility Patent Count to Rows. This will create an unsorted bar graph, summing all patent counts across all technology classes. To sort the graph, mouseover the column header on the left and click the sort icon above the header text. This will, by default, sort the bars in descending order. Next, we want to allow the user to select a USPC class to see the results for that class. We could drag either Class Code or Class name to the Filters column, then Show Filter. However, the Class Name field doesn't include the Class Code, and the Class Code field is unreadable (unless you have the USPC codes memorized!). What we want is a combined field. To create this, right-click the Dimensions tab and select Create Calculated Field and name it 'Combined Class Name'. Then, insert the following text:\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![m2-dash2](img/main2-dash2.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This will combine the class name and class code into a single field. Now drag Combined Class Name to Filters. In the Filter dialog that pops up, select the 'Use All' radio button and click Apply. Next, right-click the Combined Class Name pill in the Filters dialog and click 'Show Filter.' Then, click the arrow icon in the top-right of the filter tab (the multiple checkbox list on the right) and change the checkbox list to a single-value dropdown. Finally, let's add a Year filter. Drag the Year pill from the Dimensions tab to Filters, right-click the pill in Filters and select 'Show Filter' and press OK.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![m2-dash3](img/main2-dash3.PNG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And that's it! With just a few drag and drops, and a bit of configuring, we have a simple state comparison graph for any given technology class. We could use this viz as-is to explore a given technology class for any unusual state dominance (hinting toward further analysis), or we could expand it further (perhaps with a ratio in the tooltip of the state's share of the total patents the selected class). Also, because we combined the Class Name and Class Code into Combined Class Name, we can search a given USPC code within the filter in case we know which class we want by its code. Tableau makes it easy to dynamically explore data by way of visualization creation, and then share the results with others.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you liked this tutorial and would like to see more visualizations using USPTO data and Tableau Public, please visit the [USPTO Developer Portal](https://developer.uspto.gov). We'd love to hear from you and see what you've created!\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.11"
}
},
"nbformat": 4,
"nbformat_minor": 0
}