-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfunctions-and-recursion.html
More file actions
256 lines (211 loc) · 11.5 KB
/
functions-and-recursion.html
File metadata and controls
256 lines (211 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!DOCTYPE html>
<html lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>5 Functions and Recursion | PHP For The Web: Enough to be Dangerous</title>
<meta name="description" content="A primer on PHP with an emphasis on building for the web." />
<meta name="generator" content="bookdown 0.25 and GitBook 2.6.7" />
<meta property="og:title" content="5 Functions and Recursion | PHP For The Web: Enough to be Dangerous" />
<meta property="og:type" content="book" />
<meta property="og:description" content="A primer on PHP with an emphasis on building for the web." />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="5 Functions and Recursion | PHP For The Web: Enough to be Dangerous" />
<meta name="twitter:description" content="A primer on PHP with an emphasis on building for the web." />
<meta name="author" content="Bryan Hoffman" />
<meta name="date" content="2022-01-01" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="prev" href="loops.html"/>
<link rel="next" href="GET.html"/>
<script src="libs/jquery-3.6.0/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fuse.js@6.4.6/dist/fuse.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-clipboard.css" rel="stylesheet" />
<link href="libs/anchor-sections-1.1.0/anchor-sections.css" rel="stylesheet" />
<link href="libs/anchor-sections-1.1.0/anchor-sections-hash.css" rel="stylesheet" />
<script src="libs/anchor-sections-1.1.0/anchor-sections.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">
<div class="book-summary">
<nav role="navigation">
<ul class="summary">
<li><a href="./">PHP For The Web</a></li>
<li class="divider"></li>
<li class="chapter" data-level="1" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i><b>1</b> Introduction and Prerequisites<span></span></a></li>
<li class="chapter" data-level="2" data-path="printing.html"><a href="printing.html"><i class="fa fa-check"></i><b>2</b> Printing in the Terminal and on the Web<span></span></a></li>
<li class="chapter" data-level="3" data-path="branching.html"><a href="branching.html"><i class="fa fa-check"></i><b>3</b> Branching and Conditionals<span></span></a></li>
<li class="chapter" data-level="4" data-path="loops.html"><a href="loops.html"><i class="fa fa-check"></i><b>4</b> Loops<span></span></a></li>
<li class="chapter" data-level="5" data-path="functions-and-recursion.html"><a href="functions-and-recursion.html"><i class="fa fa-check"></i><b>5</b> Functions and Recursion<span></span></a></li>
<li class="chapter" data-level="6" data-path="GET.html"><a href="GET.html"><i class="fa fa-check"></i><b>6</b> HTTP GET Variables<span></span></a></li>
<li class="chapter" data-level="7" data-path="Forms-and-Files.html"><a href="Forms-and-Files.html"><i class="fa fa-check"></i><b>7</b> Forms and Files<span></span></a></li>
<li class="chapter" data-level="8" data-path="SESSION.html"><a href="SESSION.html"><i class="fa fa-check"></i><b>8</b> SESSION<span></span></a></li>
<li class="chapter" data-level="9" data-path="Next.html"><a href="Next.html"><i class="fa fa-check"></i><b>9</b> What Next?<span></span></a></li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i><a href="./">PHP For The Web: Enough to be Dangerous</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal" id="section-">
<div id="functions-and-recursion" class="section level1 hasAnchor" number="5">
<h1><span class="header-section-number">5</span> Functions and Recursion<a href="functions-and-recursion.html#functions-and-recursion" class="anchor-section" aria-label="Anchor link to header"></a></h1>
<p>A function is a unit of code. You can write a piece of code in a function and give it a name and then use it again and again from different places. It’s wise to create your own functions as your projects get more complex. There are many functions available to you out of the box. We’re going to use one such function “rand()” – a random number generator – to calculate pi using a technique called the Monte Carlo method. Now, of course, getting the value of pi isn’t hard. With PHP,
we could make use of a special variable “M_PI” that you’ll notice lacks the “$” which most php variables begin with. It’ll be fun to use the Monte Carlo method, and we’ll compare our value to M_PI to gauge how accurate our method is.</p>
<p>In your terminal, run <code>>php -a</code> to get access to an interactive shell. I find this useful for trying out snippets of code. Try it yourself. If we simply use rand() we get a bunch of large positive numbers. You can run this multiple times in an interactive session to see what it outputs.</p>
<p><img src="480px-Circle_area_Monte_Carlo_integration2.svg.png" /><!-- --></p>
<p>To calculate pi, I want to generate two numbers to make a coordinate. The range of each random number should be from -1 to 1. We’ll check the coordinate and see if it is inside a circle with radius one. After enough random points are placed, we can tease pi out of the ratio of total points and points inside the circle.</p>
<pre><code><?php
$x=0;
$y=0;
$inside_total = 0;
$total = 0;
for($i = 0; $i < 10000; $i++) {
// generate random numbers in (-10000,10000) and scale to (-1, 1)
$x = rand(-10000,10000)/10000;
$y = rand(-10000,10000)/10000;
// check if the random point is inside the circle
if($x*$x+$y*$y <= 1 ) {
// keep track of points inside the circle
$inside_total++;
}
// keep track of all points
$total++;
}
// estimate pi
$pi_approx = 4*($inside_total/$total);
// calculate error
$error=(($pi_approx-M_PI)/M_PI)*100;
print("Pi is approximately: $pi_approx\n");
print("The error was: ".$error."%\n");</code></pre>
<p>Let’s write our own function now. We’ll continue with something similar to what we did in the Monte Carlo example. Let’s code a function that takes a coordinate and a radius, and returns true if the coordinate is inside a circle of the specified radius and false otherwise. A function like that looks like this:</p>
<pre><code>function inside_circle ($x, $y, $radius) {
if($x*$x+$y*$y <= $radius**2) { // "$a**$b" is $a raised to the power $b
return true;
} else {
return false;
}
}</code></pre>
<p>We use return to pass a result back to wherever the original <strong>call</strong> to the function came from. We can now combine our last two pieces of code into this:</p>
<pre><code><?php
$x=0;
$y=0;
$inside_total = 0;
$total = 0;
// functions need to be declared before they are used
function inside_circle ($x, $y, $radius) {
if($x*$x+$y*$y <= $radius**2) { // "$a**$b" is $a raised to the power $b
return true;
} else {
return false;
}
}
for($i = 0; $i < 10000; $i++) {
// generate random numbers in (-10000,10000) and scale to (-1, 1)
$x = rand(-10000,10000)/10000;
$y = rand(-10000,10000)/10000;
// check if the random point is inside the circle and
// replace the conditional with a call to inside_circle
if(inside_circle($x, $y, 1)) {
// keep track of points inside the circle
$inside_total++;
}
// keep track of all points
$total++;
}
// estimate pi
$pi_approx = 4*($inside_total/$total);
// calculate error
$error=(($pi_approx-M_PI)/M_PI)*100;
print("Pi is approximately: $pi_approx\n");
print("The error was: ".$error."%\n");</code></pre>
<p>If-statements can contain if-statements, loops can contain loops, and functions can contain functions! But functions can do something a bit spooky, a function can call itself from inside itself. This is called <strong>recursion</strong>. Let’s write a recursive function to find the n-th value in the Fibonacci sequence. The Fibonacci sequence begins 1, 1, 2, 3, 5, 8, … and the rule for generating the next term is to add the last two.</p>
<pre><code>function fib($n) {
if($n == 1 || $n == 2) {
return 1;
} else {
return(fib($n-1)+fib($n-2));
}
}</code></pre>
<p>I’ll encourage you to try out the interactive PHP shell once more. Start it by entering <code>>php -a</code> in your terminal. Write the fib() function yourself and then you can call it and print the results you get by typing <code>>echo fib(1);</code></p>
<p>“echo” is just another way to print things in PHP. If you didn’t include “echo” you wouldn’t see anything. Calling fib() just returns a value, but doesn’t do anything with it. Most of the time, you’ll do something with it like store it in a variable or print it.</p>
<p>Exercises:</p>
<ol style="list-style-type: decimal">
<li><p>Write a recursive function to calculate the factorial of a positive integer or zero. It might be helpful to know that 0! is equal to 1.</p></li>
<li><p>Can you modify the code utilizing the Monte Carlo method to calculate pi, and run the simulation in three dimensions or even higher dimensional spaces? Does changing the dimension of the simulation have any impact on the accuracy of the result?</p></li>
</ol>
</div>
</section>
</div>
</div>
</div>
<a href="loops.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="GET.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
</div>
</div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/clipboard.min.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": false,
"facebook": true,
"twitter": true,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"whatsapp": false,
"all": ["facebook", "twitter", "linkedin", "weibo", "instapaper"]
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": null,
"text": null
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": ["PHP For The Web: Enough to be Dangerous by Bryan Hoffman.pdf"],
"search": {
"engine": "fuse",
"options": null
},
"toc": {
"collapse": "subsection"
}
});
});
</script>
</body>
</html>