Browse Source

Merge pull request #247 from chrboesch/formatting

added first formatting exercise
Chris Boesch 2 years ago
parent
commit
4435cebe7a
4 changed files with 125 additions and 1 deletions
  1. 1 1
      README.md
  2. 4 0
      build.zig
  3. 115 0
      exercises/099_formatting.zig
  4. 5 0
      patches/patches/099_formatting.patch

+ 1 - 1
README.md

@@ -179,7 +179,7 @@ Core Language
 * [ ] Async <--- IN PROGRESS!
 * [X] Interfaces
 * [X] Working with C
-* [ ] String formatting
+* [X] String formatting
 * [X] Bit manipulation
 
 ## Contributing

+ 4 - 0
build.zig

@@ -515,6 +515,10 @@ const exercises = [_]Exercise{
         .output = "Is this a pangram? true!",
     },
     .{
+        .main_file = "099_formatting.zig",
+        .output = "\n X |  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 \n---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+\n 1 |  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 \n\n 2 |  2   4   6   8  10  12  14  16  18  20  22  24  26  28  30 \n\n 3 |  3   6   9  12  15  18  21  24  27  30  33  36  39  42  45 \n\n 4 |  4   8  12  16  20  24  28  32  36  40  44  48  52  56  60 \n\n 5 |  5  10  15  20  25  30  35  40  45  50  55  60  65  70  75 \n\n 6 |  6  12  18  24  30  36  42  48  54  60  66  72  78  84  90 \n\n 7 |  7  14  21  28  35  42  49  56  63  70  77  84  91  98 105 \n\n 8 |  8  16  24  32  40  48  56  64  72  80  88  96 104 112 120 \n\n 9 |  9  18  27  36  45  54  63  72  81  90  99 108 117 126 135 \n\n10 | 10  20  30  40  50  60  70  80  90 100 110 120 130 140 150 \n\n11 | 11  22  33  44  55  66  77  88  99 110 121 132 143 154 165 \n\n12 | 12  24  36  48  60  72  84  96 108 120 132 144 156 168 180 \n\n13 | 13  26  39  52  65  78  91 104 117 130 143 156 169 182 195 \n\n14 | 14  28  42  56  70  84  98 112 126 140 154 168 182 196 210 \n\n15 | 15  30  45  60  75  90 105 120 135 150 165 180 195 210 225 \n\n",
+    },
+    .{
         .main_file = "999_the_end.zig",
         .output = "\nThis is the end for now!\nWe hope you had fun and were able to learn a lot, so visit us again when the next exercises are available.",
     },

+ 115 - 0
exercises/099_formatting.zig

@@ -0,0 +1,115 @@
+//
+// The output on the console looks a bit rudimentary at first glance.
+// However, if you look at the development of modern computers, you can
+// see the enormous progress that has been made over the years.
+// Starting with monochrome lines on flickering CRT monitors, modern
+// terminal emulators offer a razor-sharp image with true color and
+// nearly infinite font size thanks to modern hardware.
+//
+// In addition, they have mastered ligatures and can represent almost
+// any character in any language. This also makes the output of programs
+// on the console more atractive than ever in recent years.
+//
+// This makes it all the more important to format the presentation of
+// results in an appealing way, because that is what users appreciate,
+// quick visual comprehension of the information.
+//
+// C has set standards here over the years, and Zig is preparing to
+// follow suit. Currently, however, it still lags a bit behind the model,
+// but the Zig community is working diligently behind the scenes on
+// further options.
+//
+// Nevertheless, it is time to take a closer look at the possibilities
+// that already exist. And of course we will continue this series loosely,
+// because Zig continues to grow almost daily.
+//
+// Since there is no proper documentation on the formatting yet, the most
+// important source here is the source code:
+//
+//     https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29
+//
+//
+// And in fact, you already discover quite a lot of useful formatting.
+// These can be used in different ways, e.g. to convert numerical values
+// into text and for direct output to the console or to a file. The latter
+// is useful when large amounts of data are to be processed by other programs.
+//
+// However, we are concerned here exclusively with the output to the console.
+// But since the formatting instructions for files are the same, what you
+// learn applies universally.
+//
+// Since we basically write to debug output in Ziglings, our output usually
+// looks like this:
+//
+// std.debug.print("Text {placeholder} another text \n", .{variable});
+//
+// But how is the statement just shown formatted?
+//
+// This actually happens in several stages. On the one hand, escape
+// sequences are evaluated, there is the "\n" which means "line feed"
+// in the example. Whenever this statement is found, a new line is started
+// in the output. Escpape sequences can also be written one after the
+// other, e.g. "\n\n" will cause two line feeds.
+//
+// By the way, these formattings are passed directly to the terminal
+// program, i.e. escape sequences have nothing to do with Zig in this
+// respect. The formatting that Zig actually performs is found in the
+// curly bracket, the "placeholder", and affects the coresponding variable.
+//
+// And this is where it gets exciting, because numbers can have different
+// sizes, be positive or negative, with a decimal point or without,
+// and so on.
+//
+// In order to bring these then into a uniform format for the output,
+// instructions can be given to the placeholder:
+//
+//                print("=> {x:0>4}", .{var});
+//
+// This instruction outputs a hexadecimal number with leading zeros.
+//
+//                       => 0x0017
+//
+// Let's move on to our exercise: we want to create a table that shows us
+// the multiplication of all numbers together from 1-15. So if you search
+// for the number '5' in the row and '4' in the column (or vice versa),
+// the result of '5 x 4 = 20' should be displayed there.
+//
+//
+const std = @import("std");
+const print = std.debug.print;
+
+pub fn main() !void {
+    // the max. size of the table
+    const size = 15;
+
+    // print the header:
+    //
+    // we start with a single 'X' for the diagonal,
+    // that means there is no result
+    print("\n X |", .{});
+
+    // header row with all numbers from 1 to size
+    for (0..size) |n| {
+        print("{d:>3} ", .{n + 1});
+    }
+    print("\n", .{});
+
+    // row line
+    var n: u8 = 0;
+    while (n <= size) : (n += 1) {
+        print("---+", .{});
+    }
+    print("\n", .{});
+
+    // now the actual table
+    for (0..size) |a| {
+        print("{d:>2} |", .{a + 1});
+        for (0..size) |b| {
+            // what formatting is needed here?
+            print("{???} ", .{(a + 1) * (b + 1)});
+        }
+
+        // after each row we use double line feed
+        print("\n\n", .{});
+    }
+}

+ 5 - 0
patches/patches/099_formatting.patch

@@ -0,0 +1,5 @@
+108,109c108
+<             // what formatting is needed here?
+<             print("{???} ", .{(a + 1) * (b + 1)});
+---
+>             print("{d:>3} ", .{(a + 1) * (b + 1)});