Eksamen: REA3049 | Semester: Vår 2024 | Tema: OOP, pseudokode, Fibonacci, kalkulator, deepfakes, tidsbruk-datasett, Game of Life
I Java er klasser nettopp maler — du oppretter objekter med new-operatoren basert på klassen.
I Java skrives dette som class B extends A. B har alle A's metoder og kan i tillegg legge til nye eller overstyre eksisterende.
| a | DISPLAY c | b etter DECREMENT | c etter c+b |
|---|---|---|---|
| 2 | 5 | 3 | 5+3 = 8 |
| 3 | 8 | 2 | 8+2 = 10 |
| 4 | 10 | 1 | 10+1 = 11 |
SET num to -2
FOR hver num LESSER THAN OR EQUAL TO 2
IF num LESSER THAN 0
IF num % 2 EQUAL TO 0
DISPLAY num + " er negativt og partall"
ELSE
DISPLAY num + " er negativt og oddetall"
ENDIF
ELSE IF num EQUAL TO 0
DISPLAY num + " er null"
ELSE
IF num % 2 EQUAL TO 0
DISPLAY num + " er positivt og partall"
ELSE
DISPLAY num + " er positivt og oddetall"
ENDIF
ENDIF
ENDFOR
Algoritmen genererer Fibonacci-tallene iterativt: hvert nytt tall er summen av de to foregående, med startverdiene 0 og 1. Iterativ tabulering gir O(n) tid og O(n) plass — mye raskere enn naiv rekursjon.
// FibonacciPartall.java
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class FibonacciPartall {
public static List<BigInteger> fibonacciPartall(int antall) {
BigInteger a = BigInteger.ZERO, b = BigInteger.ONE;
List<BigInteger> partall = new ArrayList<>();
while (partall.size() < antall) {
if (a.mod(BigInteger.TWO).equals(BigInteger.ZERO)) partall.add(a);
BigInteger nestneste = a.add(b);
a = b; b = nestneste;
}
return partall;
}
public static void main(String[] args) {
System.out.println(fibonacciPartall(10));
// [0, 2, 8, 34, 144, 610, 2584, 10946, 46368, 196418]
}
}
int-grensen, det 90. overskrider long. Ved å bruke BigInteger unngår vi overflyt uavhengig av hvor langt vi går.
// Kalkulator.java
public class Kalkulator {
public double pluss(double a, double b) { return a + b; }
public double minus(double a, double b) { return a - b; }
public double gange(double a, double b) { return a * b; }
public double dele(double a, double b) {
if (b == 0) throw new ArithmeticException("Kan ikke dele på null.");
return a / b;
}
}
// TestKalkulator.java
public class TestKalkulator {
public static void main(String[] args) {
Kalkulator k = new Kalkulator();
assert k.pluss(2, 3) == 5;
assert k.minus(10, 4) == 6;
assert k.gange(3, 7) == 21;
assert k.dele(20, 4) == 5;
// Feil 1: Deling på null
try { k.dele(10, 0); }
catch (ArithmeticException e) { System.out.println("OK – fanget: " + e.getMessage()); }
// Feil 2: Deling på 0.0 returnerer Infinity (ikke unntak for double)
System.out.println("10.0 / 0.0 = " + (10.0 / 0.0)); // Infinity
// Unntak: Overflyt for int
// k.gange(Integer.MAX_VALUE, 2) returnerer korrekt double-resultat,
// men hvis vi byttet til int-baserte metoder ville det wrappet.
System.out.println("Tester ferdig.");
}
}
Identifiserte feil/unntak: (1) Deling på null — kaster ArithmeticException for int, returnerer Infinity/NaN for double (Java 9+). (2) Overflyt for heltall — Java sjekker ikke int-overflyt automatisk; Math.addExact() gir feil ved behov. (Unntak) NumberFormatException ved parsing av ugyldig brukerinput.
| Spm. | Riktig svar |
|---|---|
| a) Hva er deepfakes? | manipulerte medier |
| b) Mulig konsekvens? | økt risiko for politisk manipulering |
| c) Hvordan avsløre? | ved å bruke teknikker fra kildekritikk |
Avsløring: Lytt etter unaturlige pauser og robotiske intonasjoner. På video — se etter ujevn belysning, kanter mellom ansikt og bakgrunn som flimrer, unaturlige blunkemønstre. Ved kritiske beslutninger — særlig økonomiske transaksjoner — verifisere alltid gjennom en annen kanal.
Forebygging i bedriften:
For: Realistiske press-scenarier kan avsløre faglig modenhet bedre enn et tradisjonelt intervju. Ved åpenhet og samtykke kan det være legitimt for stillinger der krisemestring er kritisk.
Mot:
Konklusjon: Deepfakes i ansettelsesprosesser kan ha legitime formål, men forutsetter eksplisitt samtykke, klare retningslinjer for sletting av biometriske data, og grundig etisk evaluering.
// Oppgave9.java — analyse av SSB-tidsbruk-datasett (2000)
import java.io.*;
import java.util.*;
public class Oppgave9 {
private static int tidTilMinutter(String s) {
if (s == null || s.isEmpty()) return 0;
String[] del = s.split("\\.");
return Integer.parseInt(del[0]) * 60 + (del.length > 1 ? Integer.parseInt(del[1]) : 0);
}
private static List<Map<String, String>> lesData(String filsti) throws IOException {
List<Map<String, String>> rader = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filsti))) {
String[] headers = br.readLine().split(";");
String linje;
while ((linje = br.readLine()) != null) {
String[] verdier = linje.split(";", -1);
Map<String, String> rad = new LinkedHashMap<>();
for (int i = 0; i < headers.length; i++) {
rad.put(headers[i], i < verdier.length ? verdier[i] : "");
}
rader.add(rad);
}
}
return rader;
}
private static void visTabell(List<Map<String, String>> data, String kjonn) {
System.out.printf("%n%-28s%-10s%10s%n", "Aktivitet", "Kjønn", "Tidsbruk");
System.out.println("-".repeat(48));
for (Map<String, String> r : data) {
if (kjonn.equals("Alle") || r.get("Kjønn").equals(kjonn)) {
System.out.printf("%-28s%-10s%10s%n", r.get("Aktivitet"), r.get("Kjønn"), r.get("Tidsbruk"));
}
}
}
// Stolpediagram som SVG (Java har ingen innebygd diagram-bibliotek)
private static void stolpeSvg(List<Map<String, String>> data, String kjonn) throws IOException {
List<Map<String, String>> rader = data.stream()
.filter(r -> r.get("Kjønn").equals(kjonn))
.toList();
int bredde = 800, hoyde = 500, padding = 80;
int stolpebredde = Math.max(10, (bredde - padding * 2) / rader.size() - 4);
int maks = rader.stream().mapToInt(r -> tidTilMinutter(r.get("Tidsbruk"))).max().orElse(1);
StringBuilder svg = new StringBuilder();
svg.append("<svg xmlns='http://www.w3.org/2000/svg' width='").append(bredde)
.append("' height='").append(hoyde).append("'>");
for (int i = 0; i < rader.size(); i++) {
int v = tidTilMinutter(rader.get(i).get("Tidsbruk"));
int h = (hoyde - padding * 2) * v / maks;
int x = padding + i * (stolpebredde + 4);
int y = hoyde - padding - h;
svg.append("<rect x='").append(x).append("' y='").append(y)
.append("' width='").append(stolpebredde).append("' height='").append(h)
.append("' fill='#1976D2'/>");
}
svg.append("</svg>");
try (FileWriter fw = new FileWriter("stolpe_" + kjonn.toLowerCase() + ".svg")) {
fw.write(svg.toString());
}
System.out.println("Stolpediagram lagret som SVG.");
}
public static void main(String[] args) throws IOException {
List<Map<String, String>> data = lesData("tidsbruk_2000.csv");
Scanner sc = new Scanner(System.in);
System.out.print("Velg kjønn (Alle / Menn / Kvinner): ");
String raw = sc.nextLine().trim();
String kjonn = raw.substring(0, 1).toUpperCase() + raw.substring(1).toLowerCase();
visTabell(data, kjonn);
if (!kjonn.equals("Alle")) stolpeSvg(data, kjonn);
}
}
// GameOfLife.java — Conways Game of Life i Java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class GameOfLife extends JPanel {
private static final int RUTER = 30;
private static final int CELLE = 18;
private static final double START_LEVENDE = 1.0 / 3;
private boolean[][] celler = new boolean[RUTER][RUTER];
private boolean kjorer = false;
private final Timer timer;
public GameOfLife() {
Random rng = new Random();
for (int r = 0; r < RUTER; r++)
for (int k = 0; k < RUTER; k++) celler[r][k] = rng.nextDouble() < START_LEVENDE;
setPreferredSize(new Dimension(RUTER * CELLE, RUTER * CELLE));
timer = new Timer(200, e -> { nesteGenerasjon(); repaint(); });
addMouseListener(new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
int r = e.getY() / CELLE, k = e.getX() / CELLE;
if (r >= 0 && r < RUTER && k >= 0 && k < RUTER) {
celler[r][k] = !celler[r][k];
repaint();
}
}
});
}
public void toggle() { kjorer = !kjorer; if (kjorer) timer.start(); else timer.stop(); }
public void tom() { kjorer = false; timer.stop();
for (int r = 0; r < RUTER; r++) for (int k = 0; k < RUTER; k++) celler[r][k] = false;
repaint();
}
public void ettSteg() { nesteGenerasjon(); repaint(); }
private int levendeNaboer(int r, int k) {
int n = 0;
for (int dr = -1; dr <= 1; dr++)
for (int dk = -1; dk <= 1; dk++) {
if (dr == 0 && dk == 0) continue;
int nr = r + dr, nk = k + dk;
if (nr >= 0 && nr < RUTER && nk >= 0 && nk < RUTER && celler[nr][nk]) n++;
}
return n;
}
private void nesteGenerasjon() {
boolean[][] ny = new boolean[RUTER][RUTER];
for (int r = 0; r < RUTER; r++)
for (int k = 0; k < RUTER; k++) {
int n = levendeNaboer(r, k);
ny[r][k] = celler[r][k] ? (n == 2 || n == 3) : (n == 3);
}
celler = ny;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int r = 0; r < RUTER; r++)
for (int k = 0; k < RUTER; k++) {
g.setColor(celler[r][k] ? new Color(26, 43, 74) : new Color(250, 250, 250));
g.fillRect(k * CELLE, r * CELLE, CELLE - 1, CELLE - 1);
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Game of Life");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameOfLife spill = new GameOfLife();
f.setLayout(new BorderLayout());
f.add(spill, BorderLayout.CENTER);
JPanel knapper = new JPanel();
JButton bToggle = new JButton("Start/Pause"); bToggle.addActionListener(e -> spill.toggle());
JButton bSteg = new JButton("Steg"); bSteg.addActionListener(e -> spill.ettSteg());
JButton bTom = new JButton("Tøm"); bTom.addActionListener(e -> spill.tom());
knapper.add(bToggle); knapper.add(bSteg); knapper.add(bTom);
f.add(knapper, BorderLayout.SOUTH);
f.pack(); f.setLocationRelativeTo(null); f.setVisible(true);
}
}
ny-array er kritisk for korrekt Game of Life.123456/
├── oppgave5c/FibonacciPartall.java + flytskjema.pdf
├── oppgave6/Kalkulator.java + TestKalkulator.java
├── oppgave9/Oppgave9.java + tidsbruk_2000.csv
├── oppgave10/GameOfLife.java
└── README.md (Java 17+)