{"id":5536,"date":"2012-09-12T20:46:09","date_gmt":"2012-09-13T00:46:09","guid":{"rendered":"http:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=5536"},"modified":"2022-06-05T02:11:23","modified_gmt":"2022-06-05T06:11:23","slug":"16-de","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/16-de\/","title":{"rendered":"16: Rekursion"},"content":{"rendered":"<p>Wir haben gesehen, dass Funktionen es uns erlauben, Teile unseres Codes zu organisieren und wiederzuverwenden. Wir haben au\u00dferdem auch gesehen, dass Funktionen unter Verwendung anderer Funktionen definiert werden k\u00f6nnen. In dieser Lektion lernen wir, dass eine Funktion mit sich selbst definiert werden kann! Diese sehr hilfreiche Herangehensweise nennt man Rekursion. Ger\u00fcchte sagen: \"Um Rekursion zu verstehen, musst du zuerst Rekursion verstehen.\"<\/p>\n<h1>Beispiel<\/h1>\n<p>In unserer <a href=\"http:\/\/cscircles.cemc.uwaterloo.ca\/7c-de\/\">Lektion zu Schleifen<\/a> verwendeten wir eine <code>while<\/code> Schleife, um die folgende Ausgabe zu erzeugen.<\/p>\n<pre>5\n4\n3\n2\n1\nBlastoff!<\/pre>Hier ist ein Programm, das Rekursion verwendet, um den selben Effekt zu erzielen.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform0\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox0'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Ein Countdown, der Rekursion verwendet.<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 214px;'><textarea wrap='off' name='usercode0' id='usercode0'  cols=10 rows=8 readonly='readonly'  style = 'height : 214px;'  class='pyboxCode RO'>\ndef countdown(n):\n  if n == 0:\n    print('Blastoff!')\n  else:\n    print(n)\n    countdown(n - 1)\n\ncountdown(5)<\/textarea><\/div>\n<div id='pbhistory0' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit0' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(0)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(0,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse0\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"0\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"fb83afad73e49bd03eb146e614438f7c\"\/>\n<div id='pbresults0' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit0\").value = \"Run program\";document.getElementById(\"inputInUse0\").value = \"N\";<\/script>\n<\/p>\n<p>Lass uns ein paar zus\u00e4tzliche print Statements hinzuf\u00fcgen, damit wir verstehen, wie das Programm funktioniert. Diese Version des Programms holt sich au\u00dferdem den Startwert f\u00fcr den Countdown als Input.<br \/>\n<form class=\"pbform\" action=\"#\" id=\"pbform1\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox1'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Ein Countdown, der Rekursion verwendet.<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 292px;'><textarea wrap='off' name='usercode1' id='usercode1'  cols=10 rows=11 readonly='readonly'  style = 'height : 292px;'  class='pyboxCode RO'>\ndef countdown(n):\n  print('Entering countdown(',n,')')\n  if n == 0:\n    print('Blastoff!')\n  else:\n    print(n)\n    countdown(n - 1)\n  print('Exiting from countdown(',n,')')\n\nlimit = int(input())\ncountdown(limit)<\/textarea><\/div>\n<div id='pbhistory1' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput1\">You may enter input for the program in the box below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit1' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch1\" value=\"Input Switch\" onclick=\"pbInputSwitch(1,'N')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(1)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(1,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse1\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"1\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"05187437d86d37a181341f0ec0c7c999\"\/>\n<div id='pbresults1' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>pbInputSwitch(1,\"N\");<\/script>\n<\/p>\n<p>Wenn du m\u00f6chtest, kannst du <strong>Teststatements eingeben<\/strong> beim obigen Programm verwenden, um andere Eingaben auszuprobieren. Versuche es zuerst mit <code>0<\/code> und schau, was passiert, danach mit <code>1<\/code>.<\/p>\n<p>Wenn die Eingabe <code>5<\/code> ist, ruft das Programm zuerst eine Kopie der <code>countdown<\/code> Funktion auf mit <code>n=5<\/code>, was <code>5<\/code> ausgibt und <code>countdown(4)<\/code> aufruft. Dies wird fortgef\u00fchrt bis <code>countdown(0)<\/code>, welches <code>\"Blastoff!\"<\/code> ausgibt und <code>countdown<\/code> nicht mehr aufruft. Wenn Python damit fertig ist, den <code>n=0<\/code> Aufruf der <code>countdown<\/code> Funktion auszuf\u00fchren, kehrt Python zu der Funktion zur\u00fcck, die ihn urspr\u00fcnglich aufgerufen hat, n\u00e4mlich der <code>n=1<\/code> Aufruf von <code>countdown<\/code>. Dann kehren wir zur\u00fcck zum <code>n=2<\/code> Aufruf und so weiter.<\/p>\n<p>Um unser Verst\u00e4ndnis doppelt zu pr\u00fcfen, k\u00f6nnen wir auch den rekursiven Code visualisieren:<\/p>\n<p><iframe width='100%' height='480' frameborder='0' scrolling='no' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/OnlinePythonTutor3-cemc\/iframe-embed.html#code=def+countdown%28n%29%3A%0A++if+n+%3D%3D+0%3A%0A++++print%28%27Blastoff%21%27%29%0A++else%3A%0A++++print%28n%29%0A++++countdown%28n+-+1%29%0A%0Acountdown%283%29&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=3&curInstr=0&resizeContainer=true&highlightLines&width=400&rightStdout=1'><\/iframe><\/p>\n<p>Die n\u00e4chste Wendung, die die Rekursion einzigartig macht gegen\u00fcber denen, die wir vorher gesehen haben, ist,<br \/>\ndass mehrere Versionen der Funktion gleichzeitig laufen. Sozusagen korrespondiert jeweils mehr als ein Rahmen mit der gleichen Funktion. Dies ist so ziemlich das gleiche wie <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/10-de\/#funcfunc\">was wir in der Visualisierung sahen, wo eine Funktion eine andere aufrief<\/a>, nur ist jetzt die aufrufende und die aufgerufte Funktion die gleiche. Allerdings musst du vorsichtig sein um festzustellen, dass bei jedem Schritt nur die \"aktuellen\" Variablen (der neuste\/ganz untere Rahmen) wirklich benutzt werden \u2014 die nichtunteren Rahmen sind \"angehalten\" und ihre Variablen unzug\u00e4nglich.<\/p>\n<p>Jetzt bist du an der Reihe, Code zu schreiben. Modifiziere die <code>countdown<\/code> Funktion so, dass sie aufsteigend z\u00e4hlt anstatt absteigend.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform2\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox2'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Blast Up<\/span><\/div>Schreibe eine rekursive Funktion <code>countup(n)<\/code>, die 'Blastoff!' ausgibt, und im Anschluss die Zahlen <code>1<\/code> bis <code>n<\/code> in eigenen Zeilen. <a class=\"hintlink\"  id=\"hintlink3\">Tipp<\/a><div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode2' id='usercode2'  cols=10 rows=20   class='pyboxCode RW'>\ndef countdown(n):\n  if n == 0:\n    print('Blastoff!')\n  else:\n    print(n)\n    countdown(n - 1)\n<\/textarea><\/div>\n<div id='pbhistory2' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput2\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<input type='hidden' id='defaultCode2' value='def countdown(n):\\n  if n == 0:\\n    print(\\u0027Blastoff!\\u0027)\\n  else:\\n    print(n)\\n    countdown(n - 1)\\n'><\/input>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit2' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch2\" value=\"Input Switch\" onclick=\"pbInputSwitch(2,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(2)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(2,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect2' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(2,'16.countup')\" >History<\/option>\n<option name='default' data-pbonclick=\"pbSetText(2,descape($('#defaultCode2').val()))\" >Reset code to default<\/option>\n<option name='help' data-pbonclick=\"helpClick(2);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse2\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"2\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"c80791b162429ab17543828679673713\"\/>\n<div id='pbresults2' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(2);});pbInputSwitch(2,\"Y\");<\/script>\n<\/p>\n<p>Lass uns als n\u00e4chstes unser <code>countdown<\/code> Programm so modifizieren, dass wir in 2er-Schritten z\u00e4hlen. Die Ausgabe sollte 5, 3, 1, Blastoff! sein. Wir werden das Funktionsargument von <code>n-1<\/code> zu <code>n-2<\/code> \u00e4ndern. Gibt es noch etwas anderes, das ge\u00e4ndert werden muss?<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform4\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox4'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Versuche, in Zweierschritten herunterzuz\u00e4hlen<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 214px;'><textarea wrap='off' name='usercode4' id='usercode4'  cols=10 rows=8 readonly='readonly'  style = 'height : 214px;'  class='pyboxCode RO'>\ndef countdownBy2(n):\n  if n == 0:\n    print('Blastoff!')\n  else:\n    print(n)\n    countdownBy2(n - 2)\n\ncountdownBy2(5)<\/textarea><\/div>\n<div id='pbhistory4' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit4' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(4)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(4,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse4\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"4\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"33f97a92cecd10ba94680c59d48b6f7c\"\/>\n<div id='pbresults4' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit4\").value = \"Run program\";document.getElementById(\"inputInUse4\").value = \"N\";<\/script>\n<\/p>\n<p>Wie du sehen kannst, hat dieses Programm nicht so funktioniert, wie wir das wollten. Es hat <code>5, 3, 1<\/code>, wie geplant ausgedruckt, aber statt inne zu halten, hat es weitergemacht mit <code>-1, -3, -5<\/code> und lief dann endlos weiter. (Genau genommen ben\u00f6tigt es nicht nur zuviel Zeit, sondern auch zuviel Speicher, da jeder rekursive Aufruf ein bi\u00dfchen mehr Arbeitsspeicher ben\u00f6tigt.)<\/p>\n<p>Wenn wir eine rekursive Funktion entwerfen, m\u00fcssen wir vorsichtig sein, dass ihre Folge von Aufrufen nicht ewig l\u00e4uft! Ver\u00e4ndere das <code>countdownBy2<\/code> Programm oben so, dass es korrekt bei 1 (oder 2, wenn <code>n<\/code> gerade ist) stoppt und 'Blastoff!' ausdruckt.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform5\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox5'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Double Time<\/span><\/div>Ver\u00e4ndere dieses rekursive Programm so, dass es korrekt in Zweierschritten herunter z\u00e4hlt.<div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode5' id='usercode5'  cols=10 rows=20   class='pyboxCode RW'>\ndef countdownBy2(n):\n  if n == 0:\n    print('Blastoff!')\n  else:\n    print(n)\n    countdownBy2(n - 2)\n# delete this comment and enter your code here\n<\/textarea><\/div>\n<div id='pbhistory5' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput5\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<input type='hidden' id='defaultCode5' value='def countdownBy2(n):\\n  if n == 0:\\n    print(\\u0027Blastoff!\\u0027)\\n  else:\\n    print(n)\\n    countdownBy2(n - 2)\\n'><\/input>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit5' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch5\" value=\"Input Switch\" onclick=\"pbInputSwitch(5,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(5)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(5,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect5' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(5,'16.countdownby2')\" >History<\/option>\n<option name='default' data-pbonclick=\"pbSetText(5,descape($('#defaultCode5').val()))\" >Reset code to default<\/option>\n<option name='help' data-pbonclick=\"helpClick(5);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse5\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"5\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"a0d30268364f5b9dadb8a2727df0bf57\"\/>\n<div id='pbresults5' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(5);});pbInputSwitch(5,\"Y\");<\/script>\n<\/p>\n<h1>Rekursive Funktionen entwerfen<\/h1>\n<p>Eine <em>rekursive Funktion<\/em> ist lediglich eine Funktion, die sich selbst aufruft. Aber es muss einige Gelegenheiten geben, bei denen die Funktion sich nicht selbst aufruft, oder das Programm w\u00fcrde ewig laufen, wie wir das oben gesehen haben. Ein <strong>grunds\u00e4tzlicher Fall<\/strong> ist der Teil einer rekursiven Funktion, wo es sich nicht selbst aufruft. Im Beispiel oben ist es so, dass der grunds\u00e4tzliche Fall <code>n&lt;=0<\/code> war. Bei der Entwerfung einer rekursiven Funktion erfordert es, dass du vorsichtig einen grunds\u00e4tzlichen Fall ausw\u00e4hlst und sicherstellst, dass jede Funktionssequenz irgendwann einen grunds\u00e4tzlichen Fall erreicht.<\/p>\n<p>In der n\u00e4chsten \u00dcbung wurde der grunds\u00e4tzliche Fall schonmal f\u00fcr dich programmiert, aber du wirst den Rest der rekursiven Funktion schreiben.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform6\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox6'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Quersumme<\/span><\/div>Die <em>Quersumme<\/em> (englisch: digital sum) einer Zahl <code>n<\/code> ist die Summe der Ziffern, aus denen sie besteht. Schreibe eine rekursive Funktion <code>digitalSum(n)<\/code>, die eine positive Ganzzahl <code>n<\/code> nimmt und ihre Quersumme ausgibt. Zum Beispiel sollte <code>digitalSum(2019)<\/code> 12 ausgeben, weil 2+0+1+9=12. <a class=\"hintlink\"  id=\"hintlink7\">Tipp #1<\/a> <a class=\"hintlink\"  id=\"hintlink8\">Tipp #2<\/a><div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode6' id='usercode6'  cols=10 rows=20   class='pyboxCode RW'>\ndef digitalSum(n):\n  if n &lt; 10:\n return n\n else:\n # recursive case\n# delete this comment and enter your code here\n<\/textarea><\/div>\n<div id='pbhistory6' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput6\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<input type='hidden' id='defaultCode6' value='def digitalSum(n):\\n  if n < 10:\\n return n\\n else:\\n # recursive case\\n'><\/input>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit6' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch6\" value=\"Input Switch\" onclick=\"pbInputSwitch(6,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(6)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(6,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect6' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(6,'16.digitalsum')\" >History<\/option>\n<option name='default' data-pbonclick=\"pbSetText(6,descape($('#defaultCode6').val()))\" >Reset code to default<\/option>\n<option name='help' data-pbonclick=\"helpClick(6);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse6\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"6\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"fd840412e8a2abcee0f05acf2439c4ac\"\/>\n<div id='pbresults6' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(6);});pbInputSwitch(6,\"Y\");<\/script>\n<\/p>\n<p>Nun wirst du eine rekursive Funktion schreiben, die <code>Quersumme<\/code> als Subroutine aufruft.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform9\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox9'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Einstellige Quersumme<\/span><\/div> Die einstellige Quersumme (englisch: digital root) einer nicht-negativen Ganzzahl <code>n<\/code> wird folgenderma\u00dfen berechnet. Beginne damit, die Ziffern von <code>n<\/code> aufzuaddieren. Die Ziffern der Zahl, die daraus resultiert, werden dann aufsummiert und dieser Prozess wird fortgesetzt, bis eine einstellige Zahl erreicht wird. Zum Beispiel ist die einstellige Quersumme von 2019 gleich 3 weil 2+0+1+9=12 und 1+2=3. Schreibe eine rekursive Funktion <code>digitalRoot(n)<\/code>, welche die einstellige Quersumme von <code>n<\/code> ausgibt.<br\/><strong>Nimm an,<\/strong> dass eine Arbeitsdefinition von <code>digitalSum<\/code> f\u00fcr dein Programm angegeben wird.<div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode9' id='usercode9'  cols=10 rows=20   class='pyboxCode RW'>\n# delete this comment and enter your code here\n<\/textarea><\/div>\n<div id='pbhistory9' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput9\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit9' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch9\" value=\"Input Switch\" onclick=\"pbInputSwitch(9,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(9)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(9,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect9' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(9,'16.digitalroot')\" >History<\/option>\n<option name='help' data-pbonclick=\"helpClick(9);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse9\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"9\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"814f59826685f86e6d0305d26f00444c\"\/>\n<div id='pbresults9' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(9);});pbInputSwitch(9,\"Y\");<\/script>\n<\/p>\n<h1>\u00dcbungen<\/h1>\n<div class='pybox modeNeutral' id='pybox10'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Short Answer Exercise: <\/span><span class='title'>GGT<\/span><\/div>Was ist die Ausgabe des folgenden rekursiven Programms?<\/p>\n<pre>def ggT(a, b):\n  if b == 0: return a\n  return ggT(b, a % b)\nprint(ggT(20, 12))<\/pre><label for=\"pyShortAnswer10\">Your answer (enter a number): <\/label><input type=\"text\" onkeypress=\"{if (event.keyCode==13) pbShortCheck(10)}\" id=\"pyShortAnswer10\"><div class=\"pyboxbuttons\"><input type=\"hidden\" name=\"type\" value=\"number\"\/><input type=\"hidden\" name=\"correct\" value=\"4\"\/><input type=\"hidden\" name=\"slug\" value=\"16.shortgcd\"\/><input type=\"hidden\" name=\"lang\" value=\"\"\/><input type='submit' style='margin:5px;' value='Check answer' onClick = 'pbShortCheck(10)'\/><\/div><div class=\"pbresults\" id=\"pyShortResults10\"><\/div><div class=\"epilogue\">Korrekt! Dieses auff\u00e4llig kurze Programm berechnet den gr\u00f6\u00dften gemeinsamen Teiler von zwei Zahlen und ist bekannt als <a href=\"https:\/\/de.wikipedia.org\/wiki\/Euklidischer_Algorithmus\">Euklidischer Algorithmus<\/a>, einer der \u00e4ltesten bekannten Algorithmen.<\/div><\/div>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform11\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox11'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Collatz-Folge<\/span><\/div>Die <em>Collatz-Folge<\/em>, die mit einer positiven Ganzzahl <code>n<\/code> beginnt, wird erzeugt, indem man zwei einfache Regeln befolgt. Wenn <code>n<\/code> gerade ist, ist die n\u00e4chste Zahl in der Folge <code>n\/2<\/code>. Wenn <code>n<\/code> ungerade ist, ist die n\u00e4chste Zahl in der Folge <code>3*n+1<\/code>. Wenn wir den Prozess wiederholen, erzeugen wir die Collatz-Folge, die auf Englisch <code>hailstone sequence<\/code> hei\u00dft. Schreibe eine rekursive Funktion <code>hailstone(n)<\/code>, welche die Collatz-Folge erzeugt, beginnend bei <code>n<\/code>. H\u00f6re auf, wenn die Sequenz die Zahl <code>1<\/code> erreicht (sonst w\u00fcrden wir ewig in einem 1, 4, 2, 1, 4, 2, ... loop stecken bleiben) <br\/> Zum Beispiel, wenn <code>n=5<\/code>, sollte Dein Programm die folgende Folge ausgeben:<\/p>\n<pre>5\n16\n8\n4\n2\n1<\/pre><div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode11' id='usercode11'  cols=10 rows=20   class='pyboxCode RW'>\n# delete this comment and enter your code here\n<\/textarea><\/div>\n<div id='pbhistory11' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput11\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit11' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch11\" value=\"Input Switch\" onclick=\"pbInputSwitch(11,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(11)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(11,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect11' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(11,'16.hailstone')\" >History<\/option>\n<option name='help' data-pbonclick=\"helpClick(11);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse11\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"11\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"da411df42e188cbfecb772c08307194f\"\/>\n<div id='pbresults11' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(11);});pbInputSwitch(11,\"Y\");<\/script>\n<\/p>\n<p>Mathematiker glauben, dass jede Collatz-Folge irgendwann <code>1<\/code> erreicht, egal, mit welchem Wert von <code>n<\/code> wir anfangen. Es hat jedoch noch keiner beweisen k\u00f6nnen.<\/p>\n<h2>Verschachtelte Listen<\/h2>\n<p>Hier ist eine interessante nat\u00fcrliche Anwendung von Rekursion. Eine <em>verschachtelte Liste<\/em> ist eine, wo man Listen in andere Listen verpackt, m\u00f6glicherweise mehrmals. Zum Beispiel sind verschachtelte Listen von Integers <code>[[1, 2], [9, 10]]<\/code> sowie <code>[[1], 2]<\/code> und <code>x = [[1], 2, [3, [[4]]]]<\/code>. Das letzte Beispiel ist eine Liste mit drei Elementen: <code>x[0]==[1]<\/code> am Anfang, dann <code>x[1]==2<\/code>, dann <code>x[2]==[3, [[4]]]<\/code>. (So hat <code>x<\/code>, gesehen als Liste, L\u00e4nge 3). Beachte, dass eine Liste wie <code>[1, 2, 3]<\/code> auch als verschachtelte Liste gilt. <strong>K\u00f6nnen wir eine Funktion schreiben um die totale Summe <em>jeder beliebigen<\/em> verschachtelten Liste von Integern zu finden?<\/strong> Zum Beispiel sollte sie bei der Eingabe <code>[[5], 2, [10, 8, [[7]]]]<\/code> der Wert <code>32<\/code> zur\u00fcckgeben.<\/p>\n<p>Diese Aufgabe ist schwer f\u00fcr eine <code>while<\/code>- oder <code>for<\/code>-Schleife, da wir eine Funktion wollen, die mit verschachtelten Listen beliebiger Erscheinung\/Form arbeitet. Allerdings haben verschachtelte Listen eine nat\u00fcrliche rekursive Struktur:<br \/>\n<em>eine verschachtelte Liste, wo jedes ihrer Elemente entweder (a) ein Integer oder (b) eine verschachtelte Liste ist<\/em>. Und sobald wir die Summe jedes Unterteils der Hauptliste berechnen, ist die Summe dieser Werte die Gesamtsumme. Wir k\u00f6nnen dies mit dem folgenden Code ausdr\u00fccken; es benutzt <code>isinstance(x, int)<\/code>, das einen boolean-Wert liefert, der uns sagt ob <code>x<\/code> vom Typ Integer ist (im Gegensatz zur Liste).<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform12\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox12'>\n<div class=\"heading\"><span class='type'>Example: <\/span><span class='title'>Summing a Nested List<\/span><\/div>Berechnen der Summe der Elemente in einer verschachtelten Liste. Wenn du <strong>Run<\/strong> dr\u00fcckst, wirst du seine Werte an einigen Tests sehen.<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 214px;'><textarea wrap='off' name='usercode12' id='usercode12'  cols=10 rows=8 readonly='readonly'  style = 'height : 214px;'  class='pyboxCode RO'>\ndef nestedListSum(NL):\n    if isinstance(NL, int):     # case (a): NL is an integer\n        return NL               # base case\n\n    sum = 0                     # case (b): NL is a list of nested lists\n    for i in range(0, len(NL)): # add subsums from each part of the main list\n        sum = sum + nestedListSum(NL[i])\n    return sum                  # all done<\/textarea><\/div>\n<div id='pbhistory12' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput12\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit12' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch12\" value=\"Input Switch\" onclick=\"pbInputSwitch(12,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(12)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(12,'Y')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse12\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"12\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"e05466733f9098e2816e0bd8c90ff497\"\/>\n<div id='pbresults12' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>pbInputSwitch(12,\"Y\");<\/script>\n<\/p>\n<p>Wird Rekursion benutzt um verschachtelte Listen in kleinere Teile zu spalten? Zum Beispiel macht <code>nestedListSum([1, [3, 4], 5])<\/code> insgesamt 6 rekursive Aufrufe: den am Anfang, dann <code>1<\/code>, dann <code>[3, 4]<\/code>, dann <code>3<\/code>, dann <code>4<\/code>, (nach dem <code>[3, 4]<\/code> total als <code>7<\/code> zur\u00fcckgegeben wird) und als letztes bei <code>5<\/code> (nach dem die Gesamtsumme <code>13<\/code> erreicht ist). Hier ist der gleiche Code im Visualisierer.<\/p>\n<p><iframe width='100%' height='480' frameborder='0' scrolling='no' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/OnlinePythonTutor3-cemc\/iframe-embed.html#code=def+nestedListSum%28NL%29%3A%0A++if+isinstance%28NL%2C+int%29%3A%0A++++return+NL%0A%0A++sum+%3D+0%0A++for+i+in+range%280%2C+len%28NL%29%29%3A%0A++++sum+%3D+sum+%2B+nestedListSum%28NL%5Bi%5D%29%0A++return+sum%0A%0A%23+some+examples%0AnestedListSum%28129%29%0AnestedListSum%28%5B400%2C+50%2C+6%5D%29%0AnestedListSum%28%5B%5B1%2C+2%5D%2C+%5B3%2C+4%5D%2C+5%5D%29%0AnestedListSum%28%5B%5B1%2C+%5B2%2C+3%5D%2C+4%2C+5%5D%5D%29&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=3&curInstr=0&resizeContainer=true&highlightLines&width=400&rightStdout=1'><\/iframe><\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform13\" method=\"POST\">\n<div class='pybox modeNeutral ' id='pybox13'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Coding Exercise: <\/span><span class='title'>Searching a Nested List<\/span><\/div>Indem du etwas \u00e4hnliches wie <code>nestedListSum<\/code> schreibst, definiere eine rekursive Funktion <\/p>\n<pre>nestedListContains(NL, target)<\/pre> die eine verschachtelte Liste <code>NL<\/code> von Integern und einen Integer <code>target<\/code> einlie\u00dft und angibt, ob <code>target<\/code> irgendwo in der verschachtelten Liste enthalten ist. Dein Code sollte den boolean-Wert <code>True<\/code> zur\u00fcckgeben, wenn es enthalten ist, wenn nicht, dann <code>False<\/code>.<br\/>Zum Beispiel sollte <code>nestedListContains([1, [2, [3], 4]], 3)<\/code> s<code>True<\/code> ergeben und <code>nestedListContains([1, [2, [3], 4]], 5)<\/code> <code>False<\/code>.<div class=\"helpOuter\" style=\"display: none;\"><div class=\"helpInner\"><div style=\"text-align: center\">You need to create an account and log in to ask a question.<\/div><\/div><\/div><div class='pyboxTextwrap pyboxCodewrap RW resizy'  style='height: 526px;'><textarea wrap='off' name='usercode13' id='usercode13'  cols=10 rows=20   class='pyboxCode RW'>\n# delete this comment and enter your code here\n<\/textarea><\/div>\n<div id='pbhistory13' class='flexcontain' style='display:none;'><\/div>\n<div name=\"pyinput\" id=\"pyinput13\">Enter testing statements like <code>print(myfunction(\"test argument\"))<\/code> below.<div class=\"pyboxTextwrap resizy\" style=\"height: 102px;\" ><textarea wrap=\"off\" name=\"userinput\" class=\"pyboxInput\" cols=10 rows=4><\/textarea><\/div><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit13' value=' '\/><\/td>\n<td><input type='button' name='switch' id=\"switch13\" value=\"Input Switch\" onclick=\"pbInputSwitch(13,'Y')\" ><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(13)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(13,'Y')\" ><\/td>\n<\/tr><\/table><select id='pbSelect13' class='selectmore'><option name='more'>More actions...<\/option>\n<option name='history' data-pbonclick=\"historyClick(13,'17.nestedFind')\" >History<\/option>\n<option name='help' data-pbonclick=\"helpClick(13);\" >Help<\/option>\n<\/select><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse13\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"13\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"2b8315b3bdd904d8e227109f389e8aeb\"\/>\n<div id='pbresults13' class='pbresults avoidline'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>jQuery(function(){pbToggleCodeMirror(13);});pbInputSwitch(13,\"Y\");<\/script>\n<\/p>\n<h2>This Rules<\/h2>\n<p>Rekursion ist auch mit Fraktalen verwandt - Bilder, die mehrere kleinere Kopien ihrer selbst enthalten. Das Banner oben auf dieser Seite ist ein Beispiel. Die n\u00e4chste \u00dcbung f\u00fchrt ein einfaches, sich wiederholendes Muster aus, indem es Rekursion verwendet.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform14\" method=\"POST\">\n<div class='pybox modeNeutral scramble' id='pybox14'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Scramble Exercise: <\/span><span class='title'>Fractal Ruler<\/span><\/div>Entwirre die Zeilen, um ein Programm zu schaffen, das ein rekursives linealartiges Programm hervorbringt. Zum Beispiel, wenn <strong><code>n=3<\/code><\/strong>, sollte das Programm das folgende Design ausgeben.<\/p>\n<pre>-\n--\n-\n---\n-\n--\n-<\/pre><ul class=\"pyscramble\" name=\"pyscramble\" id=\"pyscramble14\">\n <li class=\"pyscramble\">def ruler(n):<\/li>\n <li class=\"pyscramble\">   print(n * &#039;-&#039;)<\/li>\n <li class=\"pyscramble\">   ruler(n - 1)<\/li>\n <li class=\"pyscramble\">  if n == 1:<\/li>\n <li class=\"pyscramble\">   print(&#039;-&#039;)<\/li>\n <li class=\"pyscramble\">  else:<\/li>\n <li class=\"pyscramble\">   ruler(n - 1)<\/li>\n<\/ul>\n<input type='hidden' id='usercode14' name='usercode14'\/>\n<div id='pbhistory14' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit14' value=' '\/><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse14\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"14\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"59abcbc14d1da6ffd9fa45fa4391fda2\"\/>\n<div id='pbresults14' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit14\").value = \"Run program\";document.getElementById(\"inputInUse14\").value = \"N\";<\/script>\n<\/p>\n<p>Gl\u00fcckwunsch! Du bist bereit, zur n\u00e4chsten \u00dcbung zu gehen!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wir haben gesehen, dass Funktionen es uns erlauben, Teile unseres Codes zu organisieren und wiederzuverwenden. Wir haben au\u00dferdem auch gesehen, dass Funktionen unter Verwendung anderer Funktionen definiert werden k\u00f6nnen. In dieser Lektion lernen wir, dass eine Funktion mit sich selbst &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/16-de\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2653,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5536","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5536","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/users\/2653"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=5536"}],"version-history":[{"count":51,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5536\/revisions"}],"predecessor-version":[{"id":15749,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5536\/revisions\/15749"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=5536"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}