{"id":1469,"date":"2022-01-12T16:43:15","date_gmt":"2022-01-12T16:43:15","guid":{"rendered":"https:\/\/salarydistribution.com\/machine-learning\/2022\/01\/12\/python-debugging-tools\/"},"modified":"2022-01-12T16:43:15","modified_gmt":"2022-01-12T16:43:15","slug":"python-debugging-tools","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2022\/01\/12\/python-debugging-tools\/","title":{"rendered":"Python debugging tools"},"content":{"rendered":"<div id=\"\">\n<p>In all programming exercises, it is difficult to go far and deep without a handy debugger. The built-in debugger, <code>pdb<\/code>, in Python is a mature and capable one that can help us a lot if you know how to use it. In this tutorial we are going see what the <code>pdb<\/code> can do for you as well as some of its alternative.<\/p>\n<p>In this tutorial you will learn:<\/p>\n<ul>\n<li>What can a debugger do<\/li>\n<li>How to control a debugger<\/li>\n<li>The limitation of Python\u2019s pdb and its alternatives<\/li>\n<\/ul>\n<p>Let\u2019s get started.<\/p>\n<div id=\"attachment_13178\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-13178\" class=\"size-full wp-image-13178\" data-cfsrc=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/thomas-park-AF2k44m22-I-unsplash.jpg\" alt=\"\" width=\"800\"><img decoding=\"async\" aria-describedby=\"caption-attachment-13178\" class=\"size-full wp-image-13178\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/thomas-park-AF2k44m22-I-unsplash.jpg\" alt=\"\" width=\"800\"><\/p>\n<p id=\"caption-attachment-13178\" class=\"wp-caption-text\">Python debugging tools<br \/>Photo by <a href=\"https:\/\/unsplash.com\/photos\/AF2k44m22-I\">Thomas Park<\/a>. Some rights reserved.<\/p>\n<\/div>\n<h2>Tutorial Overview<\/h2>\n<p>This tutorial is in 4 parts, they are<\/p>\n<ul>\n<li>The concept of running a debugger<\/li>\n<li>Walk-through of using a debugger<\/li>\n<li>Debugger in Visual Studio Code<\/li>\n<li>Using GDB on a running Python program<\/li>\n<\/ul>\n<h2>The concept of running a debugger<\/h2>\n<p>The purpose of a debugger is to provide you a slow motion button to control the flow of a program. It also allow you to freeze the program at certain point of time and examine the state.<\/p>\n<p>The simplest operation under a debugger is to <strong>step through<\/strong> the code. That is to run one line of code at a time and wait for your acknowledgment before proceeding into next. The reason we want to run the program in a stop-and-go fashion is to allow us to check the logic and value or verify the algorithm.<\/p>\n<p>For a larger program, we may not want to step through the code from the beginning as it may take a long time before we reached the line that we are interested in. Therefore, debuggers also provide a <strong>breakpoint<\/strong> feature that will kick in when a specific line of code is reached. From that point onward, we can step through it line by line.<\/p>\n<h2>Walk-through of using a debugger<\/h2>\n<p>Let\u2019s see how we can make use of a debugger with an example. The following is the Python code for showing <a href=\"https:\/\/machinelearningmastery.com\/a-gentle-introduction-to-particle-swarm-optimization\/\">particle swarm optimization<\/a> in an animation:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb5d754301463\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\nimport numpy as np<br \/>\nimport matplotlib.pyplot as plt<br \/>\nfrom matplotlib.animation import FuncAnimation<\/p>\n<p>def f(x,y):<br \/>\n    &#8220;Objective function&#8221;<br \/>\n    return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<\/p>\n<p># Compute and plot the function in 3D within [0,5]x[0,5]<br \/>\nx, y = np.array(np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100)))<br \/>\nz = f(x, y)<\/p>\n<p># Find the global minimum<br \/>\nx_min = x.ravel()[z.argmin()]<br \/>\ny_min = y.ravel()[z.argmin()]<\/p>\n<p># Hyper-parameter of the algorithm<br \/>\nc1 = c2 = 0.1<br \/>\nw = 0.8<\/p>\n<p># Create particles<br \/>\nn_particles = 20<br \/>\nnp.random.seed(100)<br \/>\nX = np.random.rand(2, n_particles) * 5<br \/>\nV = np.random.randn(2, n_particles) * 0.1<\/p>\n<p># Initialize data<br \/>\npbest = X<br \/>\npbest_obj = f(X[0], X[1])<br \/>\ngbest = pbest[:, pbest_obj.argmin()]<br \/>\ngbest_obj = pbest_obj.min()<\/p>\n<p>def update():<br \/>\n    &#8220;Function to do one iteration of particle swarm optimization&#8221;<br \/>\n    global V, X, pbest, pbest_obj, gbest, gbest_obj<br \/>\n    # Update params<br \/>\n    r1, r2 = np.random.rand(2)<br \/>\n    V = w * V + c1*r1*(pbest &#8211; X) + c2*r2*(gbest.reshape(-1,1)-X)<br \/>\n    X = X + V<br \/>\n    obj = f(X[0], X[1])<br \/>\n    pbest[:, (pbest_obj &gt;= obj)] = X[:, (pbest_obj &gt;= obj)]<br \/>\n    pbest_obj = np.array([pbest_obj, obj]).min(axis=0)<br \/>\n    gbest = pbest[:, pbest_obj.argmin()]<br \/>\n    gbest_obj = pbest_obj.min()<\/p>\n<p># Set up base figure: The contour map<br \/>\nfig, ax = plt.subplots(figsize=(8,6))<br \/>\nfig.set_tight_layout(True)<br \/>\nimg = ax.imshow(z, extent=[0, 5, 0, 5], origin=&#8217;lower&#8217;, cmap=&#8217;viridis&#8217;, alpha=0.5)<br \/>\nfig.colorbar(img, ax=ax)<br \/>\nax.plot([x_min], [y_min], marker=&#8217;x&#8217;, markersize=5, color=&#8221;white&#8221;)<br \/>\ncontours = ax.contour(x, y, z, 10, colors=&#8217;black&#8217;, alpha=0.4)<br \/>\nax.clabel(contours, inline=True, fontsize=8, fmt=&#8221;%.0f&#8221;)<br \/>\npbest_plot = ax.scatter(pbest[0], pbest[1], marker=&#8217;o&#8217;, color=&#8217;black&#8217;, alpha=0.5)<br \/>\np_plot = ax.scatter(X[0], X[1], marker=&#8217;o&#8217;, color=&#8217;blue&#8217;, alpha=0.5)<br \/>\np_arrow = ax.quiver(X[0], X[1], V[0], V[1], color=&#8217;blue&#8217;, width=0.005, angles=&#8217;xy&#8217;, scale_units=&#8217;xy&#8217;, scale=1)<br \/>\ngbest_plot = plt.scatter([gbest[0]], [gbest[1]], marker=&#8217;*&#8217;, s=100, color=&#8217;black&#8217;, alpha=0.4)<br \/>\nax.set_xlim([0,5])<br \/>\nax.set_ylim([0,5])<\/p>\n<p>def animate(i):<br \/>\n    &#8220;Steps of PSO: algorithm update and show in plot&#8221;<br \/>\n    title = &#8216;Iteration {:02d}&#8217;.format(i)<br \/>\n    # Update params<br \/>\n    update()<br \/>\n    # Set picture<br \/>\n    ax.set_title(title)<br \/>\n    pbest_plot.set_offsets(pbest.T)<br \/>\n    p_plot.set_offsets(X.T)<br \/>\n    p_arrow.set_offsets(X.T)<br \/>\n    p_arrow.set_UVC(V[0], V[1])<br \/>\n    gbest_plot.set_offsets(gbest.reshape(1,-1))<br \/>\n    return ax, pbest_plot, p_plot, p_arrow, gbest_plot<\/p>\n<p>anim = FuncAnimation(fig, animate, frames=list(range(1,50)), interval=500, blit=False, repeat=True)<br \/>\nanim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<\/p>\n<p>print(&#8220;PSO found best solution at f({})={}&#8221;.format(gbest, gbest_obj))<br \/>\nprint(&#8220;Global optimal at f({})={}&#8221;.format([x_min,y_min], f(x_min,y_min)))<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<p>51<\/p>\n<p>52<\/p>\n<p>53<\/p>\n<p>54<\/p>\n<p>55<\/p>\n<p>56<\/p>\n<p>57<\/p>\n<p>58<\/p>\n<p>59<\/p>\n<p>60<\/p>\n<p>61<\/p>\n<p>62<\/p>\n<p>63<\/p>\n<p>64<\/p>\n<p>65<\/p>\n<p>66<\/p>\n<p>67<\/p>\n<p>68<\/p>\n<p>69<\/p>\n<p>70<\/p>\n<p>71<\/p>\n<p>72<\/p>\n<p>73<\/p>\n<p>74<\/p>\n<p>75<\/p>\n<p>76<\/p>\n<p>77<\/p>\n<p>78<\/p>\n<p>79<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">numpy <\/span><span class=\"crayon-st\">as<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">np<\/span><\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">matplotlib<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">pyplot <\/span><span class=\"crayon-st\">as<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">plt<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">matplotlib<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">animation <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">FuncAnimation<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-i\">def<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">f<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;Objective function&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">3.14<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-cn\">2<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">2.72<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-cn\">2<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">sin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">3<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-cn\">1.41<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">sin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">4<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">1.73<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Compute and plot the function in 3D within [0,5]x[0,5]<\/span><\/p>\n<p><span class=\"crayon-v\">x<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-t\">array<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">meshgrid<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">linspace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">100<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">linspace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">100<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">z<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">f<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Find the global minimum<\/span><\/p>\n<p><span class=\"crayon-v\">x_min<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">ravel<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">z<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">argmin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-v\">y_min<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">ravel<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">z<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">argmin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Hyper-parameter of the algorithm<\/span><\/p>\n<p><span class=\"crayon-v\">c1<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">c2<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">0.1<\/span><\/p>\n<p><span class=\"crayon-v\">w<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">0.8<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Create particles<\/span><\/p>\n<p><span class=\"crayon-v\">n_particles<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">20<\/span><\/p>\n<p><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">random<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">seed<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">100<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">X<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">random<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">rand<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">2<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">n_particles<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">5<\/span><\/p>\n<p><span class=\"crayon-v\">V<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">random<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">randn<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">2<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">n_particles<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">0.1<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Initialize data<\/span><\/p>\n<p><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">X<\/span><\/p>\n<p><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">f<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">argmin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-v\">gbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">min<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">update<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;Function to do one iteration of particle swarm optimization&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-m\">global<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">_<\/span>obj<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Update params<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">r1<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">r2<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">random<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">rand<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">2<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e \">w *<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e \">c1*<\/span><span class=\"crayon-e \">r1*<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e \">c2*<\/span><span class=\"crayon-e \">r2*<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">reshape<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">V<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">f<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">&gt;=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">obj<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">&gt;=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">obj<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">np<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-t\">array<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">obj<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">min<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">axis<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">argmin<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">gbest_obj<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_obj<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">min<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Set up base figure: The contour map<\/span><\/p>\n<p><span class=\"crayon-v\">fig<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">plt<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">subplots<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">figsize<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">8<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">6<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">fig<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_tight_layout<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-t\">True<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">img<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">imshow<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">z<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">extent<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">origin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;lower&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">cmap<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;viridis&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">alpha<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.5<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">fig<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">colorbar<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">img<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">plot<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">x_min<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">y_min<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">marker<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;x&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">markersize<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">color<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;white&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">contours<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">contour<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">x<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">y<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">z<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">10<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">colors<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;black&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">alpha<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.4<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">clabel<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">contours<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">inline<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-t\">True<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">fontsize<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">8<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">fmt<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;%.0f&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">pbest_plot<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">scatter<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">marker<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;o&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">color<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;black&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">alpha<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.5<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">p_plot<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">scatter<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">marker<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;o&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">color<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;blue&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">alpha<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.5<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">p_arrow<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">quiver<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">color<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;blue&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">width<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.005<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">angles<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;xy&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">scale_units<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;xy&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">scale<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">gbest_plot<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">plt<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">scatter<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">marker<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;*&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">s<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">100<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">color<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8216;black&#8217;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">alpha<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.4<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_xlim<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_ylim<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">animate<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">i<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;Steps of PSO: algorithm update and show in plot&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">title<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8216;Iteration {:02d}&#8217;<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">format<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">i<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Update params<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">update<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Set picture<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_title<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">title<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">pbest_plot<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_offsets<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">pbest<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">T<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">p_plot<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_offsets<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">T<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">p_arrow<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_offsets<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">X<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">T<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">p_arrow<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_UVC<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">V<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">gbest_plot<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_offsets<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">reshape<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ax<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">pbest_plot<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">p_plot<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">p_arrow<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">gbest_plot<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-v\">anim<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">FuncAnimation<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">fig<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">animate<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">frames<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-e\">list<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">range<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">50<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">interval<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">500<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">blit<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-t\">False<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">repeat<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-t\">True<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">anim<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">save<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;PSO.gif&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">dpi<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">120<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">writer<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;imagemagick&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;PSO found best solution at f({})={}&#8221;<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">format<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">gbest<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">gbest_obj<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;Global optimal at f({})={}&#8221;<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">format<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">x_min<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-v\">y_min<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">f<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">x_min<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-v\">y_min<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>The particle swarm optimization is done by executing the <code>update()<\/code> function a number of times. Each time it runs, we are closer to the optimal solution to the objective function. We are using matplotlib\u2019s <code>FuncAnimation()<\/code> function instead of a loop to run <code>update()<\/code>. So we can capture the position of the particles at each iteration.<\/p>\n<p>Assume this program is saved as <code>pso.py<\/code>, to run this program in command line is simply to enter:<\/p>\n<p>and the solution will be print out to the screen and the animation will be saved as <code>PSO.gif<\/code>. But if we want to run it with the Python debugger, we enter the following in command line:<\/p>\n<p>The <code>-m pdb<\/code> part is to load the <code>pdb<\/code> module and let the module to execute the file <code>pso.py<\/code> for you. When you run this command, you will be welcomed with the <code>pdb<\/code> prompt as follows:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb66372380012\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<br \/>\n-&gt; import numpy as np<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<\/p>\n<p>-&gt; import numpy as np<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>At the prompt, you can type in the debugger commands. To show the list of supported commands, we can use <code>h<\/code>. And to show the detail of the specific command (such as <code>list<\/code>), we can use <code>h list<\/code>:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb67659602137\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<br \/>\n-&gt; import numpy as np<br \/>\n(Pdb) h<\/p>\n<p>Documented commands (type help &lt;topic&gt;):<br \/>\n========================================<br \/>\nEOF    c          d        h         list      q        rv       undisplay<br \/>\na      cl         debug    help      ll        quit     s        unt<br \/>\nalias  clear      disable  ignore    longlist  r        source   until<br \/>\nargs   commands   display  interact  n         restart  step     up<br \/>\nb      condition  down     j         next      return   tbreak   w<br \/>\nbreak  cont       enable   jump      p         retval   u        whatis<br \/>\nbt     continue   exit     l         pp        run      unalias  where<\/p>\n<p>Miscellaneous help topics:<br \/>\n==========================<br \/>\nexec  pdb<\/p>\n<p>(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<\/p>\n<p>-&gt; import numpy as np<\/p>\n<p>(Pdb) h<\/p>\n<p>\u00a0<\/p>\n<p>Documented commands (type help &lt;topic&gt;):<\/p>\n<p>========================================<\/p>\n<p>EOF\u00a0\u00a0\u00a0\u00a0c\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0d\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0h\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 list\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0q\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0rv\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 undisplay<\/p>\n<p>a\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cl\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 debug\u00a0\u00a0\u00a0\u00a0help\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ll\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0quit\u00a0\u00a0\u00a0\u00a0 s\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unt<\/p>\n<p>alias\u00a0\u00a0clear\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0disable\u00a0\u00a0ignore\u00a0\u00a0\u00a0\u00a0longlist\u00a0\u00a0r\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source\u00a0\u00a0 until<\/p>\n<p>args\u00a0\u00a0 commands\u00a0\u00a0 display\u00a0\u00a0interact\u00a0\u00a0n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 restart\u00a0\u00a0step\u00a0\u00a0\u00a0\u00a0 up<\/p>\n<p>b\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0condition\u00a0\u00a0down\u00a0\u00a0\u00a0\u00a0 j\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 next\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0\u00a0 tbreak\u00a0\u00a0 w<\/p>\n<p>break\u00a0\u00a0cont\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 enable\u00a0\u00a0 jump\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0p\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 retval\u00a0\u00a0 u\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0whatis<\/p>\n<p>bt\u00a0\u00a0\u00a0\u00a0 continue\u00a0\u00a0 exit\u00a0\u00a0\u00a0\u00a0 l\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pp\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0run\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unalias\u00a0\u00a0where<\/p>\n<p>\u00a0<\/p>\n<p>Miscellaneous help topics:<\/p>\n<p>==========================<\/p>\n<p>exec\u00a0\u00a0pdb<\/p>\n<p>\u00a0<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>At the beginning of a debugger session, we start with the first line of the program. Normally a Python program would start with a few lines of <code>import<\/code>. We can use <code>n<\/code> to move to the next line, or <code>s<\/code> to step into a function:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb68903039297\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<br \/>\n-&gt; import numpy as np<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(2)&lt;module&gt;()<br \/>\n-&gt; import matplotlib.pyplot as plt<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(3)&lt;module&gt;()<br \/>\n-&gt; from matplotlib.animation import FuncAnimation<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(5)&lt;module&gt;()<br \/>\n-&gt; def f(x,y):<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(10)&lt;module&gt;()<br \/>\n-&gt; x, y = np.array(np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100)))<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(11)&lt;module&gt;()<br \/>\n-&gt; z = f(x, y)<br \/>\n(Pdb) s<br \/>\n&#8211;Call&#8211;<br \/>\n&gt; \/Users\/mlm\/pso.py(5)f()<br \/>\n-&gt; def f(x,y):<br \/>\n(Pdb) s<br \/>\n&gt; \/Users\/mlm\/pso.py(7)f()<br \/>\n-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<br \/>\n(Pdb) s<br \/>\n&#8211;Return&#8211;<br \/>\n&gt; \/Users\/mlm\/pso.py(7)f()-&gt;array([[17.25&#8230; 7.46457344]])<br \/>\n-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<br \/>\n(Pdb) s<br \/>\n&gt; \/Users\/mlm\/pso.py(14)&lt;module&gt;()<br \/>\n-&gt; x_min = x.ravel()[z.argmin()]<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<\/p>\n<p>-&gt; import numpy as np<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(2)&lt;module&gt;()<\/p>\n<p>-&gt; import matplotlib.pyplot as plt<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(3)&lt;module&gt;()<\/p>\n<p>-&gt; from matplotlib.animation import FuncAnimation<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(5)&lt;module&gt;()<\/p>\n<p>-&gt; def f(x,y):<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(10)&lt;module&gt;()<\/p>\n<p>-&gt; x, y = np.array(np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100)))<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(11)&lt;module&gt;()<\/p>\n<p>-&gt; z = f(x, y)<\/p>\n<p>(Pdb) s<\/p>\n<p>&#8211;Call&#8211;<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(5)f()<\/p>\n<p>-&gt; def f(x,y):<\/p>\n<p>(Pdb) s<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(7)f()<\/p>\n<p>-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<\/p>\n<p>(Pdb) s<\/p>\n<p>&#8211;Return&#8211;<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(7)f()-&gt;array([[17.25&#8230; 7.46457344]])<\/p>\n<p>-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<\/p>\n<p>(Pdb) s<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(14)&lt;module&gt;()<\/p>\n<p>-&gt; x_min = x.ravel()[z.argmin()]<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>In <code>pdb<\/code>, the line of code will be printed before the prompt. Usually <code>n<\/code> command is what we would prefer as it executes that line of code and moves the flow at the <strong>same level<\/strong> without drill down deeper. When we are at a line that calls a function (such as line 11 of the above program, that runs <code>z = f(x, y)<\/code>) we can use <code>s<\/code> to <strong>step into<\/strong> the function. In the above example, we first step into <code>f()<\/code> function, then another step to execute the computation, and finally, collect the return value from the function to give it back to the line that invoked the function. We see there are multiple <code>s<\/code> command needed for a function as simple as one line because finding the function from the statement, calling the function, and return each takes one step. We can also see that in the body of the function, we called <code>np.sin()<\/code> like a function but the debugger\u2019s <code>s<\/code> command does not go into it. It is because the <code>np.sin()<\/code> function is not implemented in Python but in C. The <code>pdb<\/code> does not support compiled code.<\/p>\n<p>If the program is long, it is quite boring to use the <code>n<\/code> command many times to move to somewhere we are interested. We can use <code>until<\/code> command with a line number to let the debugger run the program until that line is reached:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb69524356495\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<br \/>\n-&gt; import numpy as np<br \/>\n(Pdb) until 11<br \/>\n&gt; \/Users\/mlm\/pso.py(11)&lt;module&gt;()<br \/>\n-&gt; z = f(x, y)<br \/>\n(Pdb) s<br \/>\n&#8211;Call&#8211;<br \/>\n&gt; \/Users\/mlm\/pso.py(5)f()<br \/>\n-&gt; def f(x,y):<br \/>\n(Pdb) s<br \/>\n&gt; \/Users\/mlm\/pso.py(7)f()<br \/>\n-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<br \/>\n(Pdb) s<br \/>\n&#8211;Return&#8211;<br \/>\n&gt; \/Users\/mlm\/pso.py(7)f()-&gt;array([[17.25&#8230; 7.46457344]])<br \/>\n-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<br \/>\n(Pdb) s<br \/>\n&gt; \/Users\/mlm\/pso.py(14)&lt;module&gt;()<br \/>\n-&gt; x_min = x.ravel()[z.argmin()]<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<\/p>\n<p>-&gt; import numpy as np<\/p>\n<p>(Pdb) until 11<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(11)&lt;module&gt;()<\/p>\n<p>-&gt; z = f(x, y)<\/p>\n<p>(Pdb) s<\/p>\n<p>&#8211;Call&#8211;<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(5)f()<\/p>\n<p>-&gt; def f(x,y):<\/p>\n<p>(Pdb) s<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(7)f()<\/p>\n<p>-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<\/p>\n<p>(Pdb) s<\/p>\n<p>&#8211;Return&#8211;<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(7)f()-&gt;array([[17.25&#8230; 7.46457344]])<\/p>\n<p>-&gt; return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)<\/p>\n<p>(Pdb) s<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(14)&lt;module&gt;()<\/p>\n<p>-&gt; x_min = x.ravel()[z.argmin()]<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>A command similar to <code>until<\/code> is <code>return<\/code>, which will execute the current function until the point that it is about to return. You can consider that as <code>until<\/code> with the line number equal to the last line of the current function. The <code>until<\/code> command is one-off, meaning it will bring you to that line only. If you want to stop at a particular line <strong>whenever<\/strong> it is being run, we can make a <strong>breakpoint<\/strong>\u00a0on it. For example, if we are interested in how each iteration of the optimization algorithm moves the solution, we can set a breakpoint right after the update is applied:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb6a905689699\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<br \/>\n-&gt; import numpy as np<br \/>\n(Pdb) b 40<br \/>\nBreakpoint 1 at \/Users\/mlm\/pso.py:40<br \/>\n(Pdb) c<br \/>\n&gt; \/Users\/mlm\/pso.py(40)update()<br \/>\n-&gt; obj = f(X[0], X[1])<br \/>\n(Pdb) bt<br \/>\n  \/usr\/local\/Cellar\/python@3.9\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<br \/>\n-&gt; exec(cmd, globals, locals)<br \/>\n  &lt;string&gt;(1)&lt;module&gt;()<br \/>\n  \/Users\/mlm\/pso.py(76)&lt;module&gt;()<br \/>\n-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1078)save()<br \/>\n-&gt; anim._init_draw()  # Clear the initial frame<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1698)_init_draw()<br \/>\n-&gt; self._draw_frame(frame_data)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<br \/>\n-&gt; self._drawn_artists = self._func(framedata, *self._args)<br \/>\n  \/Users\/mlm\/pso.py(65)animate()<br \/>\n-&gt; update()<br \/>\n&gt; \/Users\/mlm\/pso.py(40)update()<br \/>\n-&gt; obj = f(X[0], X[1])<br \/>\n(Pdb) p r1<br \/>\n0.8054505373292797<br \/>\n(Pdb) p r2<br \/>\n0.7543489945823536<br \/>\n(Pdb) p X<br \/>\narray([[2.77550474, 1.60073607, 2.14133019, 4.11466522, 0.2445649 ,<br \/>\n        0.65149396, 3.24520628, 4.08804798, 0.89696478, 2.82703884,<br \/>\n        4.42055413, 1.03681404, 0.95318658, 0.60737118, 1.17702652,<br \/>\n        4.67551174, 3.95781321, 0.95077669, 4.08220292, 1.33330594],<br \/>\n       [2.07985611, 4.53702225, 3.81359193, 1.83427181, 0.87867832,<br \/>\n        1.8423856 , 0.11392109, 1.2635162 , 3.84974582, 0.27397365,<br \/>\n        2.86219806, 3.05406841, 0.64253831, 1.85730719, 0.26090638,<br \/>\n        4.28053621, 4.71648133, 0.44101305, 4.14882396, 2.74620598]])<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(41)update()<br \/>\n-&gt; pbest[:, (pbest_obj &gt;= obj)] = X[:, (pbest_obj &gt;= obj)]<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(42)update()<br \/>\n-&gt; pbest_obj = np.array([pbest_obj, obj]).min(axis=0)<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(43)update()<br \/>\n-&gt; gbest = pbest[:, pbest_obj.argmin()]<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(44)update()<br \/>\n-&gt; gbest_obj = pbest_obj.min()<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&gt; \/Users\/mlm\/pso.py(1)&lt;module&gt;()<\/p>\n<p>-&gt; import numpy as np<\/p>\n<p>(Pdb) b 40<\/p>\n<p>Breakpoint 1 at \/Users\/mlm\/pso.py:40<\/p>\n<p>(Pdb) c<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(40)update()<\/p>\n<p>-&gt; obj = f(X[0], X[1])<\/p>\n<p>(Pdb) bt<\/p>\n<div class=\"crayon-line\" id=\"urvanov-syntax-highlighter-61df043e7eb6a905689699-9\">\u00a0\u00a0\/usr\/local\/Cellar\/<a href=\"\/cdn-cgi\/l\/email-protection\" class=\"__cf_email__\" data-cfemail=\"9dede4e9f5f2f3ddaeb3a4\">[email\u00a0protected]<\/a>\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<\/div>\n<p>-&gt; exec(cmd, globals, locals)<\/p>\n<p>\u00a0\u00a0&lt;string&gt;(1)&lt;module&gt;()<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(76)&lt;module&gt;()<\/p>\n<p>-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1078)save()<\/p>\n<p>-&gt; anim._init_draw()\u00a0\u00a0# Clear the initial frame<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1698)_init_draw()<\/p>\n<p>-&gt; self._draw_frame(frame_data)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<\/p>\n<p>-&gt; self._drawn_artists = self._func(framedata, *self._args)<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(65)animate()<\/p>\n<p>-&gt; update()<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(40)update()<\/p>\n<p>-&gt; obj = f(X[0], X[1])<\/p>\n<p>(Pdb) p r1<\/p>\n<p>0.8054505373292797<\/p>\n<p>(Pdb) p r2<\/p>\n<p>0.7543489945823536<\/p>\n<p>(Pdb) p X<\/p>\n<p>array([[2.77550474, 1.60073607, 2.14133019, 4.11466522, 0.2445649 ,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00.65149396, 3.24520628, 4.08804798, 0.89696478, 2.82703884,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a04.42055413, 1.03681404, 0.95318658, 0.60737118, 1.17702652,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a04.67551174, 3.95781321, 0.95077669, 4.08220292, 1.33330594],<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [2.07985611, 4.53702225, 3.81359193, 1.83427181, 0.87867832,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a01.8423856 , 0.11392109, 1.2635162 , 3.84974582, 0.27397365,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a02.86219806, 3.05406841, 0.64253831, 1.85730719, 0.26090638,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a04.28053621, 4.71648133, 0.44101305, 4.14882396, 2.74620598]])<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(41)update()<\/p>\n<p>-&gt; pbest[:, (pbest_obj &gt;= obj)] = X[:, (pbest_obj &gt;= obj)]<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(42)update()<\/p>\n<p>-&gt; pbest_obj = np.array([pbest_obj, obj]).min(axis=0)<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(43)update()<\/p>\n<p>-&gt; gbest = pbest[:, pbest_obj.argmin()]<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(44)update()<\/p>\n<p>-&gt; gbest_obj = pbest_obj.min()<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>After we set a breakpoint with the <code>b<\/code> command, we can let the debugger run our program until the breakpoint is hit. The <code>c<\/code> command means to <strong>continue<\/strong> until a trigger is met. At any point, we can use <code>bt<\/code> command to show the traceback to check how we reached here. We can also use the <code>p<\/code> command to print the variables (or an expression) to check what value they are holding.<\/p>\n<p>Indeed, we can place a breakpoint with a condition, so that it will stop only if the condition is met. The below will impose a condition that the first random number (<code>r1<\/code>) is greater than 0.5:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb6c662772648\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n(Pdb) b 40, r1 &gt; 0.5<br \/>\nBreakpoint 1 at \/Users\/mlm\/pso.py:40<br \/>\n(Pdb) c<br \/>\n&gt; \/Users\/mlm\/pso.py(40)update()<br \/>\n-&gt; obj = f(X[0], X[1])<br \/>\n(Pdb) p r1, r2<br \/>\n(0.8054505373292797, 0.7543489945823536)<br \/>\n(Pdb) c<br \/>\n&gt; \/Users\/mlm\/pso.py(40)update()<br \/>\n-&gt; obj = f(X[0], X[1])<br \/>\n(Pdb) p r1, r2<br \/>\n(0.5404045753007164, 0.2967937508800147)<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>(Pdb) b 40, r1 &gt; 0.5<\/p>\n<p>Breakpoint 1 at \/Users\/mlm\/pso.py:40<\/p>\n<p>(Pdb) c<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(40)update()<\/p>\n<p>-&gt; obj = f(X[0], X[1])<\/p>\n<p>(Pdb) p r1, r2<\/p>\n<p>(0.8054505373292797, 0.7543489945823536)<\/p>\n<p>(Pdb) c<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(40)update()<\/p>\n<p>-&gt; obj = f(X[0], X[1])<\/p>\n<p>(Pdb) p r1, r2<\/p>\n<p>(0.5404045753007164, 0.2967937508800147)<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>Indeed, we can also try to manipulate variables while we are debugging.<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb6d531290876\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n(Pdb) l<br \/>\n 35  \t    global V, X, pbest, pbest_obj, gbest, gbest_obj<br \/>\n 36  \t    # Update params<br \/>\n 37  \t    r1, r2 = np.random.rand(2)<br \/>\n 38  \t    V = w * V + c1*r1*(pbest &#8211; X) + c2*r2*(gbest.reshape(-1,1)-X)<br \/>\n 39  \t    X = X + V<br \/>\n 40 B-&gt;\t    obj = f(X[0], X[1])<br \/>\n 41  \t    pbest[:, (pbest_obj &gt;= obj)] = X[:, (pbest_obj &gt;= obj)]<br \/>\n 42  \t    pbest_obj = np.array([pbest_obj, obj]).min(axis=0)<br \/>\n 43  \t    gbest = pbest[:, pbest_obj.argmin()]<br \/>\n 44  \t    gbest_obj = pbest_obj.min()<br \/>\n 45<br \/>\n(Pdb) p V<br \/>\narray([[ 0.03742722,  0.20930531,  0.06273426, -0.1710678 ,  0.33629384,<br \/>\n         0.19506555, -0.10238065, -0.12707257,  0.28042122, -0.03250191,<br \/>\n        -0.14004886,  0.13224399,  0.16083673,  0.21198813,  0.17530208,<br \/>\n        -0.27665503, -0.15344393,  0.20079061, -0.10057509,  0.09128536],<br \/>\n       [-0.05034548, -0.27986224, -0.30725954,  0.11214169,  0.0934514 ,<br \/>\n         0.00335978,  0.20517519,  0.06308483, -0.22007053,  0.26176423,<br \/>\n        -0.12617228, -0.05676629,  0.18296986, -0.01669114,  0.18934933,<br \/>\n        -0.27623121, -0.32482898,  0.213894  , -0.34427909, -0.12058168]])<br \/>\n(Pdb) p r1, r2<br \/>\n(0.5404045753007164, 0.2967937508800147)<br \/>\n(Pdb) r1 = 0.2<br \/>\n(Pdb) p r1, r2<br \/>\n(0.2, 0.2967937508800147)<br \/>\n(Pdb) j 38<br \/>\n&gt; \/Users\/mlm\/pso.py(38)update()<br \/>\n-&gt; V = w * V + c1*r1*(pbest &#8211; X) + c2*r2*(gbest.reshape(-1,1)-X)<br \/>\n(Pdb) n<br \/>\n&gt; \/Users\/mlm\/pso.py(39)update()<br \/>\n-&gt; X = X + V<br \/>\n(Pdb) p V<br \/>\narray([[ 0.02680837,  0.16594979,  0.06350735, -0.15577623,  0.30737655,<br \/>\n         0.19911613, -0.08242418, -0.12513798,  0.24939995, -0.02217463,<br \/>\n        -0.13474876,  0.14466204,  0.16661846,  0.21194543,  0.16952298,<br \/>\n        -0.24462505, -0.138997  ,  0.19377154, -0.10699911,  0.10631063],<br \/>\n       [-0.03606147, -0.25128615, -0.26362411,  0.08163408,  0.09842085,<br \/>\n         0.00765688,  0.19771385,  0.06597805, -0.20564599,  0.23113388,<br \/>\n        -0.0956787 , -0.07044121,  0.16637064, -0.00639259,  0.18245734,<br \/>\n        -0.25698717, -0.30336147,  0.19354112, -0.29904698, -0.08810355]])<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>(Pdb) l<\/p>\n<p> 35\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0global V, X, pbest, pbest_obj, gbest, gbest_obj<\/p>\n<p> 36\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0# Update params<\/p>\n<p> 37\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0r1, r2 = np.random.rand(2)<\/p>\n<p> 38\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0V = w * V + c1*r1*(pbest &#8211; X) + c2*r2*(gbest.reshape(-1,1)-X)<\/p>\n<p> 39\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0X = X + V<\/p>\n<p> 40 B-&gt;\t\u00a0\u00a0\u00a0\u00a0obj = f(X[0], X[1])<\/p>\n<p> 41\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0pbest[:, (pbest_obj &gt;= obj)] = X[:, (pbest_obj &gt;= obj)]<\/p>\n<p> 42\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0pbest_obj = np.array([pbest_obj, obj]).min(axis=0)<\/p>\n<p> 43\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0gbest = pbest[:, pbest_obj.argmin()]<\/p>\n<p> 44\u00a0\u00a0\t\u00a0\u00a0\u00a0\u00a0gbest_obj = pbest_obj.min()<\/p>\n<p> 45<\/p>\n<p>(Pdb) p V<\/p>\n<p>array([[ 0.03742722,\u00a0\u00a00.20930531,\u00a0\u00a00.06273426, -0.1710678 ,\u00a0\u00a00.33629384,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0.19506555, -0.10238065, -0.12707257,\u00a0\u00a00.28042122, -0.03250191,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.14004886,\u00a0\u00a00.13224399,\u00a0\u00a00.16083673,\u00a0\u00a00.21198813,\u00a0\u00a00.17530208,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.27665503, -0.15344393,\u00a0\u00a00.20079061, -0.10057509,\u00a0\u00a00.09128536],<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [-0.05034548, -0.27986224, -0.30725954,\u00a0\u00a00.11214169,\u00a0\u00a00.0934514 ,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0.00335978,\u00a0\u00a00.20517519,\u00a0\u00a00.06308483, -0.22007053,\u00a0\u00a00.26176423,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.12617228, -0.05676629,\u00a0\u00a00.18296986, -0.01669114,\u00a0\u00a00.18934933,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.27623121, -0.32482898,\u00a0\u00a00.213894\u00a0\u00a0, -0.34427909, -0.12058168]])<\/p>\n<p>(Pdb) p r1, r2<\/p>\n<p>(0.5404045753007164, 0.2967937508800147)<\/p>\n<p>(Pdb) r1 = 0.2<\/p>\n<p>(Pdb) p r1, r2<\/p>\n<p>(0.2, 0.2967937508800147)<\/p>\n<p>(Pdb) j 38<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(38)update()<\/p>\n<p>-&gt; V = w * V + c1*r1*(pbest &#8211; X) + c2*r2*(gbest.reshape(-1,1)-X)<\/p>\n<p>(Pdb) n<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(39)update()<\/p>\n<p>-&gt; X = X + V<\/p>\n<p>(Pdb) p V<\/p>\n<p>array([[ 0.02680837,\u00a0\u00a00.16594979,\u00a0\u00a00.06350735, -0.15577623,\u00a0\u00a00.30737655,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0.19911613, -0.08242418, -0.12513798,\u00a0\u00a00.24939995, -0.02217463,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.13474876,\u00a0\u00a00.14466204,\u00a0\u00a00.16661846,\u00a0\u00a00.21194543,\u00a0\u00a00.16952298,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.24462505, -0.138997\u00a0\u00a0,\u00a0\u00a00.19377154, -0.10699911,\u00a0\u00a00.10631063],<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [-0.03606147, -0.25128615, -0.26362411,\u00a0\u00a00.08163408,\u00a0\u00a00.09842085,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0.00765688,\u00a0\u00a00.19771385,\u00a0\u00a00.06597805, -0.20564599,\u00a0\u00a00.23113388,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.0956787 , -0.07044121,\u00a0\u00a00.16637064, -0.00639259,\u00a0\u00a00.18245734,<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-0.25698717, -0.30336147,\u00a0\u00a00.19354112, -0.29904698, -0.08810355]])<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>In the above, we use <code>l<\/code> command to list the code around the current statement (identified by the arrow <code>-&gt;<\/code>). In the listing, we can also see the breakpoint (marked with <code>B<\/code>) is set at line 40. As we can see the current value of <code>V<\/code> and <code>r1<\/code>, we can modify <code>r1<\/code> from 0.54 to 0.2 and run the statement on <code>V<\/code> again by using <code>j<\/code> (jump) to line 38. And as we see after we execute the statement with <code>n<\/code> command, the value of <code>V<\/code> is changed.<\/p>\n<p>If we use a breakpoint and found something unexpected, chances are that it was caused by issues in a different level of the call stack. Debuggers would allow you to navigate to different levels:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb6f938730236\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n(Pdb) bt<br \/>\n  \/usr\/local\/Cellar\/python@3.9\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<br \/>\n-&gt; exec(cmd, globals, locals)<br \/>\n  &lt;string&gt;(1)&lt;module&gt;()<br \/>\n  \/Users\/mlm\/pso.py(76)&lt;module&gt;()<br \/>\n-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1091)save()<br \/>\n-&gt; anim._draw_next_frame(d, blit=False)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1126)_draw_next_frame()<br \/>\n-&gt; self._draw_frame(framedata)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<br \/>\n-&gt; self._drawn_artists = self._func(framedata, *self._args)<br \/>\n  \/Users\/mlm\/pso.py(65)animate()<br \/>\n-&gt; update()<br \/>\n&gt; \/Users\/mlm\/pso.py(39)update()<br \/>\n-&gt; X = X + V<br \/>\n(Pdb) up<br \/>\n&gt; \/Users\/mlm\/pso.py(65)animate()<br \/>\n-&gt; update()<br \/>\n(Pdb) bt<br \/>\n  \/usr\/local\/Cellar\/python@3.9\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<br \/>\n-&gt; exec(cmd, globals, locals)<br \/>\n  &lt;string&gt;(1)&lt;module&gt;()<br \/>\n  \/Users\/mlm\/pso.py(76)&lt;module&gt;()<br \/>\n-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1091)save()<br \/>\n-&gt; anim._draw_next_frame(d, blit=False)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1126)_draw_next_frame()<br \/>\n-&gt; self._draw_frame(framedata)<br \/>\n  \/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<br \/>\n-&gt; self._drawn_artists = self._func(framedata, *self._args)<br \/>\n&gt; \/Users\/mlm\/pso.py(65)animate()<br \/>\n-&gt; update()<br \/>\n  \/Users\/mlm\/pso.py(39)update()<br \/>\n-&gt; X = X + V<br \/>\n(Pdb) l<br \/>\n 60<br \/>\n 61     def animate(i):<br \/>\n 62         &#8220;Steps of PSO: algorithm update and show in plot&#8221;<br \/>\n 63         title = &#8216;Iteration {:02d}&#8217;.format(i)<br \/>\n 64         # Update params<br \/>\n 65  -&gt;     update()<br \/>\n 66         # Set picture<br \/>\n 67         ax.set_title(title)<br \/>\n 68         pbest_plot.set_offsets(pbest.T)<br \/>\n 69         p_plot.set_offsets(X.T)<br \/>\n 70         p_arrow.set_offsets(X.T)<br \/>\n(Pdb) p title<br \/>\n&#8216;Iteration 02&#8217;<br \/>\n(Pdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>(Pdb) bt<\/p>\n<div class=\"crayon-line crayon-striped-line\" id=\"urvanov-syntax-highlighter-61df043e7eb6f938730236-2\">\u00a0\u00a0\/usr\/local\/Cellar\/<a href=\"\/cdn-cgi\/l\/email-protection\" class=\"__cf_email__\" data-cfemail=\"62121b160a0d0c22514c5b\">[email\u00a0protected]<\/a>\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<\/div>\n<p>-&gt; exec(cmd, globals, locals)<\/p>\n<p>\u00a0\u00a0&lt;string&gt;(1)&lt;module&gt;()<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(76)&lt;module&gt;()<\/p>\n<p>-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1091)save()<\/p>\n<p>-&gt; anim._draw_next_frame(d, blit=False)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1126)_draw_next_frame()<\/p>\n<p>-&gt; self._draw_frame(framedata)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<\/p>\n<p>-&gt; self._drawn_artists = self._func(framedata, *self._args)<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(65)animate()<\/p>\n<p>-&gt; update()<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(39)update()<\/p>\n<p>-&gt; X = X + V<\/p>\n<p>(Pdb) up<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(65)animate()<\/p>\n<p>-&gt; update()<\/p>\n<p>(Pdb) bt<\/p>\n<div class=\"crayon-line\" id=\"urvanov-syntax-highlighter-61df043e7eb6f938730236-21\">\u00a0\u00a0\/usr\/local\/Cellar\/<a href=\"\/cdn-cgi\/l\/email-protection\" class=\"__cf_email__\" data-cfemail=\"64141d100c0b0a24574a5d\">[email\u00a0protected]<\/a>\/3.9.9\/Frameworks\/Python.framework\/Versions\/3.9\/lib\/python3.9\/bdb.py(580)run()<\/div>\n<p>-&gt; exec(cmd, globals, locals)<\/p>\n<p>\u00a0\u00a0&lt;string&gt;(1)&lt;module&gt;()<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(76)&lt;module&gt;()<\/p>\n<p>-&gt; anim.save(&#8220;PSO.gif&#8221;, dpi=120, writer=&#8221;imagemagick&#8221;)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1091)save()<\/p>\n<p>-&gt; anim._draw_next_frame(d, blit=False)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1126)_draw_next_frame()<\/p>\n<p>-&gt; self._draw_frame(framedata)<\/p>\n<p>\u00a0\u00a0\/usr\/local\/lib\/python3.9\/site-packages\/matplotlib\/animation.py(1720)_draw_frame()<\/p>\n<p>-&gt; self._drawn_artists = self._func(framedata, *self._args)<\/p>\n<p>&gt; \/Users\/mlm\/pso.py(65)animate()<\/p>\n<p>-&gt; update()<\/p>\n<p>\u00a0\u00a0\/Users\/mlm\/pso.py(39)update()<\/p>\n<p>-&gt; X = X + V<\/p>\n<p>(Pdb) l<\/p>\n<p> 60<\/p>\n<p> 61\u00a0\u00a0\u00a0\u00a0 def animate(i):<\/p>\n<p> 62\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;Steps of PSO: algorithm update and show in plot&#8221;<\/p>\n<p> 63\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 title = &#8216;Iteration {:02d}&#8217;.format(i)<\/p>\n<p> 64\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Update params<\/p>\n<p> 65\u00a0\u00a0-&gt;\u00a0\u00a0\u00a0\u00a0 update()<\/p>\n<p> 66\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Set picture<\/p>\n<p> 67\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ax.set_title(title)<\/p>\n<p> 68\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pbest_plot.set_offsets(pbest.T)<\/p>\n<p> 69\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 p_plot.set_offsets(X.T)<\/p>\n<p> 70\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 p_arrow.set_offsets(X.T)<\/p>\n<p>(Pdb) p title<\/p>\n<p>&#8216;Iteration 02&#8217;<\/p>\n<p>(Pdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>In the above, the first <code>bt<\/code> command gives the call stack when we are at the bottom frame, i.e., the deepest of the call stack. We can see that we are about to execute the statement <code>X = X + V<\/code>. Then the <code>up<\/code> command moves our focus to one level up on the call stack, which is the line running <code>update()<\/code> function (as we see at the line preceded with <code>&gt;<\/code>). Since our focus is changed, the list command <code>l<\/code> will print a different fragment of code and the <code>p<\/code> command can examine a variable in a different scope.<\/p>\n<p>The above covers most of the useful commands in the debugger. If we want to terminate the debugger (which also terminates the program), we can use the <code>q<\/code> command to quit or hit Ctrl-D if your terminal supports.<\/p>\n<h2>Debugger in Visual Studio Code<\/h2>\n<p>If you are not very comfortable to run the debugger in command line, you can rely on the debugger from your IDE. Almost always the IDE will provide you some debugging facility. In Visual Studio Code for example, you can launch the debugger in the \u201cRun\u201d menu.<\/p>\n<p>The screen below shows Visual Studio Code at debugging session. The buttons at the center top are correspond to <code>pdb<\/code> commands <code>continue<\/code>, <code>next<\/code>, <code>step<\/code>, <code>return<\/code>, <code>restart<\/code>, and <code>quit<\/code> respectively. A breakpoint can be created by clicking on the line number, which a red dot will be appeared to identify that. The bonus of using an IDE is that the variables are shown immediately at each debugging step. We can also watch for an express and show the call stack. These are at left side of the screen below.<\/p>\n<p><img class=\"aligncenter size-full wp-image-13177\" data-cfsrc=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/VSCode-Debug.png\" alt=\"\" width=\"850\"><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-13177\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/VSCode-Debug.png\" alt=\"\" width=\"850\"><\/p>\n<h2>Using GDB on a running Python program<\/h2>\n<p>The <code>pdb<\/code> from Python is suitable only for programs running from scratch. If we have a program already running but stuck, we cannot use pdb to <strong>hook into<\/strong> it to check what\u2019s going on. The Python extension from GDB, however, can do this.<\/p>\n<p>To demonstrate, let\u2019s consider a GUI application. It will wait until user\u2019s action before the program can end. Hence it is a perfect example to see how we can use <code>gdb<\/code> to hook into a running process. The code below is a \u201chello world\u201d program using PyQt5 that just create an empty window and waiting for user to close it:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb70360235897\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\nimport sys<br \/>\nfrom PyQt5.QtWidgets import QApplication, QWidget, QMainWindow<\/p>\n<p>class Frame(QMainWindow):<br \/>\n        def __init__(self):<br \/>\n                super().__init__()<br \/>\n                self.initUI()<br \/>\n        def initUI(self):<br \/>\n                self.setWindowTitle(&#8220;Simple title&#8221;)<br \/>\n                self.resize(800,600)<\/p>\n<p>def main():<br \/>\n        app = QApplication(sys.argv)<br \/>\n        frame = Frame()<br \/>\n        frame.show()<br \/>\n        sys.exit(app.exec_())<\/p>\n<p>if __name__ == &#8216;__main__&#8217;:<br \/>\n        main()<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">sys<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">PyQt5<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">QtWidgets <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">QApplication<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">QWidget<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">QMainWindow<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-t\">class<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">Frame<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">QMainWindow<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">__init__<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-r\">self<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-r\">super<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">__init__<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-r\">self<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">initUI<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">initUI<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-r\">self<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-r\">self<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">setWindowTitle<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;Simple title&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-r\">self<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">resize<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-cn\">800<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-cn\">600<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">main<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">app<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">QApplication<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">argv<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">frame<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">Frame<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">frame<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">show<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">exit<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">app<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">exec_<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">__name__<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">==<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8216;__main__&#8217;<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">main<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>Let\u2019s save this program as <code>simpleqt.py<\/code> and run it using the following in Linux under X window environment:<\/p>\n<p>The final <code>&amp;<\/code> will make it run in background. Now we can check for its process ID using the <code>ps<\/code> command:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb75694353193\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\n&#8230;<br \/>\n   3997 pts\/1    Sl     0:00 python simpleqt.py<br \/>\n&#8230;<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"hide\">\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>&#8230;<\/p>\n<p>\u00a0\u00a0 3997 pts\/1\u00a0\u00a0\u00a0\u00a0Sl\u00a0\u00a0\u00a0\u00a0 0:00 python simpleqt.py<\/p>\n<p>&#8230;<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>The <code>ps<\/code> command will tell you the process ID at the first column. If you have <code>gdb<\/code> installed with python extension, we can run<\/p>\n<p>and it will bring you into the GDB\u2019s prompt:<\/p>\n<div id=\"urvanov-syntax-highlighter-61df043e7eb77494963777\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" minimize scroll-mouseover disable-anim\">\n<p><textarea class=\"urvanov-syntax-highlighter-plain print-no\" data-settings=\"dblclick\" readonly><br \/>\nGNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git<br \/>\nCopyright (C) 2021 Free Software Foundation, Inc.<br \/>\nLicense GPLv3+: GNU GPL version 3 or later &lt;http:\/\/gnu.org\/licenses\/gpl.html&gt;<br \/>\nThis is free software: you are free to change and redistribute it.<br \/>\nThere is NO WARRANTY, to the extent permitted by law.<br \/>\nType &#8220;show copying&#8221; and &#8220;show warranty&#8221; for details.<br \/>\nThis GDB was configured as &#8220;x86_64-linux-gnu&#8221;.<br \/>\nType &#8220;show configuration&#8221; for configuration details.<br \/>\nFor bug reporting instructions, please see:<br \/>\n&lt;https:\/\/www.gnu.org\/software\/gdb\/bugs\/&gt;.<br \/>\nFind the GDB manual and other documentation resources online at:<br \/>\n    &lt;http:\/\/www.gnu.org\/software\/gdb\/documentation\/&gt;.<\/p>\n<p>For help, type &#8220;help&#8221;.<br \/>\nType &#8220;apropos word&#8221; to search for commands related to &#8220;word&#8221;&#8230;<br \/>\nReading symbols from python&#8230;<br \/>\nReading symbols from \/usr\/lib\/debug\/.build-id\/f9\/02f8a561c3abdb9c8d8c859d4243bd8c3f928f.debug&#8230;<br \/>\nAttaching to program: \/usr\/local\/bin\/python, process 3997<br \/>\n[New LWP 3998]<br \/>\n[New LWP 3999]<br \/>\n[New LWP 4001]<br \/>\n[New LWP 4002]<br \/>\n[New LWP 4003]<br \/>\n[New LWP 4004]<br \/>\n[Thread debugging using libthread_db enabled]<br \/>\nUsing host libthread_db library &#8220;\/lib\/x86_64-linux-gnu\/libthread_db.so.1&#8221;.<br \/>\n0x00007fb11b1c93ff in __GI___poll (fds=0x7fb110007220, nfds=3, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/poll.c:29<br \/>\n29      ..\/sysdeps\/unix\/sysv\/linux\/poll.c: No such file or directory.<br \/>\n(gdb) py-bt<br \/>\nTraceback (most recent call first):<br \/>\n  &lt;built-in method exec_ of QApplication object at remote 0x7fb115f64c10&gt;<br \/>\n  File &#8220;\/mnt\/data\/simpleqt.py&#8221;, line 16, in main<br \/>\n    sys.exit(app.exec_())<br \/>\n  File &#8220;\/mnt\/data\/simpleqt.py&#8221;, line 19, in &lt;module&gt;<br \/>\n    main()<br \/>\n(gdb) py-list<br \/>\n  11<br \/>\n  12    def main():<br \/>\n  13            app = QApplication(sys.argv)<br \/>\n  14            frame = Frame()<br \/>\n  15            frame.show()<br \/>\n &gt;16            sys.exit(app.exec_())<br \/>\n  17<br \/>\n  18    if __name__ == &#8216;__main__&#8217;:<br \/>\n  19            main()<br \/>\n(gdb)<\/textarea><\/p>\n<div class=\"urvanov-syntax-highlighter-main\">\n<table class=\"crayon-table\">\n<tr class=\"urvanov-syntax-highlighter-row\">\n<td class=\"crayon-nums \" data-settings=\"show\">\n<div class=\"urvanov-syntax-highlighter-nums-content\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<\/div>\n<\/td>\n<td class=\"urvanov-syntax-highlighter-code\">\n<div class=\"crayon-pre\">\n<p>GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git<\/p>\n<p>Copyright (C) 2021 Free Software Foundation, Inc.<\/p>\n<p>License GPLv3+: GNU GPL version 3 or later &lt;http:\/\/gnu.org\/licenses\/gpl.html&gt;<\/p>\n<p>This is free software: you are free to change and redistribute it.<\/p>\n<p>There is NO WARRANTY, to the extent permitted by law.<\/p>\n<p>Type &#8220;show copying&#8221; and &#8220;show warranty&#8221; for details.<\/p>\n<p>This GDB was configured as &#8220;x86_64-linux-gnu&#8221;.<\/p>\n<p>Type &#8220;show configuration&#8221; for configuration details.<\/p>\n<p>For bug reporting instructions, please see:<\/p>\n<p>&lt;https:\/\/www.gnu.org\/software\/gdb\/bugs\/&gt;.<\/p>\n<p>Find the GDB manual and other documentation resources online at:<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0&lt;http:\/\/www.gnu.org\/software\/gdb\/documentation\/&gt;.<\/p>\n<p>\u00a0<\/p>\n<p>For help, type &#8220;help&#8221;.<\/p>\n<p>Type &#8220;apropos word&#8221; to search for commands related to &#8220;word&#8221;&#8230;<\/p>\n<p>Reading symbols from python&#8230;<\/p>\n<p>Reading symbols from \/usr\/lib\/debug\/.build-id\/f9\/02f8a561c3abdb9c8d8c859d4243bd8c3f928f.debug&#8230;<\/p>\n<p>Attaching to program: \/usr\/local\/bin\/python, process 3997<\/p>\n<p>[New LWP 3998]<\/p>\n<p>[New LWP 3999]<\/p>\n<p>[New LWP 4001]<\/p>\n<p>[New LWP 4002]<\/p>\n<p>[New LWP 4003]<\/p>\n<p>[New LWP 4004]<\/p>\n<p>[Thread debugging using libthread_db enabled]<\/p>\n<p>Using host libthread_db library &#8220;\/lib\/x86_64-linux-gnu\/libthread_db.so.1&#8221;.<\/p>\n<p>0x00007fb11b1c93ff in __GI___poll (fds=0x7fb110007220, nfds=3, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/poll.c:29<\/p>\n<p>29\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0..\/sysdeps\/unix\/sysv\/linux\/poll.c: No such file or directory.<\/p>\n<p>(gdb) py-bt<\/p>\n<p>Traceback (most recent call first):<\/p>\n<p>\u00a0\u00a0&lt;built-in method exec_ of QApplication object at remote 0x7fb115f64c10&gt;<\/p>\n<p>\u00a0\u00a0File &#8220;\/mnt\/data\/simpleqt.py&#8221;, line 16, in main<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0sys.exit(app.exec_())<\/p>\n<p>\u00a0\u00a0File &#8220;\/mnt\/data\/simpleqt.py&#8221;, line 19, in &lt;module&gt;<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0main()<\/p>\n<p>(gdb) py-list<\/p>\n<p>\u00a0\u00a011\u00a0\u00a0\u00a0\u00a0<\/p>\n<p>\u00a0\u00a012\u00a0\u00a0\u00a0\u00a0def main():<\/p>\n<p>\u00a0\u00a013\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app = QApplication(sys.argv)<\/p>\n<p>\u00a0\u00a014\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0frame = Frame()<\/p>\n<p>\u00a0\u00a015\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0frame.show()<\/p>\n<p> &gt;16\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sys.exit(app.exec_())<\/p>\n<p>\u00a0\u00a017\u00a0\u00a0\u00a0\u00a0<\/p>\n<p>\u00a0\u00a018\u00a0\u00a0\u00a0\u00a0if __name__ == &#8216;__main__&#8217;:<\/p>\n<p>\u00a0\u00a019\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0main()<\/p>\n<p>(gdb)<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/table><\/div>\n<\/p><\/div>\n<p>GDB is supposed to be a debugger for compiled programs (usually from C or C++). The Python extension allows you to check the code (written in Python) being run by the Python interpreter (which is written in C). It is less feature-rich than the Python\u2019s <code>pdb<\/code> in terms of handling Python code but useful when you want to need to hook into a running process.<\/p>\n<p>The command supported under GDB are <code>py-list<\/code>, <code>py-bt<\/code>, <code>py-up<\/code>, <code>py-down<\/code>, and <code>py-print<\/code>. They are comparable to the same commands in <code>pdb<\/code> without the <code>py-<\/code> prefix.<\/p>\n<p>GDB is useful if your Python code uses a library that is compiled from C (such as numpy) and want to investigate how the it runs. It is also useful to learn why your program is frozen by checking the call stack in run time. However, it may be rarely the case that you need to use GDB to debug your machine learning project.<\/p>\n<h2>Further Readings<\/h2>\n<p>The Python <code>pdb<\/code> module\u2019s document is at<\/p>\n<p>But <code>pdb<\/code> is not the only debugger available. Some third-party tools are listed in:<\/p>\n<p>For GDB with Python extension, it is most mature to be used in Linux environment. Please see the following for more details on its usage:<\/p>\n<p>The command interface of <code>pdb<\/code> is influenced by that of GDB. Hence we can learn the technique of debugging a program in general from the latter. A good primer on how to use a debugger would be<\/p>\n<h2>Summary<\/h2>\n<p>In this tutorial, you discovered the features of Python\u2019s <code>pdb<\/code><\/p>\n<p>Specifically, you learned:<\/p>\n<ul>\n<li>What can <code>pdb<\/code> do and how to use it<\/li>\n<li>The limitation and alternatives of <code>pdb<\/code><\/li>\n<\/ul>\n<p>In the next post, we will see that <code>pdb<\/code> is also a Python function that can be called inside a Python program.<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/machinelearningmastery.com\/python-debugging-tools\/<\/p>\n","protected":false},"author":0,"featured_media":1470,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1469"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=1469"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1469\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/1470"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=1469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=1469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=1469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}