Thursday, December 12, 2019

Using Python to Gather Data from FRED for the Solow Model

This script gathers and generates data for Solow. The second two functions plot the data using matplotlib and save the visualizations in a PDF.


import pandas as pd

pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as web
import datetime
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

def gather_data(data_codesstartend = datetime.datetime.today(), freq = "A"):
    i = 0
    # dct.items() calls key and value that key points to
    for key, val in data_codes.items():
        if i == 0:
            # Create dataframe for first variable, then rename column
            df = web.DataReader(val, "fred", start, end).resample(freq).first()
            df.rename(columns = {val:key}, inplace = True
            i = None
        else:
            # If dataframe already exists, add new column
            df[key] = web.DataReader(val, "fred", start, end).resample(freq).first()
            
    return df
    
def plot_lines(dfplot_varslinewidth = 1logy = Falsefigsize = (40,20), 
    secondary_y = Nonepp = None):
    
    fig, ax = plt.subplots(figsize = figsize)
    
    legend_scale = 20 / figsize[1]
    # If no secondary_y (axis), plot all variables at once
    if secondary_y == None:
        df[plot_vars].plot.line(linewidth = linewidth, logy = logy, ax = ax)
        ax.legend(bbox_to_anchor=(01.035 + .045 * len(plot_vars) * legend_scale), 
                  loc=2)
    # Otherwise, create a new axis and plot each variable individually
    else:
        ax2 = ax.twinx()
        for var in plot_vars:
            if var == secondary_y: 
                df[var].plot.line(linewidth = linewidth, logy = logy, ax = ax2, c = "C9",
                  label = var + " (right)")
            else:
                df[var].plot.line(linewidth = linewidth, logy = logy, ax = ax)
        # If there are two axes, then gather lines from each axis
        lines = ax.get_lines() + ax2.get_lines()
        # then gather the label from each line
        labels = [l.get_label() for l in lines]
        # and use the lines and labels to create the legend
        ax.legend(lines, labels, bbox_to_anchor=(0
                1.04 + .045 * len(plot_vars) * legend_scale), loc=2)
    # Turn the text on the x-axis so that it reads vertically
    ax.tick_params(axis='x'rotation=90)
    # Get rid of tick lines perpendicular to the axis for aesthetic
    ax.tick_params('both'length=0which='both')
    # save image if PdfPages object was passed
    if pp != None: pp.savefig(fig, bbox_inches = "tight")

def plot_scatter(dfplot_varss = 75figsize = (4020), pp = None):
    # Create plot for every unique pair of variables
    for var1 in plot_vars:
        for var2 in plot_vars:
            if var1 != var2:
                fig, ax = plt.subplots(figsize = figsize)
                # Create list of years from index
                # Year will be represented by color
                df["Year"] = [int(str(ind)[:4]) for ind in df.index]
                df.plot.scatter(x = var1, y = var2, s = s, ax = ax, c = "Year",
                                cmap = "viridis")
                # Turn the text on the x-axis so that it reads vertically
                ax.tick_params(axis='x'rotation=90)
                # Get rid of tick lines perpendicular to the axis for aesthetic
                ax.tick_params('both'length=0which='both')
                # save image if PdfPages object was passed
                if pp != None: pp.savefig(fig, bbox_inches = "tight")

# Create PDF that will hold visualizations
pp = PdfPages("Capital Measures " + str(datetime.datetime.today())[:10] + ".pdf")
# set default fontsize for text in plot
plt.rcParams.update({'font.size'32})
# Choose data from FRED
# Keys will be used to name variable. Key points to FRED code
data_codes  = {"Capital Stock":"RKNANPUSA666NRUG",
               "Nominal GDP":"GDP",
               "Price Level":"GDPDEF",
               "Population":"B230RC0A052NBEA"}
# Select start and end dates
start = datetime.datetime(195011)
end = datetime.datetime(2019131)

# Check if data has been gathered.
# If data needs to be gathered again, clear variables or restart kernel
if "data_gathered" not in locals():
    df = gather_data(data_codes, start = start, 
          end = end, freq = "A")
    # After data is downloaded create new data and transform data
    # set population to millions        
    df["Population"] = df["Population"] / 10 ** 3
    # set NGDP to millions
    df["Nominal GDP"] = df["Nominal GDP"] * 10 ** 3
    # Make 2011 base year for price level to match capital stock values
    df["Price Level"] = df["Price Level"].div(df["Price Level"].loc["2011"].values[0])
    # Create RGDP using 2011 prices
    df["Real GDP"] = df["Nominal GDP"].div(df["Price Level"])
    # Use population as proxy for L
   # y = Y / L
    df["Real GDP Per Capita"] = df["Real GDP"].div(df["Population"])
    # k = K / L
    df["Effective Capital Stock"] = df["Capital Stock"].div(df["Population"])
    # Estimate Solow's A
    # y = Ak**.5
    # A = y / k ** .5
    df["Efficiency of Capital"] = df["Real GDP Per Capita"].div(df["Effective Capital Stock"] ** (1/2))
    data_gathered = True

####### Plot Variables #######
plot_vars = ["Effective Capital Stock"]
plot_lines(df, plot_vars, linewidth = 3logy = Truepp = pp)
plot_vars = ["Efficiency of Capital""Real GDP Per Capita"]
plot_lines(df, plot_vars, linewidth = 3logy = True
           secondary_y = "Efficiency of Capital"pp = pp)

plot_scatter(df, plot_vars, pp = pp)

pp.close()


Some figures generated:



Friday, December 14, 2018

Creating a List of Prime Numbers with a Simple Generator Function

In working on curriculum for Introduction to Computational Economics, I like to imagine puzzles that I might have my students solve. One of these is to create a list of prime numbers. Usually I do this by using a couple of for-loops and some if statements. So today I thought, maybe I can do this with a generator. Well, it worked :)

primes = [i for i in range(2,100) if True not in [i % j == 0 for j in range(2,i)]] 
P.S. 0012 hrs CST: My wife pointed out that I need only test half of the numbers between 1 and i.  The new code is faster :)

primes = [i for i in range(2,100) if True not in [i % j == 0 for j in range(2,int(i / 2 + 1))]]

Tuesday, November 27, 2018

GitHub: Heuristic Sugarscape

A model of Sugarscape with exchanging agents whose decisions are guided by heuristics can be found on Github.

Saturday, November 10, 2018

Building a Contract in Solidity and Uploading it to a Test Blockchain

In this lesson, we will write a contract and execute it on a test blockchain. The Ownable contract uses solidity 0.4.8, which is not the current version of solidity. For this reason we will debug the contract, replacing deprecated terms and syntax.

If you have not, you will need to download Visual Studio Code and install Juan Blanco’s Solidity compiler. You will need to download and install Node.js. This will allow you to download and install truffle with the command:

npm install truffle

You will also need to download and install Ganache, which will automatically set up the test blockchain.

To start, open PowerShell to start a new project with Truffle. Navigate to your desired directory and create a new folder with the mkdir command.  Since we will build the Ownable contract in this folder, name the folder ownable:

mkdir ownable
cd ownable

Once you have navigated to the new folder, create a new project using truffle:

truffle init

The console should return the following text:

Compile:        truffle compile
Migrate:        truffle migrate
Test contracts: truffle test

Now that you have initialized a project with truffle, it is time to create a contract. We are going to copy a contract from Chapter 7, page 148, of Blockchain: A PracticalGuide to Developing Business, Law, and Technology Solutions.

Write the following code in a Visual Studio file and save it as Ownable.sol under the contracts folder, created during the truffle initialization of the ownable folder.

pragma solidity ^0.4.8;
// module handling and transfer of contract ownership
contract Ownable {
    address public owner;
    function Ownable() {
        owner = msg.sender;
    }
    modifier onlyOwner {
        if(msg.sender != owner) revert();
        _;
    }
    function transferOwnership(address _newOwner) external onlyOwner {
        owner = _newOwner;
        TransferOwnership(msg.sender, _newOwner);
    }
    event TransferOwnership(address indexed _from, address indexed _to);
}

Now compile your code. You may use the short-cut F5 for this. Make sure that you have opened the file explorer. If not, you can use the command CTRL + SHIFT + E. Upon compiling the code, you should see a list of errors, under the PROBLEMS tab. We will solve these one at a time.




Debugging

The first error is not significant to the execution of the program. To make it disappear, we can enter a command above the first line:
//solium-disable linebreak-style
pragma solidity ^0.4.8;
// module handling and transfer of contract ownership
...

The next two errors appear on line 6:



The first error indicates we should have specified and access keyword like: public, private, internal or external. The second error notes that constructor() should be used to define a constructor for the class instead of function Ownable(). Edit the script to reflect this:
contract Ownable {
    address public owner;
    constructor() public {
        owner = msg.sender;
...

We change function Ownable() to constructor(). We also add the term public after the constructor. This allows the constructor to be called from both inside and outside of the contract.
A comprehensive list of visibility keywords for functions and state variables:
·        public - all can access the referenced object
·        external – The object cannot be accessed from outside of the contract
·        internal - only this contract and contracts deriving from it can access the object
·        private – the object can only be accessed only from this contract

After making the edits for the constructor, the errors for line 6 have disappeared.




Next is an error concerning the calling of revert().  The error suggests that a string should be passed into the revert function. We could pass one like this:

    modifier onlyOwner {
        if (msg.sender != owner) revert(“Error: non-owner access denied”);
        _;
...

The error disappears, but when we upload the contract to the blockchain, this will require more gas than if we do not pass a string to revert(). For now, we can leave this blank. The error will not affect anything.

To solve the next error, we need to call the event on line 15 using the term emit. This is required by more recent versions of solidity:

    function transferOwnership(address _newOwner) external onlyOwner {
        owner = _newOwner;
        emit TransferOwnership(msg.sender, _newOwner);
    }
...

If you have followed the instructions to this point, there should remain only the error concerning require() from line 6. The contract is ready to be executed. Before we do this, we will need to create a migration file for the Ownable contract and modify the Truffle.js file to point to a private blockchain.
Compile and Migrate
In order to upload the contract, we need to first convert the contract to a form that is readable in javascript. Then, this will be converted to byte code which is uploaded to the blockchain.
Using Visual Studio let’s create a javascript file called  2_ownable_migration.js , and save it under the ownable/migrations folder.
var Ownable  = artifacts.require('./Ownable.sol');
module.exports = function(deployer) {
    deployer.deploy(Ownable);
};

When the files are compiled using truffle, this script will be used to upload to the blockchain the json file representing the compiled contract.
Next, edit the truffle.js file, located in the ownable folder. This file identifies the network that will be used to locate the test blockchain to which we will upload the contract. Replace this code:
module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // to customize your Truffle configuration!
};

With the following:

module.exports = {
  networks: {
      development: {
          host: 'localhost',
          port: 7545,
          network_id: '*'
      }
  }
};

This points to the test blockchain on your local machine, that is created when you launch Ganache.
Now that everything is ready, make sure that you have navigated in the PowerShell to the ownable folder. Compile the contract using the commands:
truffle compile

If you were successful, you should see the following text:

Compiling .\contracts\Migrations.sol...
Compiling .\contracts\Ownable.sol...
Writing artifacts to .\build\contracts

Next, migrate the contracts to the blockchain. First, we will need to open Ganache so that there is a blockchain with which we can interact through truffle. When you launch Ganache, you will see the accounts created for the test blockchain:



Only the genesis block has been created. We will now upload the contract to the test blockchain by using the command:

truffle migrate

This will yield the following in the PowerShell

Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x2bcc6f737e1244ee9be0db52bf59dd0e954b4c3c9ae2028b3f4479bd13d57cd6
  Migrations: 0xe9ab13bb64959432cf38416759cc2e4c0db7d6be
Saving successful migration to network...
  ... 0x661b37c2202a45457151ec65f23f15080f23238724c8d665db12df4bb67a6afc
Saving artifacts...
Running migration: 2_ownable_migration.js
  Deploying Ownable...
  ... 0x6603eaf64060e817a202810c5b6f717f3492a2f5d07fcef221b2af45057f5773
  Ownable: 0xcea93908c932064d61cd2dd1f72c974b190cc3ce
Saving successful migration to network...
  ... 0x6bfd670baad0f28816e6d0df7f2b9cd40e64b32fa70d2e3da73c241edcb09f47
Saving artifacts...

This reflects that blocks have been added to the genesis block. We also observe this in Ganache:



Create an Instance of the Contract
Now we can call the truffle console. Since we have already edited the truffle.js file, truffle will automatically connect to the network housing the test blockchain.

truffle console

If you have successfully connected the network provided by Ganache, you should see the following:

truffle(development)>

To create an instance of the contract, we must first create a variable using javascript commands. Enter the following lines one by one into the truffle console:

var ownable;
Ownable.deployed().then(function(instance){ownable = instance;})
ownable.transferOwnership(web3.eth.accounts[1]);

The command var ownable; creates a new object called ownable. The next line defines this object as an instance of the contract that we created.
After both commands the truffle console will return the result ‘undefined’.

If you are familiar with programming already, you will see that the contract is essentially a class. Finally we transfer ownership of the contract from the account identified by index [0] to the account identified by index[1].

The event is executed and logged, yielding the following text in the console:

{ tx: '0x20a8fd775c5c26868b18b2b61c127e6acdbc02e509fb28783aa9594b9195c9bc',
  receipt:
   { transactionHash: '0x20a8fd775c5c26868b18b2b61c127e6acdbc02e509fb28783aa9594b9195c9bc',
     transactionIndex: 0,
     blockHash: '0xa433b974f3ea4ae87aa94229263f64b2b3947056d77ca7be6212a569a5d8cf27',
     blockNumber: 5,
     gasUsed: 29986,
     cumulativeGasUsed: 29986,
     contractAddress: null,
     logs: [ [Object] ],
     status: '0x1',
     logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000400000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000800000000000004010002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000060000000000000000000000000000100000' },
  logs:
   [ { logIndex: 0,
       transactionIndex: 0,
       transactionHash: '0x20a8fd775c5c26868b18b2b61c127e6acdbc02e509fb28783aa9594b9195c9bc',
       blockHash: '0xa433b974f3ea4ae87aa94229263f64b2b3947056d77ca7be6212a569a5d8cf27',
       blockNumber: 5,
       address: '0xcea93908c932064d61cd2dd1f72c974b190cc3ce',
       type: 'mined',
       event: 'TransferOwnership',
       args: [Object] } ] }

Congratulations, you have successfully built and executed your first contract!

*Ingrid Caton shares credit for this post