Method returns wrong value in main class - java

Whenever I run InschrijvingApplicatie, I get a wrong value out of line System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes); because the int should be "10" when I enter 'p' in this line
System.out.printf("Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
I'm supposing there is something wrong at the line int maxBroodjes = (inschrijving.geefAantalPersonen() * 5); but can't seem to figure out what.
How the output should look like
The excercise is: for a company that is inviting employees ('w' in the code), employee with a partner ('p') and guests ('g') and letting them fill in their name, what sort of visitor (employee + partner, guest or employee) they are, then asking how many sandwiches the person wants (guest and employee can max require 5 sandwiches, employee+partner can request 10) and the max value is shown in the integer (max %d). All of this is in a loop until the user writes "no" (but the first char is used => resulting in 'n') when asked "Zijn er nog inschrijvingen", and if the answer is yes, it repeats.
Inschrijving.java
package domein;
public class Inschrijving {
private String naam;
private char categorie;
private int aantalBroodjes;
public Inschrijving(String naam, char categorie) {
setNaam(naam);
setCategorie(categorie);
}
public String getNaam() {
return naam;
}
private void setNaam(String naam) {
this.naam = naam;
}
public char getCategorie() {
return categorie;
}
private void setCategorie(char categorie) {
if (categorie == 'w' || categorie == 'p' || categorie == 'g') {
this.categorie = categorie;
} else {
this.categorie = 'g';
}
}
public int getAantalBroodjes() {
return aantalBroodjes;
}
public void setAantalBroodjes(int aantalBroodjes) {
if (aantalBroodjes <= (geefAantalPersonen() * 5)) {
this.aantalBroodjes += aantalBroodjes;
} else {
this.aantalBroodjes += (geefAantalPersonen() * 2);
}
}
public int geefAantalPersonen() {
switch (categorie) {
case 'w':
case 'g':
return 1;
default:
return 2;
}
}
}
InschrijvingApplicatie
package ui;
import domein.Inschrijving;
import java.util.Scanner;
public class InschrijvingApplicatie {
public static void main(String[] args) {
Scanner invoer = new Scanner(System.in);
String antwoord;
char eersteLetter;
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.nextLine();
eersteLetter = antwoord.toLowerCase().charAt(0);
String naam = null;
String categorie;
char categorieEersteLetter = 0;
int werknemer = 0;
int werknemerMetPartner = 0;
int gast = 0;
int aantalBroodjes;
int tijdelijk;
Inschrijving inschrijving = new Inschrijving(naam, categorieEersteLetter);
if (eersteLetter != 'n') {
do {
System.out.println("Wie mag ik inschrijven? ");
naam = invoer.next();
do {
System.out.printf("Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
categorie = invoer.next();
categorieEersteLetter = categorie.toLowerCase().charAt(0);
switch (categorieEersteLetter) {
case 'w':
werknemer++;
break;
case 'p':
werknemerMetPartner++;
break;
case 'g':
gast++;
break;
}
} while (categorieEersteLetter != 'w' && categorieEersteLetter != 'p' && categorieEersteLetter != 'g');
int maxBroodjes = (inschrijving.geefAantalPersonen() * 5);
do {
System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes);
tijdelijk = invoer.nextInt();
} while (tijdelijk > maxBroodjes);
aantalBroodjes = tijdelijk;
inschrijving.setAantalBroodjes(aantalBroodjes);
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.next();
eersteLetter = antwoord.toLowerCase().charAt(0);
} while (eersteLetter != 'n');
}
System.out.printf("Er komen %d werknemer(s) zonder partner, %d werknemer(s) met partner en %d gast(en) naar de receptie. Er dienen %d broodjes besteld te worden.", werknemer, werknemerMetPartner, gast, inschrijving.getAantalBroodjes());
}
}

There are some problems with your approach, it may work but you shouldn't do that way.
First, you store the total sandwiches requested for all invited peopled in only one Inschrijving object, it make no sense! (Do I need to know the total sandwiches requested or only ones requested by me?). So, change setAantalBroodjes in your Inschrijving class to :
public void setAantalBroodjes(int aantalBroodjes) {
this.aantalBroodjes = aantalBroodjes;
}
Second, The requirement is take a list of people and do something with them, so you should consider use a data structure support you store a list of people like an Array or an ArrayList, then you can do whatever you want with your data once user stop input (eersteLetter == 'n' in your case).
List<Inschrijving> inschrijven = new ArrayList<>();
try (Scanner invoer = new Scanner(System.in)) { // http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html
System.out.println("Zijn er nog inschrijvingen? ");
String antwoord = invoer.nextLine();
char eersteLetter = antwoord.toLowerCase().charAt(0);
while (eersteLetter != 'n') {
Inschrijving inschrijving = null;
System.out.println("Wie mag ik inschrijven? ");
String naam = invoer.nextLine();
char categorieEersteLetter = 0;
do {
System.out.printf(
"Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
String categorie = invoer.nextLine();
categorieEersteLetter = categorie.toLowerCase().charAt(0);
} while (categorieEersteLetter != 'w' && categorieEersteLetter != 'p' && categorieEersteLetter != 'g');
inschrijving = new Inschrijving(naam, categorieEersteLetter);
int maxBroodjes = (inschrijving.geefAantalPersonen() * 5);
int tijdelijk;
do {
System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes);
tijdelijk = invoer.nextInt();
invoer.nextLine(); // https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo
} while (tijdelijk > maxBroodjes);
inschrijving.setAantalBroodjes(tijdelijk);
inschrijven.add(inschrijving);
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.nextLine();
eersteLetter = antwoord.toLowerCase().charAt(0);
}
}
When the user finished their input:
// Do stuffs with your list of people here
int werknemer = 0;
int werknemerMetPartner = 0;
int gast = 0;
int aantalBroodjes = 0;
for (Inschrijving inschrijving : inschrijven) {
char categorie = inschrijving.getCategorie();
switch (categorie) {
case 'w':
werknemer++;
break;
case 'p':
werknemerMetPartner++;
break;
case 'g':
gast++;
break;
}
aantalBroodjes += inschrijving.getAantalBroodjes();
}
System.out.printf(
"Er komen %d werknemer(s) zonder partner, %d werknemer(s) met partner en %d gast(en) naar de receptie. Er dienen %d broodjes besteld te worden.",
werknemer, werknemerMetPartner, gast, aantalBroodjes);
Because you are new to java, I use a foreach loop here to make example, after learning about OOP and familiar with java, I suggest you reaserch Java 8 Stream api and lambda expression to work with collection types.

Related

arraylist in java, getting all the data print out

I am learning Java right now and I am trying to use ArrayList in my project, but it doesn't work. Help please...
public class TestCalculator {
public static void main(String[]args){
ArrayList<BMICalculator> bmilist = new ArrayList<>();
//ArrayList<Double> bmilist = new ArrayList<Double>();
do {
double lengte = getLength("Geef de lengte in Meters:");
double gewicht = getGewicht("Geef het gewicht in Kg:");
BMICalculator bmi = new BMICalculator(lengte, gewicht);
bmi.setBmi(bmi.calculateBMI());
bmilist.add(bmi);
for(double i = 0;i < bmilist.size(); i++){
//System.out.println(i);
JOptionPane.showMessageDialog(null, "List:" + i);
}
JOptionPane.showMessageDialog(null, "Bmi: " + String.format("%s", bmi.toString()));
} while(getUserAnswer() == 'J');
}
public static double getLength(String message){
String lengte = JOptionPane.showInputDialog(message);
return Double.parseDouble(lengte);
}
public static double getGewicht(String message){
String gewicht = JOptionPane.showInputDialog(message);
return Double.parseDouble(gewicht);
}
public static char getUserAnswer(){
String answer = JOptionPane.showInputDialog("Wil je opnieuw: j/n?");
return Character.toUpperCase(answer.charAt(0));
}
}
I cant get anything print out of that list. Every time someone calculates his BMI, it should put them in an Arraylist and when they click "continue", no... then it should return all the BMI's they calculated.
You misused a loop with a list structure
for (int i = 0; i < bmilist.size(); i++) {
JOptionPane.showMessageDialog(null, "List:" + bmilist.get(i).getBmi());
}
Try the for loop with int variable
do {
double lengte = getLength("Geef de lengte in Meters:");
double gewicht = getGewicht("Geef het gewicht in Kg:");
BMICalculator bmi = new BMICalculator(lengte, gewicht);
bmi.setBmi(bmi.calculateBMI());
bmilist.add(bmi);
// int variable instead of double inside for loop
for(int i = 0;i < bmilist.size(); i++){
JOptionPane.showMessageDialog(null, "List:" + bmilist.get(i));
}
}while(getUserAnswer() == 'J');
ArrayList<BMICalculator> bmilist = new ArrayList<>();
do {
double lengte = getLength("Geef de lengte in Meters:");
double gewicht = getGewicht("Geef het gewicht in Kg:");
BMICalculator bmi = new BMICalculator(lengte, gewicht);
bmi.setBmi(bmi.calculateBMI());
bmilist.add(bmi);
JOptionPane.showMessageDialog(null, String.format("%s", bmi.toString()));
} while(getUserAnswer() == 'J');
System.out.println("Lengte Gewicht BMI");
for(int i = 0;i < bmilist.size(); i++)
{ System.out.printf("%-10s%-10s%s\n",bmilist.get(i).getLengte(),bmilist.get(i).getGewicht(),String.format("%.2f", bmilist.get(i).getBmi()));
}
}

How to test found element in to vector?

HI
after adding there or more variables to the vector i get the problem
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1
at java.base/java.util.Vector.get(Vector.java:747)
at Universitaet.studAngeleldet(Universitaet.java:163) == methode studAngeleldet
at Main.main(Main.java:169) == case 6
public class Student extends Person {
Vector<LVA> studentLVA = new Vector();
public class LVA {
Vector<Student> lvaStudent = new Vector();
public class Universitaet {
Vector<Dozent> dozent = new Vector();
private int anzhal_dozenten =0;
Vector<LVA> lvas = new Vector();
public boolean studAngeleldet(String a , String b){
boolean found = false;
for (int i = 0 ; i < studenten.size() ; i++){
if(studenten.get(i).studentLVA.isEmpty()){
break;
}
for(int j = 0 ; j < lvas.size() ; j++){
if(lvas.get(j).lvaStudent.isEmpty()){
break;
}
if(a.equals(lvas.get(j).lvaStudent.get(j).getMN()) && b.equals(studenten.get(i).studentLVA.get(i).getCode())){
found = true;
}
}
}
return found;
}
case 6:
System.out.println("Bitte Geben Sie Die Matrikelnummer:");
String mn1 = in.nextLine();
if(uni.isHere(mn1)){
System.out.println("Der Studnet exisitert nicht!");
break;
}
System.out.println("Bitte geben sie Das code des LVA:");
String code1 = in.nextLine();
if(uni.isExist(code1)){
System.out.println("Der LVA not found!");
break;
}
if(uni.studAngeleldet(mn1, code1)){
System.out.println("Der student is schone zum LVA anmedet");
break;
}
System.out.println("Der student wurde anmeldet");
uni.sudentzuLvaAnmelden(mn1 , code1);
break;
In the following line you use the index j of lvas vector.
if(a.equals(lvas.get(j).**lvaStudent.get(j)**.getMN())
Since lvaStudent is a vector by itself you must iterate through it with an own loop.
The same applies to studentLVA.

Programming OO and classes

I'm trying this ex but i cant find the problem; i can run it but it isn't as i would.
It should be a switch for light bulbs; i have my main:
import java.util.Scanner;
public class UsoLampadina {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner (System.in);
// Select the maximum number of clicks
System.out.println("Selezionare il numero massimo di click: ");
int click = scanner.nextInt();
char s;
int i= 0;
Lampadina lamp = new Lampadina ( click , i);
while (i >= 0){
// Select the operation to be performed
// V = Displays the status of the light bulb
// C = Change the state of the bulb
// Enter the selected operation:
System.out.println("Selezionare l'operazione da eseguire: ");
System.out.println("[V] Visualizza lo stato della lampadina");
System.out.println("[C] Cambia lo stato della lampadina");
System.out.println("Immettere l'operazione selezionata: ");
s = scanner.next().charAt(0);
switch (s) {
case 'V': lamp.Stato(); break;
case 'C': i = lamp.Click(); break;
// Select a correct character
default: System.out.println(" Selezionare un carattere corretto");
}
}
// The light bulb broke!!!
System.out.println("La lampadina si è rotta!!!");
return;
}
}
That open a menu where u can choose to see if the bulb is on or off (lamp.Stato()) or to change it state (turn off if it is on and viceversa, lamp.Click()).
And my second class:
public class Lampadina {
public int maxClick;
public int c = 0;
public int i;
public Lampadina ( int a, int b) {
a = maxClick;
b = i;
}
public int Click() {
while (click >= c ) {
if ( i == 1 ) {
c++;
i = 0;
return i;
}
else if (i == 0) {
c++;
i = 1;
return i;
}
}
i = -1;
return i;
}
public void Stato () {
if (i == 0) {
// The light bulb is off
System.out.println("La lampadina è spenta");
}
else if (i == 1) {
// The light bulb is on
System.out.println("La lampadina è accesa");
}
else if (i == -1) {
// The light bulb is broken
System.out.println("La lampadina è rotta");
}
}
}
Here i have the bulb's constructor method; and auxiliares (Click, Stato).
"Stato" works but i have problems with "Click"; it doesn't do what it should:
the idea is that if the bulb is turned off (i == 0) it tunrs it on (return i = 1) and viceversa; c is a counter that, when it reachs the maxClicks (that u give as input in the main as a parametrer of the object "bulb") number; the bulb breaks.
when i run the programm it doesnt do the right number of cicle before the lamp breaks down
you are setting parameter a and b to values instead set values to parameters
public Lampadina(int a, int b) {
maxClick=a;
i=b;
}

Reading a Binary file in java and displaying it

Im trying to read my binary file that i created for a country with at least 5 gold medals. When im trying to read the file and then displaying it. it shows:
?????††††††††††††††???†††††††††††††††† 27 27 38 92. It displays part of the information. This is my code at the moment:
import java.io.*;
import java.util.*;
class Pays
implements Comparable<Pays>
{
private String nom;
private int gold;
private int silver;
private int bronze;
private int sum;
public Pays(String nom,int gold,int silver, int bronze,int sum)
{
this.nom = nom;
this.gold=gold;
this.silver=silver;
this.bronze=bronze;
this.sum=sum;
}
public int compareTo(Pays autre) {
return nom.toUpperCase().trim().compareTo( autre.nom.toUpperCase().trim() );
}
public String getNom(){ return nom; }
public int getGold(){ return gold; }
public int getSilver(){ return silver; }
public int getBronze(){ return bronze; }
public int getSum(){return sum;}
public boolean equals(Object obj)
{
if (this == obj)
return true;
else
if ( ! (obj instanceof Pays))
return false;
else
{
Pays autre = (Pays) obj;
return nom.trim().equalsIgnoreCase(autre.nom.trim());
}
}
public void ecrire(DataOutputStream aCreer)
throws IOException
{
aCreer.writeBytes(nom);
aCreer.writeInt(gold);
aCreer.writeInt(silver);
aCreer.writeInt(bronze);
aCreer.writeInt(sum);
}
}
class numba3{
static LinkedList<Pays> lireCreer(String nomFichier)
throws IOException
{ LinkedList<Pays> liste = new LinkedList<Pays>();
boolean existeFichier = true ;
FileReader fr = null;
try {
fr = new FileReader (nomFichier) ;
}
catch ( java.io.FileNotFoundException erreur) {
System.out.println("Probleme d'ouvrir le fichier " +
nomFichier);
existeFichier = false ;
}
if (existeFichier) {
BufferedReader entree = new BufferedReader(fr);
boolean finFichier = false ;
while ( !finFichier ) {
String uneLigne = entree.readLine();
if (uneLigne == null)
finFichier = true ;
else {
String nom = uneLigne.substring(0, 38);
int gold = Integer.parseInt(uneLigne.substring(38,43).trim());
int silver = Integer.parseInt(uneLigne.substring(43,48).trim());
int bronze = Integer.parseInt(uneLigne.substring(48).trim());
int sum=gold+silver+bronze;
liste.add(new Pays(nom,gold,silver,bronze,sum));
}
}
entree.close();
}
return liste;
}
static void afficher(LinkedList<Pays> liste,int numero){
for(int i=0;i<numero;i++){
System.out.printf("%30s %10d %10d %10d %10d\n",liste.get(i).getNom(),liste.get(i).getGold(),liste.get(i).getSilver(),liste.get(i).getBronze(),liste.get(i).getSum());
}
}
public static void quickSort(LinkedList<Pays> liste, int low, int high) {
if (liste.isEmpty() == true || liste.size()== 0)
return;
if (low >= high)
return;
int middle = low + (high - low) / 2;
int pivot = liste.get(middle).getSum();
int i = low, j = high;
while (i <= j) {
while (liste.get(i).getSum() > pivot) {
i++;
}
while (liste.get(j).getSum() < pivot) {
j--;
}
if (i <= j) {
Pays temp=liste.get(i);
liste.set(i,liste.get(j));
liste.set(j,temp);
i++;
j--;
}
}
if (low < j)
quickSort(liste, low, j);
if (high > i)
quickSort(liste, i, high);
}
static void afficherPays(LinkedList<Pays>liste,String nom){
for(int i=0;i<liste.size();i++){
if(liste.get(i).equals(new Pays(nom, 0, 0, 0,0))){
System.out.printf("%30s %10d %10d %10d %10d\n",liste.get(i).getNom(),liste.get(i).getGold(),liste.get(i).getSilver(),liste.get(i).getBronze(),liste.get(i).getSum());
}
}
}
static void creerBinaire(LinkedList<Pays> liste, int gold,String nomBinaire)
throws IOException
{
DataOutputStream aCreer = new DataOutputStream
( new FileOutputStream(nomBinaire));
for (int i = 0; i < liste.size(); i++)
{
if ( liste.get(i).getGold() >= gold)
liste.get(i).ecrire(aCreer);
}
aCreer.close();
System.out.println("\nOn vient de creer le fichier binaire : " + nomBinaire);
}
static LinkedList<Pays> readBinaire(String nomALire)
throws IOException{
System.out.println("On lit le fichier binaire du nom " + nomALire);
LinkedList<Pays> unVect = new LinkedList<Pays> ();
DataInputStream aLire = new DataInputStream
( new FileInputStream(nomALire));
boolean finFichier = false ;
String nom = "";
int rang = 0;
while ( ! finFichier ) {
try {
for (int i = 0; i < 19; i++)
nom += aLire.readChar();
} catch ( EOFException e ) {
finFichier = true;
}
if (!finFichier) {
int gold=aLire.readInt(),
silver=aLire.readInt(),
bronze=aLire.readInt(),
sum=aLire.readInt();
Pays pers = new Pays(nom, gold, silver, bronze, sum);
unVect.add(pers);
}
}
aLire.close();
return unVect;
}
public static void main(String[]args)throws IOException
{
LinkedList<Pays> liste = lireCreer("Olym_ete.txt");
System.out.println("");
System.out.println("1)Determine et afficher les 5 premier pays qui ont gagne plus de medailles en totale: ");
quickSort(liste,0, liste.size()-1);
afficher(liste,5);
System.out.println("");
System.out.println("2)Afficher les information des pays FRANCE, JAPON, ESPAGNE: ");
afficherPays(liste,"FRANCE");
afficherPays(liste,"JAPON");
afficherPays(liste,"ESPAGNE");
System.out.println("");
System.out.println("3)Cree a partir de la liste un fichier binaire qui ont gagne au moins de 5 medailles en or: ");
creerBinaire(liste, 5,"AtLeastFiveGold.bin");
LinkedList<Pays> plusKeFive = readBinaire("AtLeastFiveGold.bin");
System.out.println(plusKeFive.size());
System.out.printf("%30s %10d %10d %10d %10d\n",plusKeFive.get(1).getNom(),plusKeFive.get(1).getGold(),plusKeFive.get(1).getSilver(),plusKeFive.get(1).getBronze(),plusKeFive.get(1).getSum());
}
}
I can't figure out how to get rid of the symbols. I suspect that i have made a mistake while reading the binary file in readBinaire() but i cannot seem to figure out where i went wrong.
A char in Java is a 16-bit Unicode character. A "byte" is an 8-bit byte.
You're using writeBytes to write a string as 38 bytes, but readChar to read them back in as 19 characters. writeBytes will write the low order 8 bits of each 16-bit character of the string. So if your string was "ABCD", the bytes it would write are
0x41 0x42 0x43 0x44
Then when you read them back in as 16-bit characters, it will read the first two characters either as
0x4142 0x4344
or
0x4241 0x4443
depending on how the byte ordering is handled. Either way, instead of "ABCD", you will get some strange Unicode characters whose code points are U+4142 or U+4241, and U+4344 or U+4443. (They are probably not displaying correctly.)

Deleting a node in a family tree

I'm trying to calclulate the best way to delete a node in a family tree. First, a little description of how the app works.
My app makes the following assumption:
Any node can only have one partner. That means that any child a single node has, it will also be the partner nodes child too. Therefore, step relations, divorces etc aren't compensated for. A node always has two parents - A mother and father cannot be added seperately. If the user doesn't know the details - the nodes attributes are set to a default value.
Also any node can add parents, siblings, children to itself. Therefore in law relationships can be added.
EDIT: After studying Andreas' answer, I have come to realise that my code may need some re-working. I'm trying to add my source but it exceeds the limit of charracters...Any advice?
Here is the FamilyTree Class:
package familytree;
import java.io.PrintStream;
public class FamilyTree {
private static final int DISPLAY_FAMILY_MEMBERS = 1;
private static final int ADD_FAMILY_MEMBER = 2;
private static final int REMOVE_FAMILY_MEMBER = 3;
private static final int EDIT_FAMILY_MEMBER = 4;
private static final int SAVE_FAMILY_TREE = 5;
private static final int LOAD_FAMILY_TREE = 6;
private static final int DISPLAY_ANCESTORS = 7;
private static final int DISPLAY_DESCENDANTS = 8;
private static final int QUIT = 9;
private Input in;
private Family family;
private PrintStream out;
public FamilyTree(Input in, PrintStream out) {
this.in = in;
this.out = out;
family = new Family();
}
public void start() {
out.println("\nWelcome to the Family Tree Builder");
initialise();
while (true) {
displayFamilyTreeMenu();
int command = getCommand();
if (quit(command)) {
break;
}
executeOption(command);
}
}
private int getCommand() {
return getInteger("\nEnter command: ");
}
private int getInteger(String message) {
while (true) {
out.print(message);
if (in.hasNextInt()) {
int n = in.nextInt();
in.nextLine();
return n;
} else {
in.nextLine();
out.println("Your input was not understood. Please try again.");
}
}
}
//good
private void displayFamilyTreeMenu() {
out.println("\nFamily Tree Menu");
out.println(DISPLAY_FAMILY_MEMBERS + ". Display Family Members");
out.println(ADD_FAMILY_MEMBER + ". Add Family Member");
out.println(REMOVE_FAMILY_MEMBER + ". Remove Family Member");
out.println(EDIT_FAMILY_MEMBER + ". Edit Family Member");
out.println(SAVE_FAMILY_TREE + ". Save Family Tree");
out.println(LOAD_FAMILY_TREE + ". Load Family Tree");
out.println(DISPLAY_ANCESTORS + ". Display Ancestors");
out.println(DISPLAY_DESCENDANTS + ". Display Descendants");
out.println(QUIT + ". Quit");
}
//good
private boolean quit(int opt) {
return (opt == QUIT) ? true : false;
}
//good
private void executeOption(int choice) {
switch (choice) {
case DISPLAY_FAMILY_MEMBERS:
displayFamilyMembers();
break;
case ADD_FAMILY_MEMBER:
addFamilyMember();
break;
case REMOVE_FAMILY_MEMBER:
removeMember();
break;
case EDIT_FAMILY_MEMBER:
editMember();
break;
case SAVE_FAMILY_TREE:
saveFamilyTree();
break;
case LOAD_FAMILY_TREE:
loadFamilyTree();
break;
case DISPLAY_ANCESTORS:
displayAncestors();
break;
case DISPLAY_DESCENDANTS:
displayDescendants();
break;
default:
out.println("Not a valid option! Try again.");
break;
}
}
private void removeMember() {
displayFamilyMembers();
int choice = selectMember();
if (choice >= 0) {
FamilyMember f = family.getFamilyMember(choice);
if (f.getIndex() == 0) {
out.println("Cannot delete yourself!");
return;
}
deleteMember(f);
}
}
private void deleteMember(FamilyMember f) {
//remove from tree
family.removeMember(f);
//remove all links to this person
if (f.hasParents()) {
f.getMother().removeChild(f);
f.getFather().removeChild(f);
}
if(f.getPartner()!=null){
f.getPartner().setPartner(null);
f.setPartner(null);
}
if (f.hasChildren()) {
for (FamilyMember member : f.getChildren()) {
if (f == member.getMother()) {
member.setMother(null);
}
if (f == member.getFather()) {
member.setFather(null);
}
if (f == member.getPartner()) {
member.setPartner(null);
}
}
}
}
private void saveFamilyTree() {
out.print("Enter file name: ");
String fileName = in.nextLine();
FileOutput output = new FileOutput(fileName);
family.save(output);
output.close();
saveRelationships();
}
private void saveRelationships() {
FileOutput output = new FileOutput("Relationships.txt");
family.saveRelationships(output);
output.close();
}
private void loadFamilyTree() {
out.print("Enter file name: ");
String fileName = in.nextLine();
FileInput input = new FileInput(fileName);
family.load(input);
input.close();
loadRelationships();
}
private void loadRelationships() {
FileInput input = new FileInput("Relationships.txt");
family.loadRelationships(input);
input.close();
}
//for selecting family member for editing adding nodes etc
private void displayFamilyMembers() {
out.println("\nDisplay Family Members");
int count = 0;
for (FamilyMember member : family.getFamilyMembers()) {
out.println();
if (count + 1 < 10) {
out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName());
out.println(" " + member.getGender());
out.println(" " + member.getDob());
out.println(" Generation: " + (member.getGeneration() + 1));
} else {
out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName());
out.println(" " + member.getGender());
out.println(" " + member.getDob());
out.println(" Generation: " + (member.getGeneration() + 1));
}
count++;
}
}
private int selectRelative() {
out.println("\nSelect Relative");
out.println("1. Add Parents");
out.println("2. Add Child");
out.println("3. Add Partner");
out.println("4. Add Sibling");
//out.print("\nEnter Choice: ");
//int choice = in.nextInt();
int choice = getInteger("\nEnter Choice: ");
if (choice > 0 && choice < 5) {
return choice;
}
return (-1);
}
private void addFamilyMember() {
if (family.getFamilyMembers().isEmpty()) {
out.println("No Members To Add To");
return;
}
int memberIndex = selectMember();
if (memberIndex >= 0) {
FamilyMember member = family.getFamilyMember(memberIndex);
int relative = selectRelative();
if (relative > 0) {
out.println("\nAdd Member");
//if choice is valid
switch (relative) {
case 1:
//adding parents
FamilyMember mum, dad;
if (!member.hasParents()) {
out.println("Enter Mothers Details");
mum = addMember(relative, "Female");
out.println("\nEnter Fathers Details");
dad = addMember(relative, "Male");
member.linkParent(mum);
member.linkParent(dad);
mum.linkPartner(dad);
mum.setGeneration(member.getGeneration() - 1);
dad.setGeneration(member.getGeneration() - 1);
sortGenerations();
} else {
out.println(member.getFirstName() + " " + member.getLastName() + " already has parents.");
}
break;
case 2:
//adding child
if (member.getPartner() == null) {
FamilyMember partner;
if (member.getGender().equals("Male")) {
out.println("Enter Mothers Details");
partner = addMember(1, "Female");
} else {
out.println("Enter Fathers Details");
partner = addMember(1, "Male");
}
//create partner
member.linkPartner(partner);
partner.setGeneration(member.getGeneration());
out.println();
}
out.println("Enter Childs Details");
FamilyMember child = addMember(relative, "");
child.linkParent(member);
child.linkParent(member.getPartner());
child.setGeneration(member.getGeneration() + 1);
sortGenerations();
break;
case 3:
//adding partner
if (member.getPartner() == null) {
out.println("Enter Partners Details");
FamilyMember partner = addMember(relative, "");
member.linkPartner(partner);
partner.setGeneration(member.getGeneration());
} else {
out.println(member.getFirstName() + " " + member.getLastName() + " already has a partner.");
}
break;
case 4:
//adding sibling
if (member.getFather() == null) {
out.println("Enter Mothers Details");
mum = addMember(1, "Female");
out.println("\nEnter Fathers Details");
dad = addMember(1, "Male");
member.linkParent(mum);
member.linkParent(dad);
mum.linkPartner(dad);
mum.setGeneration(member.getGeneration() - 1);
dad.setGeneration(member.getGeneration() - 1);
sortGenerations();
out.println("\nEnter Siblings Details");
} else {
out.println("Enter Siblings Details");
}
FamilyMember sibling = addMember(relative, "");
//create mum and dad
mum = member.getMother();
dad = member.getFather();
sibling.linkParent(mum);
sibling.linkParent(dad);
sibling.setGeneration(member.getGeneration());
break;
}
} else {
out.println("Invalid Option!");
}
} else {
out.println("Invalid Option!");
}
}
private int selectMember() {
displayFamilyMembers();
//out.print("\nSelect Member: ");
//int choice = in.nextInt();
int choice = getInteger("\nSelect Member: ");
if (choice > 0 && choice <= family.getFamilyMembers().size()) {
return (choice - 1);
}
return -1;
}
private void editMember() {
int choice = selectMember();
if (choice >= 0) {
out.println("Select Detail To Edit: ");
out.println("1. Name");
out.println("2. Gender");
out.println("3. Date of Birth");
//out.print("\nEnter Choice: ");
//int opt = in.nextInt();
int opt = getInteger("\nEnter Choice: ");
if (opt > 0 && opt < 4) {
switch (opt) {
case 1: //name
out.print("Enter New First Name: ");
String fName = in.nextLine();
out.print("Enter New Last Name: ");
String lName = in.nextLine();
family.changeName(fName, lName, choice);
break;
case 2: //Gender
FamilyMember f = family.getFamilyMember(choice);
String gender = f.getGender();
if (f.getChildren().isEmpty()) {
gender = selectGender();
family.changeGender(gender, choice);
} else {
//swap genders
//swap mother father relationships for kids
swapGenders(f, choice);
}
break;
case 3:
String dob = enterDateOfBirth();
family.changeDOB(dob, choice);
}
} else {
out.println("Invalid Choice!");
}
}
}
private FamilyMember addMember(int option, String gender) {
out.print("Enter First Name: ");
String fName = formatString(in.nextLine().trim());
out.print("Enter Last Name: ");
String lName = formatString(in.nextLine().trim());
//String gender;
if (option != 1) { //if not adding parents
gender = selectGender();
}
String dob = enterDateOfBirth();
FamilyMember f = family.getFamilyMember(family.addMember(fName, lName, gender, dob));
f.setIndex(family.getFamilyMembers().size() - 1);
return (f);
}
private String selectGender() {
String gender = null;
out.println("Select Gender");
out.println("1. Male");
out.println("2. Female");
//out.print("Enter Choice: ");
//int gOpt = in.nextInt();
int gOpt = getInteger("Enter Choice: ");
if (gOpt == 1) {
gender = "Male";
} else if (gOpt == 2) {
gender = "Female";
} else {
out.println("Invalid Choice");
}
return gender;
}
private void swapGenders(FamilyMember f, int choice) {
String gender;
out.println("\nNOTE: Editing A Parent Nodes Gender Will Swap Parents Genders\n"
+ "And Swap Mother/Father Relationships For All Children.");
out.println("\nContinue:");
out.println("1. Yes");
out.println("2. No");
//out.print("\nEnter Choice: ");
//int select = in.nextInt();
int select = getInteger("\nEnter Choice: ");
if (select > 0 && select < 3) {
switch (select) {
case 1:
//swap relationships
gender = selectGender();
//if selected gender is different
if (!gender.equals(f.getGender())) {
//swap
String g = f.getGender();
family.changeGender(gender, choice);
family.changeGender(g, f.getPartner().getIndex());
if (g.equals("Male")) {
for (FamilyMember m : f.getChildren()) {
m.setMother(f);
m.setFather(f.getPartner());
}
} else {
for (FamilyMember m : f.getChildren()) {
m.setFather(f);
m.setMother(f.getPartner());
}
}
}
break;
case 2:
break;
}
} else {
out.println("Invalid Choice");
}
}
private String formatString(String s) {
String firstLetter = s.substring(0, 1);
String remainingLetters = s.substring(1, s.length());
s = firstLetter.toUpperCase() + remainingLetters.toLowerCase();
return s;
}
private String enterDateOfBirth() {
out.print("Enter Year Of Birth (0 - 2011): ");
String y = in.nextLine();
out.print("Enter Month Of Birth (1-12): ");
String m = in.nextLine();
if (m.trim().equals("")) {
m = "0";
}
if (Integer.parseInt(m) < 10) {
m = "0" + m;
}
m += "-";
out.print("Enter Date of Birth (1-31): ");
String d = in.nextLine();
if (d.trim().equals("")) {
d = "0";
}
if (Integer.parseInt(d) < 10) {
d = "0" + d;
}
d += "-";
String dob = d + m + y;
while (!DateValidator.isValid(dob)) {
out.println("Invalid Date. Try Again:");
dob = enterDateOfBirth();
}
return (dob);
}
private void displayAncestors() {
out.print("\nDisplay Ancestors For Which Member: ");
int choice = selectMember();
if (choice >= 0) {
FamilyMember node = family.getFamilyMember(choice);
FamilyMember ms = findRootNode(node, 0, 2, -1);
FamilyMember fs = findRootNode(node, 1, 2, -1);
out.println("\nPrint Ancestors");
out.println("\nMothers Side");
if(ms==null){
out.println("Member has no mother");
}else{
printDescendants(ms, node, ms.getGeneration());
}
out.println("\nFathers Side");
if(fs==null){
out.println("Member has no father");
}else{
printDescendants(fs, node, fs.getGeneration());
}
} else {
out.println("Invalid Option!");
}
}
private void displayDescendants() {
out.print("\nDisplay Descendants For Which Member: ");
int choice = selectMember();
if (choice >= 0) {
FamilyMember node = family.getFamilyMember(choice);
out.println("\nPrint Descendants");
printDescendants(node, null, 0);
} else {
out.println("Invalid Option!");
}
}
private FamilyMember findRootNode(FamilyMember node, int parent, int numGenerations, int count) {
FamilyMember root;
count++;
if (count < numGenerations) {
if (parent == 0) {
if(node.hasMother()){
node = node.getMother();
}else{
return node;
}
} else {
if(node.hasFather()){
node = node.getFather();
}else{
return node;
}
}
root = findRootNode(node, 1, numGenerations, count);
return root;
}
return node;
}
private int findHighestLeafGeneration(FamilyMember node) {
int gen = node.getGeneration();
for (int i = 0; i < node.getChildren().size(); i++) {
int highestChild = findHighestLeafGeneration(node.getChild(i));
if (highestChild > gen) {
gen = highestChild;
}
}
return gen;
}
private void printDescendants(FamilyMember root, FamilyMember node, int gen) {
out.print((root.getGeneration() + 1) + " " + root.getFullName());
out.print(" [" + root.getDob() + "] ");
if (root.getPartner() != null) {
out.print("+Partner: " + root.getPartner().getFullName() + " [" + root.getPartner().getDob() + "] ");
}
if (root == node) {
out.print("*");
}
out.println();
if (!root.getChildren().isEmpty() && root != node) {
for (int i = 0; i < root.getChildren().size(); i++) {
for (int j = 0; j < root.getChild(i).getGeneration() - gen; j++) {
out.print(" ");
}
printDescendants(root.getChild(i), node, gen);
}
} else {
return;
}
}
//retrieve highest generation
public int getRootGeneration() {
int min = family.getFamilyMember(0).getGeneration();
for (int i = 0; i < family.getFamilyMembers().size(); i++) {
min = Math.min(min, family.getFamilyMember(i).getGeneration());
}
return Math.abs(min);
}
public void sortGenerations() {
int amount = getRootGeneration();
for (FamilyMember member : family.getFamilyMembers()) {
member.setGeneration(member.getGeneration() + amount);
}
}
//test method - temporary
private void initialise() {
family.addMember("Bart", "Simpson", "Male", "18-03-1985");
family.getFamilyMember(0).setIndex(0);
family.addMember("Homer", "Simpson", "Male", "24-09-1957");
family.getFamilyMember(1).setIndex(1);
family.addMember("Marge", "Simpson", "Female", "20-07-1960");
family.getFamilyMember(2).setIndex(2);
family.addMember("Lisa", "Simpson", "Female", "28-01-1991");
family.getFamilyMember(3).setIndex(3);
family.addMember("Abe", "Simpson", "Male", "10-03-1920");
family.getFamilyMember(4).setIndex(4);
family.addMember("Mona", "Simpson", "Female", "18-09-1921");
family.getFamilyMember(5).setIndex(5);
//set relationships
family.getFamilyMember(0).setMother(family.getFamilyMember(2));
family.getFamilyMember(0).setFather(family.getFamilyMember(1));
family.getFamilyMember(3).setMother(family.getFamilyMember(2));
family.getFamilyMember(3).setFather(family.getFamilyMember(1));
family.getFamilyMember(1).addChild(family.getFamilyMember(3));
family.getFamilyMember(1).addChild(family.getFamilyMember(0));
family.getFamilyMember(2).addChild(family.getFamilyMember(3));
family.getFamilyMember(2).addChild(family.getFamilyMember(0));
family.getFamilyMember(1).setPartner(family.getFamilyMember(2));
family.getFamilyMember(2).setPartner(family.getFamilyMember(1));
family.getFamilyMember(4).setPartner(family.getFamilyMember(5));
family.getFamilyMember(5).setPartner(family.getFamilyMember(4));
family.getFamilyMember(1).setMother(family.getFamilyMember(5));
family.getFamilyMember(1).setFather(family.getFamilyMember(4));
family.getFamilyMember(4).addChild(family.getFamilyMember(1));
family.getFamilyMember(5).addChild(family.getFamilyMember(1));
family.getFamilyMember(0).setGeneration(2);
family.getFamilyMember(1).setGeneration(1);
family.getFamilyMember(2).setGeneration(1);
family.getFamilyMember(3).setGeneration(2);
family.getFamilyMember(4).setGeneration(0);
family.getFamilyMember(5).setGeneration(0);
}
}
All tasks require the same effort. It will always go like this:
public void deleteFamilyMember(FamilyMember member) {
member.mother.children.remove(member);
member.father.children.remove(member);
member.partner.children.remove(member);
for (FamilyMember child:children) {
if (child.father == member) child.father = null;
if (child.mother == member) child.mother = null;
if (child.partner == member) child.partner = null;
}
// now all references to this member are eliminated, gc will do the rest.
}
Example:
Homer.mother = ??
Homer.father = ??
Homer.partner = Marge
Homer.children = {Bart, Lisa, Maggie}
Marge.mother = ??
Marge.father = ??
Marge.partner = Homer
Marge.children = {Bart, Lisa, Maggie}
Bart.mother = Marge
Bart.father = Homer
Bart.partner = null
Bart.children = {}
Lisa.mother = Marge
Lisa.father = Homer
Lisa.partner = null
Lisa.children = {}
Maggie.mother = Marge
Maggie.father = Homer
Maggie.partner = null
Maggie.children = {}
To remove Bart from the familiy tree, we should set Bart's mother and father attribute to null and need to remove Bart from Homer's and Marge's list of children.
To remove Marge, we have to set her partner's partner to null (Homer.partner) and visit all children to clear their mother attribute (that's this child.mother part of the code above)
I would model things differently and do the work in the FamilyMember class. Here's a sample implementation:
public class FamilyMember{
public enum Gender{
MALE, FEMALE
}
private final Set<FamilyMember> exPartners =
new LinkedHashSet<FamilyMember>();
public Set<FamilyMember> getExPartners(){
return new LinkedHashSet<FamilyMember>(exPartners);
}
public FamilyMember getFather(){
return father;
}
public FamilyMember getMother(){
return mother;
}
public Set<FamilyMember> getSiblings(){
final Set<FamilyMember> set =
father == null && mother == null ? Collections
.<FamilyMember> emptySet() : new HashSet<FamilyMember>();
if(father != null){
set.addAll(father.children);
}
if(mother != null){
set.addAll(mother.children);
}
set.remove(this);
return set;
}
public String getName(){
return name;
}
private final Gender gender;
private FamilyMember partner;
private final FamilyMember father;
private final FamilyMember mother;
private final Set<FamilyMember> children =
new LinkedHashSet<FamilyMember>();
private final String name;
public FamilyMember haveChild(final String name, final Gender gender){
if(partner == null){
throw new IllegalStateException("Partner needed");
}
final FamilyMember father = gender == Gender.MALE ? this : partner;
final FamilyMember mother = father == this ? partner : this;
return new FamilyMember(father, mother, name, gender);
}
public Set<FamilyMember> getChildren(){
return new LinkedHashSet<FamilyMember>(children);
}
#Override
public String toString(){
return "[" + name + ", " + gender + "]";
}
public FamilyMember(final String name, final Gender gender){
this(null, null, name, gender);
}
public FamilyMember(final FamilyMember father,
final FamilyMember mother,
final String name,
final Gender gender){
if(name == null){
throw new IllegalArgumentException("A kid needs a name!");
}
if(gender == null){
throw new IllegalArgumentException("Which is it going to be?");
}
this.father = father;
this.name = name;
this.gender = gender;
if(father != null){
father.children.add(this);
}
this.mother = mother;
if(mother != null){
mother.children.add(this);
}
}
public FamilyMember hookUpWith(final FamilyMember partner){
if(partner.gender == gender){
throw new IllegalArgumentException(
"Sorry, same-sex-marriage would make things too complicated");
}
this.partner = partner;
partner.partner = this;
return this;
}
public FamilyMember splitUp(){
if(partner == null){
throw new IllegalArgumentException("Hey, I don't have a partner");
} else{
partner.partner = null;
exPartners.add(partner);
partner.exPartners.add(this);
partner = null;
}
return this;
}
public FamilyMember getPartner(){
return partner;
}
}
And here's the much more expressive code you can write that way:
FamilyMember marge = new FamilyMember("Marge", Gender.FEMALE);
FamilyMember homer = new FamilyMember("Homer", Gender.MALE);
homer.hookUpWith(marge);
FamilyMember bart = homer.haveChild("Bart", Gender.MALE);
FamilyMember lisa = marge.haveChild("Lisa", Gender.FEMALE);
System.out.println("Homer & Marge: " + marge + ", "
+ marge.getPartner());
homer.splitUp();
FamilyMember dolores =
marge
.hookUpWith(new FamilyMember("New Guy", Gender.MALE))
.haveChild("Dolores", Gender.FEMALE);
FamilyMember bruno =
homer
.hookUpWith(new FamilyMember("New Girl", Gender.FEMALE))
.haveChild("Bruno", Gender.MALE);
System.out.println(
"Marge & Partner: " + marge + ", " + marge.getPartner());
System.out.println("Marge's Ex-Partners: " + marge.getExPartners());
System.out.println(
"Homer & Partner: " + homer + ", " + homer.getPartner());
System.out.println("Homer's Ex-Partners: " + homer.getExPartners());
System.out.println("Marge's kids: " + marge.getChildren());
System.out.println("Homer's kids: " + homer.getChildren());
System.out.println("Dolores's siblings: " + dolores.getSiblings());
System.out.println("Brunos's siblings: " + bruno.getSiblings());
Output:
Homer & Marge: [Marge, FEMALE], [Homer, MALE]
Marge & Partner: [Marge, FEMALE], [New Guy, MALE]
Marge's Ex-Partners: [[Homer, MALE]]
Homer & Partner: [Homer, MALE], [New Girl, FEMALE]
Homer's Ex-Partners: [[Marge, FEMALE]]
Marge's kids: [[Bart, MALE], [Lisa, FEMALE], [Dolores, FEMALE]]
Homer's kids: [[Bart, MALE], [Lisa, FEMALE], [Bruno, MALE]]
Dolores's siblings: [[Bart, MALE], [Lisa, FEMALE]]
Brunos's siblings: [[Bart, MALE], [Lisa, FEMALE]]

Categories