Vending maschine

Sandro95

Bekanntes Mitglied
Hey Leute , ich soll eine Wending Maschine programmieren . (Siehe Bild)
Soweit habe ich alles fertig , nur fehlt mir der Abschnitt des kaufs.

Wenn der User zB ein Sirt für 20 dollar kauft , sollen halt zB 1x 20 Dollar abgezogen werden. Aber man könnte ja die 20 Dollar anders aufteilen ,dass 2x 10 dollar abgezogen werden. Ich haabeleider absolut keine Idee wie ich das umsetzen soll.
Für jede Hilfe wäre ich mega dankbar !

Der user hat ein array mit {10,10,10,10,10,10,10} Index 1 ist zB für die 10x einen dollar .

Meine User Klasse , Main und eine Produkt klasse von 3 sind wie folgt:



Java:
import java.util.Scanner;

public class VendingMachine {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

//        User me = new User();
//        System.out.println(me.getWallet(3));
//        me.setWallet(3, one.buy());
//        System.out.println(me.getWallet(3));
//       

        System.out.println("Welcome to the vending Machine !");
        User user = new User();

        int choice = 1;
        int buyOrNot = 0;

        while (choice < 5) {
            System.out.println("\n"
                    + "Please choose between the following products:\n1. Food 2. Drinks. 3. Tshirts");

            choice = scanner.nextInt();

            switch (choice) {

            case 1:
                Food food = new Food("Sandwich", 20);
                food.description();
                System.out.println(
                        "\nWould you like to buy the selected item?\nChoose the 1 for purchase.\nSelect the 2 for cancel");

                buyOrNot = scanner.nextInt();

                if (buyOrNot == 1) {
                    food.buy();
                    break;
                } else if (buyOrNot == 2) {
                    break;
                  }

                break;
            case 2:
                Drinks drink = new Drinks("Cola", 3);
                drink.description();
                System.out.println(
                        "\nWould you like to buy the selected item?\nChoose the 1 for purchase.\nSelect the 2 for cancel");

                buyOrNot = scanner.nextInt();

                if (buyOrNot == 1) {
                    drink.buy();
                    break;
                } else if (buyOrNot == 2) {
                    break;

                }

                break;
            case 3:
                Shirt shirt = new Shirt("Adidas", 3);
                shirt.description();
                System.out.println(
                        "\nWould you like to buy the selected item?\nChoose the 1 for purchase.\nSelect the 2 for cancel");

                buyOrNot = scanner.nextInt();

                if (buyOrNot == 1) {
                    shirt.buy();
                    break;
                } else if (buyOrNot == 2) {
                    break;

                }

                break;
            case 4:
                System.out.println("Goodbye. Have a nice day!");
                choice = 5;
                break;
            default:
                System.out.println("Please choose a point between 1 and 4");
                choice = scanner.nextInt();
            }

        }

    }

}



public class Food extends Products implements IProduct {


    public Food(String name, int costs) {
        super(name ,costs);
    }

    public int buy() {
        return super.getCosts();
    }

    public void description() {
        System.out.println("This product is a " + super.getName());
    }

    public void use() {

        System.out.println("The food must be eaten");

    }

}



public class User {
    
    // Array for the  different kind of Dollars index 0 = 1Dollar etc.
    private int [] wallet;
    
    public User() {
        this.wallet= new int [] {10,10,10,10,10,10,10,10,10};
    }
    
    public int  getWallet(int index) {
        return this.wallet[index];
    }
    
    public void setWallet(int index, int costs) {
        //this.wallet[index] = this.wallet[index]-costs;
        
        
    }
    
    
}
 

Anhänge

  • WhatsApp Image 2021-03-07 at 13.48.14.jpeg
    WhatsApp Image 2021-03-07 at 13.48.14.jpeg
    172 KB · Aufrufe: 34

Sandro95

Bekanntes Mitglied
PS: mir ist klar , dass ich schauen muss ob der preis zB zwischen 10 und 19 liegt dann soll von dort und dort etwas abgezogen werden . aber nehmen wir mal an der preis ist dann 18 , dieser muss ja trotzdem anders behandelt werden als 15
 

Robert Zenz

Top Contributor
Wenn der User zB ein Sirt für 20 dollar kauft , sollen halt zB 1x 20 Dollar abgezogen werden. Aber man könnte ja die 20 Dollar anders aufteilen ,dass 2x 10 dollar abgezogen werden. Ich haabeleider absolut keine Idee wie ich das umsetzen soll.
Das ist relativ komplex. Was du vermutlich brauchst ist eine Abfrage an den Benutzer welche Stueckelung dieser verwenden will. Also welche Geldscheine aus seiner Brieftasche verwendet werden sollen. Dann musst du diese zusammenzaehlen und sehen ob es genug ist. Vergiss dabei aber auch nicht eine Moeglichkeit einzubauen dass der Benutzer seine Eingabe von vorne beginnen kann. Stell dir dabei am besten die Stueckelungsauswahl an einem Bankomat vor.

Du hast hier schon ganz gut begonnen in dem dir die "wallet" Variable angelegt hast. Da dies aber als Uebung fuer dich dienen soll, wuerde ich noch weiter gehen, und ein Wallet durch eine eigene Klasse repraesentieren lassen. Das kannst du dann sehr schoen wegkapseln, dass zum Beispiel deine verwendeten Klassen nie etwas von dem Index wissen muessen. Das koenntest du zum Beispiel so machen:

Java:
public class Wallet {
    private static final int[] BANKNOTE_VALUES = new int[] { 5, 10, 20, 50, 100 };
    private int[] banknotes = new int[BANKNOTE_VALUES.length];
    
    public Wallet() {
        super();
    }

    public Wallet modifyBanknotes(int value, int amount) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
        
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.

        if ((banknotes[banknoteIndex] + amount) < 0) {
            // TODO Amount could be negative to remove notes.
        }

        banknotes[banknoteIndex] = banknotes[banknoteIndex] + amount;
        
        return this;
    }

    public Wallet removeBanknotes(Wallet otherWallet) {
        // TODO Get all values from the other wallet and remove them from this one.
    }

    public Wallet setBanknotes(int value, int amount) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
        verifyIsZeroOrPositive(amount); // TODO Must be implemented.
       
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.
        
        banknotes[banknoteIndex] = amount;
        
        return this;
    }
    
    public int getBanknoteAmount(int value) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
        
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.
        
        return banknotes[banknoteIndex];
    }
   
    public int getTotalValue() {
        // TODO Count all banknotes and return the total value contained.
    }
}

Damit kannst du ganz einfach das die Brieftasche verwalten. Wenn du jetzt den Benutzer nach Geldscheinen fragst, legst du dir am besten eine zweite Brieftasche fuer den eingegebenen Betrag an. In etwas in dieser Art:

Java:
Wallet userInputWallet = new Wallet();

// TODO Imagine user-input here.
int banknotesValue = getUserInputForValue();
int banknotesAmount = getUserInputForAmount();

if (user.getWallet().getBanknoteAmount(banknotesValue) >= banknotesAmount) {
    userInputWallet.modifyBanknotes(banknotesValue, banknotesAmount);
}

// After the user said they are done:

if (userInputWallet.getTotalValue() == priceToPay) {
    user.getWallet().removeBanknotes(userInputWallet);
} else if (userInputWallet.getTotalValue() == priceToPay) {
    // TODO User selected too much, what you gonna do?
} else {
    // TODO User selected too little.
}

Ich bin nicht ganz gluecklich damit, um ehrlich zu sein, aber ich denke es waere mal ein guter Anfang.
 

Robert Zenz

Top Contributor
Betreffend wenn der Benutzer zu viele Banknote selektiert hat, kannst du eigentlich nur versuchen die beste Menge an Banknoten fuer den Preis zu finden basierend auf der Anzahl der Banknoten die du gerade hast. Das ist etwas komplizierter und mir faellt gerade kein guter und einfacher Weg dazu ein auszer dass ganz mit roher Gewalt durchzuprobieren (was kein Problem waere bei dieser Anzahl an Banknoten).
 

Sandro95

Bekanntes Mitglied
erstmals , vielen dank für deine Hilfe @Robert Zenz !
Also du bist der Meinung , dass ich das Wallet als eigene Klasse lieber implementieren soll als ein Array in der Klasse User ?
Dementsprechend benötige ich dan nja bei User eine Assoziation zum Wallet ?
Mir ist noch nicht ganz bewusst , warum ich in der Klasse Wallet jetzt zwei Arrays benötige , und wie ich genau die rechnung mache wie ich oben schon beschrieben habe..
 

Robert Zenz

Top Contributor
Eine extra Klasse hat den Vorteil das du es suaber kapseln kannst, und kannst ja jederzeit eine Instanz als Feld in "User" anlegen.

Das hatte ich vergessen dazu zuschreiben, du hast recht. "BANKNOTES_VALUES" hat zwei Zwecke. Zum einen pruefen ob es sich um einen gueltigen Geldscheinwert handelt, und zum anderen dient es als Index-Provider fuer "banknotes". Also wenn du jetzt die Anzahl der 20er veraendern willst, waere das zum Beispiel:

Java:
int banknoteIndex = Arrays.indexOf(BANKNOTES_VALUES, 20).

banknotes[banknoteIndex] = 5;

Dadurch musst du deine interne Repraesentation (naemlich das Array) nicht nach Auszen tragen, und von Auszen wird immer nur mit dem Wert der Banknote zugegriffen. Das kapselt das sehr schoen weg.

Wie du dann herausfindest welche Banknoten du wirklich brauchst, hier ist etwas Pseudo-Code wie ich mir das vorstellen koennte:

Java:
int totalPriceToPay = 24985289345;
int remainingPriceToPay = totalPriceToPay;

for (banknoteValue from largest to smallest in wallet AND remainingPriceToPay > 0) {
    int banknotesAmount = wallet.getBanknotesAmount(banknoteValue);
    int banknotesValue = banknotesAmount * banknoteValue;
   
    if (banknotesValue > remainingPriceToPay) {
       // More than enough available, use the least amoutn needed.
      int banknotesNeeded = (remainingPriceToPay / banknoteValue)
     
      remainingPriceToPay = remainingPriceToPay - (banknotesNeeded * banknotesValue);
    } else if (banknotesValue <= remainingPriceToPay) {
        remainingPriceToPay = remainingPriceToPay - banknotesValue;
    }
}

Sehr Pseudo, aber besser faellt es mir gerade nicht ein.
 

Sandro95

Bekanntes Mitglied
Danke für deine Mühe , hat mir weiter geholfen ! ich schaue es mir nachher in Ruhe an und versuche das umzusetzen. Wenn ich noch Fragen habe würde ich mich melden :) danke bis hier hin ! @Robert Zenz
 

Sandro95

Bekanntes Mitglied
Eine extra Klasse hat den Vorteil das du es suaber kapseln kannst, und kannst ja jederzeit eine Instanz als Feld in "User" anlegen.

Das hatte ich vergessen dazu zuschreiben, du hast recht. "BANKNOTES_VALUES" hat zwei Zwecke. Zum einen pruefen ob es sich um einen gueltigen Geldscheinwert handelt, und zum anderen dient es als Index-Provider fuer "banknotes". Also wenn du jetzt die Anzahl der 20er veraendern willst, waere das zum Beispiel:

Java:
int banknoteIndex = Arrays.indexOf(BANKNOTES_VALUES, 20).

banknotes[banknoteIndex] = 5;

Dadurch musst du deine interne Repraesentation (naemlich das Array) nicht nach Auszen tragen, und von Auszen wird immer nur mit dem Wert der Banknote zugegriffen. Das kapselt das sehr schoen weg.

Wie du dann herausfindest welche Banknoten du wirklich brauchst, hier ist etwas Pseudo-Code wie ich mir das vorstellen koennte:

Java:
int totalPriceToPay = 24985289345;
int remainingPriceToPay = totalPriceToPay;

for (banknoteValue from largest to smallest in wallet AND remainingPriceToPay > 0) {
    int banknotesAmount = wallet.getBanknotesAmount(banknoteValue);
    int banknotesValue = banknotesAmount * banknoteValue;
  
    if (banknotesValue > remainingPriceToPay) {
       // More than enough available, use the least amoutn needed.
      int banknotesNeeded = (remainingPriceToPay / banknoteValue)
    
      remainingPriceToPay = remainingPriceToPay - (banknotesNeeded * banknotesValue);
    } else if (banknotesValue <= remainingPriceToPay) {
        remainingPriceToPay = remainingPriceToPay - banknotesValue;
    }
}

Sehr Pseudo, aber besser faellt es mir gerade nicht ein.
Das alles kommt ja in der Klasse Wallet rein . In USer benötoge ich dann ja eine Assoziation zu Wallet oder nicht ?
ansonsten benötigt der user eig nichts oder ?
Man könnte dem User im Konstruktor eine Wallet instanz mittels ein attribut Wallet wallet doch einfach zu weisen ?
 

Robert Zenz

Top Contributor
In USer benötoge ich dann ja eine Assoziation zu Wallet oder nicht ?
ansonsten benötigt der user eig nichts oder ?
So wie du es im Moment strukturiert hast, denke nicht, nein.
Man könnte dem User im Konstruktor eine Wallet instanz mittels ein attribut Wallet wallet doch einfach zu weisen ?
Ja, einfach eine Instanz als Feld auf der Klasse.
@Robert Zenz das ganze ist echt komplexer als ich dachte und heute abend ist noch abgabe ..
Ich weisz das klingt jetzt gemein, aber da hast du noch einiges vor dir. Koennte eng werden wenn ich mir die Vorgaben und deinen Stand aus dem ersten Beitrag anschaue.
 

Sandro95

Bekanntes Mitglied
@Robert Zenz jetzt hast du mir meine ganze Hoffnung genoommen..:D also bis 0:00 uhr habe ich noch Zeit..

So wie du es im Moment strukturiert hast, denke nicht, nein.

Ja, einfach eine Instanz als Feld auf der Klasse.

Ich weisz das klingt jetzt gemein, aber da hast du noch einiges vor dir. Koennte eng werden wenn ich mir die Vorgaben und deinen Stand aus dem ersten Beitrag anschaue.
Kennst du vlt eine gute Seite wo sowas oder etwas ähnliches beschrieben wird ? Habs mir ehrlich gesagt leichter vorgestellt und jetzt habe ich enormen druck..
 

Robert Zenz

Top Contributor
Wird sportlich, aber koennte klappen. Halte dich dann aber auch nicht mit Struktur auf, Hauptsache es tut das was du brauchst. Spielt keine Rolle wie das Ding dann aussieht.

Kennst du vlt eine gute Seite wo sowas oder etwas ähnliches beschrieben wird ? Habs mir ehrlich gesagt leichter vorgestellt und jetzt habe ich enormen druck..
Was meinst?
 

Sandro95

Bekanntes Mitglied
Du hast mir ja schon einiges erklärt wofür ich dir mehr als dankbar bin . Doch leider weiß ich wirklich nicht , wie ich das genau umzusetzen habe .. Kennst du vlt ein gutes video , ne Seite oder der artiges welche mr helfen würde.. ?
Das ist relativ komplex. Was du vermutlich brauchst ist eine Abfrage an den Benutzer welche Stueckelung dieser verwenden will. Also welche Geldscheine aus seiner Brieftasche verwendet werden sollen. Dann musst du diese zusammenzaehlen und sehen ob es genug ist. Vergiss dabei aber auch nicht eine Moeglichkeit einzubauen dass der Benutzer seine Eingabe von vorne beginnen kann. Stell dir dabei am besten die Stueckelungsauswahl an einem Bankomat vor.

Du hast hier schon ganz gut begonnen in dem dir die "wallet" Variable angelegt hast. Da dies aber als Uebung fuer dich dienen soll, wuerde ich noch weiter gehen, und ein Wallet durch eine eigene Klasse repraesentieren lassen. Das kannst du dann sehr schoen wegkapseln, dass zum Beispiel deine verwendeten Klassen nie etwas von dem Index wissen muessen. Das koenntest du zum Beispiel so machen:

Java:
public class Wallet {
    private static final int[] BANKNOTE_VALUES = new int[] { 5, 10, 20, 50, 100 };
    private int[] banknotes = new int[BANKNOTE_VALUES.length];
   
    public Wallet() {
        super();
    }

    public Wallet modifyBanknotes(int value, int amount) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
       
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.

        if ((banknotes[banknoteIndex] + amount) < 0) {
            // TODO Amount could be negative to remove notes.
        }

        banknotes[banknoteIndex] = banknotes[banknoteIndex] + amount;
       
        return this;
    }

    public Wallet removeBanknotes(Wallet otherWallet) {
        // TODO Get all values from the other wallet and remove them from this one.
    }

    public Wallet setBanknotes(int value, int amount) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
        verifyIsZeroOrPositive(amount); // TODO Must be implemented.
      
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.
       
        banknotes[banknoteIndex] = amount;
       
        return this;
    }
   
    public int getBanknoteAmount(int value) {
        verifyIsAllowedBanknoteValue(value); // TODO Must be implemented.
       
        int banknoteIndex = getBanknoteIndex(value); // TODO Must be implemented.
       
        return banknotes[banknoteIndex];
    }
  
    public int getTotalValue() {
        // TODO Count all banknotes and return the total value contained.
    }
}

Damit kannst du ganz einfach das die Brieftasche verwalten. Wenn du jetzt den Benutzer nach Geldscheinen fragst, legst du dir am besten eine zweite Brieftasche fuer den eingegebenen Betrag an. In etwas in dieser Art:

Java:
Wallet userInputWallet = new Wallet();

// TODO Imagine user-input here.
int banknotesValue = getUserInputForValue();
int banknotesAmount = getUserInputForAmount();

if (user.getWallet().getBanknoteAmount(banknotesValue) >= banknotesAmount) {
    userInputWallet.modifyBanknotes(banknotesValue, banknotesAmount);
}

// After the user said they are done:

if (userInputWallet.getTotalValue() == priceToPay) {
    user.getWallet().removeBanknotes(userInputWallet);
} else if (userInputWallet.getTotalValue() == priceToPay) {
    // TODO User selected too much, what you gonna do?
} else {
    // TODO User selected too little.
}

Ich bin nicht ganz gluecklich damit, um ehrlich zu sein, aber ich denke es waere mal ein guter Anfang.
 

Robert Zenz

Top Contributor
Nein, leider nicht. Die Aufgabe ist sehr gut, ich glaube dafuer gibt es keine General-Loesung, sondern die muss man sich aus den unterschiedlichsten Quellen zusammen suchen.
 

Sandro95

Bekanntes Mitglied
ich habe ja soweit alles , bis auf das mit dem Wallat und den kauf .. sitze da schon STunden dran langsam verzweifel ich ..:D Hast du vlt sonst noch ein Tipp oder eine Kleine Hilfe für mich ? du würdest mir echt damit helfen
Nein, leider nicht. Die Aufgabe ist sehr gut, ich glaube dafuer gibt es keine General-Loesung, sondern die muss man sich aus den unterschiedlichsten Quellen zusammen suchen.
 

Sandro95

Bekanntes Mitglied
Dieser Abschnitt gehört doch in der Main , richtig ? also in meiner VendingMachine Klasse @Robert Zenz

Java:
Wallet userInputWallet = new Wallet();

// TODO Imagine user-input here.
int banknotesValue = getUserInputForValue();
int banknotesAmount = getUserInputForAmount();

if (user.getWallet().getBanknoteAmount(banknotesValue) >= banknotesAmount) {
    userInputWallet.modifyBanknotes(banknotesValue, banknotesAmount);
}

// After the user said they are done:

if (userInputWallet.getTotalValue() == priceToPay) {
    user.getWallet().removeBanknotes(userInputWallet);
} else if (userInputWallet.getTotalValue() == priceToPay) {
    // TODO User selected too much, what you gonna do?
} else {
    // TODO User selected too little.
}
 

Robert Zenz

Top Contributor
Ja, das brauchst du in der Hauptverarbeitungslogik.

Nein, direkten Hinweis habe ich leider keinen mehr fuer dich. Da muss man einfach probieren wie man das am besten loest, muesste ich auch erst machen.
 

Robert Zenz

Top Contributor
Doch, einen Hinweis habe ich noch. Du kannst es dir beim Rueckzahlen einfach machen. Der Benutzer waehlt eine Stueckelung aus, und du zahlst ihm beinhart Wechselgeld in 1er Muenzen zurueck. Also wenn der Benutzer jetzt ein Produkt fuer 15 Euro kauft, und 10 Euro, 20 Euro und 50 Euro als Bezaehlung auswaehlt, ziehst du ihm das ab, und zahlst ihm den Restbetrag einfach als 55x 1 Euro Muenzen zurueck in sein Wallet. Dann ersparst du dir das ganz rumgerechne, und der Benutzer hat halt Pech gehabt.

Dann brauchst du auch einfach nur pruefen ob es genug Geld ist, und der Ueberschuss ist ganz einfach ausgerechnet.
 

Neue Themen


Oben