... | @@ -311,7 +311,8 @@ Modern C++11 and newer provide the `std::transform` method. Combined with |
... | @@ -311,7 +311,8 @@ Modern C++11 and newer provide the `std::transform` method. Combined with |
|
|
|
|
|
Java has the `java.util.stream` package, which provides similar functionality
|
|
Java has the `java.util.stream` package, which provides similar functionality
|
|
to Python comprehensions and C++ `std::transform`. However, in Java, we would
|
|
to Python comprehensions and C++ `std::transform`. However, in Java, we would
|
|
end up dealing with the `Integer` wrapper class if we wanted to use a non-array data structure.
|
|
end up dealing with the `Integer` wrapper class if we wanted to use a non-array
|
|
|
|
data structure.
|
|
|
|
|
|
|
|
|
|
> **Word Count - Java Streams**
|
|
> **Word Count - Java Streams**
|
... | @@ -618,9 +619,12 @@ This leads to a far more concise and readable computation. |
... | @@ -618,9 +619,12 @@ This leads to a far more concise and readable computation. |
|
sum(f_of_x_values))
|
|
sum(f_of_x_values))
|
|
```
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### The Final Main Function
|
|
|
|
|
|
|
|
Now we can tackle the final (and **true**) main function...
|
|
|
|
|
|
```python
|
|
```python
|
|
def main_without_a_table_flip():
|
|
def main_without_a_table_flip():
|
|
"""
|
|
"""
|
... | @@ -650,14 +654,74 @@ def main_without_a_table_flip(): |
... | @@ -650,14 +654,74 @@ def main_without_a_table_flip(): |
|
sum(f_of_x_values))
|
|
sum(f_of_x_values))
|
|
|
|
|
|
print(f"| {num_points:>16} | {integral_result:^20.8f} |")
|
|
print(f"| {num_points:>16} | {integral_result:^20.8f} |")
|
|
|
|
```
|
|
|
|
|
|
|
|
In CS 417/517 (Computational Methods) I used this example to demonstrate a few
|
|
|
|
things... including how the number of points used to approximate the integral
|
|
|
|
can increase the accuracy of the estimate.
|
|
|
|
|
|
|
|
First... I add a fourth command line argument...
|
|
|
|
|
|
|
|
```python
|
|
|
|
num_points = int(sys.argv[1]) # Unused in this version of main
|
|
|
|
limit_a = float(sys.argv[2])
|
|
|
|
limit_b = float(sys.argv[3])
|
|
|
|
max_magnitude = int(sys.argv[4])
|
|
|
|
```
|
|
|
|
|
|
|
|
Now... things get a little interesting...
|
|
|
|
|
|
|
|
```python
|
|
|
|
max_num_points = 2 ** max_magnitude
|
|
|
|
point_sequence = list(generate_random_points(math_f, limit_a, limit_b, max_num_points))
|
|
|
|
```
|
|
|
|
|
|
|
|
Even thought `generate_random_points` is a generator expression... I can turn
|
|
|
|
it into a list. However, this only works because `generate_random_points` is a
|
|
|
|
finite sequence (i.e., it stops generating points).
|
|
|
|
|
|
|
|
Instead of generating points repeatedly each time the loop executes...
|
|
|
|
|
|
|
|
```python
|
|
|
|
for magnitude in range(0, max_magnitude + 1):
|
|
|
|
num_points = 2 ** magnitude
|
|
|
|
|
|
|
|
f_of_x_values = (y for x, y in point_sequence[:num_points])
|
|
|
|
|
|
|
|
integral_result = ((limit_b - limit_a) /
|
|
|
|
float(num_points) *
|
|
|
|
sum(f_of_x_values))
|
|
|
|
|
|
|
|
print(f"| {num_points:>16} | {integral_result:^20.8f} |")
|
|
|
|
```
|
|
|
|
|
|
|
|
I determine the maximum number of points needed in the final loop iteration and
|
|
|
|
sample them (albeit naively) using:
|
|
|
|
|
|
|
|
```
|
|
|
|
point_sequence[:num_points])
|
|
|
|
```
|
|
|
|
|
|
|
|
This is an example of Python's list slicing syntax. The `[:num_points]` takes
|
|
|
|
all the points from the beginning of the list (i.e., `0`) up to (but not
|
|
|
|
including) the index specified by `num_points`.
|
|
|
|
|
|
|
|
|
|
|
|
### If `__main__`
|
|
|
|
|
|
|
|
The last chunk is what tells the Python interpreter what to run.
|
|
|
|
|
|
|
|
```
|
|
if __name__ == "__main__":
|
|
if __name__ == "__main__":
|
|
# naive_main()
|
|
# naive_main()
|
|
# not_so_naive_main()
|
|
# not_so_naive_main()
|
|
main_without_a_table_flip()
|
|
main_without_a_table_flip()
|
|
```
|
|
```
|
|
|
|
|
|
|
|
This allows us to run our script directly. If we import the Python script into
|
|
|
|
a larger program the `__name__ == "__main__"` will evaluate to `False`...
|
|
|
|
allowing us to call our functions from a larger program.
|
|
|
|
|
|
|
|
|
|
## If Time Permits
|
|
## If Time Permits
|
|
|
|
|
... | | ... | |