-
-
Open source lectures
-
-
diff --git a/source/rst/matplotlib.rst b/source/rst/matplotlib.rst
index 049aaa6..3fc6bfe 100644
--- a/source/rst/matplotlib.rst
+++ b/source/rst/matplotlib.rst
@@ -342,7 +342,7 @@ Here's one solution
def f(x, θ):
return np.cos(np.pi * θ * x ) * np.exp(- x)
-
+
θ_vals = np.linspace(0, 2, 10)
x = np.linspace(0, 5, 200)
fig, ax = plt.subplots()
diff --git a/source/rst/need_for_speed.rst b/source/rst/need_for_speed.rst
index e3433ec..916bbb9 100644
--- a/source/rst/need_for_speed.rst
+++ b/source/rst/need_for_speed.rst
@@ -8,13 +8,10 @@ Python for Scientific Computing
.. contents:: :depth: 2
-In addition to what's in Anaconda, this lecture will need the following libraries:
-
-.. code-block:: ipython
- :class: hide-output
-
- !pip install --upgrade quantecon
+.. epigraph::
+ "We should forget about small efficiencies, say about 97% of the time:
+ premature optimization is the root of all evil." -- Donald Knuth
@@ -45,6 +42,15 @@ addressing the following questions:
* How is the situation changing over time?
+In addition to what's in Anaconda, this lecture will need
+
+.. code-block:: ipython
+ :class: hide-output
+
+ !conda install -y quantecon
+
+
+
Scientific Libraries
=============================
diff --git a/source/rst/numba.rst b/source/rst/numba.rst
index 08d7848..77650e3 100644
--- a/source/rst/numba.rst
+++ b/source/rst/numba.rst
@@ -13,7 +13,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie
.. code-block:: ipython
:class: hide-output
- !pip install --upgrade quantecon
+ !conda install -y quantecon
Please also make sure that you have the latest version of Anaconda, since old
versions are a :doc:`common source of errors
`.
@@ -175,7 +175,7 @@ The basic idea is this:
* Python is very flexible and hence we could call the function `qm` with many
types.
- * e.g., ``x0`` could be a NumPy array or a list, ``n`` could be an integer or a float, etc.
+ * e.g., ``x0`` could be a NumPy array or a list, ``n`` could be an integer or a float, etc.
* This makes it hard to *pre*-compile the function.
diff --git a/source/rst/pandas.rst b/source/rst/pandas.rst
index fce8bae..9b98762 100644
--- a/source/rst/pandas.rst
+++ b/source/rst/pandas.rst
@@ -29,6 +29,7 @@ of fields such as data science and machine learning.
Here's a popularity comparison over time against STATA, SAS, and `dplyr `_ courtesy of Stack Overflow Trends
.. figure:: /_static/lecture_specific/pandas/pandas_vs_rest.png
+ :scale: 55%
Just as `NumPy `_ provides the basic array data type plus core array operations, pandas
@@ -37,15 +38,15 @@ Just as `NumPy `_ provides the basic array data type plus
#. endows them with methods that facilitate operations such as
- * reading in data
+ * reading in data
- * adjusting indices
+ * adjusting indices
- * working with dates and time series
+ * working with dates and time series
- * sorting, grouping, re-ordering and general data munging [#mung]_
+ * sorting, grouping, re-ordering and general data munging [#mung]_
- * dealing with missing values, etc., etc.
+ * dealing with missing values, etc., etc.
More sophisticated statistical functionality is left to other packages, such
as `statsmodels `__ and `scikit-learn `__, which are built on top of pandas.
@@ -177,7 +178,7 @@ Supposing you have this data saved as ``test_pwt.csv`` in the present working di
.. code-block:: python3
- df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-source-py/master/source/_static/lecture_specific/pandas/data/test_pwt.csv')
+ df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/master/source/_static/lecture_specific/pandas/data/test_pwt.csv')
type(df)
.. code-block:: python3
@@ -437,7 +438,7 @@ With these imports:
.. code-block:: python3
- import datetime as dt
+ import datetime as dt
from pandas_datareader import data
Write a program to calculate the percentage price change over 2019 for the following shares:
@@ -465,18 +466,18 @@ Here's the first part of the program
def read_data(ticker_list,
start=dt.datetime(2019, 1, 2),
- end=dt.datetime(2019, 12, 31)):
+ end=dt.datetime(2019, 12, 31)):
"""
- This function reads in closing price data from Yahoo
+ This function reads in closing price data from Yahoo
for each tick in the ticker_list.
"""
ticker = pd.DataFrame()
-
+
for tick in ticker_list:
prices = data.DataReader(tick, 'yahoo', start, end)
closing_prices = prices['Close']
ticker[tick] = closing_prices
-
+
return ticker
ticker = read_data(ticker_list)
@@ -484,7 +485,26 @@ Here's the first part of the program
Complete the program to plot the result as a bar graph like this one:
.. figure:: /_static/lecture_specific/pandas/pandas_share_prices.png
- :scale: 80%
+ :scale: 50%
+
+.. _pd_ex2:
+
+Exercise 2
+----------
+
+Using the method ``read_data`` introduced in :ref:`Exercise 1 `, write a program to obtain year-on-year percentage change for the following indices:
+
+.. code-block:: python3
+
+ indices_list = {'^GSPC': 'S&P 500',
+ '^IXIC': 'NASDAQ',
+ '^DJI': 'Dow Jones',
+ '^N225': 'Nikkei'}
+
+Complete the program to show summary statistics and plot the result as a time series graph like this one:
+
+.. figure:: /_static/lecture_specific/pandas/pandas_indices_pctchange.png
+ :scale: 53%
Solutions
=========
@@ -493,7 +513,7 @@ Exercise 1
----------
There are a few ways to approach this problem using Pandas to calculate
-the percentage change.
+the percentage change.
First, you can extract the data and perform the calculation such as:
@@ -504,7 +524,7 @@ First, you can extract the data and perform the calculation such as:
price_change = (p2 - p1) / p1 * 100
price_change
-Alternatively you can use an inbuilt method ``pct_change`` and configure it to
+Alternatively you can use an inbuilt method ``pct_change`` and configure it to
perform the correct calculation using ``periods`` argument.
.. code-block:: python3
@@ -525,6 +545,53 @@ Then to plot the chart
price_change.plot(kind='bar', ax=ax)
plt.show()
+Exercise 2
+----------
+
+Following the work you did in :ref:`Exercise 1 `, you can query the data using ``read_data`` by updating the start and end dates accordingly.
+
+.. code-block:: python3
+
+ indices_data = read_data(
+ indices_list,
+ start=dt.datetime(1928, 1, 2),
+ end=dt.datetime(2020, 12, 31)
+ )
+
+Then, extract the first and last set of prices per year as DataFrames and calculate the yearly returns such as:
+
+.. code-block:: python3
+
+ yearly_returns = pd.DataFrame()
+
+ for index, name in indices_list.items():
+ p1 = indices_data.groupby(indices_data.index.year)[index].first() # Get the first set of returns as a DataFrame
+ p2 = indices_data.groupby(indices_data.index.year)[index].last() # Get the last set of returns as a DataFrame
+ returns = (p2 - p1) / p1
+ yearly_returns[name] = returns
+
+ yearly_returns
+
+Next, you can obtain summary statistics by using the method ``describe``.
+
+.. code-block:: python3
+
+ yearly_returns.describe()
+
+Then, to plot the chart
+
+.. code-block:: python3
+
+ fig, axes = plt.subplots(2, 2, figsize=(10, 6))
+
+ for iter_, ax in enumerate(axes.flatten()): # Flatten 2-D array to 1-D array
+ index_name = yearly_returns.columns[iter_] # Get index name per iteration
+ ax.plot(yearly_returns[index_name]) # Plot pct change of yearly returns per index
+ ax.set_ylabel("percent change", fontsize = 12)
+ ax.set_title(index_name)
+
+ plt.tight_layout()
+
.. rubric:: Footnotes
.. [#mung] Wikipedia defines munging as cleaning data from one raw form into a structured, purged one.
diff --git a/source/rst/parallelization.rst b/source/rst/parallelization.rst
index 1f1723c..2d51e09 100644
--- a/source/rst/parallelization.rst
+++ b/source/rst/parallelization.rst
@@ -13,7 +13,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie
.. code-block:: ipython
:class: hide-output
- !pip install --upgrade quantecon
+ !conda install -y quantecon
Overview
@@ -41,7 +41,7 @@ This is particularly important in scientific programming, which requires handlin
In this lecture we discuss parallelization for scientific computing, with a focus on
-#. the best tools for parallelization in Python and
+#. the best tools for parallelization in Python and
#. how these tools can be applied to quantitative economic problems.
@@ -101,7 +101,7 @@ Advantages and Disadvantages
----------------------------
Multithreading is more lightweight because most system and memory resources
-are shared by the threads.
+are shared by the threads.
In addition, the fact that multiple threads all access a shared pool of memory
is extremely convenient for numerical programming.
@@ -147,6 +147,7 @@ Now, let's look at the output of the `htop` system monitor on our machine while
this code is running:
.. figure:: /_static/lecture_specific/parallelization/htop_parallel_npmat.png
+ :scale: 45%
We can see that 4 of the 8 CPUs are running at full speed.
@@ -284,10 +285,10 @@ The code simulates updating the wealth :math:`w_t` of a household via the rule
w_{t+1} = R_{t+1} s w_t + y_{t+1}
-Here
+Here
-* :math:`R` is the gross rate of return on assets
-* :math:`s` is the savings rate of the household and
+* :math:`R` is the gross rate of return on assets
+* :math:`s` is the savings rate of the household and
* :math:`y` is labor income.
We model both :math:`R` and :math:`y` as independent draws from a lognormal
@@ -350,7 +351,7 @@ wealth of the group at the end of a long simulation.
Moreover, provided the simulation period is long enough, initial conditions
don't matter.
-* This is due to something called ergodicity, which we will discuss `later on `_.
+* This is due to something called ergodicity, which we will discuss `later on `_.
So, in summary, we are going to simulate 50,000 households by
diff --git a/source/rst/python_advanced_features.rst b/source/rst/python_advanced_features.rst
index d658fda..c838b36 100644
--- a/source/rst/python_advanced_features.rst
+++ b/source/rst/python_advanced_features.rst
@@ -796,15 +796,15 @@ Here's what happens
* The call ``f(x)``
- * Creates a local namespace
+ * Creates a local namespace
- * Adds ``x`` to local namespace, bound to ``[1]``
+ * Adds ``x`` to local namespace, bound to ``[1]``
- * The list ``[1]`` is modified to ``[2]``
+ * The list ``[1]`` is modified to ``[2]``
- * Returns the list ``[2]``
+ * Returns the list ``[2]``
- * The local namespace is deallocated, and local ``x`` is lost
+ * The local namespace is deallocated, and local ``x`` is lost
* Global ``x`` has been modified
@@ -1769,7 +1769,7 @@ Write a function to recursively compute the :math:`t`-th Fibonacci number for an
Exercise 2
----------
-Complete the following code, and test it using `this csv file `__, which we assume that you've put in your current working directory
+Complete the following code, and test it using `this csv file `__, which we assume that you've put in your current working directory
.. code-block:: python3
diff --git a/source/rst/python_by_example.rst b/source/rst/python_by_example.rst
index ec6cf15..0f2bded 100644
--- a/source/rst/python_by_example.rst
+++ b/source/rst/python_by_example.rst
@@ -416,10 +416,10 @@ On the other hand, it takes a bit of care to get right, so please remember:
* The line before the start of a code block always ends in a colon
- * ``for i in range(10):``
- * ``if x > y:``
- * ``while x < 100:``
- * etc., etc.
+ * ``for i in range(10):``
+ * ``if x > y:``
+ * ``while x < 100:``
+ * etc., etc.
* All lines in a code block **must have the same amount of indentation**.
diff --git a/source/rst/python_essentials.rst b/source/rst/python_essentials.rst
index fa25558..8b731bd 100644
--- a/source/rst/python_essentials.rst
+++ b/source/rst/python_essentials.rst
@@ -559,11 +559,11 @@ The rule is:
* Expressions that evaluate to zero, empty sequences or containers (strings, lists, etc.) and ``None`` are all equivalent to ``False``.
- * for example, ``[]`` and ``()`` are equivalent to ``False`` in an ``if`` clause
+ * for example, ``[]`` and ``()`` are equivalent to ``False`` in an ``if`` clause
* All other values are equivalent to ``True``.
- * for example, ``42`` is equivalent to ``True`` in an ``if`` clause
+ * for example, ``42`` is equivalent to ``True`` in an ``if`` clause
diff --git a/source/rst/python_oop.rst b/source/rst/python_oop.rst
index 9f20c4d..3a723fb 100644
--- a/source/rst/python_oop.rst
+++ b/source/rst/python_oop.rst
@@ -148,11 +148,11 @@ OOP is useful for the same reason that abstraction is useful: for recognizing an
For example,
-* *a Markov chain* consists of a set of states and a collection of transition probabilities for moving across states
+* *a Markov chain* consists of a set of states, an initial probability distribution over states, and a collection of probabilities of moving across states
* *a general equilibrium theory* consists of a commodity space, preferences, technologies, and an equilibrium definition
-* *a game* consists of a list of players, lists of actions available to each player, player payoffs as functions of all players' actions, and a timing protocol
+* *a game* consists of a list of players, lists of actions available to each player, each player's payoffs as functions of all other players' actions, and a timing protocol
These are all abstractions that collect together "objects" of the same "type".
@@ -179,10 +179,57 @@ Let's build some simple classes to start off.
.. _oop_consumer_class:
+Before we do so, in order to indicate some of the power of Classes, we'll define two functions that we'll call ``earn`` and ``spend``.
+
+.. code-block:: python3
+
+ def earn(w,y):
+ "Consumer with inital wealth w earns y"
+ return w+y
+
+ def spend(w,x):
+ "consumer with initial wealth w spends x"
+ new_wealth = w -x
+ if new_wealth < 0:
+ print("Insufficient funds")
+ else:
+ return new_wealth
+
+The ``earn`` function takes a consumer's initial wealth :math:`w` and adds to it her current earnings :math:`y`.
+
+The ``spend`` function takes a consumer's initial wealth :math:`w` and deducts from it her current spending :math:`x`.
+
+We can use these two functions to keep track of a consumer's wealth as she earns and spends.
+
+For example
+
+.. code-block:: python3
+
+ w0=100
+ w1=earn(w0,10)
+ w2=spend(w1,20)
+ w3=earn(w2,10)
+ w4=spend(w3,20)
+ print("w0,w1,w2,w3,w4 = ", w0,w1,w2,w3,w4)
+
+
+A *Class* bundles a set of data tied to a particular *instance* together with a collection of functions that operate on the data.
+
+In our example, an *instance* will be the name of particular *person* whose *instance data* consist solely of its wealth.
+
+(In other examples *instance data* will consist of a vector of data.)
+
+In our example, two functions ``earn`` and ``spend`` can be applied to the current instance data.
+
+Taken together, the instance data and functions are called *methods*.
+
+These can be readily accessed in ways that we shall describe now.
+
+
Example: A Consumer Class
-------------------------
-First, we'll build a ``Consumer`` class with
+We'll build a ``Consumer`` class with
* a ``wealth`` attribute that stores the consumer's wealth (data)
@@ -190,9 +237,9 @@ First, we'll build a ``Consumer`` class with
* a ``spend`` method, where ``spend(x)`` either decreases wealth by ``x`` or returns an error if insufficient funds exist
-Admittedly a little contrived, this example of a class helps us internalize some new syntax.
+Admittedly a little contrived, this example of a class helps us internalize some peculiar syntax.
-Here's one implementation
+Here how we set up our Consumer class.
.. code-block:: python3
@@ -220,28 +267,28 @@ There's some special syntax here so let's step through carefully
* The ``class`` keyword indicates that we are building a class.
-This class defines instance data ``wealth`` and three methods: ``__init__``, ``earn`` and ``spend``
+The ``Consumer`` class defines instance data ``wealth`` and three methods: ``__init__``, ``earn`` and ``spend``
-* ``wealth`` is *instance data* because each consumer we create (each instance of the ``Consumer`` class) will have its own separate wealth data.
+* ``wealth`` is *instance data* because each consumer we create (each instance of the ``Consumer`` class) will have its own wealth data.
-The ideas behind the ``earn`` and ``spend`` methods were discussed above.
+The ``earn`` and ``spend`` methods deploy the functions we described earlier and that can potentially be applied to the ``wealth`` instance data.
-Both of these act on the instance data ``wealth``.
The ``__init__`` method is a *constructor method*.
-Whenever we create an instance of the class, this method will be called automatically.
+Whenever we create an instance of the class, the ``__init_`` method will be called automatically.
Calling ``__init__`` sets up a "namespace" to hold the instance data --- more on this soon.
-We'll also discuss the role of ``self`` just below.
+We'll also discuss the role of the peculiar ``self`` bookkeeping device in detail below.
+Usage
+^^^^^^
-Usage
-^^^^^
+Here's an example in which we use the class ``Consumer`` to crdate an instance of a consumer whom we affectionately name :math:`c1`.
-Here's an example of usage
+After we create consumer :math:`c1` and endow it with initial wealth :math:`10`, we'll apply the ``spend`` method.
.. code-block:: python3
@@ -255,7 +302,7 @@ Here's an example of usage
c1.spend(100)
-We can of course create multiple instances each with its own data
+We can of course create multiple instances, i.e., multiple consumers, each with its own name and data
.. code-block:: python3
@@ -269,7 +316,7 @@ We can of course create multiple instances each with its own data
c1.wealth
-In fact, each instance stores its data in a separate namespace dictionary
+Each instance, i.e., each consumer, stores its data in a separate namespace dictionary
.. code-block:: python3
@@ -283,20 +330,21 @@ When we access or set attributes we're actually just modifying the dictionary
maintained by the instance.
Self
-^^^^
+^^^^^
+
If you look at the ``Consumer`` class definition again you'll see the word
`self` throughout the code.
-The rules with ``self`` are that
+The rules for using ``self`` in creating a Class are that
* Any instance data should be prepended with ``self``
- * e.g., the ``earn`` method references ``self.wealth`` rather than just ``wealth``
+ * e.g., the ``earn`` method uses ``self.wealth`` rather than just ``wealth``
-* Any method defined within the class should have ``self`` as its first argument
+* A method defined within the code that defines the class should have ``self`` as its first argument
- * e.g., ``def earn(self, y)`` rather than just ``def earn(y)``
+ * e.g., ``def earn(self, y)`` rather than just ``def earn(y)``
* Any method referenced within the class should be called as ``self.method_name``
@@ -307,7 +355,7 @@ Details
In this section, we look at some more formal details related to classes and ``self``
-* You might wish to skip to :ref:`the next section ` on first pass of this lecture.
+* You might wish to skip to :ref:`the next section ` the first time you read this lecture.
* You can return to these details after you've familiarized yourself with more examples.
@@ -364,8 +412,8 @@ Example: The Solow Growth Model
For our next example, let's write a simple class to implement the Solow growth model.
-The Solow growth model is a neoclassical growth model where the amount of
-capital stock per capita :math:`k_t` evolves according to the rule
+The Solow growth model is a neoclassical growth model in which the per capita
+capital stock :math:`k_t` evolves according to the rule
.. math::
:label: solow_lom
@@ -375,13 +423,13 @@ capital stock per capita :math:`k_t` evolves according to the rule
Here
-* :math:`s` is an exogenously given savings rate
+* :math:`s` is an exogenously given saving rate
* :math:`z` is a productivity parameter
* :math:`\alpha` is capital's share of income
* :math:`n` is the population growth rate
* :math:`\delta` is the depreciation rate
-The **steady state** of the model is the :math:`k` that solves :eq:`solow_lom` when :math:`k_{t+1} = k_t = k`.
+A **steady state** of the model is a :math:`k` that solves :eq:`solow_lom` when :math:`k_{t+1} = k_t = k`.
Here's a class that implements this model.
@@ -394,7 +442,7 @@ Some points of interest in the code are
* The ``update`` method uses ``h`` to update capital as per :eq:`solow_lom`.
- * Notice how inside ``update`` the reference to the local method ``h`` is ``self.h``.
+ * Notice how inside ``update`` the reference to the local method ``h`` is ``self.h``.
The methods ``steady_state`` and ``generate_sequence`` are fairly self-explanatory
@@ -464,7 +512,7 @@ The common steady state is also plotted for comparison
lb = f'capital series from initial state {s.k}'
ax.plot(s.generate_sequence(T), 'o-', lw=2, alpha=0.6, label=lb)
- ax.set_xlabel('$k_{t+1}$', fontsize=14)
+ ax.set_xlabel('$t$', fontsize=14)
ax.set_ylabel('$k_t$', fontsize=14)
ax.legend()
plt.show()
@@ -474,7 +522,7 @@ The common steady state is also plotted for comparison
Example: A Market
-----------------
-Next, let's write a class for a simple one good market where agents are price takers.
+Next, let's write a class for competitive market in which buyers and sellers are both price takers.
The market consists of the following objects:
@@ -484,7 +532,7 @@ The market consists of the following objects:
Here
-* :math:`p` is price paid by the consumer, :math:`Q` is quantity and :math:`t` is a per-unit tax.
+* :math:`p` is price paid by the buyer, :math:`Q` is quantity and :math:`t` is a per-unit tax.
* Other symbols are demand and supply parameters.
@@ -511,7 +559,7 @@ Here's our implementation.
raise ValueError('Insufficient demand.')
def price(self):
- "Return equilibrium price"
+ "Compute equilibrium price"
return (self.ad - self.az + self.bz * self.tax) / (self.bd + self.bz)
def quantity(self):
@@ -619,7 +667,7 @@ Example: Chaos
Let's look at one more example, related to chaotic dynamics in nonlinear systems.
-One simple transition rule that can generate complex dynamics is the logistic map
+A simple transition rule that can generate erratic time paths is the logistic map
.. math::
:label: quadmap2
@@ -637,7 +685,7 @@ Here's one implementation
class Chaos:
"""
- Models the dynamical system with :math:`x_{t+1} = r x_t (1 - x_t)`
+ Models the dynamical system :math:`x_{t+1} = r x_t (1 - x_t)`
"""
def __init__(self, x0, r):
"""
@@ -727,7 +775,7 @@ Special Methods
.. index::
single: Object-Oriented Programming; Special Methods
-Python provides special methods with which some neat tricks can be performed.
+Python provides special methods that come in handy.
For example, recall that lists and tuples have a notion of length and that this length can be queried via the ``len`` function
diff --git a/source/rst/scipy.rst b/source/rst/scipy.rst
index d52222d..00deb19 100644
--- a/source/rst/scipy.rst
+++ b/source/rst/scipy.rst
@@ -231,9 +231,9 @@ To understand the idea, recall the well-known game where
* Player B asks if it's less than 50
- * If yes, B asks if it's less than 25
+ * If yes, B asks if it's less than 25
- * If no, B asks if it's less than 75
+ * If no, B asks if it's less than 75
And so on.
diff --git a/source/rst/troubleshooting.rst b/source/rst/troubleshooting.rst
index fe71a7a..7655335 100644
--- a/source/rst/troubleshooting.rst
+++ b/source/rst/troubleshooting.rst
@@ -35,9 +35,9 @@ You also need to keep the external code libraries, such as `QuantEcon.py
For this task you can either
-* use `pip install --upgrade quantecon` on the command line, or
+* use `conda upgrade quantecon` on the command line, or
-* execute `!pip install --upgrade quantecon` within a Jupyter notebook.
+* execute `!conda upgrade quantecon` within a Jupyter notebook.
If your local environment is still not working you can do two things.
@@ -54,7 +54,7 @@ Reporting an Issue
===================
One way to give feedback is to raise an issue through our `issue tracker
-`__.
+`__.
Please be as specific as possible. Tell us where the problem is and as much
detail about your local set up as you can provide.
diff --git a/theme/minimal/static/css/qe.python.css b/theme/minimal/static/css/qe.python.css
index 30efad0..6a312c3 100644
--- a/theme/minimal/static/css/qe.python.css
+++ b/theme/minimal/static/css/qe.python.css
@@ -76,40 +76,6 @@
}
}
-/* Tabs for alternate index tocs */
-.index-tabs {
- margin:3rem 0;
- list-style: none;
- padding:0;
- display: flex;
- border:1px solid #DEDEE2;
- border-width: 0 0 1px 1px;
- border-radius: 5px 5px 0 0;
-}
-.index-tabs li {
- position: relative;
- bottom:-1px;
- margin:0;
-}
-.index-tabs li a {
- border-width:1px 1px 1px 0;
- border-radius: 5px 5px 0 0;
- padding:1rem 2rem;
- color: #444;
- font-weight: 700;
- display: block;
- border:1px solid #DEDEE2;
- background-color: #F2F2F6;
-}
-.index-tabs li a:hover {
- background-color: #fbfbfb;
- text-decoration: none;
-}
-.index-tabs li.active a {
- border-bottom:1px solid #fff;
- background-color: #fff;
- font-weight: 700;
-}
/* Other */
#qe-notebook-header {
diff --git a/theme/minimal/static/sloan_logo.png b/theme/minimal/static/sloan_logo.png
index d17735c..a938a58 100644
Binary files a/theme/minimal/static/sloan_logo.png and b/theme/minimal/static/sloan_logo.png differ