diff --git a/src/main/java/edu/ntnu/idatt2003/Controller/UserController.java b/src/main/java/edu/ntnu/idatt2003/Controller/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..1963bff245b5b0e4bbbbf599e4efee3976bc934b
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/Controller/UserController.java
@@ -0,0 +1,11 @@
+package edu.ntnu.idatt2003.Controller;
+
+public class UserController {
+
+  public void readDescriptionFromFile() {
+
+  }
+
+
+
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java
index fae533f8ef229476f6587c932eab55de6c7859b3..f26969f17e1ea0dba3b2465b1d504b8e2240743b 100644
--- a/src/main/java/edu/ntnu/idatt2003/Main.java
+++ b/src/main/java/edu/ntnu/idatt2003/Main.java
@@ -6,6 +6,7 @@ import edu.ntnu.idatt2003.model.ChaosGameDescription;
 import edu.ntnu.idatt2003.model.Matrix2x2;
 import edu.ntnu.idatt2003.model.Transform2D;
 import edu.ntnu.idatt2003.model.Vector2d;
+import edu.ntnu.idatt2003.view.UI;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -27,6 +28,9 @@ public class Main {
     ChaosGame game = new ChaosGame(description, 100, 100);
     game.runSteps(10000);
     game.getCanvas().showCanvas();
+
+    UI ui = new UI();
+    ui.start();
     }
 
   }
diff --git a/src/main/java/edu/ntnu/idatt2003/view/TextRenderer.java b/src/main/java/edu/ntnu/idatt2003/view/TextRenderer.java
new file mode 100644
index 0000000000000000000000000000000000000000..9bc904284d8a84d088ab679c69bf45ec6d7b2f27
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/view/TextRenderer.java
@@ -0,0 +1,37 @@
+package edu.ntnu.idatt2003.view;
+
+/**
+ * Represents a text renderer.
+ * Contains constants for menu options and methods for showing the menu, entering a path and entering steps.
+ * Goal: act as a view for a text renderer.
+ *
+ */
+
+public class TextRenderer {
+
+  public static final String READ_FILE = "1";
+  public static final String WRITE_FILE = "2";
+  public static final String RUN_ITERATIONS = "3";
+  public static final String SHOW_CANVAS = "4";
+  public static final String EXIT = "5";
+
+  public void showMenu() {
+    System.out.println("Menu:");
+    System.out.println("1. Read description from file");
+    System.out.println("2. Write description to file");
+    System.out.println("3. Run ChaosGame a given number of steps");
+    System.out.println("4. Show Canvas");
+    System.out.println("5. Exit");
+  }
+
+  public void enterPath() {
+    System.out.println("Enter path to file:");
+  }
+
+  public void enterSteps() {
+    System.out.println("Enter number of steps:");
+  }
+
+
+
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/view/UI.java b/src/main/java/edu/ntnu/idatt2003/view/UI.java
new file mode 100644
index 0000000000000000000000000000000000000000..49b30d4cd328bdb6aba48f5a96ee1177c424fd45
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/view/UI.java
@@ -0,0 +1,177 @@
+package edu.ntnu.idatt2003.view;
+
+import static edu.ntnu.idatt2003.view.TextRenderer.READ_FILE;
+import static edu.ntnu.idatt2003.view.TextRenderer.EXIT;
+import static edu.ntnu.idatt2003.view.TextRenderer.RUN_ITERATIONS;
+import static edu.ntnu.idatt2003.view.TextRenderer.SHOW_CANVAS;
+import static edu.ntnu.idatt2003.view.TextRenderer.WRITE_FILE;
+
+import edu.ntnu.idatt2003.model.ChaosGame;
+import edu.ntnu.idatt2003.model.ChaosGameDescription;
+import edu.ntnu.idatt2003.model.ChaosGameFileHandler;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+/**
+ * Represents a user interface.
+ * Contains methods for starting the UI, reading a description from a file, writing a description to a file,
+ * running iterations and showing the canvas.
+ * Includes a scanner for user input, and instances of TextRenderer, ChaosGameFileHandler, ChaosGame and ChaosGameDescription.
+ * Goal: act as a view for a user interface.
+ */
+
+public class UI {
+  TextRenderer textRenderer = new TextRenderer();
+  ChaosGameFileHandler chaosGameFileHandler = new ChaosGameFileHandler();
+  ChaosGameDescription description;
+  ChaosGame chaosGame;
+  private final Scanner scanner = new Scanner(System.in);
+
+  /**
+   * Starts the user interface. Asks the user for input and performs the corresponding action.
+   * Breaks the loop when the user chooses to exit, which is when the user inputs "5".
+   * Invalid input will result in a message.
+   */
+
+  public void start() {
+    String choice;
+    do {
+      textRenderer.showMenu();
+      choice = getUserChoice();
+      switch (choice) {
+        case READ_FILE:
+          readDescriptionFromFile();
+          break;
+        case WRITE_FILE:
+          writeDescriptionToFile();
+          break;
+        case RUN_ITERATIONS:
+          runIterations();
+          break;
+        case SHOW_CANVAS:
+          ShowCanvas();
+          break;
+        default:
+          System.out.println("Invalid choice");
+          break;
+      }
+    } while (!choice.equals(EXIT));
+  }
+
+  /**
+   * Gets the user's choice.
+   *
+   * @return The user's choice.
+   */
+
+  public static String getUserChoice() {
+    Scanner scanner = new Scanner(System.in);
+    return scanner.nextLine();
+  }
+
+  /**
+   * Gets the user's input, and checks if it is empty.
+   *
+   * @return The user's input.
+   */
+
+  public String textInput() {
+    String text;
+    do {
+      text = scanner.nextLine();
+      if (text.isEmpty()) {
+        System.out.println("Input cannot be empty. Please try again.");
+      }
+    } while (text.isEmpty());
+    return text;
+  }
+
+  /**
+   * Gets the user's input, and checks if it is a number and whether it is empty.
+   *
+   * @return The user's input.
+   */
+
+
+  public int numberInput() {
+    int number;
+    while (true) {
+      String input = scanner.nextLine();
+      if (!input.isEmpty()) {
+        try {
+          number = Integer.parseInt(input);
+          break;
+        } catch (NumberFormatException e) {
+          System.out.println("Invalid input. Please enter a valid number.");
+        }
+      } else {
+        System.out.println("Input cannot be empty. Please try again.");
+      }
+    }
+    return number;
+  }
+
+  /**
+   * Reads a description from a file.
+   * Asks the user for the path to the file, and reads the already existing description from the file.
+   * Sets the description and chaosGame to the new description.
+   * If the file is not found, a message will be shown.
+   */
+
+
+  public void readDescriptionFromFile(){
+    textRenderer.enterPath();
+    String pathToFile = textInput();
+    ChaosGameDescription newDescription;
+    try {
+      newDescription = chaosGameFileHandler.readFromFile(pathToFile);
+      System.out.println("file read successfully");
+    } catch (FileNotFoundException e) {
+      throw new RuntimeException("File '" + pathToFile + "' not found." + e.getMessage());
+    }
+    this.description = newDescription;
+    chaosGame = new ChaosGame(description, 30, 30);
+    System.out.println("description set successfully");
+  }
+
+  /**
+   * Writes a description to a file.
+   * Asks the user for the path to the file, and writes the description to the file.
+   * If the file is not found, a message will be shown.
+   */
+
+  public void writeDescriptionToFile() {
+    textRenderer.enterPath();
+    String pathToFile = textInput();
+    chaosGameFileHandler.writeToFile(description, pathToFile);
+  }
+
+  /**
+   * Runs iterations.
+   * Asks the user for the number of steps to run the simulation.
+   * Runs the simulation for the specified number of steps.
+   */
+
+  public void runIterations() {
+    if(chaosGame == null || description == null) {
+      System.out.println("description or chaosGame is null");
+      return;
+    }
+    textRenderer.enterSteps();
+    int steps = numberInput();
+    chaosGame.runSteps(steps);
+  }
+
+  /**
+   * Shows the canvas, and ensures that chaosGame is not null.
+   */
+
+  public void ShowCanvas() {
+    if(chaosGame == null) {
+      System.out.println("chaosGame is null");
+      return;
+    }
+    chaosGame.getCanvas().showCanvas();
+  }
+
+}
diff --git a/src/test/resources/Affine2DExample.txt b/src/test/resources/Affine2DExample.txt
index 8a6aa80fbe35c794e09a71da78fdfb8693f3b799..9cde8defe9eade9b41014b33cba1183ca4a6bd5f 100644
--- a/src/test/resources/Affine2DExample.txt
+++ b/src/test/resources/Affine2DExample.txt
@@ -3,4 +3,4 @@ Affine2D # Type of transform
 1, 1 # Upper right
 .5, 0, 0, .5, 0, 0 # 1st transform (a00, a01, a10, a11, b0, b1)
 .5, 0, 0, .5, .25, .5 # 2nd transform
-.5, 0, 0, .5, .5, 0
\ No newline at end of file
+.5, 0, 0, .5, .5, 0 # 3rd transform
\ No newline at end of file
diff --git a/src/test/resources/Affine2DExampleOutput.txt b/src/test/resources/Affine2DExampleOutput.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a13c7bbee7de674c7c117564efc044186b1fcb53
--- /dev/null
+++ b/src/test/resources/Affine2DExampleOutput.txt
@@ -0,0 +1,6 @@
+Affine2D
+0.0, 0.0
+1.0, 1.0
+0.500000, 0.000000, 0.000000, 0.500000, 0.0, 0.0
+0.500000, 0.000000, 0.000000, 0.500000, 0.25, 0.5
+0.500000, 0.000000, 0.000000, 0.500000, 0.5, 0.0
diff --git a/src/test/resources/JuliaExample.txt b/src/test/resources/JuliaExample.txt
index 27394a9f0cedc82f5c5c9753570d197240bcf8df..f7c285ef9127942468c9ae5caf221748a1f5283b 100644
--- a/src/test/resources/JuliaExample.txt
+++ b/src/test/resources/JuliaExample.txt
@@ -1,4 +1,4 @@
-Julia # Type of transform
--1.6, -1 # Lower left
-1.6, 1 # Upper right
--.74543, .11301 # Real and imaginary parts of the constant c
\ No newline at end of file
+Julia
+-1.6, -1.0
+1.6, 1.0
+-0.74543, 0.11301