about summary refs log tree commit diff
path: root/usth/ICT2.2/labwork/3
diff options
context:
space:
mode:
Diffstat (limited to 'usth/ICT2.2/labwork/3')
-rw-r--r--usth/ICT2.2/labwork/3/3_labwork3.pdfbin0 -> 1520939 bytes
-rw-r--r--usth/ICT2.2/labwork/3/C++/README.md10
-rw-r--r--usth/ICT2.2/labwork/3/C++/automobile.cc56
-rw-r--r--usth/ICT2.2/labwork/3/C++/automobile.h20
-rw-r--r--usth/ICT2.2/labwork/3/C++/button-test.cc14
-rw-r--r--usth/ICT2.2/labwork/3/C++/button.h14
-rw-r--r--usth/ICT2.2/labwork/3/C++/cow-test.cc9
-rw-r--r--usth/ICT2.2/labwork/3/C++/cow.cc11
-rw-r--r--usth/ICT2.2/labwork/3/C++/cow.h17
-rw-r--r--usth/ICT2.2/labwork/3/C++/name-card-test.cc14
-rw-r--r--usth/ICT2.2/labwork/3/C++/name-card.cc47
-rw-r--r--usth/ICT2.2/labwork/3/C++/name-card.h18
-rw-r--r--usth/ICT2.2/labwork/3/C++/shopping-cart-test.cc19
-rw-r--r--usth/ICT2.2/labwork/3/C++/shopping-cart.h16
-rw-r--r--usth/ICT2.2/labwork/3/C++/vector-test.cc20
-rw-r--r--usth/ICT2.2/labwork/3/C++/vector.cc19
-rw-r--r--usth/ICT2.2/labwork/3/C++/vector.h17
-rw-r--r--usth/ICT2.2/labwork/3/Java/Automobile.java68
-rw-r--r--usth/ICT2.2/labwork/3/Java/Button.java50
-rw-r--r--usth/ICT2.2/labwork/3/Java/ButtonTest.java12
-rw-r--r--usth/ICT2.2/labwork/3/Java/Cow.java36
-rw-r--r--usth/ICT2.2/labwork/3/Java/CowTest.java9
-rw-r--r--usth/ICT2.2/labwork/3/Java/NameCard.java67
-rw-r--r--usth/ICT2.2/labwork/3/Java/NameCardTest.java9
-rw-r--r--usth/ICT2.2/labwork/3/Java/README.md10
-rw-r--r--usth/ICT2.2/labwork/3/Java/ShoppingCart.java27
-rw-r--r--usth/ICT2.2/labwork/3/Java/ShoppingCartTest.java16
-rw-r--r--usth/ICT2.2/labwork/3/Java/Vector.java39
-rw-r--r--usth/ICT2.2/labwork/3/Java/VectorTest.java10
29 files changed, 674 insertions, 0 deletions
diff --git a/usth/ICT2.2/labwork/3/3_labwork3.pdf b/usth/ICT2.2/labwork/3/3_labwork3.pdf
new file mode 100644
index 0000000..0c9c533
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/3_labwork3.pdf
Binary files differdiff --git a/usth/ICT2.2/labwork/3/C++/README.md b/usth/ICT2.2/labwork/3/C++/README.md
new file mode 100644
index 0000000..8cd208f
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/README.md
@@ -0,0 +1,10 @@
+# Labwork 3: Implementations in C++
+
+At this point I've come to realized that like Thanos, C++ is inevitable.
+Despite my disgust toward the language (TBH I don't like Java any better),
+I need to know it enough, at least at the read-only level.
+
+Compilation of tests could be done as follows (on Unix-like system of course,
+since poor Windows users don't even have a standard C/C++ compiler):
+
+    c++ <classname>*.cc
diff --git a/usth/ICT2.2/labwork/3/C++/automobile.cc b/usth/ICT2.2/labwork/3/C++/automobile.cc
new file mode 100644
index 0000000..d274a60
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/automobile.cc
@@ -0,0 +1,56 @@
+#include <regex>
+#include <stdexcept>
+#include <string>
+
+#include "automobile.h"
+
+using namespace std;
+
+const regex license_pattern ("[0-9A-Z]+");
+
+void
+Automobile::set_license (string s)
+{
+  smatch m;
+  if (!regex_match (s, m, license_pattern))
+    throw invalid_argument{"invalid license plate"};
+  license = s;
+}
+
+void
+Automobile::set_fuel (double x)
+{
+  if (x < 0)
+    throw invalid_argument{"negative fuel"};
+  fuel = x;
+}
+
+void
+Automobile::set_speed (double x)
+{
+  speed = (x < 0) ? 0 : x;
+}
+
+Automobile::Automobile (string l, double f, double s)
+{
+  set_license (l);
+  set_fuel (f);
+  set_speed (s);
+}
+
+void
+Automobile::accelerate (double v)
+{
+  if (v < 0)
+    throw invalid_argument{"negative acceleration"};
+  if (fuel)
+    set_speed (speed + v);
+}
+
+void
+Automobile::decelerate (double v)
+{
+  if (v < 0)
+    throw invalid_argument{"negative deceleration"};
+  set_speed (speed - v);
+}
diff --git a/usth/ICT2.2/labwork/3/C++/automobile.h b/usth/ICT2.2/labwork/3/C++/automobile.h
new file mode 100644
index 0000000..0e65865
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/automobile.h
@@ -0,0 +1,20 @@
+#include <string>
+
+using namespace std;
+
+class Automobile
+{
+  double fuel;
+  double speed;
+  string license;
+public:
+  Automobile (string, double, double);
+  string get_license () { return license; }
+  double get_fuel () { return fuel; }
+  double get_speed () { return speed; }
+  void set_license (string);
+  void set_fuel (double);
+  void set_speed (double);
+  void accelerate (double);
+  void decelerate (double);
+};
diff --git a/usth/ICT2.2/labwork/3/C++/button-test.cc b/usth/ICT2.2/labwork/3/C++/button-test.cc
new file mode 100644
index 0000000..7164b2f
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/button-test.cc
@@ -0,0 +1,14 @@
+#include <iostream>
+
+#include "button.h"
+
+using namespace std;
+
+int
+main ()
+{
+  Button butt ("foo", "bar");
+  butt.depress ();
+  butt.undepress ();
+  cout << "button " << butt.label << " color " << butt.color << endl;
+}
diff --git a/usth/ICT2.2/labwork/3/C++/button.h b/usth/ICT2.2/labwork/3/C++/button.h
new file mode 100644
index 0000000..92fa685
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/button.h
@@ -0,0 +1,14 @@
+#include <string>
+
+using namespace std;
+
+class Button
+{
+  bool state;
+public:
+  string label;
+  string color;
+  Button (string l, string c) : label {l}, color {c}, state {false} {}
+  void depress () { state = true; }
+  void undepress () { state = false; }
+};
diff --git a/usth/ICT2.2/labwork/3/C++/cow-test.cc b/usth/ICT2.2/labwork/3/C++/cow-test.cc
new file mode 100644
index 0000000..ea7b86d
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/cow-test.cc
@@ -0,0 +1,9 @@
+#include "cow.h"
+
+int
+main ()
+{
+  Cow cow ("foo", "bar", 7);
+  cow.age = -4;   // some casting happens here
+  cow.moo ();
+}
diff --git a/usth/ICT2.2/labwork/3/C++/cow.cc b/usth/ICT2.2/labwork/3/C++/cow.cc
new file mode 100644
index 0000000..84fabc8
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/cow.cc
@@ -0,0 +1,11 @@
+#include <iostream>
+
+#include "cow.h"
+
+using namespace std;
+
+void
+Cow::moo ()
+{
+  cout << "Moo...!" << endl;
+}
diff --git a/usth/ICT2.2/labwork/3/C++/cow.h b/usth/ICT2.2/labwork/3/C++/cow.h
new file mode 100644
index 0000000..df7ffd9
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/cow.h
@@ -0,0 +1,17 @@
+#include <string>
+
+using namespace std;
+
+class Cow
+{
+  // The reason these have private access
+  // is that their no way a cow's name and breed can be changed.
+  string name;
+  string breed;
+public:
+  unsigned age;
+
+  Cow (string n, string b, unsigned a) : name {n}, breed {b}, age {a} {}
+  Cow (string n, string b) : name {n}, breed {b}, age {0} {}
+  void moo ();
+};
diff --git a/usth/ICT2.2/labwork/3/C++/name-card-test.cc b/usth/ICT2.2/labwork/3/C++/name-card-test.cc
new file mode 100644
index 0000000..b459d0d
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/name-card-test.cc
@@ -0,0 +1,14 @@
+#include <iostream>
+
+#include "name-card.h"
+
+using namespace std;
+
+int
+main ()
+{
+  NameCard card ("Foobar Baz", "420-69", "foo@bar.baz");
+  cout << "Name: " << card.get_name () << endl
+       << "Phone: " << card.get_phone () << endl
+       << "Email: " << card.get_email () << endl;
+}
diff --git a/usth/ICT2.2/labwork/3/C++/name-card.cc b/usth/ICT2.2/labwork/3/C++/name-card.cc
new file mode 100644
index 0000000..b6c0751
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/name-card.cc
@@ -0,0 +1,47 @@
+#include <regex>
+#include <stdexcept>
+#include <string>
+
+#include "name-card.h"
+
+using namespace std;
+
+const regex name_pattern ("[ A-Za-z]+");
+const regex phone_pattern ("[-0-9]+");
+// This should be good enough I guess?
+const regex email_pattern ("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
+
+void
+NameCard::set_name (string s)
+{
+  // I miss Raku so much
+  smatch m;
+  if (!regex_match (s, m, name_pattern))
+    throw invalid_argument{"invalid name"};
+  name = s;
+}
+
+void
+NameCard::set_phone (string s)
+{
+  smatch m;
+  if (!regex_match (s, m, phone_pattern))
+    throw invalid_argument{"invalid number"};
+  phone = s;
+}
+
+void
+NameCard::set_email (string s)
+{
+  smatch m;
+  if (!regex_match (s, m, email_pattern))
+    throw invalid_argument{"invalid name"};
+  email = s;
+}
+
+NameCard::NameCard (string n, string p, string e)
+{
+  set_name (n);
+  set_phone (p);
+  set_email (e);
+}
diff --git a/usth/ICT2.2/labwork/3/C++/name-card.h b/usth/ICT2.2/labwork/3/C++/name-card.h
new file mode 100644
index 0000000..08e76a7
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/name-card.h
@@ -0,0 +1,18 @@
+#include <string>
+
+using namespace std;
+
+class NameCard
+{
+  string name;
+  string phone;
+  string email;
+public:
+  string get_name () { return name; }
+  string get_phone () { return phone; }
+  string get_email () { return email; }
+  void set_name (string);
+  void set_phone (string);
+  void set_email (string);
+  NameCard (string, string, string);
+};
diff --git a/usth/ICT2.2/labwork/3/C++/shopping-cart-test.cc b/usth/ICT2.2/labwork/3/C++/shopping-cart-test.cc
new file mode 100644
index 0000000..4833e70
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/shopping-cart-test.cc
@@ -0,0 +1,19 @@
+#include <iostream>
+
+#include "shopping-cart.h"
+
+using namespace std;
+
+int
+main ()
+{
+  ShoppingCart cart;
+  cart.add_to_cart ("foo");
+  cart.add_to_cart ("foo");
+  cart.add_to_cart ("bar");
+  cart.remove_from_cart ("baz");
+  cout << cart.count ("foo") << ' '
+       << cart.count ("bar") << ' '
+       << cart.count ("baz") << endl;
+  cart.check_out ();
+}
diff --git a/usth/ICT2.2/labwork/3/C++/shopping-cart.h b/usth/ICT2.2/labwork/3/C++/shopping-cart.h
new file mode 100644
index 0000000..c1450e7
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/shopping-cart.h
@@ -0,0 +1,16 @@
+#include <string>
+#include <unordered_map>
+
+using namespace std;
+
+class ShoppingCart
+{
+  // quite of an improvement over the Java version
+  unordered_map<string, int> contents;
+public:
+  void add_to_cart (string item) { contents[item]++; }
+  void remove_from_cart (string item) { contents[item] = 0; }
+  // to make this class useful anyhow
+  int count (string item) { return contents[item]; }
+  void check_out () { contents.clear (); }
+};
diff --git a/usth/ICT2.2/labwork/3/C++/vector-test.cc b/usth/ICT2.2/labwork/3/C++/vector-test.cc
new file mode 100644
index 0000000..647c8a6
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/vector-test.cc
@@ -0,0 +1,20 @@
+#include <iostream>
+
+#include "vector.h"
+
+using namespace std;
+
+int
+main ()
+{
+  Vector u (4, 20);
+  Vector v (6, 9);
+  cout << "u = (" << u.x << ", " << u.y << ")" << endl;
+  cout << "v = (" << v.x << ", " << v.y << ")" << endl;
+  Vector w {u + v};
+  cout << "u + v = (" << w.x << ", " << w.y << ")" << endl;
+  w = u - v;
+  cout << "u - v = (" << w.x << ", " << w.y << ")" << endl;
+  w = u * v;
+  cout << "u * v = (" << w.x << ", " << w.y << ")" << endl;
+}
diff --git a/usth/ICT2.2/labwork/3/C++/vector.cc b/usth/ICT2.2/labwork/3/C++/vector.cc
new file mode 100644
index 0000000..5ac56de
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/vector.cc
@@ -0,0 +1,19 @@
+#include "vector.h"
+
+Vector
+operator+ (Vector u, Vector v)
+{
+  return u += v;
+}
+
+Vector
+operator- (Vector u, Vector v)
+{
+  return u -= v;
+}
+
+Vector
+operator* (Vector u, Vector v)
+{
+  return u *= v;
+}
diff --git a/usth/ICT2.2/labwork/3/C++/vector.h b/usth/ICT2.2/labwork/3/C++/vector.h
new file mode 100644
index 0000000..8433e79
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/C++/vector.h
@@ -0,0 +1,17 @@
+class Vector
+{
+public:
+  int x;
+  int y;
+
+  Vector (int ex, int why) : x {ex}, y {why} {}
+  Vector () : x {0}, y{0} {}
+
+  Vector& operator+= (Vector v) { x += v.x, y += v.y; return *this; }
+  Vector& operator-= (Vector v) { x -= v.x, y -= v.y; return *this; }
+  Vector& operator*= (Vector v) { x *= v.x, y *= v.y; return *this; }
+};
+
+Vector operator+ (Vector, Vector);
+Vector operator- (Vector, Vector);
+Vector operator* (Vector, Vector);
diff --git a/usth/ICT2.2/labwork/3/Java/Automobile.java b/usth/ICT2.2/labwork/3/Java/Automobile.java
new file mode 100644
index 0000000..14a82ef
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/Automobile.java
@@ -0,0 +1,68 @@
+import java.util.regex.Pattern;
+
+class Automobile
+{
+  private static final Pattern licensePattern = Pattern.compile("[0-9A-Z]+");
+  private double fuel;
+  private double speed;
+  private String license;
+
+  public double getFuel()
+  {
+    return fuel;
+  }
+
+  public double getSpeed()
+  {
+    return speed;
+  }
+
+  public String getLicense()
+  {
+    return license;
+  }
+
+  public void setFuel(double fuel)
+  {
+    if (fuel < 0)
+      throw new IllegalArgumentException(
+        "fuel must be nonnegative, instead got " + fuel);
+    this.fuel = fuel;
+  }
+
+  public void setSpeed(double speed)
+  {
+    this.speed = Math.max(0, speed);
+  }
+
+  public void setLicense(String license)
+  {
+    if (!licensePattern.matcher(license).matches())
+      throw new IllegalArgumentException("invalid license: " + license);
+    this.license = license;
+  }
+
+  public Automobile(double f, double s, String l)
+  {
+    setFuel(f);
+    setSpeed(s);
+    setLicense(l);
+  }
+
+  public void accelerate(double v)
+  {
+    if (v < 0)
+      throw new IllegalArgumentException(
+        "acceleration must be nonnegative, instead got " + v);
+    if (fuel > 0)
+      setSpeed(speed + v);
+  }
+
+  public void decelerate(double v)
+  {
+    if (v < 0)
+      throw new IllegalArgumentException(
+        "deceleration must be nonnegative, instead got " + v);
+    setSpeed(speed - v);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/Button.java b/usth/ICT2.2/labwork/3/Java/Button.java
new file mode 100644
index 0000000..8a26b3f
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/Button.java
@@ -0,0 +1,50 @@
+public class Button
+{
+  private String label;
+  private String color;
+  private boolean state;
+
+  public Button(String label, String color)
+  {
+    this.label = label;
+    this.color = color;
+    this.state = false;
+  }
+
+  public String toString()
+  {
+    return String.format("<button %s with color %s and state %s>",
+                         label, color, state);
+  }
+
+  // To be honest these getters and setters are really redundant in this case
+  public String getLabel()
+  {
+    return label;
+  }
+
+  public String getColor()
+  {
+    return color;
+  }
+
+  public void setLabel(String label)
+  {
+    this.label = label;
+  }
+
+  public void setColor(String color)
+  {
+    this.color = color;
+  }
+
+  public void dePress()
+  {
+    this.state = true;
+  }
+
+  public void unDepress()
+  {
+    this.state = false;
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/ButtonTest.java b/usth/ICT2.2/labwork/3/Java/ButtonTest.java
new file mode 100644
index 0000000..51dd4d2
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/ButtonTest.java
@@ -0,0 +1,12 @@
+class ButtonTest
+{
+  public static void main(String... args)
+  {
+    Button button = new Button("foo", "bar");
+    System.out.println(button);
+    button.setLabel("fu");
+    button.setColor("baz");
+    button.dePress();
+    System.out.println(button);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/Cow.java b/usth/ICT2.2/labwork/3/Java/Cow.java
new file mode 100644
index 0000000..36a1051
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/Cow.java
@@ -0,0 +1,36 @@
+public class Cow
+{
+  private String name;
+  private String breed;
+  private int age;
+
+  public Cow(String name, String breed)
+  {
+    this(name, breed, 0);
+  }
+
+  public Cow(String name, String breed, int age)
+  {
+    this.name = name;
+    this.breed = breed;
+    setAge(age);
+  }
+
+  public static void moo()
+  {
+    System.out.println("Moo...!");
+  }
+
+  public int getAge()
+  {
+    return age;
+  }
+
+  public void setAge(int age)
+  {
+    if (age < 0)
+      throw new IllegalArgumentException(
+        "age must be nonnegative, instead got " + age);
+    this.age = age;
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/CowTest.java b/usth/ICT2.2/labwork/3/Java/CowTest.java
new file mode 100644
index 0000000..1a13f67
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/CowTest.java
@@ -0,0 +1,9 @@
+class CowTest   // there's no reason to import a test what-so-ever
+{
+  public static void main(String... args)
+  {
+    Cow cow = new Cow("foo", "bar", 7);
+    cow.setAge(-4);
+    cow.moo();
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/NameCard.java b/usth/ICT2.2/labwork/3/Java/NameCard.java
new file mode 100644
index 0000000..165d5f9
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/NameCard.java
@@ -0,0 +1,67 @@
+import java.util.regex.Pattern;
+
+public class NameCard
+{
+  private static final Pattern namePattern = Pattern.compile("[ A-Za-z]+");
+  private static final Pattern phonePattern = Pattern.compile("[-0-9]*");
+  // I have not learnt regex properly
+  private static final Pattern emailPattern = Pattern.compile(
+    "(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
+
+  private String name;
+  private String phone;
+  private String email;
+
+  public String getName()
+  {
+    return name;
+  }
+
+  public String getPhone()
+  {
+    return phone;
+  }
+
+  public String getEmail()
+  {
+    return email;
+  }
+
+  public void setName(String name)
+  {
+    if (!namePattern.matcher(name).matches())
+      throw new IllegalArgumentException("invalid name: " + name);
+    this.name = name;
+  }
+
+  public void setPhone(String phone)
+  {
+    if (!phonePattern.matcher(phone).matches())
+      throw new IllegalArgumentException("invalid phone number: " + phone);
+    this.phone = phone;
+  }
+
+  public void setEmail(String email)
+  {
+    if (!emailPattern.matcher(email).matches())
+      throw new IllegalArgumentException("invalid email: " + email);
+    this.email = email;
+  }
+
+  public NameCard(String name)
+  {
+    this(name, "", "");
+  }
+
+  public NameCard(String name, String phone)
+  {
+    this(name, phone, "");
+  }
+
+  public NameCard(String name, String phone, String email)
+  {
+    setName(name);
+    setPhone(phone);
+    setEmail(email);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/NameCardTest.java b/usth/ICT2.2/labwork/3/Java/NameCardTest.java
new file mode 100644
index 0000000..ed66343
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/NameCardTest.java
@@ -0,0 +1,9 @@
+class NameCardTest
+{
+  public static void main(String... args)
+  {
+    NameCard card = new NameCard("Foobar Baz", "420-69", "foo@bar.baz");
+    System.out.printf("Name: %s\nPhone: %s\nEmail: %s\n",
+                      card.getName(), card.getPhone(), card.getEmail());
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/README.md b/usth/ICT2.2/labwork/3/Java/README.md
new file mode 100644
index 0000000..f0c494a
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/README.md
@@ -0,0 +1,10 @@
+# Labwork 3: Implementations in Java
+
+For the ease of typing, the test files are named `<classname>Test.java`
+instead of `<classname>TestDrive.java`.
+To rename them to the original requirement, use Perl `rename` and GNU `sed`
+
+```sh
+rename s/Test/TestDrive/ *Test.java
+sed -i s/Test/TestDrive/ *TestDrive.java
+```
diff --git a/usth/ICT2.2/labwork/3/Java/ShoppingCart.java b/usth/ICT2.2/labwork/3/Java/ShoppingCart.java
new file mode 100644
index 0000000..f5e23ad
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/ShoppingCart.java
@@ -0,0 +1,27 @@
+import java.util.ArrayList;
+import java.util.List;
+
+public class ShoppingCart
+{
+  private List<String> cartContents = new ArrayList<String>();
+
+  public boolean addToCart(String content)
+  {
+    return cartContents.add(content);
+  }
+
+  public boolean removeFromCart(String content)
+  {
+    return cartContents.remove(content);
+  }
+
+  public void checkOut()
+  {
+    cartContents.clear();
+  }
+
+  public String toString()
+  {
+    return "Cart content(s): " + String.join(", ", cartContents);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/ShoppingCartTest.java b/usth/ICT2.2/labwork/3/Java/ShoppingCartTest.java
new file mode 100644
index 0000000..315f9f4
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/ShoppingCartTest.java
@@ -0,0 +1,16 @@
+class ShoppingCartTest
+{
+  public static void main(String... args)
+  {
+    ShoppingCart cart = new ShoppingCart();
+    System.out.println(cart);
+    cart.addToCart("foo");
+    cart.addToCart("bar");
+    cart.addToCart("baz");
+    System.out.println(cart);
+    cart.removeFromCart("bar");
+    System.out.println(cart);
+    cart.checkOut();
+    System.out.println(cart);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/Vector.java b/usth/ICT2.2/labwork/3/Java/Vector.java
new file mode 100644
index 0000000..3fc9137
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/Vector.java
@@ -0,0 +1,39 @@
+public class Vector
+{
+  // There's nothing to validate
+  public int x;
+  public int y;
+
+  public Vector()
+  {
+    this(0, 0);
+  }
+
+  public Vector(int x, int y)
+  {
+    this.x = x;
+    this.y = y;
+  }
+
+  public String toString()
+  {
+    // I feel bad writing this
+    return "(" + x + ", " + y + ")";
+  }
+
+  public Vector add(Vector other)
+  {
+    return new Vector(this.x + other.x, this.y + other.y);
+  }
+
+  public Vector subtract(Vector other)
+  {
+    return new Vector(this.x - other.x, this.y - other.y);
+  }
+
+  public Vector multiply(Vector other)
+  {
+    // instruction unclear, applying element-wise multiplication
+    return new Vector(this.x * other.x, this.y * other.y);
+  }
+}
diff --git a/usth/ICT2.2/labwork/3/Java/VectorTest.java b/usth/ICT2.2/labwork/3/Java/VectorTest.java
new file mode 100644
index 0000000..4f0a4a3
--- /dev/null
+++ b/usth/ICT2.2/labwork/3/Java/VectorTest.java
@@ -0,0 +1,10 @@
+class VectorTest
+{
+  public static void main(String... args)
+  {
+    Vector u = new Vector(4, 20);
+    Vector v = new Vector(6, 9);
+    System.out.printf("u = %s\nv = %s\nu + v = %s\nu - v = %s\nu * v = %s\n",
+                      u, v, u.add(v), u.subtract(v), u.multiply(v));
+  }
+}