JavaJava · Chapterبەش 13 · Lectureوانە 13.1
Project: A Student Marks Managerپڕۆژیلە: بەڕێوەبەری نمرەی قوتابیان
The final project of the Java track, built step by step with the five-part method: a teacher's marks book in the terminal. A Student class that refuses bad data, a MarksBook with an ArrayList, statistics (average, highest, lowest) and sorting by mark with a lambda, a switch menu inside a do-while loop, safe input with exceptions, and a UTF-8 marks file that keeps Kurdish names. A full two-day sample session, tests with wrong input and a broken file, six extensions, where to go next with Java, and the whole track on one page.
کۆتایی تراکی Java، هەنگاو بە هەنگاو بە شێوازە پێنج بەشییەکە: دەفتەری نمرەی مامۆستایەک لە . Student کە هەڵە ڕەت دەکاتەوە، MarksBook بە ArrayListـێکەوە، ئامار (تێکڕا، بەرزترین، نزمترین) و بە نمرە بە lambda، switch لە ناو do-whileـدا، بێ مەترسی بە و نمرەی UTF-8 کە ناوی کوردی دەپارێزێت. دانیشتنێکی نموونەیی دوو ڕۆژە، تاقیکردنەوە بە هەڵە و تێکچوو، شەش درێژکراوە، Java دواتر بۆ کوێ و هەموو تراکەکە لە یەک پەڕەدا.
What you will learnچی فێر دەبیت
- Plan a program with the five-part method: scenario, flowchart, algorithm, code and examples.
- Split a program into classes with one job each, and protect the data with a checking constructor.
- Build a menu with a switch inside a do-while loop, and read input that never crashes the program.
- Compute statistics and sort objects with a lambda, and save and load a UTF-8 file with Kurdish names.
- Test a program with wrong input and broken files, extend it, and choose where to go next with Java.
- بە شێوازە پێنج بەشییەکە پلان بکەیت: ، ، ، کۆد و نموونە.
- بکەیت بە چەند کە هەر یەکەیان یەک کاری هەبێت و بە پشکنەر بپارێزیت.
- بە switch لە ناو do-whileـدا دروست بکەیت و بە شێوەیەک بخوێنیتەوە کە هەرگیز تێک نەشکێنێت.
- ئامار بژمێریت و بە lambda ڕیز بکەیت و UTF-8 بە ناوی کوردییەوە پاشەکەوت و بار بکەیت.
- بە هەڵە و تێکچوو تاقی بکەیتەوە، پەرەی پێ بدەیت و هەڵبژێریت دواتر لەگەڵ Java بۆ کوێ بچیت.
The project: a teacher's marks bookپڕۆژیلە: دەفتەری نمرەی مامۆستایەک
This is the last lesson of the Java track, and in it you build one complete program from what you have learned. A teacher wants a marks book on the computer: add students with their marks, list them in the order they were added or by mark, see the average, the highest and the lowest mark, and find everything again tomorrow. The program runs in the terminal; the picture shows the goal.
ئەمە دوایین وانەی تراکی Javaـیە و تێیدا بە ئەوەی فێری بوویت تەواو دروست دەکەیت. مامۆستایەک دەفتەرێکی نمرەی لەسەر دەوێت: قوتابی لەگەڵ نمرەکانیان زیاد بکات، بە ڕیزی زیادکردن یان بە نمرە لیستیان بکات، تێکڕا، بەرزترین و نزمترین نمرە ببینێت و سبەینێ هەموو شتێک دیسان بدۆزێتەوە. لە کار دەکات؛ وێنەکە ئامانجەکە پیشان دەدات.
It uses a class with private fields and a constructor that checks its data, an ArrayList, a switch menu inside a do-while loop, exceptions for wrong input, sorting with a lambda and a UTF-8 file. Every step links to the lesson that taught it.
بە private و کە دەپشکنێت، ArrayListـێک، switch لە ناو do-whileـدا، بۆ هەڵە، بە lambda و UTF-8 بەکار دەهێنێت. هەر هەنگاوێک بەستەری ئەو وانەیەی هەیە کە فێری کردوویت.
Step 1: the scenarioهەنگاوی 1: نەخشەنامە
A good project is planned before it is coded. The five-part method (The project method) goes scenario → flowchart → algorithm → code → examples. First the : what the program must do, in plain words.
باش پێش پلانی بۆ دادەنرێت. شێوازە پێنج بەشییەکە (شێوازی پڕۆژە) بەم ڕیزەیە: ← ← ← کۆد ← نموونەکان. یەکەم : دەبێت چی بکات، بە وشەی ئاسایی.
- Show a menu again and again until the teacher chooses 0.
- 1: read a name and a mark (a whole number from 0 to 100) and add the student. Refuse a wrong mark or an empty name with a clear message, and never crash.
- 2: list the students in the order they were added; 3: list them by mark, largest first.
- 4: show the number of students, the average with one decimal, and the highest and the lowest mark; say so when the book is empty.
- 5: save to
marks.txt; 0: save and exit. At the start, loadmarks.txtif it exists. - Kurdish names must be saved and loaded unchanged.
- دووپاتە و دووپاتە پیشان بدە تا مامۆستا 0 هەڵدەبژێرێت.
- 1: ناوێک و نمرەیەک بخوێنەرەوە ( لە 0 تا 100) و قوتابییەکە زیاد بکە. نمرەی هەڵە یان ناوی بەتاڵ بە پەیامێکی ڕوون ڕەت بکەرەوە و هەرگیز تێک مەشکێ.
- 2: قوتابیان بە ڕیزی زیادکردنیان لیست بکە؛ 3: بە نمرە لیستیان بکە، گەورەترین یەکەم.
- 4: ژمارەی قوتابیان، تێکڕا بە یەک ژمارەی دوای خاڵ و بەرزترین و نزمترین نمرە پیشان بدە؛ ئەگەر دەفتەرەکە بەتاڵ بوو بیڵێ.
- 5: لە
marks.txtـدا پاشەکەوت بکە؛ 0: پاشەکەوت بکە و دەرچۆ. لە سەرەتادا، ئەگەرmarks.txtهەبوو باری بکە. - ناوە کوردییەکان دەبێت بەبێ گۆڕان پاشەکەوت و بار بکرێن.
Step 2: the flowchartهەنگاوی 2: هێڵکاریی ڕەوت
The flowchart draws the menu loop with the shared symbols (Flowchart symbols): ovals for start and end, parallelograms for input and output, rectangles for steps and diamonds for decisions. The switch picks one branch, and the loop repeats while the choice is not 0. Because the question comes at the end, it is a do-while loop: the menu is shown at least once (do-while).
بە هێما هاوبەشەکان دەکێشێت (هێماکانی هێڵکاریی ڕەوت): هێلکەیی بۆ دەستپێک و کۆتایی، لاکێشەی لار بۆ و ، لاکێشە بۆ هەنگاوەکان و چوارگۆشەی لار بۆ بڕیارەکان. switch یەک لق هەڵدەبژێرێت و دووپاتە دەبێتەوە تا کاتێک هەڵبژاردنەکە 0 نەبێت. چونکە پرسیارەکە لە کۆتاییدا دێت، do-whileـە: لانیکەم یەک جار پیشان دەدرێت (do-while).
Step 3: the algorithm and three classesهەنگاوی 3: ئەلگۆریزمەکە و سێ کلاس
Now the steps as , still without Java:
ئێستا هەنگاوەکان وەک ، هێشتا بەبێ Java:
load marks.txt if it exists
repeat
show the menu with the number of students
choice = read a whole number (ask again until it is one)
choice 1: read a name and a mark; add a Student, or say why not
choice 2: show all students in the order they were added
choice 3: show the students, largest mark first
choice 4: if the book is empty, say so;
else show the count, the average, the highest and the lowest
choice 5 or 0: save marks.txt
any other number: say "There is no ... in the menu"
until choice is 0
say "Goodbye!"Then split the work (Decomposition). Student holds one checked student, MarksBook keeps the list and does the work on it, and MarksApp talks to the teacher. The shows each class with its fields (–, private) and its methods (+, public):
پاشان کارەکە دابەش بکە (دابەشکردن). Student یەک قوتابیی پشکنراو هەڵدەگرێت، MarksBook هەڵدەگرێت و کارەکانی لەسەر دەکات و MarksApp قسە لەگەڵ مامۆستا دەکات. هەر لەگەڵ (–، private) و (+، public) پیشان دەدات:
Step 4a: the Student classهەنگاوی 4a: کلاسی Student
A Student has two private final fields and getters (Encapsulation). The constructor checks its data and throws an IllegalArgumentException for a bad name or mark (throw), so a wrong student can never exist. A ; in a name is refused too, because the file will put ; between the name and the mark:
Student دوو private final و هەیە (کەپسوولکردن). دەپشکنێت و بۆ ناو یان نمرەی هەڵە IllegalArgumentException فڕێ دەدات (throw)، بۆیە قوتابیی هەڵە هەرگیز بوونی نابێت. ; لە ناودا ڕەت دەکرێتەوە، چونکە ; دەخاتە نێوان ناو و نمرە:
public class Student {
private final String name;
private final int mark;
public Student(String name, int mark) {
if (name.isEmpty()) {
throw new IllegalArgumentException("a name is needed");
}
if (name.contains(";")) { // ; separates name and mark in the file
throw new IllegalArgumentException("a name may not contain ;");
}
if (mark < 0 || mark > 100) {
throw new IllegalArgumentException("a mark must be from 0 to 100");
}
this.name = name;
this.mark = mark;
}
public String getName() {
return name;
}
public int getMark() {
return mark;
}
@Override
public String toString() {
return name + " " + mark;
}
}public class StudentTest {
public static void main(String[] args) {
Student aram = new Student("Aram", 85);
System.out.println(aram + " | name: " + aram.getName() + " | mark: " + aram.getMark());
try {
new Student("Shilan", 120);
} catch (IllegalArgumentException e) {
System.out.println("Refused: " + e.getMessage());
}
new Student("", 70); // not caught: the program stops
}
}$ java StudentTest Aram 85 | name: Aram | mark: 85 Refused: a mark must be from 0 to 100 Exception in thread "main" java.lang.IllegalArgumentException: a name is needed at Student.<init>(Student.java:7) at StudentTest.main(StudentTest.java:10)
The caught exception printed its message; the uncaught one stopped the test, as it should. The menu will catch it and tell the teacher.
پەیامەکەی چاپ کرد؛ ئەوەی نەگیرا تاقیکردنەوەکەی وەستاند، وەک پێویستە. دەیگرێت و بە مامۆستا دەڵێت.
Step 4b: MarksBook: the list and the statisticsهەنگاوی 4b: MarksBook: لیستەکە و ئامارەکان
MarksBook keeps an ArrayList<Student> and does every job on it. all() returns a copy, so no other class can change the real list. byMark() sorts a copy with a lambda, largest first (Lambdas). highest() and lowest() use Collections.max and Collections.min with Comparator.comparingInt (comparing):
MarksBook ArrayList<Student>ـێک هەڵدەگرێت و هەموو کارێک لەسەری دەکات. all() کۆپییەک دەگەڕێنێتەوە، بۆیە هیچ تر ناتوانێت بگۆڕێت. byMark() کۆپییەک بە lambda ڕیز دەکات، گەورەترین یەکەم (lambda). highest() و lowest() Collections.max و Collections.min لەگەڵ Comparator.comparingInt بەکار دەهێنن (comparing):
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MarksBook {
private final List<Student> students = new ArrayList<>();
public void add(Student s) {
students.add(s);
}
public int size() {
return students.size();
}
public List<Student> all() { // a copy: nobody can change our list
return new ArrayList<>(students);
}
public List<Student> byMark() { // the largest mark first
List<Student> copy = all();
copy.sort((a, b) -> Integer.compare(b.getMark(), a.getMark()));
return copy;
}
public double average() {
int total = 0;
for (Student s : students) {
total += s.getMark();
}
return (double) total / students.size();
}
public Student highest() {
return Collections.max(students, Comparator.comparingInt(Student::getMark));
}
public Student lowest() {
return Collections.min(students, Comparator.comparingInt(Student::getMark));
}
}public class BookTest {
public static void main(String[] args) {
MarksBook book = new MarksBook();
book.add(new Student("Aram", 85));
book.add(new Student("Shilan", 91));
book.add(new Student("Karwan", 58));
book.add(new Student("Dilan", 72));
System.out.println("all: " + book.all());
System.out.println("by mark: " + book.byMark());
System.out.println("average: " + book.average());
System.out.println("highest: " + book.highest() + ", lowest: " + book.lowest());
}
}$ java BookTest all: [Aram 85, Shilan 91, Karwan 58, Dilan 72] by mark: [Shilan 91, Aram 85, Dilan 72, Karwan 58] average: 76.5 highest: Shilan 91, lowest: Karwan 58
(double) total / students.size() divides as a decimal; total / students.size() would cut 76.5 down to 76 (Dividing whole numbers). With no students it would divide 0.0 by 0 and give NaN, so the menu checks size() == 0 first.
(double) total / students.size() بە ژمارەی دەیی دابەش دەکات؛ total / students.size() 76.5 دەبڕێت بۆ 76 (دابەشکردنی ژمارە تەواوەکان). بەبێ قوتابی 0.0 دابەش 0 دەکات و NaN دەدات، بۆیە سەرەتا size() == 0 دەپشکنێت.
Step 4c: safe input with readIntهەنگاوی 4c: نێوخستەی بێ مەترسی بە readInt
Teachers make typing mistakes. If a mark is read with a bare Integer.parseInt, one wrong word stops the whole program:
مامۆستاکان لە نووسیندا هەڵە دەکەن. ئەگەر نمرەیەک تەنیا بە Integer.parseInt بخوێنرێتەوە، یەک وشەی هەڵە هەموو دەوەستێنێت:
import java.util.Scanner;
public class ReadMark {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Mark (0-100): ");
int mark = Integer.parseInt(input.nextLine().trim());
System.out.println("Mark: " + mark);
}
}$ java ReadMark Mark (0-100): ninety Exception in thread "main" java.lang.NumberFormatException: For input string: "ninety" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:668) at java.base/java.lang.Integer.parseInt(Integer.java:786) at ReadMark.main(ReadMark.java:7)
readInt reads a whole line, tries Integer.parseInt and catches the NumberFormatException, asking again until a whole number comes (A safe input loop). Reading only whole lines, never nextInt(), also avoids the Enter that nextInt() leaves behind (The nextLine trap):
readInt دێڕێکی تەواو دەخوێنێتەوە، Integer.parseInt تاقی دەکاتەوە و NumberFormatException دەگرێت و دووپاتە دەپرسێت تا دێت (خولێکی نێوخستەی بێ مەترسی). خوێندنەوەی تەنیا دێڕی تەواو، هەرگیز nextInt() نا، ئەو Enterـەش لادەبات کە nextInt() بەجێی دەهێڵێت (تەڵەی nextLine):
static int readInt(String prompt) { // asks until a whole number comes
while (true) {
System.out.print(prompt);
String text = input.nextLine().trim();
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
System.out.println("\"" + text + "\" is not a whole number. Try again.");
}
}
}parseInt also reads Eastern Arabic digits, so a teacher who types ٧٢ gets 72. For printing, the program uses String.format(Locale.ROOT, "%.1f", …), so the average looks like 76.5 on every computer (Locale.ROOT).
parseInt ژمارەی عەرەبیی ڕۆژهەڵاتیش دەخوێنێتەوە، بۆیە مامۆستایەک کە ٧٢ بنووسێت 72 وەردەگرێت. بۆ چاپکردن، String.format(Locale.ROOT, "%.1f", …) بەکار دەهێنێت، بۆیە تێکڕا لەسەر هەموو وەک 76.5 دەردەکەوێت (Locale.ROOT).
Testing with wrong inputتاقیکردنەوە بە نێوخستەی هەڵە
A program is tested with the inputs that could break it, not only with the good ones. This run tries the statistics on an empty book, a word instead of a mark, a mark of 120, an empty name and a menu number that does not exist:
بە وا تاقی دەکرێتەوە کە دەتوانێت تێکی بشکێنێت، نەک تەنیا بە باش. ئەم کارپێکردنە ئامار لەسەر دەفتەرێکی بەتاڵ، وشەیەک لە جیاتی نمرە، نمرەی 120، ناوێکی بەتاڵ و ژمارەیەکی کە بوونی نییە تاقی دەکاتەوە:
$ java MarksApp == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 4 No marks yet. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 1 Name: Karwan Mark (0-100): ninety "ninety" is not a whole number. Try again. Mark (0-100): 58 Added Karwan. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 1 Name: Dilan Mark (0-100): 120 Not added: a mark must be from 0 to 100. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 1 Name: Mark (0-100): 70 Not added: a name is needed. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 9 There is no 9 in the menu. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 3 1. Karwan: 58 == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 0 Exit Choose: 0 Goodbye!
Every wrong input got a clear message, and the program kept running. ninety was caught by readInt; 120 and the empty name by the Student constructor; 9 by default.
هەموو هەڵە پەیامێکی ڕوونی وەرگرت و بەردەوام بوو. ninety لە readIntـدا گیرا؛ 120 و ناوە بەتاڵەکە لە Studentـدا؛ 9 لە defaultـدا.
Step 4e: saving and loading a UTF-8 fileهەنگاوی 4e: پاشەکەوتکردن و بارکردنی فایلێکی UTF-8
Memory forgets when the program ends; a file remembers (Why files?). save writes one line per student, name;mark, and load splits each line at ;. Both name UTF-8, so Kurdish names come back unchanged on every computer (Kurdish out and back in):
کاتێک کۆتایی دێت لەبیری دەچێت؛ لەبیری دەمێنێت (بۆچی فایلەکان؟). save بۆ هەر قوتابییەک دێڕێکی وەک name;mark دەنووسێت و load هەر دێڕێک لە ;ـدا لەت دەکات. هەردووکیان UTF-8 دیاری دەکەن، بۆیە ناوە کوردییەکان لەسەر هەموو بەبێ گۆڕان دەگەڕێنەوە (کوردی، چوونە دەرەوە و هاتنەوە):
public void save(Path file) throws IOException {
List<String> lines = new ArrayList<>();
for (Student s : students) {
lines.add(s.getName() + ";" + s.getMark()); // one student per line
}
Files.write(file, lines, StandardCharsets.UTF_8);
}
public int load(Path file) throws IOException {
int loaded = 0;
for (String line : Files.readAllLines(file, StandardCharsets.UTF_8)) {
String[] parts = line.split(";");
if (parts.length != 2) {
System.out.println("Skipped a bad line: " + line);
continue;
}
try {
add(new Student(parts[0], Integer.parseInt(parts[1])));
loaded++;
} catch (IllegalArgumentException e) { // NumberFormatException is one too
System.out.println("Skipped a bad line: " + line);
}
}
return loaded;
}A line that cannot be read is skipped with a message instead of stopping the program. One catch (IllegalArgumentException e) covers both a bad number and a bad student, because NumberFormatException is a subclass of IllegalArgumentException (The exception family). MarksApp calls load at the start and save on 5 and 0, and catches IOException:
دێڕێک کە ناخوێنرێتەوە بە پەیامێک تێدەپەڕێنرێت، لە جیاتی وەستاندنی . یەک catch (IllegalArgumentException e) هەم ژمارەی هەڵە و هەم قوتابیی هەڵە دەگرێتەوە، چونکە NumberFormatException جۆرێکە لە IllegalArgumentException () (خێزانی هەڵاوێردەکان). MarksApp لە سەرەتادا load و لە 5 و 0ـدا save بانگ دەکات و IOException دەگرێت:
static void load(MarksBook book) {
if (!Files.exists(FILE)) {
System.out.println("No " + FILE + " yet: a new marks book.");
return;
}
try {
int n = book.load(FILE);
System.out.println("Loaded " + FILE + " (students: " + n + ").");
} catch (IOException e) {
System.out.println("Could not read " + FILE + ": " + e.getMessage());
}
}
static void save(MarksBook book) {
try {
book.save(FILE);
System.out.println("Saved " + FILE + " (students: " + book.size() + ").");
} catch (IOException e) {
System.out.println("Could not save: " + e.getMessage());
}
}The complete programبەرنامە تەواوەکە
Here are the final MarksBook and MarksApp; Student is unchanged from step 4a. Put the three files in one folder, compile them together and run MarksApp (Compile and run):
ئەمانە MarksBook و MarksAppـی کۆتایین؛ Student لە هەنگاوی 4aـوە نەگۆڕاوە. سێ بخە یەک ، پێکەوە کۆمپایلیان بکە و MarksApp کار پێ بکە (کۆمپایل و کارپێکردن):
javac Student.java MarksBook.java MarksApp.java
java MarksAppimport java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MarksBook {
private final List<Student> students = new ArrayList<>();
public void add(Student s) {
students.add(s);
}
public int size() {
return students.size();
}
public List<Student> all() { // a copy: nobody can change our list
return new ArrayList<>(students);
}
public List<Student> byMark() { // the largest mark first
List<Student> copy = all();
copy.sort((a, b) -> Integer.compare(b.getMark(), a.getMark()));
return copy;
}
public double average() {
int total = 0;
for (Student s : students) {
total += s.getMark();
}
return (double) total / students.size();
}
public Student highest() {
return Collections.max(students, Comparator.comparingInt(Student::getMark));
}
public Student lowest() {
return Collections.min(students, Comparator.comparingInt(Student::getMark));
}
public void save(Path file) throws IOException {
List<String> lines = new ArrayList<>();
for (Student s : students) {
lines.add(s.getName() + ";" + s.getMark()); // one student per line
}
Files.write(file, lines, StandardCharsets.UTF_8);
}
public int load(Path file) throws IOException {
int loaded = 0;
for (String line : Files.readAllLines(file, StandardCharsets.UTF_8)) {
String[] parts = line.split(";");
if (parts.length != 2) {
System.out.println("Skipped a bad line: " + line);
continue;
}
try {
add(new Student(parts[0], Integer.parseInt(parts[1])));
loaded++;
} catch (IllegalArgumentException e) { // NumberFormatException is one too
System.out.println("Skipped a bad line: " + line);
}
}
return loaded;
}
}import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
public class MarksApp {
static final Path FILE = Path.of("marks.txt");
static final Scanner input = new Scanner(System.in);
public static void main(String[] args) {
MarksBook book = new MarksBook();
load(book);
int choice;
do {
System.out.println();
System.out.println("== Marks book (students: " + book.size() + ") ==");
System.out.println("1 Add a student 2 Show all 3 Show by mark");
System.out.println("4 Statistics 5 Save 0 Save and exit");
choice = readInt("Choose: ");
switch (choice) {
case 1 -> addStudent(book);
case 2 -> show(book.all());
case 3 -> show(book.byMark());
case 4 -> statistics(book);
case 5, 0 -> save(book);
default -> System.out.println("There is no " + choice + " in the menu.");
}
} while (choice != 0);
System.out.println("Goodbye!");
}
static void load(MarksBook book) {
if (!Files.exists(FILE)) {
System.out.println("No " + FILE + " yet: a new marks book.");
return;
}
try {
int n = book.load(FILE);
System.out.println("Loaded " + FILE + " (students: " + n + ").");
} catch (IOException e) {
System.out.println("Could not read " + FILE + ": " + e.getMessage());
}
}
static void save(MarksBook book) {
try {
book.save(FILE);
System.out.println("Saved " + FILE + " (students: " + book.size() + ").");
} catch (IOException e) {
System.out.println("Could not save: " + e.getMessage());
}
}
static int readInt(String prompt) { // asks until a whole number comes
while (true) {
System.out.print(prompt);
String text = input.nextLine().trim();
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
System.out.println("\"" + text + "\" is not a whole number. Try again.");
}
}
}
static void addStudent(MarksBook book) {
System.out.print("Name: ");
String name = input.nextLine().trim();
int mark = readInt("Mark (0-100): ");
try {
book.add(new Student(name, mark));
System.out.println("Added " + name + ".");
} catch (IllegalArgumentException e) {
System.out.println("Not added: " + e.getMessage() + ".");
}
}
static void show(List<Student> list) {
if (list.isEmpty()) {
System.out.println("The marks book is empty.");
}
int number = 1;
for (Student s : list) {
System.out.println(number + ". " + s.getName() + ": " + s.getMark());
number++;
}
}
static void statistics(MarksBook book) {
if (book.size() == 0) {
System.out.println("No marks yet.");
return;
}
System.out.println("Students: " + book.size());
System.out.println("Average: " + String.format(Locale.ROOT, "%.1f", book.average()));
System.out.println("Highest: " + book.highest());
System.out.println("Lowest: " + book.lowest());
}
}Step 5: examples: two days with the marks bookهەنگاوی 5: نموونەکان: دوو ڕۆژ لەگەڵ دەفتەری نمرە
The last step of the method runs examples and checks the answers by hand. On day 1 the teacher types four students, with Kurdish names and a few mistakes, and leaves with 0; cat marks.txt shows the file. On day 2 the program loads it, and Hana is added:
دوایین هەنگاوی شێوازەکە نموونە کار پێ دەکات و وەڵامەکان بە دەست دەپشکنێت. لە ڕۆژی 1ـدا مامۆستا چوار قوتابی بە ناوی کوردی و چەند هەڵەیەکەوە دەنووسێت و بە 0 دەردەچێت؛ cat marks.txt پیشان دەدات. لە ڕۆژی 2ـدا باری دەکات و Hana زیاد دەکرێت:
$ java MarksApp No marks.txt yet: a new marks book. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 4 No marks yet. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: ئارام Mark (0-100): 85 Added ئارام. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: شیلان Mark (0-100): ninety "ninety" is not a whole number. Try again. Mark (0-100): 91 Added شیلان. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: کاروان Mark (0-100): 120 Not added: a mark must be from 0 to 100. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: کاروان Mark (0-100): 58 Added کاروان. == Marks book (students: 3) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: Dilan Mark (0-100): ٧٢ Added Dilan. == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 2 1. ئارام: 85 2. شیلان: 91 3. کاروان: 58 4. Dilan: 72 == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 3 1. شیلان: 91 2. ئارام: 85 3. Dilan: 72 4. کاروان: 58 == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 4 Students: 4 Average: 76.5 Highest: شیلان 91 Lowest: کاروان 58 == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 0 Saved marks.txt (students: 4). Goodbye! $ cat marks.txt ئارام;85 شیلان;91 کاروان;58 Dilan;72 $ java MarksApp Loaded marks.txt (students: 4). == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 3 1. شیلان: 91 2. ئارام: 85 3. Dilan: 72 4. کاروان: 58 == Marks book (students: 4) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: Hana Mark (0-100): 64 Added Hana. == Marks book (students: 5) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 4 Students: 5 Average: 74.0 Highest: شیلان 91 Lowest: کاروان 58 == Marks book (students: 5) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 0 Saved marks.txt (students: 5). Goodbye! $ cat marks.txt ئارام;85 شیلان;91 کاروان;58 Dilan;72 Hana;64
Check by hand: and, with Hana, . ninety and 120 were refused, ٧٢ became 72, and the Kurdish names came back from the file unchanged.
بە دەست بیپشکنە: و لەگەڵ Hana، . ninety و 120 ڕەت کرانەوە، ٧٢ بوو بە 72 و ناوە کوردییەکان بەبێ گۆڕان لە گەڕانەوە.
Testing: a broken marks fileتاقیکردنەوە: فایلێکی نمرەی تێکچوو
A text file can be edited by hand, and then it can break. This test writes a marks.txt with three bad lines and starts the program:
دەتوانرێت بە دەست دەستکاری بکرێت و ئەو کاتە دەتوانێت تێک بچێت. ئەم تاقیکردنەوەیە marks.txtـێک بە سێ دێڕی هەڵەوە دەنووسێت و کار پێ دەکات:
$ printf 'Aram;85\nSoran;abc\nLana\nRebin;140\nHana;64\n' > marks.txt $ java MarksApp Skipped a bad line: Soran;abc Skipped a bad line: Lana Skipped a bad line: Rebin;140 Loaded marks.txt (students: 2). == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 2 1. Aram: 85 2. Hana: 64 == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 0 Saved marks.txt (students: 2). Goodbye! $ cat marks.txt Aram;85 Hana;64
The good lines load and the program keeps running. But choice 0 saved only the two good students, so the broken lines are gone for good. The extension "Keep a backup" below fixes that.
دێڕە دروستەکان بار دەکرێن و بەردەوام دەبێت. بەڵام هەڵبژاردنی 0 تەنیا دوو قوتابییە دروستەکەی پاشەکەوت کرد، بۆیە دێڕە تێکچووەکان بۆ هەمیشە ڕۆیشتن. درێژکراوەی « هەڵبگرە» لە خوارەوە ئەمە چارەسەر دەکات.
Extend the projectپڕۆژیلەکە پەرە پێ بدە
A project is never finished. Each extension below was written and run; try it yourself before you open the answer.
هەرگیز تەواو نابێت. هەر یەکێک لەم درێژکراوانەی خوارەوە نووسراوە و کاری پێ کراوە؛ پێش کردنەوەی وەڵامەکە خۆت هەوڵی بدە.
Write static String grade(int mark) with a switch expression: 90–100 A, 80–89 B, 70–79 C, 60–69 D, 50–59 E, below 50 F (an example scale; schools use different ones). Test it with 100, 90, 89, 72, 50, 49 and 0.
static String grade(int mark) بە بنووسە: 90–100 A، 80–89 B، 70–79 C، 60–69 D، 50–59 E، خوار 50 F (پێوەرێکی نموونەیی؛ قوتابخانەکان پێوەری جیاواز بەکار دەهێنن). بە 100، 90، 89، 72، 50، 49 و 0 تاقی بکەرەوە.
Hintئاماژە
Switch on mark / 10.
switch لەسەر mark / 10 بکە.
Show answerوەڵامەکە پیشان بدە
public class Grades {
static String grade(int mark) { // an example scale; schools differ
return switch (mark / 10) {
case 10, 9 -> "A";
case 8 -> "B";
case 7 -> "C";
case 6 -> "D";
case 5 -> "E";
default -> "F";
};
}
public static void main(String[] args) {
for (int mark : new int[] {100, 90, 89, 72, 50, 49, 0}) {
System.out.println(mark + " -> " + grade(mark));
}
}
}$ java Grades 100 -> A 90 -> A 89 -> B 72 -> C 50 -> E 49 -> F 0 -> F
mark / 10 turns 72 into 7 (integer division), so each case covers ten marks; case 10, 9 puts 100 with the A marks (switch expressions).
mark / 10 72 دەکات بە 7 ()، بۆیە هەر حاڵەتێک دە نمرە دەگرێتەوە؛ case 10, 9 100 دەخاتە ڕیزی نمرەکانی A (دەربڕینەکانی switch).
Add menu item 6, Find. Keep a HashMap<String, Student> next to the list, with lower-case names as keys, so that a search for shilan finds Shilan. Refuse a name that is already in the book.
بڕگەی 6، Find، بۆ زیاد بکە. HashMap<String, Student>ـێک لە تەنیشت هەڵبگرە، بە ناوی پیتی بچووک وەک ، تا گەڕان بۆ shilan Shilan بدۆزێتەوە. ناوێک ڕەت بکەرەوە کە پێشتر لە دەفتەرەکەدایە.
Hintئاماژە
Store s.getName().toLowerCase() as the key in add.
لە addـدا s.getName().toLowerCase() وەک هەڵبگرە.
Show answerوەڵامەکە پیشان بدە
private final Map<String, Student> byName = new HashMap<>(); // name -> student
public void add(Student s) {
String key = s.getName().toLowerCase();
if (byName.containsKey(key)) {
throw new IllegalArgumentException(s.getName() + " is already in the book");
}
students.add(s);
byName.put(key, s);
}
public Student find(String name) { // null when nobody has this name
return byName.get(name.toLowerCase());
} static void find(MarksBook book) {
System.out.print("Name: ");
Student s = book.find(input.nextLine().trim());
if (s == null) {
System.out.println("Nobody with that name.");
} else {
System.out.println(s.getName() + " has " + s.getMark() + ".");
}
}$ java MarksApp No marks.txt yet: a new marks book. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 1 Name: Aram Mark (0-100): 85 Added Aram. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 1 Name: Shilan Mark (0-100): 91 Added Shilan. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 1 Name: aram Mark (0-100): 60 Not added: aram is already in the book. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 6 Name: shilan Shilan has 91. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 6 Name: Rebin Nobody with that name. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 6 Find 0 Save and exit Choose: 0 Saved marks.txt (students: 2). Goodbye!
The map finds a name in one step (HashMap), and toLowerCase() makes the search ignore capitals. add throws for a name that is already a key, and addStudent prints the message. Also add import java.util.HashMap; and import java.util.Map; at the top of MarksBook.java, the line case 6 -> find(book); to the switch and 6 Find to the menu.
HashMapـەکە بە یەک هەنگاو ناوێک دەدۆزێتەوە (HashMap) و toLowerCase() وا دەکات گەڕانەکە پیتی گەورە پشتگوێ بخات. add بۆ ناوێک کە پێشتر بێت فڕێ دەدات و addStudent پەیامەکە چاپ دەکات. هەروەها import java.util.HashMap; و import java.util.Map; لە سەرەتای MarksBook.java، دێڕی case 6 -> find(book); بۆ switch و 6 Find بۆ زیاد بکە.
Add menu item 7, Remove: read a name and remove that student, whatever the capitals.
بڕگەی 7، Remove، زیاد بکە: ناوێک بخوێنەرەوە و ئەو قوتابییە لاببە، هەر پیتێکی گەورە یان بچووکی هەبێت.
Show answerوەڵامەکە پیشان بدە
public boolean remove(String name) { // true when someone was removed
return students.removeIf(s -> s.getName().equalsIgnoreCase(name));
} static void remove(MarksBook book) {
System.out.print("Name: ");
String name = input.nextLine().trim();
if (book.remove(name)) {
System.out.println("Removed " + name + ".");
} else {
System.out.println("Nobody called " + name + ".");
}
}$ java MarksApp No marks.txt yet: a new marks book. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 1 Name: Aram Mark (0-100): 85 Added Aram. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 1 Name: Karwan Mark (0-100): 58 Added Karwan. == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 7 Name: karwan Removed karwan. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 7 Name: Lana Nobody called Lana. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 2 1. Aram: 85 == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 7 Remove 0 Save and exit Choose: 0 Saved marks.txt (students: 1). Goodbye!
removeIf with equalsIgnoreCase removes every matching student and returns true when it removed one (removeIf). In MarksApp, add case 7 -> remove(book); and 7 Remove to the menu.
removeIf لەگەڵ equalsIgnoreCase هەموو قوتابییەکی گونجاو لادەبات و کاتێک یەکێکی لابرد true دەگەڕێنێتەوە (removeIf). لە MarksAppـدا case 7 -> remove(book); زیاد بکە و 7 Remove بخەرە ناو .
Print one bar of # per student, one # for every 10 marks, with the names and marks lined up.
بۆ هەر قوتابییەک ستوونێک لە # چاپ بکە، بۆ هەر 10 نمرە یەک #، بە ناو و نمرەی ڕێکخراو لە ستووندا.
Show answerوەڵامەکە پیشان بدە
import java.util.List;
public class Chart {
public static void main(String[] args) {
List<Student> students = List.of(new Student("Aram", 85), new Student("Shilan", 91),
new Student("Karwan", 58), new Student("Dilan", 72));
for (Student s : students) {
String bar = "#".repeat(s.getMark() / 10); // one # for every 10 marks
System.out.printf("%-7s %-10s %d%n", s.getName(), bar, s.getMark());
}
}
}$ java Chart Aram ######## 85 Shilan ######### 91 Karwan ##### 58 Dilan ####### 72
Before save overwrites marks.txt, copy the old file to marks.txt.bak, so that lines skipped by load are not lost.
پێش ئەوەی save بەسەر marks.txtـدا بنووسێت، کۆپی بکە بۆ marks.txt.bak، تا ئەو دێڕانەی load تێیپەڕاندوون ون نەبن.
Show answerوەڵامەکە پیشان بدە
public void save(Path file) throws IOException {
if (Files.exists(file)) { // keep the last version as marks.txt.bak
Path backup = Path.of(file + ".bak");
Files.copy(file, backup, StandardCopyOption.REPLACE_EXISTING);
}
List<String> lines = new ArrayList<>();
for (Student s : students) {
lines.add(s.getName() + ";" + s.getMark()); // one student per line
}
Files.write(file, lines, StandardCharsets.UTF_8);
}$ printf 'Aram;85\nSoran;abc\nHana;64\n' > marks.txt $ java MarksApp Skipped a bad line: Soran;abc Loaded marks.txt (students: 2). == Marks book (students: 2) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 0 Saved marks.txt (students: 2). Goodbye! $ cat marks.txt Aram;85 Hana;64 $ cat marks.txt.bak Aram;85 Soran;abc Hana;64
Files.copy with REPLACE_EXISTING keeps the last version, broken line included, in marks.txt.bak. Add import java.nio.file.StandardCopyOption; at the top of MarksBook.java.
Files.copy لەگەڵ REPLACE_EXISTING دوایین وەشان، دێڕە تێکچووەکەشەوە، لە marks.txt.bakـدا دەهێڵێتەوە. import java.nio.file.StandardCopyOption; لە سەرەتای MarksBook.javaـدا زیاد بکە.
Run the program with input that ends in the middle, for example printf '1\nAram\n' | java MarksApp or Ctrl+D in the terminal. What happens, and how can readInt handle it?
بە کار پێ بکە کە لە ناوەڕاستدا کۆتایی دێت، بۆ نموونە printf '1\nAram\n' | java MarksApp یان Ctrl+D لە . چی ڕوو دەدات و readInt چۆن دەتوانێت مامەڵەی لەگەڵ بکات؟
Show answerوەڵامەکە پیشان بدە
$ java MarksApp No marks.txt yet: a new marks book. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: Aram Mark (0-100): Exception in thread "main" java.util.NoSuchElementException: No line found at java.base/java.util.Scanner.nextLine(Scanner.java:1651) at MarksApp.readInt(MarksApp.java:59) at MarksApp.addStudent(MarksApp.java:71) at MarksApp.main(MarksApp.java:23)
nextLine() throws NoSuchElementException: "No line found". Ask hasNextLine() first and, when the input has ended, answer 0, which saves and exits:
nextLine() NoSuchElementException فڕێ دەدات: «No line found». سەرەتا hasNextLine() بپرسە و کاتێک کۆتایی هات، 0 بگەڕێنەرەوە کە پاشەکەوت دەکات و دەردەچێت:
static int readInt(String prompt) { // asks until a whole number comes
while (true) {
System.out.print(prompt);
if (!input.hasNextLine()) { // the input has ended (Ctrl+D)
System.out.println();
return 0; // 0 = save and exit
}
String text = input.nextLine().trim();
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
System.out.println("\"" + text + "\" is not a whole number. Try again.");
}
}
}$ java MarksApp No marks.txt yet: a new marks book. == Marks book (students: 0) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: 1 Name: Aram Mark (0-100): 85 Added Aram. == Marks book (students: 1) == 1 Add a student 2 Show all 3 Show by mark 4 Statistics 5 Save 0 Save and exit Choose: Saved marks.txt (students: 1). Goodbye!
Where next with JavaJava دواتر بۆ کوێ؟
You can now write, test and organise a real Java program. Some directions from here:
ئێستا دەتوانیت ڕاستەقینەی Java بنووسیت، تاقی بکەیتەوە و ڕێکی بخەیت. چەند ئاڕاستەیەک لێرەوە:
- Newer Java: records write a data class like
Studentin one line (below),switchgets pattern matching, and since Java 25 a first program can be justvoid main()(Java versions). - Desktop apps with windows, buttons and charts: JavaFX.
- Web back ends: Spring Boot runs the servers and APIs of many companies and banks (back end).
- Android apps: Google recommends Kotlin first (as of November 2026), a language that runs on the same platform and works side by side with Java code (Native apps).
- More of the language: threads (several jobs at the same time), regular expressions (patterns in text) and unit tests with JUnit.
- Python next to Java: compare the two languages you know in Python next to Java.
- Javaـی نوێتر: record وەک
Studentلە یەک دێڕدا دەنووسێت (لە خوارەوە)،switchpattern matching وەردەگرێت و لە Java 25ـەوە یەکەم دەتوانێت تەنیاvoid main()بێت (وەشانەکانی Java). - ئەپی دێسکتۆپ بە پەنجەرە، دوگمە و چارتەوە: JavaFX.
- وێب: Spring Boot ڕاژەکار و APIـی زۆر کۆمپانیا و بانک بەڕێوە دەبات.
- ئەپی Android: Google سەرەتا Kotlin پێشنیار دەکات (تا نۆڤەمبەری 2026)، زمانێک کە لەسەر هەمان سەکۆ کار دەکات و لە تەنیشت کۆدی Javaـەوە کار دەکات (ئەپی ڕەسەن).
- زیاتر لە زمانەکە: threads (چەند کارێک لە هەمان کاتدا)، (نەخشەی دەق) و تاقیکردنەوەی یەکەیی بە JUnit.
- Python لە تەنیشت Java: دوو زمانەکەی دەیانزانیت لە Python لە تەنیشت Javaـدا بەراورد بکە.
Common mistakesهەڵە باوەکان
| You wroteنووسیت | What happensچی ڕوو دەدات | Fixچارەسەر |
|---|---|---|
Integer.parseInt(text) with no try/catchInteger.parseInt(text) بەبێ try/catch | NumberFormatException: For input string: "ninety" | Ask again in a loop: readInt.لە دووپاتە بپرسە: readInt. |
input.nextInt(), then input.nextLine() for the nameinput.nextInt()، پاشان input.nextLine() بۆ ناو | the name is read as ""ناوەکە وەک "" دەخوێنرێتەوە | Read whole lines and use parseInt.دێڕی تەواو بخوێنەرەوە و parseInt بەکار بهێنە. |
total / students.size()total / students.size() | 76 instead of 76.576 لە جیاتی 76.5 | (double) total / students.size()(double) total / students.size() |
| The average of an empty bookتێکڕای دەفتەرێکی بەتاڵ | NaN (0.0 / 0)NaN (0.0 / 0) | Check size() == 0 first.سەرەتا size() == 0 بپشکنە. |
return students; from all()return students; لە all()ـەوە | other code can change the bookکۆدی تر دەتوانێت دەفتەرەکە بگۆڕێت | Return a copy: new ArrayList<>(students).کۆپییەک بگەڕێنەرەوە: new ArrayList<>(students). |
String.format("%.1f", avg) on a computer set to Kurdish or ArabicString.format("%.1f", avg) لەسەر کە ڕێکخستنی کوردی یان عەرەبیی هەیە | the average may print as ٧٦٫٥تێکڕا لەوانەیە وەک ٧٦٫٥ چاپ بێت | String.format(Locale.ROOT, …)String.format(Locale.ROOT, …) |
new FileWriter("marks.txt") on Java 17new FileWriter("marks.txt") لەسەر Java 17 | the computer's own charset: Kurdish names can break on some systems خودی : ناوە کوردییەکان لە هەندێک سیستەمدا تێک دەچن | Files with StandardCharsets.UTF_8.Files لەگەڵ StandardCharsets.UTF_8. |
| Leaving with Ctrl+C instead of 0دەرچوون بە Ctrl+C لە جیاتی 0 | the new marks are lostنمرە نوێیەکان ون دەبن | Choose 0 (save and exit) or 5 (save).0 (پاشەکەوت و دەرچوون) یان 5 (پاشەکەوت) هەڵبژێرە. |
Input that ends while nextLine() waits کە کۆتایی دێت لە کاتێکدا nextLine() چاوەڕێ دەکات | NoSuchElementException: No line found | hasNextLine() first (extension).سەرەتا hasNextLine() (درێژکراوە). |
| A separator that can appear in a nameجیاکەرەوەیەک کە دەتوانێت لە ناودا بێت | broken lines in the fileدێڕی تێکچوو لە | Refuse ; in names, in the constructor.لە ; لە ناودا ڕەت بکەرەوە. |
Summaryکورتە
- Plan first with the five-part method: scenario, flowchart, algorithm (pseudocode), code, examples.
- Split the program into classes with one job each:
Student(checked data),MarksBook(the list and the work on it),MarksApp(talking to the user). - Refuse bad data in the constructor with IllegalArgumentException; ask again for bad input with
readInt; skip bad file lines with a message. - A
switchinside ado-whileloop is the classic menu; 0 saves and exits. - Save one line per object in a UTF-8 text file and load it at the start; test with wrong input and broken files, not only with good data.
- سەرەتا بە شێوازە پێنج بەشییەکە پلان دابنێ: ، ، ()، کۆد، نموونەکان.
- بکە بە چەند کە هەر یەکەیان یەک کاری هەیە:
Student( پشکنراو)،MarksBook( و کار لەسەری)،MarksApp(قسەکردن لەگەڵ بەکارهێنەر). - هەڵە لە بە IllegalArgumentException ڕەت بکەرەوە؛ بۆ هەڵە بە
readIntدووپاتە بپرسە؛ دێڕی هەڵەی بە پەیامێک تێپەڕێنە. switchلە ناوdo-whileـدا شێوەی کلاسیکیی ؛ 0 پاشەکەوت دەکات و دەردەچێت.- بۆ هەر دێڕێک لە UTF-8ـدا پاشەکەوت بکە و لە سەرەتادا باری بکە؛ بە هەڵە و تێکچوو تاقی بکەرەوە، نەک تەنیا بە باش.
Why does readInt read whole lines?بۆچی readInt دێڕی تەواو دەخوێنێتەوە؟
So that a wrong word can be caught and the user asked again, and so that no Enter is left behind for the next nextLine().
تا وشەی هەڵە بگیرێت و دووپاتە پرسیار لە بەکارهێنەر بکرێت، هەروەها تا هیچ Enterـێک بۆ nextLine()ـی دواتر بەجێ نەمێنێت.
What does the program do with a line Soran;abc in marks.txt?بەرنامەکە چی لە دێڕی Soran;abcـی ناو marks.txt دەکات؟
It prints "Skipped a bad line: Soran;abc" and loads the other lines.
«Skipped a bad line: Soran;abc» چاپ دەکات و دێڕەکانی تر بار دەکات.
Where does sorting by mark happen, and how?ڕیزکردن بە نمرە لە کوێ و چۆن ڕوو دەدات؟
In MarksBook.byMark(): a copy of the list is sorted with a lambda, largest mark first.
لە MarksBook.byMark()ـدا: کۆپییەکی بە lambda ڕیز دەکرێت، گەورەترین نمرە یەکەم.
The Java track in one pageتراکی Java لە یەک پەڕەدا
You have finished the Java track: 11 chapters and 33 lessons, from your first program to this project. Here it is in one page, to look back at or to revise before an exam:
تراکی Javaـت تەواو کرد: 11 بەش و 33 وانە، لە یەکەم تا ئەم . لێرەدا لە یەک پەڕەدایە، بۆ ئاوڕدانەوە یان پێداچوونەوە پێش تاقیکردنەوە:
Next steps: build the extensions above, then choose a direction from Where next. Chapters 1–2 (What is programming?, Algorithms and flowcharts) are shared by every track, and the Python track teaches the same ideas in another language (Python next to Java).
هەنگاوەکانی داهاتوو: درێژکراوەکانی سەرەوە دروست بکە، پاشان ئاڕاستەیەک لە دواتر بۆ کوێ هەڵبژێرە. بەشەکانی 1–2 (بەرنامەسازی چییە؟، ئەلگۆریزمەکان و هێڵکارییەکانی ڕەوت) بۆ هەموو تراکەکان هاوبەشن و تراکی Python هەمان بیرۆکەکان بە زمانێکی تر فێر دەکات (Python لە تەنیشت Java).
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Related lecturesوانە پەیوەندیدارەکان
- Python Next to JavaPython لە تەنیشت Javaـەوە
- Algorithms, Pseudocode and Flowchartsئەلگۆریزمەکان، نیمچەکۆد و هێڵکارییەکانی ڕەوت
- Exceptions: try, catch and finallyهەڵاوێردەکان: try، catch و finally
- Constructors, Modifiers and Encapsulationدروستکەرەکان، دیاریکەرەکان و کەپسوولکردن
- HashMap and HashSetHashMap و HashSet
- The switch Statementڕستەی switch
- Project: A Word-Scramble Gameپڕۆژیلە: یاریی پیتە تێکەڵەکان
- Project: Binary to Decimal Converterپڕۆژیلە: گۆڕینی دووانی بۆ دەیی
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.

