I am new to programming and I have a simple program I am working on for fun that keeps track of my money. For instance, I want it to record how much money is in my wallet. So I will give it some data, and it complies. However, when I rerun the program at a different time to add or subtract money from my wallet for example, it will revert back to 0 instead of saving the changes I made before.
I assume I have to make a txt file for this data to save to, and then have it read it every time I run the program?
//here is my wallet class
public class Wallet extends UserInterface{
public String WalletName;
public double WalletCash;
public Wallet(String name) {
this.WalletName = name;
}
public String addCashtoWallet(double income) {
WalletCash += income;
return "Added $" + income + "to " + this.WalletName;
}
public String removeCashfromWallet(double cost) {
WalletCash -= cost;
return "Removed $" + cost + "from " + this.WalletName;
}
}
The output when I add money to the wallet for example, will be
"Your wallet now has $64.0 would you like to do anything else"
However, when I run the program again, it will say 0, but I want it to display the 64 dollars I added before. How do I get it to save this data?
You could use a file to keep your information and load the information at the startup.
https://stackabuse.com/reading-and-writing-files-in-java/
Or you can use a database to keep that information.
https://www.tutorialspoint.com/jdbc/jdbc-sample-code.htm
I advice you first to try to use a file, after that you could try using a database (e.g. MySQL, MariaDB, PostgreSQL)
It's not 'memory', it's called 'persistent storage'.
And simple TXT file is a worst solution, like for me. I suggest you to use at least structured file like JSON, but better - an embedded database like HSQLDB.
Related
I was just trying to create this small android app in android studio to convert currency.
I used 2 Spinner objects to hold only 3 values (USD, POUND, EURO) :
if(actualType.equals("USD")){
if(wantedType.equals("POUND")){
montantConv = montantNonConv * 0.87;
}
else if(wantedType.equals("EURO")){
montantConv = montantNonConv;
}
}
else if(actualType.equals("POUND")){
if(wantedType.equals("EURO")){
montantConv = montantNonConv * 1.15;
}
else if(wantedType.equals("USD")){
montantConv = montantNonConv * 1.15;
}
}
else if(actualType.equals("EURO")){
if(wantedType.equals("USD")){
montantConv = montantNonConv * 1;
}
else if(wantedType.equals("POUND")){
montantConv = montantNonConv * 0.87;
}
}
With if-else the code is too long for a combination of only 3 choices (input + output).
i was just wondering is there a better algorithm to do this ? How does the online ones do it that have 50+ currencies to chose from ?
As you are finding out, putting names of the currencies in the conversion logic is not a good idea. The same applies with the conversion values. You should want to write code to minimize things like that. You want the actual conversion logic coded without explicitly knowing ("hard coding") the names of the currencies or their exchange rates.
Rather than have something like actualType.equals("POUND") in your code, you want to try to have code that has each value represented by a variable: actualType.equals(otherType).
In real life, your data would come from an external source, such as a text file, a database, or another computer. In your small demo app, you might want to have the data load when the program starts, and be stored using array(s) and or (a) Collection object(s). At this time, you would also load the values in the Spinner objects, with the same data.
You might think about whether it is worth having another class or not:
class Money {
String name;
double conversionValue;
Money (String name, double value) {
this.name = name;
conversionValue = value;
}
And so on. (Note: I omitted visibility specifiers.)
In your conversion app, you could simulate the external source with an array:
Money [] market = { new Money ("Euro", 1.00), new Money ("USD", 1.00),
new Money ("Pound", 1.15), new Money ("Yen", 0.007),
new Money ("Rupee", 0.0125), ... };
An alternative to creating another class to glue a currency and exchange factor is to use a Map <String, Double>, with the name of the currency as the key and the exchange factor as the value.
So, the conversion app might have a method like this:
public double convertMoney (String selling, int amt, String buying)
{ ...
Depending on how the names and values were stored, it would use the string values to look up 2 conversion values. The exchange rate would be conversion value associated with selling divided by the conversion value associated with buying.
I dont know how well I'll be able to ask this question, but given a text file I need to parse through and extract the productID data and store it in a HashSet, userID data and store it in a HashSet, and the review/score and store it in an ArrayList. They also need to be used to create a graph, where the productID is connected with an edge between the userID.
The data is found here http://snap.stanford.edu/data/web-FineFoods.html
You can ignore review/time, review/helpfulness, review/summary, and review/text information, they dont need to be stored in memory.
My current code looks like this:
import java.io.*;
import java.util.*;
import java.nio.charset.*;
public class Reviews
{
String fileName = "newfinefoods.txt";
GraphType<String> foodReview;
HashSet<String> productID;
HashSet<String> userID;
ArrayList<String> review;
int counter; //was using this to make sure I'm counting all the lines which I think I am
public Reviews(){
foodReview = new GraphType<>();
productID = new HashSet<>();
userID = new HashSet<>();
review = new ArrayList<>();
counter = 0;
}
public int numReviews(){
return review.size();
}
public int numProducts(){
return productID.size();
}
public int numUsers(){
return userID.size();
}
public void setupGraph(){
Scanner fileScanner;
String line = "";
try{
fileScanner = new Scanner (new File (fileName), "UTF-8");
String pr = "";
while(fileScanner.hasNextLine()){
line = fileScanner.nextLine();
String[] reviewInfo = line.split(": ");
String productInfo = reviewInfo[1];
System.out.println(productInfo);
}
}
catch (IOException e){
System.out.println(e);
}
}
public static void main(String[] args){
Reviews review = new Reviews();
review.setupGraph();
System.out.println("Number of Reviews:" + review.numReviews());
System.out.println("Number of Products:" + review.numProducts());
System.out.println("Number of Users:" + review.numUsers());
}
}
Whenever I run the code, looking in the array reviewInfo at 1, it only prints one set of data, but if I change it to 0 it seems to print all the information (just not the info that I need). I need to create this graph and get the info from the data but I am really just super stuck, and any tips or help would be very appreciated!
Here is a sample of the data:
product/productId: B001E4KFG0
review/userId: A3SGXH7AUHU8GW
review/profileName: delmartian
review/helpfulness: 1/1
review/score: 5.0
review/time: 1303862400
review/summary: Good Quality Dog Food
review/text: I have bought several of the Vitality canned dog food products and have found them all to be of good quality. The product looks more like a stew than a processed meat and it smells better. My Labrador is finicky and she appreciates this product better than most.
product/productId: B00813GRG4
review/userId: A1D87F6ZCVE5NK
review/profileName: dll pa
review/helpfulness: 0/0
review/score: 1.0
review/time: 1346976000
review/summary: Not as Advertised
review/text: Product arrived labeled as Jumbo Salted Peanuts...the peanuts were actually small sized unsalted. Not sure if this was an error or if the vendor intended to represent the product as "Jumbo".
product/productId: B000LQOCH0
review/userId: ABXLMWJIXXAIN
review/profileName: Natalia Corres "Natalia Corres"
review/helpfulness: 1/1
review/score: 4.0
review/time: 1219017600
review/summary: "Delight" says it all
review/text: This is a confection that has been around a few centuries. It is a light, pillowy citrus gelatin with nuts - in this case Filberts. And it is cut into tiny squares and then liberally coated with powdered sugar. And it is a tiny mouthful of heaven. Not too chewy, and very flavorful. I highly recommend this yummy treat. If you are familiar with the story of C.S. Lewis' "The Lion, The Witch, and The Wardrobe" - this is the treat that seduces Edmund into selling out his Brother and Sisters to the Witch.
product/productId: B000UA0QIQ
Initial approach of your design is right, but you should structure it a little more:
Method setupGraph should be splitted in little specific and parametrized methods:
Since the users and products are part of the class' state, I deem it better that the class' constructor receives the scanner as an input parameter. Then, after initializing the state variables, it should call setupGraph (which should be private) passing the input scanner.
setupGraph shall receive an input scanner and take the responsibility of reading lines from it, and give a proper treatment to the IOExceptions that might arise. On each line, it should merely call another private method for processing the read line. If you want to count all the read lines, this is where you should place the increment.
The processing line method shall receive an input string, and take the responsibility of deciding if it contains a product data, a user data, a score data, or none. This must be done through properly parsing its contents.
Here is where you can use String.split() to get the name and value of each line, and then evaluate the name to decide where to store the value. And if you want to count all the processed lines, this is where you should place the increment.
Last, main method shall take the responsability of instancing the scanner and passing it when constructing the Reviews object. In this way, you could receive the file name as input argument from the command line, so your program would become flexible.
Realise that the only public methods of your class should be the constructor and the getters. And state variables shuld be private.
I would like to read data from my config.yml. It's saving data like (playerName: value). I want to check, if player's name value is equals to 0, then ban him. But still don't know how to read those values. I was searching around spigot forum but nothing worked.
#EventHandler
public void OnDeath(PlayerDeathEvent event) {
Player player = event.getEntity().getPlayer();
String playerName = player.getName();
int lives;
if (!livesMap.containsKey(player)) {
// Set the default amount of lives to 2. (3 minus 1, since the player already died once)
lives = 2;
plugin.getConfig().set(playerName, lives);
plugin.saveConfig();
} else {
// Subtract one from the player's lives
lives = livesMap.get(player) - 1;
// Saving playerName and lives
plugin.getConfig().set(playerName, lives);
plugin.saveConfig();
}
livesMap.put(player, lives);
My data is saving like this, but i want to know what method should i use to read values.
Lucky for you, bukkit already has classes you can use for this!
import org.bukkit.configuration.file.FileConfiguration;
FileConfiguration config = getConfig();
This call will inherently load your config.yml file.
You can then access values by doing something like this:
config.getString("yml.object.here");
Let me know if you have any other questions!
TIP: If you store your player names in a list you can get a list of them!
plugin.getConfig().getInt(playerName).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm writing a program with 3 options. So the first one is about the employee- (create / remove / update / get information about employee / save to file). Before creating a new employee I have to choose his type(programmer or qa)(difference between them is that programmer have a specific programming language and qa have amount of worked hours). So moving forward when I create a new user I have to enter name / surname / age / prog.language;
The second option in my program is that I can create a team which must be made from 3 employees. So from a list of employees you select one for team lead and other 2 for 'workers'.
And the last one is that you can create a task.
(you need to give a name for task, specific language which is required from a second team member and amount of worked hours from a third member). So this task can be later assigned to a specific team.
So lets talk about my problem right now:
Creating new employees, making new teams works 100%, also creating new tasks works fine as well, but when I try to check does my selected team meets requirements for tasks I'm receiving tons of errors. I've tried to select specific member from a team and check his programming language and receiving null. However, after debugging I saw that information comes,but when i try to reach exactly that language appears null.
Here's my code how looks my programmer class:
package com.wep;
public class Programuotojas extends Darbuotojas {
protected String programavimoKalba;
#Override
public String toString() {
return "Programuotojas: " + vardas + ",pavarde " + pavarde + ",amzius " + amzius + ",programavimo kalba " + programavimoKalba;
}
public Programuotojas(String vardas, String pavarde, int amzius, String programavimoKalba) {
super(vardas, pavarde, amzius);
this.programavimoKalba = programavimoKalba;
}
Programuotojas(){}
public String getProgramavimoKalba() {
return programavimoKalba;
}
public void setProgramavimoKalba(String programavimoKalba) {
this.programavimoKalba = programavimoKalba;
}
}
And here's my try to check his language:
KomanduValdymas.getInstance().komanduArray.get(0).getPirmasDarbuotojas(programuotojas.getProgramavimoKalba());
KomanduValdymas is a class where I create new teams. If u need more code from there let me know. Thanks, hope you guys got my problem
private void pridetiDarbuotoja() {
System.out.println("[1] Pridėti programuotoją");
System.out.println("[2] Pridėti testuotoją");
Scanner SI = new Scanner(System.in);
int userSelects = Integer.parseInt(SI.nextLine());
if (userSelects == 1) {
System.out.println("Iveskite:");
System.out.println("Varda, pavarde, amziu, darbine programavimo kalba");
String enters[] = SI.nextLine().split(" ");
darbuotojuArray.add(new Programuotojas(enters[0], enters[1], Integer.parseInt(enters[2]), enters[3]));
System.out.println("Darbuotojas itrauktas i sarasa");
} else {
System.out.println("Iveskite:");
System.out.println("Varda, pavarde, amziu, isdirbtas testavimo valandas");
String enters[] = SI.nextLine().split(" ");
darbuotojuArray.add(new Testuotojas(enters[0], enters[1], Integer.parseInt(enters[2]), Integer.parseInt(enters[3])));
}
darbuotojuValdiklis();
}
You appear to be under the impression that creating a new Programuotojas will update the value of your variable programuotojas automatically. That is not the case.
You need a statement that starts with programuotojas = in order to affect such a change.
Just wondering, why did the people who invented Java write methods like setAccessible(boolean flag), which makes the access-modifiers (specially private) useless and cannot protect fields, methods, and constructors from being reached? Look at the following simple example:
public class BankAccount
{
private double balance = 100.0;
public boolean withdrawCash(double cash)
{
if(cash <= balance)
{
balance -= cash;
System.out.println("You have withdrawn " + cash + " dollars! The new balance is: " + balance);
return true;
}
else System.out.println("Sorry, your balance (" + balance + ") is less than what you have requested (" + cash + ")!");
return false;
}
}
import java.lang.reflect.Field;
public class Test
{
public static void main(String[] args) throws Exception
{
BankAccount myAccount = new BankAccount();
myAccount.withdrawCash(150);
Field f = BankAccount.class.getDeclaredFields()[0];
f.setAccessible(true);
f.set(myAccount, 1000000); // I am a millionaire now ;)
myAccount.withdrawCash(500000);
}
}
OUTPUT:
Sorry, your balance (100.0) is less than what you have requested
(150.0)! You have withdrawn 500000.0 dollars! The new balance is: 500000.0
Because some code is trusted code -- i.e., if a local application wants to do this, maybe it's not a big deal. For untrusted code, though -- i.e., an applet, or a web start application, or RMI stubs, or any other downloaded code -- there's a SecurityManager in place, which (generally based on a policy file) has the opportunity to say "Sorry, Charlie" and deny the setAccessible() request.
Well, once you have released a Java program, anyone is free to reverse engineer, or de-compile, it anyways, so if someone wanted it badly enough, they would probably be able to access your your "privates" anyway.
What you can do however, is to forbid any foreign code to access your stuff in your runtime. That is, if you're for instance using someone else's code you could disable reflections, access to files etc before those libraries are used.
Search for ClassLoader and Security Manager to find out more. Here's something that looks relevant.