diff --git a/24_depth_was_the_furthest_i_got_before_i_got_an_error_message.png b/24_depth_was_the_furthest_i_got_before_i_got_an_error_message.png new file mode 100644 index 0000000..d3b9159 Binary files /dev/null and b/24_depth_was_the_furthest_i_got_before_i_got_an_error_message.png differ diff --git a/Reflection.md b/Reflection.md new file mode 100644 index 0000000..79798a5 --- /dev/null +++ b/Reflection.md @@ -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. diff --git a/desktop.png b/desktop.png new file mode 100644 index 0000000..af26895 Binary files /dev/null and b/desktop.png differ diff --git a/myart13.png b/myart13.png new file mode 100644 index 0000000..261da73 Binary files /dev/null and b/myart13.png differ diff --git a/myart15.png b/myart15.png new file mode 100644 index 0000000..0884727 Binary files /dev/null and b/myart15.png differ diff --git a/myart16.png b/myart16.png new file mode 100644 index 0000000..b550bf4 Binary files /dev/null and b/myart16.png differ diff --git a/myart22.png b/myart22.png new file mode 100644 index 0000000..844ee9f Binary files /dev/null and b/myart22.png differ diff --git a/myart23.png b/myart23.png new file mode 100644 index 0000000..3328487 Binary files /dev/null and b/myart23.png differ diff --git a/myart24.png b/myart24.png new file mode 100644 index 0000000..0a39166 Binary files /dev/null and b/myart24.png differ diff --git a/myart25.png b/myart25.png new file mode 100644 index 0000000..55fdfa6 Binary files /dev/null and b/myart25.png differ diff --git a/myart26.png b/myart26.png new file mode 100644 index 0000000..60536c8 Binary files /dev/null and b/myart26.png differ diff --git a/myart27.png b/myart27.png new file mode 100644 index 0000000..2995073 Binary files /dev/null and b/myart27.png differ diff --git a/myart29.png b/myart29.png new file mode 100644 index 0000000..e6e4d91 Binary files /dev/null and b/myart29.png differ diff --git a/myart9.png b/myart9.png new file mode 100644 index 0000000..0f5e346 Binary files /dev/null and b/myart9.png differ diff --git a/recursive_art.py b/recursive_art.py index 6292170..157afd4 100644 --- a/recursive_art.py +++ b/recursive_art.py @@ -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): @@ -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 def evaluate_random_function(f, x, y): @@ -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, @@ -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): @@ -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)) @@ -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 # 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") diff --git a/when_you_try_to_be_too_ambitious_and_set_the_depth_from_17_to_19.png b/when_you_try_to_be_too_ambitious_and_set_the_depth_from_17_to_19.png new file mode 100644 index 0000000..a579286 Binary files /dev/null and b/when_you_try_to_be_too_ambitious_and_set_the_depth_from_17_to_19.png differ