diff options
Diffstat (limited to 'Homework/cs4700/dart')
| -rw-r--r-- | Homework/cs4700/dart/fractal.dart | 161 | ||||
| -rw-r--r-- | Homework/cs4700/dart/streams.dart | 106 |
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.'); + } +} |
