{"id":5380,"date":"2022-01-27T06:28:57","date_gmt":"2022-01-27T06:28:57","guid":{"rendered":"https:\/\/www.aiproblog.com\/index.php\/2022\/01\/27\/setting-breakpoints-and-exception-hooks-in-python\/"},"modified":"2022-01-27T06:28:57","modified_gmt":"2022-01-27T06:28:57","slug":"setting-breakpoints-and-exception-hooks-in-python","status":"publish","type":"post","link":"https:\/\/www.aiproblog.com\/index.php\/2022\/01\/27\/setting-breakpoints-and-exception-hooks-in-python\/","title":{"rendered":"Setting Breakpoints and Exception Hooks in Python"},"content":{"rendered":"<p>Author: Stefania Cristina<\/p>\n<div>\n<p>There are different ways of debugging code in Python, one of which is to introduce breakpoints into the code at points where one would like to invoke a Python debugger. The statements that one would use to enter a debugging session at different call sites, depend on the version of the Python interpreter that one is working with, as we shall be seeing in this tutorial.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>In this tutorial, you will discover various ways of setting breakpoints in different versions of Python.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>After completing this tutorial, you will know:<\/p>\n<ul>\n<li>How to invoke the <code>pdb<\/code> debugger in earlier versions of Python.<\/li>\n<li>How to make use of the new, built-in<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a29a520714862\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function introduced in Python 3.7.<span class=\"Apple-converted-space\">\u00a0<\/span>\n<\/li>\n<li>How to write your own<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a29f514819099\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function to simplify the debugging process in earlier versions of Python.<\/li>\n<li>How to use a post-mortem debugger<\/li>\n<\/ul>\n<p>Let\u2019s get started.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<div id=\"attachment_13189\" style=\"width: 1034px\" class=\"wp-caption aligncenter\">\n<a href=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-scaled.jpg\"><img decoding=\"async\" aria-describedby=\"caption-attachment-13189\" loading=\"lazy\" class=\"wp-image-13189 size-large\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-1024x767.jpg\" alt=\"\" width=\"1024\" height=\"767\" srcset=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-1024x767.jpg 1024w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-300x225.jpg 300w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-768x576.jpg 768w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-1536x1151.jpg 1536w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/01\/cover_breakpoints-2048x1535.jpg 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"><\/a><\/p>\n<p id=\"caption-attachment-13189\" class=\"wp-caption-text\">Setting Breakpoints in Different Versions of Python<br \/>Photo by <a href=\"https:\/\/unsplash.com\/photos\/OfBDvcXuA88\">Josh Withers<\/a>, some rights reserved.<\/p>\n<\/div>\n<h2><b>Tutorial overview<\/b><\/h2>\n<p>This tutorial is divided into three parts; they are:<\/p>\n<ul>\n<li>Setting Breakpoints in Python Code\n<ul>\n<li>Invoking the pdb Debugger in Earlier Versions of Python<\/li>\n<li>Using the <code>breakpoint()<\/code> Function in Python 3.7<\/li>\n<\/ul>\n<\/li>\n<li>Writing One\u2019s Own <code>breakpoint()<\/code> Function for Earlier Versions of Python<\/li>\n<li>Limitations of the <code>breakpoint()<\/code> function<\/li>\n<\/ul>\n<h2><b>Setting breakpoints in Python code<\/b><\/h2>\n<p><a href=\"https:\/\/machinelearningmastery.com\/python-debugging-tools\/\">We have previously seen<\/a> that one way of debugging a Python script is to run it in the command line with the Python debugger.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>In order to do so, we would need to use of the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2a0614995212\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-i\">m<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-k \">pdb<\/span><\/span><\/span>\u00a0command that loads the pdb module before executing the Python script. In the same command line interface, we would then follow this by a specific debugger command of choice, such as<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2a1984230321\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">n<\/span><\/span><\/span>\u00a0to move to the next line, or<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2a2951217967\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">s<\/span><\/span><\/span>\u00a0if our intention is to step into a function.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>This method could become quickly cumbersome as the length of the code increases. One way to address this problem and gain better control over where to break your code, is to insert a breakpoint directly into the code.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<h3><b>Invoking the pdb debugger in earlier versions of Python<\/b><\/h3>\n<p>Doing so prior to Python 3.7 would require you to<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2a3590730323\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-r\">import<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-k \">pdb<\/span><\/span><\/span>, and to call<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2a4568619001\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">pdb<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_trace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0at the point in your code where you would like to enter an interactive debugging session.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>If we reconsider, as an example, the code for <a href=\"https:\/\/machinelearningmastery.com\/the-attention-mechanism-from-scratch\/\">implementing the general attention mechanism<\/a>, we can break into the code as follows:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">from numpy import array\r\nfrom numpy import random\r\nfrom numpy import dot\r\nfrom scipy.special import softmax\r\n\r\n# importing the Python debugger module\r\nimport pdb\r\n\r\n# encoder representations of four different words\r\nword_1 = array([1, 0, 0])\r\nword_2 = array([0, 1, 0])\r\nword_3 = array([1, 1, 0])\r\nword_4 = array([0, 0, 1])\r\n\r\n# stacking the word embeddings into a single array\r\nwords = array([word_1, word_2, word_3, word_4])\r\n\r\n# generating the weight matrices\r\nrandom.seed(42)\r\nW_Q = random.randint(3, size=(3, 3))\r\nW_K = random.randint(3, size=(3, 3))\r\nW_V = random.randint(3, size=(3, 3))\r\n\r\n# generating the queries, keys and values\r\nQ = dot(words, W_Q)\r\nK = dot(words, W_K)\r\nV = dot(words, W_V)\r\n\r\n# inserting a breakpoint\r\npdb.set_trace()\r\n\r\n# scoring the query vectors against all key vectors\r\nscores = dot(Q, K.transpose())\r\n\r\n# computing the weights by a softmax operation\r\nweights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n\r\n# computing the attention by a weighted sum of the value vectors\r\nattention = dot(weights, V)\r\n\r\nprint(attention)<\/pre>\n<p>Executing the script now opens up the <code>pdb<\/code> debugger right before we compute the variable <code>scores<\/code>, and we can proceed to issue any debugger commands of choice, such as<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2ab591142266\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">n<\/span><\/span><\/span>\u00a0to move to the next line, or<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2ad644306664\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">c<\/span><\/span><\/span>\u00a0to continue execution:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">\/Users\/mlm\/main.py(33)&lt;module&gt;()\r\n-&gt; scores = dot(Q, K.transpose())\r\n(Pdb) n\r\n&gt; \/Users\/mlm\/main.py(36)&lt;module&gt;()\r\n-&gt; weights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n(Pdb) c\r\n[[0.98522025 1.74174051 0.75652026]\r\n [0.90965265 1.40965265 0.5       ]\r\n [0.99851226 1.75849334 0.75998108]\r\n [0.99560386 1.90407309 0.90846923]]<\/pre>\n<p>Although functional, this is not the most elegant and intuitive approach of inserting a breakpoint into your code. Python 3.7 implements a more straightforward way of doing so, as we shall see next.<\/p>\n<h3><b>Using the breakpoint() function in Python 3.7\u00a0<\/b><\/h3>\n<p>Python 3.7 comes with a built-in<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2af370023656\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0function that enters the Python debugger at the call site (or the point in the code at which the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b0985935759\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0statement is placed).<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>When called, the default implementation of the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b1588441469\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function will call<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b2081255008\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">breakpointhook<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>, which in turn calls the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b3166928155\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">pdb<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_trace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0function. This is convenient because we will not need to<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b4110252678\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-r\">import<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-k \">pdb<\/span><\/span><\/span>\u00a0and call<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b5861907163\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">pdb<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_trace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0explicitly ourselves.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>Let\u2019s reconsider the code for implementing the general attention mechanism, and now introduce a breakpoint via the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b6135065024\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> statement:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">from numpy import array\r\nfrom numpy import random\r\nfrom scipy.special import softmax\r\n\r\n# encoder representations of four different words\r\nword_1 = array([1, 0, 0])\r\nword_2 = array([0, 1, 0])\r\nword_3 = array([1, 1, 0])\r\nword_4 = array([0, 0, 1])\r\n\r\n# stacking the word embeddings into a single array\r\nwords = array([word_1, word_2, word_3, word_4])\r\n\r\n# generating the weight matrices\r\nrandom.seed(42)\r\nW_Q = random.randint(3, size=(3, 3))\r\nW_K = random.randint(3, size=(3, 3))\r\nW_V = random.randint(3, size=(3, 3))\r\n\r\n# generating the queries, keys and values\r\nQ = words @ W_Q\r\nK = words @ W_K\r\nV = words @ W_V\r\n\r\n# inserting a breakpoint\r\nbreakpoint()\r\n\r\n# scoring the query vectors against all key vectors\r\nscores = Q @ K.transpose()\r\n\r\n# computing the weights by a softmax operation\r\nweights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n\r\n# computing the attention by a weighted sum of the value vectors\r\nattention = weights @ V\r\n\r\nprint(attention)<\/pre>\n<p>One advantage of using the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b8007333287\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function is that, in calling the default implementation of<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2b9893798595\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">breakpointhook<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> the value of a new environment variable,<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2ba792632461\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">PYTHONBREAKPOINT<\/span><\/span><\/span>, is consulted. This environment variable can take various values, based on which different operations can be performed.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>For example, setting the value of<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2bb003366010\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">PYTHONBREAKPOINT<\/span><\/span><\/span> to 0 disables all breakpoints. Hence, your code could contain as many breakpoints as necessary, but these can be easily stopped from<span class=\"Apple-converted-space\">\u00a0<\/span>halting the execution of the code without having to remove them physically. If (for example) the name of the script containing the code is <em>main.py<\/em>, we would disable all breakpoints by calling it in the command line interface as follows:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">PYTHONBREAKPOINT=0 python main.py<\/pre>\n<p>Otherwise, we can achieve the same outcome by setting the environment variable in the code itself:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">from numpy import array\r\nfrom numpy import random\r\nfrom scipy.special import softmax\r\n\r\n# setting the value of the PYTHONBREAKPOINT environment variable\r\nimport os\r\nos.environ['PYTHONBREAKPOINT'] = '0'\r\n\r\n# encoder representations of four different words\r\nword_1 = array([1, 0, 0])\r\nword_2 = array([0, 1, 0])\r\nword_3 = array([1, 1, 0])\r\nword_4 = array([0, 0, 1])\r\n\r\n# stacking the word embeddings into a single array\r\nwords = array([word_1, word_2, word_3, word_4])\r\n\r\n# generating the weight matrices\r\nrandom.seed(42)\r\nW_Q = random.randint(3, size=(3, 3))\r\nW_K = random.randint(3, size=(3, 3))\r\nW_V = random.randint(3, size=(3, 3))\r\n\r\n# generating the queries, keys and values\r\nQ = words @ W_Q\r\nK = words @ W_K\r\nV = words @ W_V\r\n\r\n# inserting a breakpoint\r\nbreakpoint()\r\n\r\n# scoring the query vectors against all key vectors\r\nscores = Q @ K.transpose()\r\n\r\n# computing the weights by a softmax operation\r\nweights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n\r\n# computing the attention by a weighted sum of the value vectors\r\nattention = weights @ V\r\n\r\nprint(attention)<\/pre>\n<p>The value of<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2be067918154\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">PYTHONBREAKPOINT<\/span><\/span><\/span> is consulted every time that<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2bf952661080\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">breakpointhook<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> is called. This means that the value of this environment variable can be changed during the code execution and the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c0638422800\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function would respond accordingly. <span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>The<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c1234807166\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-v\">PYTHONBREAKPOINT<\/span><\/span><\/span> environment variable can also be set to other values, such as to the name of a callable. Say, for instance, that we\u2019d like to use a different Python debugger other than pdb, such as ipdb (run<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c2367208105\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">install <\/span><span class=\"crayon-v\">ipdb<\/span><\/span><\/span>\u00a0first, if the debugger has not yet been installed). In this case, we would call the <em>main.py<\/em> script in the command line interface, and hook the debugger without making any changes to the code itself:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">PYTHONBREAKPOINT=ipdb.set_trace python main.py<\/pre>\n<p>In doing so, the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c4724916945\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function enters the ipdb debugger at the next call site:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy37\/main.py(33)&lt;module&gt;()\r\n     32 # scoring the query vectors against all key vectors\r\n---&gt; 33 scores = Q @ K.transpose()\r\n     34 \r\n\r\nipdb&gt; n\r\n&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy37\/main.py(36)&lt;module&gt;()\r\n     35 # computing the weights by a softmax operation\r\n---&gt; 36 weights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n     37 \r\n\r\nipdb&gt; c\r\n[[0.98522025 1.74174051 0.75652026]\r\n [0.90965265 1.40965265 0.5       ]\r\n [0.99851226 1.75849334 0.75998108]\r\n [0.99560386 1.90407309 0.90846923]]<\/pre>\n<p>The function can also take input arguments as,<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c6880957912\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-v\">args<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-o\">*<\/span><span class=\"crayon-v\">kws<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>, which are then passed on to<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c7262569364\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-k \">sys<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">breakpointhook<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>. This is because any callable (such as a third party debugger module) might accept optional arguments, which can be passed through the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c8618617070\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<h2><b>Writing your own breakpoint() function in earlier versions of Python<\/b><\/h2>\n<p>Let\u2019s return to the fact that versions of Python earlier than v3.7 do not come with the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2c9484635724\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function readily built in. We can write our own.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>Similarly to how the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2ca759871832\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function is implemented from Python 3.7 onwards, we can implement a function that checks the value of an environment variable and:<\/p>\n<ul>\n<li>Skips all breakpoints in the code if the value of the environment variable is set to 0.<\/li>\n<li>Enters into the default Python pdb debugger if the environment variable is an empty string.<\/li>\n<li>Enters into another debugger as specified by the value of the environment variable.<span class=\"Apple-converted-space\">\u00a0<\/span>\n<\/li>\n<\/ul>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n\r\n# defining our breakpoint() function\r\ndef breakpoint(*args, **kwargs):\r\n    import importlib\r\n    # reading the value of the environment variable\r\n    val = os.environ.get('PYTHONBREAKPOINT')\r\n    # if the value has been set to 0, skip all breakpoints\r\n    if val == '0':\r\n        return None\r\n    # else if the value is an empty string, invoke the default pdb debugger\r\n    elif len(val) == 0:\r\n        hook_name = 'pdb.set_trace'\r\n    # else, assign the value of the environment variable\r\n    else:\r\n        hook_name = val\r\n    # split the string into the module name and the function name\r\n    mod, dot, func = hook_name.rpartition('.')\r\n    # get the function from the module\r\n    module = importlib.import_module(mod)\r\n    hook = getattr(module, func)\r\n\r\n    return hook(*args, **kwargs)\r\n\r\n...<\/pre>\n<p>We can include this function into the code and run it (using a Python 2.7 interpreter, in this case). If we set the value of the environment variable to an empty string, we find that the pdb debugger stops at the point in the code at which we have placed our<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2cc696490581\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function. We can then issue debugger commands into the command line from there onwards:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">from numpy import array\r\nfrom numpy import random\r\nfrom numpy import dot\r\nfrom scipy.special import softmax\r\n\r\n# setting the value of the environment variable\r\nimport os\r\nos.environ['PYTHONBREAKPOINT'] = ''\r\n\r\n\r\n# defining our breakpoint() function\r\ndef breakpoint(*args, **kwargs):\r\n    import importlib\r\n    # reading the value of the environment variable\r\n    val = os.environ.get('PYTHONBREAKPOINT')\r\n    # if the value has been set to 0, skip all breakpoints\r\n    if val == '0':\r\n        return None\r\n    # else if the value is an empty string, invoke the default pdb debugger\r\n    elif len(val) == 0:\r\n        hook_name = 'pdb.set_trace'\r\n    # else, assign the value of the environment variable\r\n    else:\r\n        hook_name = val\r\n    # split the string into the module name and the function name\r\n    mod, dot, func = hook_name.rpartition('.')\r\n    # get the function from the module\r\n    module = importlib.import_module(mod)\r\n    hook = getattr(module, func)\r\n\r\n    return hook(*args, **kwargs)\r\n\r\n\r\n# encoder representations of four different words\r\nword_1 = array([1, 0, 0])\r\nword_2 = array([0, 1, 0])\r\nword_3 = array([1, 1, 0])\r\nword_4 = array([0, 0, 1])\r\n\r\n# stacking the word embeddings into a single array\r\nwords = array([word_1, word_2, word_3, word_4])\r\n\r\n# generating the weight matrices\r\nrandom.seed(42)\r\nW_Q = random.randint(3, size=(3, 3))\r\nW_K = random.randint(3, size=(3, 3))\r\nW_V = random.randint(3, size=(3, 3))\r\n\r\n# generating the queries, keys and values\r\nQ = dot(words, W_Q)\r\nK = dot(words, W_K)\r\nV = dot(words, W_V)\r\n\r\n# inserting a breakpoint\r\nbreakpoint()\r\n\r\n# scoring the query vectors against all key vectors\r\nscores = dot(Q, K.transpose())\r\n\r\n# computing the weights by a softmax operation\r\nweights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n\r\n# computing the attention by a weighted sum of the value vectors\r\nattention = dot(weights, V)\r\n\r\nprint(attention)<\/pre>\n<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(32)breakpoint()-&gt;None\r\n-&gt; return hook(*args, **kwargs)\r\n(Pdb) n\r\n&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(59)&lt;module&gt;()\r\n-&gt; scores = dot(Q, K.transpose())\r\n(Pdb) n\r\n&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(62)&lt;module&gt;()\r\n-&gt; weights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n(Pdb) c\r\n[[0.98522025 1.74174051 0.75652026]\r\n [0.90965265 1.40965265 0.5       ]\r\n [0.99851226 1.75849334 0.75998108]\r\n [0.99560386 1.90407309 0.90846923]]<\/pre>\n<p>Similarly, if we set the environment variable to:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">os.environ['PYTHONBREAKPOINT'] = 'ipdb.set_trace'<\/pre>\n<p>The<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2d0286329561\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function that we have implemented now enters the ipdb debugger and stops at the call site:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(31)breakpoint()\r\n     30 \r\n---&gt; 31     return hook(*args, **kwargs)\r\n     32 \r\n\r\nipdb&gt; n\r\n&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(58)&lt;module&gt;()\r\n     57 # scoring the query vectors against all key vectors\r\n---&gt; 58 scores = dot(Q, K.transpose())\r\n     59 \r\n\r\nipdb&gt; n\r\n&gt; \/Users\/Stefania\/Documents\/PycharmProjects\/BreakpointPy27\/main.py(61)&lt;module&gt;()\r\n     60 # computing the weights by a softmax operation\r\n---&gt; 61 weights = softmax(scores \/ K.shape[1] ** 0.5, axis=1)\r\n     62 \r\n\r\nipdb&gt; c\r\n[[0.98522025 1.74174051 0.75652026]\r\n [0.90965265 1.40965265 0.5       ]\r\n [0.99851226 1.75849334 0.75998108]\r\n [0.99560386 1.90407309 0.90846923]]<\/pre>\n<p>Setting the environment variable to 0, simply skips all breakpoints and the computed attention output is returned in the command line, as expected:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">os.environ['PYTHONBREAKPOINT'] = '0'<\/pre>\n<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">[[0.98522025 1.74174051 0.75652026]\r\n [0.90965265 1.40965265 0.5       ]\r\n [0.99851226 1.75849334 0.75998108]\r\n [0.99560386 1.90407309 0.90846923]]<\/pre>\n<p>This facilitates the process of breaking into the code for Python versions earlier than v3.7, because it now becomes a matter of setting the value of an environment variable, rather than having to manually introduce (or remove) the<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2d4020445890\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-r\">import<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-k \">pdb<\/span><span class=\"crayon-sy\">;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-k \">pdb<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">set_trace<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span>\u00a0statement at different call sites in the code.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<h2>Limitations of the <code>breakpoint()<\/code> function<\/h2>\n<p>The <code>breakpoint()<\/code> function allows you to bring in the debugger at some point of the program. You need to find the exact position that you need the debugger to put the breakpoint into it. If you consider the following code:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">try:\r\n    func()\r\nexcept:\r\n    breakpoint()\r\n    print(\"exception!\")<\/pre>\n<p>this will bring you the debugger when the function <code>func()<\/code> raised exceptions. It can triggered by the function itself, or deep inside some other functions that it calls. But the debugger will start at the line <code>print(\"exception!\")<\/code> above. Which may not be very useful.<\/p>\n<p>The way that we can bring up the debugger at the point of exception is called the <strong>post-mortem debugger<\/strong>. It works by asking Python to register the debugger <code>pdb.pm()<\/code> as the exception handler when uncaught exception is raised. When it is called, it will look for the last exception raised and start the debugger at that point. To use the post-mortem debugger, we just need to add the following code before the program is run:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import sys\r\nimport pdb\r\n\r\ndef debughook(etype, value, tb):\r\n    pdb.pm() # post-mortem debugger\r\nsys.excepthook = debughook<\/pre>\n<p>This is handy because nothing else need to be changed in the program. As an example, assume we want to evaluate the average of $1\/x$ using the following program. It is quite easy to overlook some corner cases but we can catch the issue when an exception is raised:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import sys\r\nimport pdb\r\nimport random\r\n\r\ndef debughook(etype, value, tb):\r\n    pdb.pm() # post-mortem debugger\r\nsys.excepthook = debughook\r\n\r\n# Experimentally find the average of 1\/x where x is a random integer in 0 to 9999\r\nN = 1000\r\nrandomsum = 0\r\nfor i in range(N):\r\n    x = random.randint(0,10000)\r\n    randomsum += 1\/x\r\n\r\nprint(\"Average is\", randomsum\/N)<\/pre>\n<p>when we run the above program, the program may terminate or it may raise a division by zero exception, depends on whether the random number generator ever produces zero in the loop. In that case, we may see the following:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">&gt; \/Users\/mlm\/py_pmhook.py(17)&lt;module&gt;()\r\n-&gt; randomsum += 1\/x\r\n(Pdb) p i\r\n16\r\n(Pdb) p x\r\n0<\/pre>\n<p>which we found the exception is raised at which line and we can check the value of the variables as we can usually do in <code>pdb<\/code>.<\/p>\n<p>In fact, it is more convenient to print the traceback and the exception when the post-mortem debugger is launched:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import sys\r\nimport pdb\r\nimport traceback\r\n\r\ndef debughook(etype, value, tb):\r\n    traceback.print_exception(etype, value, tb)\r\n    print() # make a new line before launching post-mortem\r\n    pdb.pm() # post-mortem debugger\r\nsys.excepthook = debughook<\/pre>\n<p>and the debugger session will be started as follows:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">Traceback (most recent call last):\r\n  File \"\/Users\/mlm\/py_pmhook.py\", line 17, in &lt;module&gt;\r\n    randomsum += 1\/x\r\nZeroDivisionError: division by zero\r\n\r\n&gt; \/Users\/mlm\/py_pmhook.py(17)&lt;module&gt;()\r\n-&gt; randomsum += 1\/x\r\n(Pdb)<\/pre>\n<\/p>\n<h2><b>Further Reading<\/b><\/h2>\n<p>This section provides more resources on the topic if you are looking to go deeper.<\/p>\n<h3><b>Websites<\/b><\/h3>\n<ul>\n<li>Python pdb module, <a href=\"https:\/\/docs.python.org\/3\/library\/pdb.html\">https:\/\/docs.python.org\/3\/library\/pdb.html<\/a>\n<\/li>\n<li>Python built-in breakpoint(), <a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0553\/\">https:\/\/www.python.org\/dev\/peps\/pep-0553\/<\/a>\n<\/li>\n<\/ul>\n<h2><b>Summary<\/b><\/h2>\n<p>In this tutorial, you discovered various ways of setting breakpoints in different versions of Python.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>Specifically, you learned:<\/p>\n<ul>\n<li>How to invoke the pdb debugger in earlier versions of Python.<span class=\"Apple-converted-space\">\u00a0<\/span>\n<\/li>\n<li>How to make use of the new, built-in<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2e9148817338\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function introduced in Python 3.7.<span class=\"Apple-converted-space\">\u00a0<\/span>\n<\/li>\n<li>How to write your own<br \/>\n\t\t\t<span id=\"urvanov-syntax-highlighter-61f195589a2eb963449807\" class=\"urvanov-syntax-highlighter-syntax urvanov-syntax-highlighter-syntax-inline  crayon-theme-classic crayon-theme-classic-inline urvanov-syntax-highlighter-font-monaco\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important;\"><span class=\"crayon-pre urvanov-syntax-highlighter-code\" style=\"font-size: 12px !important; line-height: 15px !important;font-size: 12px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\"><span class=\"crayon-e\">breakpoint<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/span><\/span> function to simplify the debugging process in earlier versions of Python.<\/li>\n<\/ul>\n<p>Do you have any questions?<\/p>\n<p>Ask your questions in the comments below and I will do my best to answer.<\/p>\n<p>The post <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/setting-breakpoints-and-exception-hooks-in-python\/\">Setting Breakpoints and Exception Hooks in Python<\/a> appeared first on <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/\">Machine Learning Mastery<\/a>.<\/p>\n<\/div>\n<p><a href=\"https:\/\/machinelearningmastery.com\/setting-breakpoints-and-exception-hooks-in-python\/\">Go to Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Stefania Cristina There are different ways of debugging code in Python, one of which is to introduce breakpoints into the code at points where [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/www.aiproblog.com\/index.php\/2022\/01\/27\/setting-breakpoints-and-exception-hooks-in-python\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":5381,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/5380"}],"collection":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/comments?post=5380"}],"version-history":[{"count":0,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/5380\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media\/5381"}],"wp:attachment":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media?parent=5380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/categories?post=5380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/tags?post=5380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}