Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completed computational art #6

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Reflection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
My project was appropriately scoped, at least in the beginning. I started the project and got it working early on in the week. It was easy to get into once I got started, but somehow, I ended up spending the rest of the time I allocated to this class fooling around with ridiculous depth settings and trying out unnecessary elementary functions. I also didn't follow the exact definition of depth (i.e. I placed functions that take only x and functions that take both x and y in the same level of depth), but given how random the functions are supposed to be and how I ran the depth level from at least 7 to 9, it didn't make that much of a difference in the bigger picture.

I did not have a concrete plan for unit testing other than using the included doctests for remap_interval and color_map and adding print statements in between testing. Given that build_random_function and evaluate_random_function are supposed to be, well, random, there wasn't really much I could do in terms of writing more doctests. However, it was helpful to use print statements between the functions I wrote to make sure that the function was indeed building itself and the depth updating.

Going forward, I will use what I learned about recursion for future projects. It still feels weird calling the function from within the function, but I'm beginning to wrap my head around the concept. In the future, I should also allocate some time to extensions instead of using it all on making silly images. Although that was really fun, I could have improved on consolidating my evaluating_function statements, either with lists or lambda functions.
Binary file added desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart22.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart23.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart25.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart26.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart27.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart29.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myart9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 97 additions & 13 deletions recursive_art.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
"""TODO: Put your header comment here."""
"""
Generates computational art in png format

@author: Vivien Chen

"""

import random
from PIL import Image
import math


def build_random_function(min_depth, max_depth):
Expand All @@ -17,11 +23,38 @@ def build_random_function(min_depth, max_depth):

Returns:
The randomly generated function represented as a nested list.
(See the assignment writ-eup for details on the representation of
(See the assignment write-up for details on the representation of
these functions)
"""
# TODO: implement this
pass
# Comment out function to exclude it from building blocks.
functions = [
["prod", ["x"], ["y"]],
["avg", ["x"], ["y"]],
["cos_pi", ["x"]],
["sin_pi", ["x"]],
["square", ["x"]],
["cube", ["x"]],
["negative", ["x"]],
["sum", ["x"], ["y"]],
["mag", ["x"], ["y"]],
["square_x_y", ["x"], ["y"]],
]

depth = random.randint(min_depth, max_depth)

func = list(random.choice(functions))

if depth == 1:
return list(random.choice([["x"], ["y"]]))

elif depth > 1:
if len(func) == 2:
func[1] = build_random_function(depth - 1, depth - 1)
elif len(func) == 3:
func[1] = build_random_function(depth - 1, depth - 1)
func[2] = build_random_function(depth - 1, depth - 1)

return func

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely written readable code. 👍 The way you wrote this code makes it really clear what the function is doing.



def evaluate_random_function(f, x, y):
Expand All @@ -43,8 +76,49 @@ def evaluate_random_function(f, x, y):
>>> evaluate_random_function(["y"],0.1,0.02)
0.02
"""
# TODO: implement this
pass
def evaluate_single_function(func, x, y=None):
"""Evaluate the single function func with inputs x,y.

Args:
func: the single function to evaluate
x: the value of x to be used to evaluate the function
y: the value of y to be used to evaluate the function, set to None by default

Returns:
The single function value
"""
if func == "x":
return x
elif func == "y":
return y
elif func == "prod":
return x * y
elif func == "avg":
return 0.5 * (x + y)
elif func == "cos_pi":
return math.cos(math.pi * x)
elif func == "sin_pi":
return math.sin(math.pi * x)
elif func == "square":
return x ** 2
elif func == "cube":
return x ** 3
elif func == "negative":
return -x
elif func == "sum":
return x + y
elif func == "mag":
return math.sqrt(x**2 + y**2)
elif func == "square_x_y":
return x**2 + y**2

if len(f) == 1:
return evaluate_single_function(f[0], x, y)
elif len(f) == 2:
return evaluate_single_function(f[0], evaluate_random_function(f[1], x, y))
elif len(f) == 3:
return evaluate_single_function(f[0], evaluate_random_function(f[1], x, y),
evaluate_random_function(f[2], x, y))


def remap_interval(val,
Expand Down Expand Up @@ -80,8 +154,13 @@ def remap_interval(val,
>>> remap_interval(5, 4, 6, 1, 2)
1.5
"""
# TODO: implement this
pass
frontEnd = val - input_interval_start
backEnd = input_interval_end - val

interval_ = (output_interval_end - output_interval_start) / (frontEnd + backEnd)
output_ = output_interval_start + (frontEnd * interval_)

return output_


def color_map(val):
Expand Down Expand Up @@ -137,9 +216,14 @@ def generate_art(filename, x_size=350, y_size=350):
x_size, y_size: optional args to set image dimensions (default: 350)
"""
# Functions for red, green, and blue channels - where the magic happens!
red_function = ["x"]
green_function = ["y"]
blue_function = ["x"]
red_function = build_random_function(7, 9)
green_function = build_random_function(7, 9)
blue_function = build_random_function(7, 9)

# Print functions for viewing pleasure
print("RED FUNCTION:", red_function)
print("GREEN FUNCTION:", green_function)
print("BLUE FUNCTION:", blue_function)

# Create image and loop over all pixels
im = Image.new("RGB", (x_size, y_size))
Expand All @@ -164,8 +248,8 @@ def generate_art(filename, x_size=350, y_size=350):
# Create some computational art!
# TODO: Un-comment the generate_art function call after you

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove these placeholders for your final code

# implement remap_interval and evaluate_random_function
# generate_art("myart.png")
generate_art("myart.png")

# Test that PIL is installed correctly
# TODO: Comment or remove this function call after testing PIL install
test_image("noise.png")
# test_image("noise.png")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.