summaryrefslogtreecommitdiff
path: root/Homework/cs4700/dart
diff options
context:
space:
mode:
Diffstat (limited to 'Homework/cs4700/dart')
-rw-r--r--Homework/cs4700/dart/fractal.dart161
-rw-r--r--Homework/cs4700/dart/streams.dart106
2 files changed, 267 insertions, 0 deletions
diff --git a/Homework/cs4700/dart/fractal.dart b/Homework/cs4700/dart/fractal.dart
new file mode 100644
index 0000000..c075325
--- /dev/null
+++ b/Homework/cs4700/dart/fractal.dart
@@ -0,0 +1,161 @@
+import 'package:flutter/material.dart';
+import 'dart:math' as math;
+
+/// Your code should go into the DrawFractal class.
+
+/// The fractal is drawn as an extension of the CustomPainter.
+class DrawFractal extends CustomPainter {
+ var level = 10; // max level of fractal
+
+ // Constructor that initializes the level of the fractal
+ DrawFractal(value) {
+ level = value;
+ }
+
+ // Recursively draw the fractal
+ void fractal(Canvas canvas, int level) {
+ if (level >= this.level) {
+ return;
+ }
+
+ final paint = Paint()
+ ..color = Colors.black
+ ..strokeWidth = 1;
+
+ // Recursively draw the left branch
+ canvas.save();
+ canvas.rotate(math.pi / 6);
+ canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint);
+ canvas.translate(50 / level, 50 / level);
+
+ fractal(canvas, level + 1);
+ canvas.restore();
+
+ // As we go up the call stack, draw the right branch
+ canvas.rotate(-math.pi / 6);
+ canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint);
+ canvas.translate(50 / level, 50 / level);
+ fractal(canvas, level + 1);
+ }
+
+ /// Called when the canvas is (re)painted, perform the initial moving of the
+ /// fractal to the center and other actions here such as the initial call to fractal.
+ @override
+ void paint(Canvas canvas, Size size) {
+ fractal(canvas, 1);
+ }
+
+ /// Always repaint
+ @override
+ bool shouldRepaint(CustomPainter oldDelegate) {
+ return true;
+ }
+}
+
+// The code before here is to set up the flutter app and run it. You may not have to
+// change this code.
+
+/// Run the application
+void main() => runApp(MyApp());
+
+/// The application runs a streambuilder widget
+class MyApp extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ // The title of my application
+ title: 'My flutter application',
+ home: StreamBuilderSetup(),
+ debugShowCheckedModeBanner: false,
+ );
+ }
+}
+
+/// Stream to generate numbers from 1 to 10
+Stream<int> generateNumbers = (() async* {
+ await Future<void>.delayed(const Duration(seconds: 2));
+
+ for (int i = 1; i <= 10; i++) {
+ await Future<void>.delayed(const Duration(seconds: 1));
+ yield i;
+ }
+})();
+
+/// Setup a streambuild widget
+class StreamBuilderSetup extends StatefulWidget {
+ @override
+ State<StatefulWidget> createState() {
+ return _StreamBuilderSetupState();
+ }
+}
+
+/// The innards of the streambuilder widget
+class _StreamBuilderSetupState extends State<StreamBuilderSetup> {
+ /// Boilerplate for initializing the state of the widget
+ @override
+ initState() {
+ super.initState();
+ }
+
+ /// Build the widget, it consists of a title and a SizedBox where the
+ /// drawing of the fractal (but could be anything takes place)
+ /// Most of this is boilerplate code.
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ // Title bar for the widget
+ title: const Text('Draw a Fractal in Flutter'),
+ ),
+ // Box in which to draw the fractal
+ body: SizedBox(
+ width: double.infinity,
+ child: Center(
+ child: StreamBuilder<int>(
+ stream: generateNumbers,
+ initialData: 0,
+ builder: (
+ BuildContext context,
+ AsyncSnapshot<int> snapshot,
+ ) {
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const CircularProgressIndicator(),
+ Visibility(
+ visible: snapshot.hasData,
+ child: Text(
+ snapshot.data.toString(),
+ style:
+ const TextStyle(color: Colors.black, fontSize: 24),
+ ),
+ ),
+ ],
+ );
+ } else if (snapshot.connectionState == ConnectionState.active ||
+ snapshot.connectionState == ConnectionState.done) {
+ if (snapshot.hasError) {
+ return const Text('Error');
+ } else if (snapshot.hasData) {
+ return Center(
+ child: CustomPaint(
+ // Set up a canvas of size 500 by 5000
+ size: const Size(500, 500),
+ // Draw the fractal passing the level from the stream
+ painter: DrawFractal(snapshot.data)),
+ );
+ } else {
+ return const Text('Empty data');
+ }
+ } else {
+ return Text('State: ${snapshot.connectionState}');
+ }
+ },
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/Homework/cs4700/dart/streams.dart b/Homework/cs4700/dart/streams.dart
new file mode 100644
index 0000000..b7d7b26
--- /dev/null
+++ b/Homework/cs4700/dart/streams.dart
@@ -0,0 +1,106 @@
+import 'dart:io';
+
+// Generates a stream of n fibonacci numbers, sleeping 1 second every iteration
+Stream<int> Function() fibonnaciNumbers(int n) {
+ final Stream<int> Function() func = (() async* {
+ var x = 0, y = 1;
+ for (int i = 0; i <= n; i++) {
+ yield x;
+ sleep(new Duration(seconds: 1));
+ y += x;
+ x = y - x;
+ }
+ });
+ return func;
+}
+
+// Filters a stream of integers with a function predicate determining to each of the elements in the stream.
+Stream<int> Function() streamFilter(Stream<int> stream, bool Function(int) f) {
+ final Stream<int> Function() func = (() async* {
+ await for (var i in stream) {
+ if (f(i)) {
+ yield i;
+ }
+ }
+ });
+ return func;
+}
+
+// Iterates over a stream, accumulatively applying a binary function to a stream of integers until the last
+// element and returns the accumulation.
+Stream<int> Function() streamAccumulation(
+ Stream<int> stream, int Function(int, int) f, initial) {
+ final Stream<int> Function() func = (() async* {
+ int a = initial;
+ await for (var i in stream) {
+ a = f(a, i);
+ yield a;
+ }
+ });
+ return func;
+}
+
+Stream<int> Function() generateNumbers(int n) {
+ final Stream<int> Function() func = (() async* {
+ for (int i = 1; i <= n; i++) {
+ await Future<void>.delayed(const Duration(seconds: 1));
+ yield i;
+ }
+ });
+ return func;
+}
+
+// Given a list of lists, returns a list containing all the non-null elements of each list into a single list
+List? flatten(List<List?>? aList) {
+ if (aList == null) return null;
+ return aList
+ .where((i) => i != null)
+ .expand((i) => i!)
+ .where((i) => i != null)
+ .toList();
+}
+
+// Generates a nested list where each element's index i is in a sublist of depth i+1.
+// For example, deepen([1,2,3]) => [1, [2, [3]]]
+List? deepen(List? aList) {
+ if (aList == null) return null;
+ return aList.reversed
+ .fold([], (a, x) => (a != null && a.isEmpty) ? [x] : [x, a]);
+}
+
+void main(List<String> arguments) async {
+ print('flattening [[0,1], [2]] yields ${flatten([
+ [0, 1],
+ [2]
+ ])}');
+ print('flattening [[0,1], [2], null] yields ${flatten([
+ [0, 1],
+ [2],
+ null
+ ])}');
+ print('flattening [[0,1, null], [2]] yields ${flatten([
+ [0, 1, null],
+ [2]
+ ])}');
+ print('flattening null yields ${flatten(null)}');
+ print('flattening [null] yields ${flatten([null])}');
+ print('deepening [0,1,2] yields ${deepen([0, 1, 2])}');
+ print('deepening [0,null,2] yields ${deepen([0, null, 2])}');
+ print('deepening [0] yields ${deepen([0])}');
+ print('deepening [] yields ${deepen([])}');
+ print('deepening null yields ${deepen(null)}');
+ await for (final number in fibonnaciNumbers(7)()) {
+ print('fibonnaci number is ${number}');
+ }
+ await for (final number in streamFilter(generateNumbers(10)(), ((a) {
+ return a % 2 == 0;
+ }))()) {
+ print('filtered number is $number');
+ }
+
+ await for (final number in streamAccumulation(generateNumbers(10)(), ((a, b) {
+ return a + b;
+ }), 0)()) {
+ print('cumulative number is $number.');
+ }
+}