I have two methods
*`public boolean validateMarks() {
return (this.qualifyingMarks >= 65 && this.qualifyingMarks <= 100);
}
public boolean validateCourseId() {
return (this.courseId >= 1001 && this.courseId <= 1005);
}`*
validateMarks(): Used to validate qualifying exam marks - qualifying marks is in the range of 65 to 100(both inclusive)
validateCourseId(): Used to validate the course entered, based on the courseId - given in the table above
calculateCourseFee(): Used to calculate the course fee after applying the discount.
So when is less than 65 print print "not elegible, you've failed" and when the course is not valid "course is not correct, please try again with the correct number of the course"
and this is my calculateCourseFee method
***if(this.validateMarks()) {
this.courseFee = fee - (fee * discount);
System.out.println("****Course Allocation Details****" + "\n" +
"Student Name: " + this.getStudentName() + "\n" +
"Course Id: " + this.getCourseId() + "\n" +
"Qualifying Exam Marks: " + this.getQualifyingMarks() + "\n" +
"Student's Registration Id: " + this.getRegistrationId() + "\n" +
"Total Course Fee: " + this.getCourseFee() + "\n" +
"Hostel Required: " + hostel);
}else {
System.out.println("wrong for marks ");
}
if(this.validateCourseId()) {
this.courseFee = fee - (fee * discount);
System.out.println("****Course Allocation Details****" + "\n" +
"Student Name: " + this.getStudentName() + "\n" +
"Course Id: " + this.getCourseId() + "\n" +
"Qualifying Exam Marks: " + this.getQualifyingMarks() + "\n" +
"Student's Registration Id: " + this.getRegistrationId() + "\n" +
"Total Course Fee: " + this.getCourseFee() + "\n" +
"Hostel Required: " + hostel);
}else {
System.out.println("Wroog for course");
}
***
I make two different ifs for the two requirements, but everytime I run it, it prints the else statement to, even if marks is greather than 65... am I missing something?
Reviewing my code and tell me what am I missing or what am I doing wrong
The portion of the code you have shown here seems to be working as expected.
public class Driver {
public static void main(String args[]) {
Eligible e1 = new Eligible();
e1.calculateCourseFee();
}
}
class Eligible{
int qualifyingMarks = 66;
int courseId = 1002;
public boolean validateMarks() {
return (this.qualifyingMarks >= 65 && this.qualifyingMarks <= 100);
}
public boolean validateCourseId() {
return (this.courseId >= 1001 && this.courseId <= 1005);
}
public void calculateCourseFee(){
if(this.validateMarks()) {
System.out.println("works for marks");
}else {
System.out.println("wrong for marks ");
}
if(this.validateCourseId()) {
System.out.println("works for course");
}else {
System.out.println("Wroog for course");
}
}
}
output:
works for marks
works for course
Maybe the issues is with how you set the values for the qualifyingMarks and courseId variables?
I wish I could give you a like or thumbs up, I finally did it, thanks to all of your answers you gave me, and I just combined the two ifs into one. here's the code:
if(this.validateCourseId() && this.validateMarks()) {
this.courseFee = fee - (fee * discount);
System.out.println("****Course Allocation Details****" + "\n" +
"Student Name: " + this.getStudentName() + "\n" +
"Course Id: " + this.getCourseId() + "\n" +
"Qualifying Exam Marks: " + this.getQualifyingMarks() + "\n" +
"Student's Registration Id: " + this.getRegistrationId() + "\n" +
"Total Course Fee: " + this.getCourseFee() + "\n" +
"Hostel Required: " + hostel);
}else if(!this.validateCourseId()) {
System.out.println("Wrong course");
}
else if(!this.validateMarks()) {
System.out.println("You've failed");
}
Thanks everyone!!
maybe qualifyingMarks is zero or another value, print qualifyingMarks in method "validateMarks",u will get the reason of your problem.
I have this challenge to create a facebook-like counter that will show how many people liked a post. I'm relatively new to Java, but have managed to do it. My question is - Is there a more practical and short way of writing the below method?
im just using a simple static array in the Main called users[] with some names in it.
public static void facebookCounter(String users[])
{
if(users.length == 1)
{
System.out.println(users[0] + " liked this");
}
else if(users.length == 2)
{
System.out.println(users[0] + " " + users[1] + " liked this.");
}
else if(users.length > 2)
{
System.out.println(users[0] + " " + users[1] + " and " + (users.length-2) + " others liked this");
}
}
Sorry if my pasted code is not formatted well, I pasted it from my intelliJ
Thanks to anyone who has any ideas!
Another approach could be using switch statement rather than if/else:
public static void facebookCounter(String users[]) {
switch (users.length) {
case 0: break;
case 1:
System.out.println(users[0] + " liked this");
break;
case 2:
System.out.println(users[0] + " " + users[1] + " liked this.");
break;
default:
System.out.println(users[0] + " " + users[1] + " and " + (users.length-2) + " others liked this");
}
}
My suggestion is to stream the first 1 or 2 array items (depending on array's length), collect to String with a joining space char. then, add appropriate suffix:
public static void facebookCounter(String users[])
{
String msg = IntStream.range(0, Math.min(2, users.length))
.mapToObj(i -> users[i])
.collect(Collectors.joining(" "));
if (users.length > 2) msg += " and " + (users.length-2) + " others";
msg += " liked this";
System.out.println(msg);
}
EDIT:
the suffix can be specified in the joining() method:
System.out.println(
IntStream.range(0, Math.min(2, users.length))
.mapToObj(i -> users[i])
.collect(Collectors.joining(" ", "",
users.length > 2 ? " and " + (users.length-2) + " others liked this" : " liked this"
)
)
);
public boolean saveHighScore(Client c) throws SQLException {
long totallvlexp = (long) (c.playerXP[0]) + (c.playerXP[1]) + (c.playerXP[2]) + (c.playerXP[3]) + (c.playerXP[4]) + (c.playerXP[5]) + (c.playerXP[6]) + (c.playerXP[7]) + (c.playerXP[8]) + (c.playerXP[9]) + (c.playerXP[10]) + (c.playerXP[11]) + (c.playerXP[12]) + (c.playerXP[13]) + (c.playerXP[14]) + (c.playerXP[15]) + (c.playerXP[16]) + (c.playerXP[17]) + (c.playerXP[18]) + (c.playerXP[19]) + (c.playerXP[20]);
int totallevell = (int) (c.getLevelForXP(c.playerXP[0]) + c.getLevelForXP(c.playerXP[1]) + c.getLevelForXP(c.playerXP[2]) + c.getLevelForXP(c.playerXP[3]) + c.getLevelForXP(c.playerXP[4]) + c.getLevelForXP(c.playerXP[5]) + c.getLevelForXP(c.playerXP[6]) + c.getLevelForXP(c.playerXP[7]) + c.getLevelForXP(c.playerXP[8]) + c.getLevelForXP(c.playerXP[9]) + c.getLevelForXP(c.playerXP[10]) + c.getLevelForXP(c.playerXP[11]) + c.getLevelForXP(c.playerXP[12]) + c.getLevelForXP(c.playerXP[13]) + c.getLevelForXP(c.playerXP[14]) + c.getLevelForXP(c.playerXP[15]) + c.getLevelForXP(c.playerXP[16]) + c.getLevelForXP(c.playerXP[17]) + c.getLevelForXP(c.playerXP[18]) + c.getLevelForXP(c.playerXP[19]) + c.getLevelForXP(c.playerXP[20]));
String delQuery1 = "DELETE FROM `skills` WHERE playerName = '"+c.playerName+"';";
String delQuery2 = "DELETE FROM `skillsoverall` WHERE playerName = '"+c.playerName+"';";
String delQuery3 = "DELETE FROM `playerrights` WHERE playerName = '"+c.playerName+"';";
String insQuery1 = "INSERT INTO `skills` (`playerName`,`Attacklvl`,`Attackxp`,`Defencelvl`,`Defencexp`,`Strengthlvl`,`Strengthxp`,`Hitpointslvl`,`Hitpointsxp`,`Rangelvl`,`Rangexp`,`Prayerlvl`,`Prayerxp`,`Magiclvl`,`Magicxp`,`Cookinglvl`,`Cookingxp`,`Woodcuttinglvl`,`Woodcuttingxp`,`Fletchinglvl`,`Fletchingxp`,`Fishinglvl`,`Fishingxp`,`Firemakinglvl`,`Firemakingxp`,`Craftinglvl`,`Craftingxp`,`Smithinglvl`,`Smithingxp`,`Mininglvl`,`Miningxp`,`Herblorelvl`,`Herblorexp`,`Agilitylvl`,`Agilityxp`,`Thievinglvl`,`Thievingxp`,`Slayerlvl`,`Slayerxp`,`Farminglvl`,`Farmingxp`,`Runecraftlvl`,`Runecraftxp`) VALUES ('"+c.playerName+"',"+c.playerLevel[0]+","+c.playerXP[0]+","+c.playerLevel[1]+","+c.playerXP[1]+","+c.playerLevel[2]+","+c.playerXP[2]+","+c.playerLevel[3]+","+c.playerXP[3]+","+c.playerLevel[4]+","+c.playerXP[4]+","+c.playerLevel[5]+","+c.playerXP[5]+","+c.playerLevel[6]+","+c.playerXP[6]+","+c.playerLevel[7]+","+c.playerXP[7]+","+c.playerLevel[8]+","+c.playerXP[8]+","+c.playerLevel[9]+","+c.playerXP[9]+","+c.playerLevel[10]+","+c.playerXP[10]+","+c.playerLevel[11]+","+c.playerXP[11]+","+c.playerLevel[12]+","+c.playerXP[12]+","+c.playerLevel[13]+","+c.playerXP[13]+","+c.playerLevel[14]+","+c.playerXP[14]+","+c.playerLevel[15]+","+c.playerXP[15]+","+c.playerLevel[16]+","+c.playerXP[16]+","+c.playerLevel[17]+","+c.playerXP[17]+","+c.playerLevel[18]+","+c.playerXP[18]+","+c.playerLevel[19]+","+c.playerXP[19]+","+c.playerLevel[20]+","+c.playerXP[20]+");";
String insQuery2 = "INSERT INTO `skillsoverall` (`playerName`,`lvl`,`xp`) VALUES ('"+c.playerName+"',"+totallevell+","+totallvlexp+");";
String insQuery3 = "INSERT INTO `playerrights` (`playerName`,`rank`) VALUES ('"+c.playerName+"',"+c.playerRights+");";
String[] delQueries = {delQuery1, delQuery2, delQuery3};
String[] insQueries = {insQuery1, insQuery2, insQuery3};
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
try(Connection conX = DriverManager.getConnection("jdbc:mysql://localhost/highscores","root","root")) {
try(Statement stmtX = conX.createStatement()) {
for(int i = 0; i < delQueries.length; i++)
{
stmtX.executeUpdate(delQueries[i]);
stmtX.executeUpdate(insQueries[i]);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}
Using this code how could I make it faster? If I used UPDATE instead would it make it faster? If it would please show me how to do that with the code I provided. I'm not very good with SQL, again just helping out a friend.
Some ways to improve this:
Use UPDATE statement and use the value of the primary key in the WHERE clause. This is in case you know the id. If you don't know it, then
Use UPDATE statement properly. Add a proper index on the columns you will use for the WHERE clause, in case is a single column and it's not the primary key and this statement may be executed several times.
Update the relevant columns, not all the columns (unless you are updating all the values for that row, which is something odd but not impossible).
Since you want/need to update everything or nothing, then you should use a transaction. You can start a transaction by using Connection#setAutoCommit(false); and close it by using Connection#commit. In case of errors, use Connection#rollback() and none of the operations will affect the database.
Stop using Statement so naively. If your queries need to be parameterized, then use PreparedStatement instead.
In your database, do this:
ALTER TABLE skills ADD INDEX idx_playerName (playerName);
Here's part of your Java code updated using the statements above:
public boolean saveHighScore(Client c) throws SQLException {
long totallvlexp = (long) (c.playerXP[0]) + (c.playerXP[1]) + (c.playerXP[2]) + (c.playerXP[3]) + (c.playerXP[4]) + (c.playerXP[5]) + (c.playerXP[6]) + (c.playerXP[7]) + (c.playerXP[8]) + (c.playerXP[9]) + (c.playerXP[10]) + (c.playerXP[11]) + (c.playerXP[12]) + (c.playerXP[13]) + (c.playerXP[14]) + (c.playerXP[15]) + (c.playerXP[16]) + (c.playerXP[17]) + (c.playerXP[18]) + (c.playerXP[19]) + (c.playerXP[20]);
int totallevell = (int) (c.getLevelForXP(c.playerXP[0]) + c.getLevelForXP(c.playerXP[1]) + c.getLevelForXP(c.playerXP[2]) + c.getLevelForXP(c.playerXP[3]) + c.getLevelForXP(c.playerXP[4]) + c.getLevelForXP(c.playerXP[5]) + c.getLevelForXP(c.playerXP[6]) + c.getLevelForXP(c.playerXP[7]) + c.getLevelForXP(c.playerXP[8]) + c.getLevelForXP(c.playerXP[9]) + c.getLevelForXP(c.playerXP[10]) + c.getLevelForXP(c.playerXP[11]) + c.getLevelForXP(c.playerXP[12]) + c.getLevelForXP(c.playerXP[13]) + c.getLevelForXP(c.playerXP[14]) + c.getLevelForXP(c.playerXP[15]) + c.getLevelForXP(c.playerXP[16]) + c.getLevelForXP(c.playerXP[17]) + c.getLevelForXP(c.playerXP[18]) + c.getLevelForXP(c.playerXP[19]) + c.getLevelForXP(c.playerXP[20]));
boolean result = true;
String updateSkillsSql = "UPDATE skills"
+ " SET `Attacklvl`=?,"
+ " `Attackxp`=?,"
+ " `Defencelvl`=?,"
+ " `Defencexp`=?,"
+ " `Strengthlvl`=?,"
+ " `Strengthxp`=?,"
+ " `Hitpointslvl`=?,"
+ " `Hitpointsxp`=?,"
+ " `Rangelvl`=?,"
+ " `Rangexp`=?,"
+ " `Prayerlvl`=?,"
+ " `Prayerxp`=?,"
+ " `Magiclvl`=?,"
+ " `Magicxp`=?,"
+ " `Cookinglvl`=?,"
+ " `Cookingxp`=?,"
+ " `Woodcuttinglvl`=?,"
+ " `Woodcuttingxp`=?,"
+ " `Fletchinglvl`=?,"
+ " `Fletchingxp`=?,"
+ " `Fishinglvl`=?,"
+ " `Fishingxp`=?,"
+ " `Firemakinglvl`=?,"
+ " `Firemakingxp`=?,"
+ " `Craftinglvl`=?,"
+ " `Craftingxp`=?,"
+ " `Smithinglvl`=?,"
+ " `Smithingxp`=?,"
+ " `Mininglvl`=?,"
+ " `Miningxp`=?,"
+ " `Herblorelvl`=?,"
+ " `Herblorexp`=?,"
+ " `Agilitylvl`=?,"
+ " `Agilityxp`=?,"
+ " `Thievinglvl`=?,"
+ " `Thievingxp`=?,"
+ " `Slayerlvl`=?,"
+ " `Slayerxp`=?,"
+ " `Farminglvl`=?,"
+ " `Farmingxp`=?,"
+ " `Runecraftlvl`=?,"
+ " `Runecraftxp`=?"
+ " WHERE playerName = ?";
//do similar for the other queries...
//not needed since JDBC 4, noted since you're using Java 7
//Class.forName("com.mysql.jdbc.Driver").newInstance();
try(Connection con = DriverManager.getConnection("jdbc:mysql://localhost/highscores","root","root")) {
//when storing multiple data, it's better to use a transaction
con.setAutoCommit(false);
try(PreparedStatement pstmt = con.prepareStatement(updateSkillsSql);
//declare the other PreparedStatements for each update sql statement here...
) {
//do something like this for every PreparedStatement
setParameters(pstmt,
c.playerLevel[0], c.playerXP[0],
c.playerLevel[1], c.playerXP[1],
c.playerLevel[2], c.playerXP[2],
c.playerLevel[3], c.playerXP[3],
c.playerLevel[4], c.playerXP[4],
c.playerLevel[5], c.playerXP[5],
c.playerLevel[6], c.playerXP[6],
c.playerLevel[7], c.playerXP[7],
c.playerLevel[8], c.playerXP[8],
c.playerLevel[9], c.playerXP[9],
c.playerLevel[10], c.playerXP[10],
c.playerLevel[11], c.playerXP[11],
c.playerLevel[12], c.playerXP[12],
c.playerLevel[13], c.playerXP[13],
c.playerLevel[14], c.playerXP[14],
c.playerLevel[15], c.playerXP[15],
c.playerLevel[16], c.playerXP[16],
c.playerLevel[17], c.playerXP[17],
c.playerLevel[18], c.playerXP[18],
c.playerLevel[19], c.playerXP[19],
c.playerLevel[20], c.playerXP[20],
c.playerName);
pstmt.executeUpdate();
} catch (Exception e) {
System.out.println(String.format("There's a problem when saving the data of player %s.", c.playerName));
e.printStackTrace(System.out);
con.rollback();
result = false;
}
if (result) {
con.commit();
con.setAutoCommit(true);
}
} catch (Exception e) {
System.out.println(String.format("There's a problem when saving the data of player %s.", c.playerName));
e.printStackTrace(System.out);
result = false;
}
return result;
}
//created method to add parameters despite its type
private void setParameters(PreparedStatement pstmt, Object ... args) {
int i = 1;
for (Object arg : args) {
pstmt.setObject(i++, arg);
}
}
The biggest cost in either your DELETE / INSERT approach or an UPDATE approach is probably your WHERE clause.
Doing the UPDATE or DELETE with a WHERE pointing at playerName = 'FriendlyNameOfPlayer' is brutal. You could make it a little better if you created an index on that field.
You'd create the index with something along the lines of...
CREATE INDEX playerName_ix ON skills (playerName)
CREATE INDEX playerName_ix ON skillsoverall (playerName)
Read more on some additional options that may be relevant on a case by case basis here.
A better practice would be to target the rows by their PK (maybe an auto-incrementing integer?). Ideally, the schema behind this would be a table called Player_Master with an autoincrementing integer as the PK, then the friendly name of the player stored in another column. Tables like those referenced in your code snippit should be storing the PK values from Player_Master (instead of the friendly name), which would be FK's. Your DELETE statement would instead look like...
DELETE FROM `skills` WHERE skills.playerID = 37
Redoing the schema would be the "correct" way to do it, but I get that every project may not have the time or resources required for a total teardown / redo. If your buddy is saying "can you make this faster?", you could do the index and walk away. If the question were "how do I do this right?", I'd start the clock on billable hours, because from the small glimpse into the code and schema provided, it's not a quick fix.
I'll also wristslap you for calling raw executes of cobbled together TSQL statements. There are better ways to do this.
this is probably a very basic problem but as I am only a beginner, this is confusing me. I am trying to make capitalise the first letter of a string, which I have done with the following code:
public String capitalizeFirstLetter(String product){
String productCap = product.substring(0, 1).toUpperCase() + product.substring(1);
return productCap; }
And then this capitalised version of the product just be placed in a letter writer method:
public void writeALetterChallenge(String nameFirst, String nameLast, String city, String product, String company, double retail, int numItem){
UI.println("Dear " + nameFirst);
UI.println(" You have been especially selected from the people of " + city);
UI.println("to receive a special offer for "+ product);
UI.println(productCap + " from " + company + " is a premium brand prodcut and"); UI.printf("retails for $%1.2f" + ". But, " + nameFirst + ",if you order your " + product + "\n", (retail));
UI.println("today, you can purchase it for just $" + (retail - (retail * 0.60)) + ", a saving of 60%!");
UI.println("As a special bonus, just for the " + nameLast + "family, if you order"); UI.println(numItem + " " + product + " today, you will get an additional 10% off - "); UI.println("an amazing price for " + product + " of just $" + (retail - (retail * 0.70)) + "!");
UI.println(" ");
UI.println("Hurry today and send in your order for " + product + " from " + company); UI.println("and make these fantastic savings.");
UI.println(" "); }
However my problem is that when I compile, I get the error that productCap cannot be found. So I've obviously missed something. How do I go about getting the productCap variable from the first method to be included in the second?
Any explanation on this would be great, thanks!
You should call your method:
UI.println(capitalizeFirstLetter(product) + " from " + compan ...
I think instead of this
UI.println(productCap + " from " + company + " is a premium brand prodcut and");
you want to have this
UI.println(capitalizeFirstLetter(product) + " from " + company + " is a premium brand prodcut and");
YOu can call your method as follows
UI.println(capitalizeFirstLetter(product) + " from " + company + " is a premium brand prodcut and");
Your variable productCap is local to method CapitalizaFirstLetter() and hence not accessible in another method.
To access the value of productCap, simply call CapitalizeFirstLetter() method so that it returns the value of productCap.