human
Write me a Python program to find where the slowdown is, based on the amount of time spent on a particular line given the following:
I am working on the file "Sessions/Session03/Day4/Profiling_solns.ipynb".
The first task is:
Problem 2b
OK, now try running the cProfile module with it in order to produce some profiling statistics.  You can do this by running:
python -m cProfile -o sort.prof sort.py
This will produce an output profile file called sort.prof.  You can do a variety of things with sort.prof, but you'll need a few programs to do this.  First, install pyprof2html with: pip install pyprof2html.  Then, try:
pyprof2html sort.prof
This will produce a html directory, and you can just open up the enclosed index.html file to bring it to your browser.  You can see function by function, what is taking the most time!  You can click on column headers to change which sorting occurs.
Problem 2c
But there are graphical ways of representing these data effectively.  Download snakeviz, another means of viewing your profile data.  You can do this with pip install snakeviz.  And then open up the same file with snakeviz:
snakeviz sort.prof
This should bring up another graphical interface for analyzing the profile data.  Switch to icicle mode, and explore the information a bit.  Try to figure out where the "hot" sections of the code are.  Namely, what is the most expensive function that is running in terms of time?
Problem 2d
OK, so if that's the most expensive, we better speed it up.  We can investigate line-by-line how slow/fast things are, but we need another package for that called line_profiler.  Go ahead and install this with pip install line_profiler.  
Go back to the source code file, and add a @profile line directly above the slow function.  line_profiler automatically installed a file called kernprof to your $PYTHONPATH, which is used with the following format at the command line: 
kernprof.py -v -l your_script your_script_args
Start up kernprof and we'll look at the slow function in our sort program!  See if you can find where the slowdown is, based on the amount of time spent on a particular line.  Can you fix this line to not be so inefficient?
Hint: Remember the ways we discussed for optimizing code: In-place operations, string...
Can you write Python program for it?
assistant
#Here is Python program to find where the slowdown is, based on the amount of time spent on a particular line.

from matplotlib import pyplot as plt
import numpy as np
import random

class Galaxy():
    """
    Galaxy class for simply representing a galaxy.
    """
    def __init__(self, total_mass, cold_gas_mass, stellar_mass, age=0):
        self.total_mass = total_mass
        self.cold_gas_mass = cold_gas_mass
        self.stellar_mass = stellar_mass
        self.age = age
        self.SFR = 0
        self.color = 'red'
        
    def __repr__(self):
        return "Galaxy (m_total = %.1g; m_cold = %.1g; m_stars = %.1g; age = %.1g; SFR = %0.2f)" % \
                (self.total_mass, self.cold_gas_mass, self.stellar_mass, self.age, self.SFR)
        
class EvolvingGalaxy(Galaxy):
    """
    Galaxy class for representing a galaxy that can evolve over time.
    """
    def current_state(self):
        """
        Return a tuple of the galaxy's total_mass, cold_gas_mass, stellar_mass, age, and SFR
        """
        return (self.total_mass, self.cold_gas_mass, self.stellar_mass, self.age, self.SFR)
    
    def calculate_star_formation_rate(self):
        """
        Calculate the star formation rate by taking a random number between 0 and 1 
        normalized by the galaxy total mass / 1e12; 
        
        Also updates the galaxy's color to blue if SFR > 0.01, otherwise color = red
        """
        self.SFR = random.random() * (self.total_mass / 1e12)
        if self.SFR > 0.01: 
            self.color = 'blue'
        else:
            self.color = 'red'
            
    def accrete_gas_from_IGM(self, time):
        """
        Allow the galaxy to accrete cold gas from the IGM at a variable rate normalized to
        the galaxy's mass
        """
        cold_gas_accreted = random.random() * 0.1 * time * (self.total_mass / 1e12)
        self.cold_gas_mass += cold_gas_accreted
        self.total_mass += cold_gas_accreted
        
    def form_stars(self, time):
        """
        Form stars according to the current star formation rate and time available
        If unable cold gas, then shut off star...