checking condition loop with scanner - conditional-statements

I am trying to write a code that will loop you in case you provide wrong data. The problem is that I need to have some type of "Bad data" message for both 2 cases:
- you enter not an integer value
- you enter the value below 0
In this code if you type a letter, it loops you with a message: "Bad data", but if you type for example negative value like -10 Bad data is not appearing (even though validation works and you need to correct number to positive)
How can I do it more universal, so in both scenarios sysout with print on-screen Bad data
Random rand = new Random();
int los = rand.nextInt(11);
int NumberOfPlayers ;
Scanner scan7 = new Scanner(System.in);
System.out.println(" Type number of players :");
do {
while (!scan7.hasNextInt()){
System.out.println(" Bad data");
scan7.next();
}
NumberOfPlayers = scan7.nextInt();
}while (NumberOfPlayers < 0);

you are only validating if scanner has next int, you do not validate it's value, and integers can be negative.
try this solution:
do {
while (!scan7.hasNextInt()) {
System.out.println(" Bad data");
scan7.next();
}
NumberOfPlayers = scan7.nextInt();
if (NumberOfPlayers <= 0) {
System.out.println(" Number must be larger than zero");
}
} while (NumberOfPlayers <= 0);
After checking for next int, I added part checking value of provided int.
ALSO please remember about naming variables and classes - start with small letter, so in your case NumberOfPlayers should be numberOfPlayers.
Why you named scanner scan7? is there valid reason for that name? if no, you should avoid adding numbers to names.

Related

What numbering system is used by terminal when outputing to a script

I'm currently learning C programming, and wrote a script similar to one I've written in Python before. My goal is to learn how to pass input to an application and have it process the data I pass it.
The problem I'm having now is the feedback my application is giving me. I wrote a simple application to read keyboard input and give 1 of 3 responses based on what input I give it. The code is as follows:
/*Input test.*/
#include<stdio.h>
#include<stdlib.h>
char input;
const int option_a = 1;
const int option_b = 2;
int main()
{
printf("Lets get started! a for on or b for off?\n");
while(1)
{
input = getchar();
if(input == option_a)
{
printf("We're on.!\n");
}
else if(input == option_b)
{
printf("Off we go.\n");
}
else
{
printf("Excuse me, but I didn't get that.\n");
}
}
return 0;
}
Simply option_a is me pressing the 1 key on keyboard, and option_b is key 2. When I press these keys, or any key for that matter, the application will always go to the "else" portion of the decision tree. Saying that, it's clear to me that, and I'll say with a lack of a better term/expression, that my application isn't seeing my input as the decimal number 1 or 2.
From the terminal, what is the structure of the data I'm sending to my application, or simply put, what does my 1or 2 "look" like to my application?
When you are taking input with getchar() you are getting an char value. But you are comparing it with an integer. Instead of comparing with the integer, you can compare the input with corresponding characters. For example, use
const char option_a = '1';
const char option_b = '2';
I believe you want to find the American Standard Code for information interchange(ASCII) table. 0 = 48, 1 = 49, 2 = 50,...I had the same problem while working with arduino’s serial monitor, and it should all be covered by the same standard.

how to count the number of integers input by the user

i have to make a program that reads an arbitrarily long integer input from the user and finds the sum of the digits. i was thinking about making the program do a loop until the integer count is zero and adding up the sum of the numbers the user typed in. but im not sure how to write that since im a beginner at java. this is what i got from my try at it
import java.util.Scanner;
public class sumofnumberstest {
public static void main(String[] args) {
int data;
int sum = 0;
Scanner input = new Scanner(System.in);
System.out.print( "Enter an integer ): ");
data = input.nextInt();
int length = data.length
do {
data %10;
sum += data;
} while (data.length >=0 & = 100000000000000000000000000000 );
System.out.println("The sum is " + sum);
}
}
your question is similar to a previously asked question. Take a look here -> How to read each individual digit of a number in Java
Here's a simple implementation of what you're trying to do:
https://stackoverflow.com/a/39861955/6913557

How would I add a count for guesses and a best score in a simple Guessing game with multiple methods?

so I am having trouble with being able to have a proper TOTAL guess counter. my code needs to be basic so please dont offer me advice for doing anything you think is not trivial. currently, my code plays a game, then asks the user if they want to play again and its a simple Y or N. if yes, another games plays and if no then then game ends and it reports the results of every game played such: the total games, guesses per game, and the best game (reports game that had lowest guess count). my issues are being able to accurately count ALL THE GUESSES from every game. I am able to report results and track the total games played correctly but i cant figure out how to report a result that tracks the guesses per game, adds them all up, finds the smallest one.
import java.util.*;
public class Guess2{
// The range for what numbers the correct answer is allowed to be.
public static final int MAX = 2;
// Main method that calls the other methods for the game to run properly.
public static void main (String [] args) {
Scanner console = new Scanner(System.in);
introduction();
int userGuess = game(console);
int numGames = 1;
System.out.print("Do you want to play again? ");
String putYesNo = console.next();
while (putYesNo.equalsIgnoreCase("y")) {
System.out.println();
game(console);
numGames++;
System.out.print("Do you want to play again? ");
putYesNo = console.next();
}
if (putYesNo.equalsIgnoreCase("n")) {
System.out.println();
finalScores(console,totalGuess,numGames);
}
}
// Method to play the guessing game using the input from the console(parameter) via the user playing the game.
public static int game(Scanner console){
Random answer = new Random();
int correct = answer.nextInt(MAX) + 1;
System.out.println("I'm thinking of a number between 1 and " + MAX + "...");
int userGuess = 0; // This is used to prime the while loop.
int numGuess = 0; // This is used to start the count at 1.
int totalGuess = 0;
while (userGuess != correct){
System.out.print("Your guess? ");
userGuess = console.nextInt();
if (userGuess > correct){
System.out.println("It's lower.");
} else if (userGuess < correct){
System.out.println("It's higher.");
}
numGuess++;
}
if (userGuess == correct && numGuess == 1){
System.out.println("You got it right in 1 guess");
} else if (userGuess == correct && numGuess != 1){
System.out.println("You got it right in " + numGuess + " guesses");
}
totalGuess =+ numGuess;
return totalGuess; // This Returns the number of total guesses for this single game.
}
/* Method used to report the Users' final statistics of the game(s).
Uses information from the user input via the console,
the sum of guesses used for every game, and the total number of games played. */
public static void finalScores(Scanner console, int totalGuesses, int numGames){
System.out.println("Overall results:");
System.out.println(" total games = " + numGames);
System.out.println(" total guesses = " + totalGuesses);
System.out.println(" guesses/game = " + iLoveRounding(1.0*totalGuesses/numGames));
System.out.println(" best game = " );
}
// Method that introduces the User to the Game.
public static void introduction() {
System.out.println("This program allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and");
System.out.println(MAX + " and will allow you to guess until");
System.out.println("you get it. For each guess, I will tell you");
System.out.println("whether the right answer is higher or lower");
System.out.println("than your guess.");
System.out.println();
}
/* Method used to round the "guessing/game" ratio to 1 decimal place.
The return value of this method returns the ratio in decimal form with only 1 didgit, so
The scores method can report it properly. */
public static double iLoveRounding(double round){
return Math.round(round * 10.0) / 10.0;
}
}
You could look into making an integer ArrayList to hold all of the guesses per game. Then, when you are printing the results, you could first print out the whole ArrayList to represent the guesses per game, then call 'Collections.sort(yourArrayList)', which will sort the ArrayList from lowest to highest, then print out the first element of the ArrayList.
I'd recommend the integer ArrayList over a simple integer array, since the array will require you to define the size beforehand. An ArrayList can be dynamic, and you can change the size according to the number of times the user plays the game.

Why is java program skipping my inner loop?

Hello I'm a beginning programming Student and I am practicing using loops to validate input. Unfortunately, the loop works but skips the inner loop entirely... I get now error message or prompt...
Here is my code: [I BORROWED IT FROM AN ANSWER ON THIS SITE ABOUT VALIDATING INPUT SO I COULD TEST IT.]
import java.util.Scanner;
public class ValidationTest
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int number;
do {
System.out.println("Please enter a positive number!");
while (!sc.hasNextInt())
{
System.out.println("That's not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
} while (number <= 0);
System.out.println("Thank you! Got " + number);
}
}
The inner loop :
while (!sc.hasNextInt())
{
System.out.println("That's not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
only check if your input is not a number, if you input -123, the function !sc.hasNextInt() is false so it'll skip the loop, if you want to check the number is negative, add this check after the assign number value:
if(number <= 0 ){
System.out.println("The number is negative!");
}
You don't have to make another loop for checking the number is negative or not because of the first loop had it, and do...while loop will make sure you have to run the loop at least one time
The while loop will be skipped if the condition (in parentheses after while) is false when the while loop is first executed.
You can use a debugger to step through the code to see what is going on.
If you do not know how to use a debugger, stop everything you are doing and do some Google searches or whatever you need to do to find out how to use one.
your int number is NaN (not a number). Try setting it to -1, so you can enter the first loop.
In second loop sc didn't ever scan for input it's only initialized.

Determine credit card type by number?

Can credit card type be determined solely from the credit card number?
Is this recommended or should we always ask client for the type of credit card they're using?
I Googled about it and found this algorithm: http://cuinl.tripod.com/Tips/o-1.htm , is this reliable?
Yes, the site you mentioned is correct. Many sites, incl. Google Checkout I believe, rely on automatic detection of the card type. It's convenient, makes the UI less cluttered (one less input box) and saves time. Go ahead!
I have heard one good reason to make them pick (even though you can figure it out). So that they know the list of credit cards you accept.
As a consumer, I hate choosing a card first. I want to just start typing the number.
This issue is discussed in Wroblewski's Web Form Design on pages 153-154. It's in the section "Removing Questions" of the chapter "Unnecessary Inputs." The example given is Paypal, which highlights the type of card when you've typed in your number.
I am pretty certain that at least for MasterCard, Visa, Discover, and American Express that that is accurate. I have never worked with any of the others.
See the very bottom of this page:
http://www.merchantplus.com/resources/pages/credit-card-logos-and-test-numbers/
Also this might be useful to you"
http://www.beachnet.com/~hstiles/cardtype.html
This is pretty interesting to:
http://en.wikipedia.org/wiki/Bank_card_number
here is the script that i use that works with current card ranges. also does a validity check on the number.
/**
* checks a given string for a valid credit card
* #returns:
* -1 invalid
* 1 mastercard
* 2 visa
* 3 amex
* 4 diners club
* 5 discover
* 6 enRoute
* 7 jcb
*/
function checkCC(val) {
String.prototype.startsWith = function (str) {
return (this.match("^" + str) == str)
}
Array.prototype.has=function(v,i){
for (var j=0;j<this.length;j++){
if (this[j]==v) return (!i ? true : j);
}
return false;
}
// get rid of all non-numbers (space etc)
val = val.replace(/[^0-9]/g, "");
// now get digits
var d = new Array();
var a = 0;
var len = 0;
var cval = val;
while (cval != 0) {
d[a] = cval%10;
cval -= d[a];
cval /= 10;
a++;
len++;
}
if (len < 13)
return -1;
var cType = -1;
// mastercard
if (val.startsWith("5")) {
if (len != 16)
return -1;
cType = 1;
} else
// visa
if (val.startsWith("4")) {
if (len != 16 && len != 13)
return -1;
cType = 2;
} else
// amex
if (val.startsWith("34") || val.startsWith("37")) {
if (len != 15)
return -1;
cType = 3;
} else
// diners
if (val.startsWith("36") || val.startsWith("38") || val.startsWith("300") || val.startsWith("301") || val.startsWith("302") || val.startsWith("303") || val.startsWith("304") || val.startsWith("305")) {
if (len != 14)
return -1;
cType = 4;
} else
// discover
if (val.startsWith("6011")) {
if (len != 15 && len != 16)
return -1;
cType = 5;
} else
// enRoute
if (val.startsWith("2014") || val.startsWith("2149")) {
if (len != 15 && len != 16)
return -1;
// any digit check
return 6;
} else
// jcb
if (val.startsWith("3")) {
if (len != 16)
return -1;
cType = 7;
} else
// jcb
if (val.startsWith("2131") || val.startsWith("1800")) {
if (len != 15)
return -1;
cType = 7;
} else
return - 1;
// invalid cc company
// lets do some calculation
var sum = 0;
var i;
for (i = 1; i < len; i += 2) {
var s = d[i] * 2;
sum += s % 10;
sum += (s - s%10) /10;
}
for (i = 0; i < len; i += 2)
sum += d[i];
// musst be %10
if (sum%10 != 0)
return - 1;
return cType;
}
Here's Complete C# or VB code for all kinds of CC related things on codeproject.
IsValidNumber
GetCardTypeFromNumber
GetCardTestNumber
PassesLuhnTest
This article has been up for a couple years with no negative comments.
Wikipedia contains a list of most card prefixes. Some cards are missing from the link you posted. It also appears that the link you provided is valid.
One reason to ask for the card type is for extra validation, compare what the user provided against the number.
This is the php version of same algorithm mentioned in 1st post
<?php
function CreditCardType($CardNo)
{
/*
'*CARD TYPES *PREFIX *WIDTH
'American Express 34, 37 15
'Diners Club 300 to 305, 36 14
'Carte Blanche 38 14
'Discover 6011 16
'EnRoute 2014, 2149 15
'JCB 3 16
'JCB 2131, 1800 15
'Master Card 51 to 55 16
'Visa 4 13, 16
*/
//Just in case nothing is found
$CreditCardType = "Unknown";
//Remove all spaces and dashes from the passed string
$CardNo = str_replace("-", "",str_replace(" ", "",$CardNo));
//Check that the minimum length of the string isn't less
//than fourteen characters and -is- numeric
If(strlen($CardNo) < 14 || !is_numeric($CardNo))
return false;
//Check the first two digits first
switch(substr($CardNo,0, 2))
{
Case 34: Case 37:
$CreditCardType = "American Express";
break;
Case 36:
$CreditCardType = "Diners Club";
break;
Case 38:
$CreditCardType = "Carte Blanche";
break;
Case 51: Case 52: Case 53: Case 54: Case 55:
$CreditCardType = "Master Card";
break;
}
//None of the above - so check the
if($CreditCardType == "Unknown")
{
//first four digits collectively
switch(substr($CardNo,0, 4))
{
Case 2014:Case 2149:
$CreditCardType = "EnRoute";
break;
Case 2131:Case 1800:
$CreditCardType = "JCB";
break;
Case 6011:
$CreditCardType = "Discover";
break;
}
}
//None of the above - so check the
if($CreditCardType == "Unknown")
{
//first three digits collectively
if(substr($CardNo,0, 3) >= 300 && substr($CardNo,0, 3) <= 305)
{
$CreditCardType = "American Diners Club";
}
}
//None of the above -
if($CreditCardType == "Unknown")
{
//So simply check the first digit
switch(substr($CardNo,0, 1))
{
Case 3:
$CreditCardType = "JCB";
break;
Case 4:
$CreditCardType = "Visa";
break;
}
}
return $CreditCardType;
}
?>
The code you linked has an incomplete BIN/range list for Discover, omits Diner's club (which now belongs to Discover anyway), lists card types that no longer exist and should be folded into other types (enRoute, Carte Blanche), and ignores the increasingly-important Maestro International cart type.
As #Alex confirmed, it's possible to determine the card type from the BIN number, and numerous companies do it but doing so consistently and correctly is not trivial: card brands constantly change, and keeping track of things becomes more complicated as you try to handle regional debit cards (Laser in Ireland, Maestro in Europe, etc) - I have not found a free and maintained (correct) piece of code or algorithm for this anywhere.
As #MitMaro poined out, Wikipedia contains a high-level list of card identifiers, and also a more-specific list of BIN numbers and ranges, which is a good start, and as gbjbaanb commented, Barclays has a publically-published list (but it does not seem to include Discover for some reason - presumably they don't process on the Discover network?)
Trivial as it may seem, a correct card-identification algorithm/method/function takes work to maintain, so unless your detection routine is non-critical/informational (eg #Simon_Weaver's suggestion), OR you're going to put in the work to keep it current, I would recommend that you skip the automatic detection.
Stripe has provided this fantastic javascript library for card scheme detection. Let me add few code snippets and show you how to use it.
Firstly Include it to your web page as
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.2.3/jquery.payment.js " ></script>
Secondly use the function cardType for detecting the card scheme.
$(document).ready(function() {
var type = $.payment.cardType("4242 4242 4242 4242"); //test card number
console.log(type);
});
Here are the reference links for more examples and demos.
Stripe blog for jquery.payment.js
Github repository
Here's a quick a dirty way to determine the card type automatically and show it to the user while they're typing.
That means
a) the user doesnt have to pick it and
b) they wont waste time looking for a dropdown that doesnt exist.
Very simple jQuery version for Amex, Visa and Mastercard.
if you need other card types you can take the
$('[id$=CreditCardNumber]').assertOne().keyup(function(){
// rules taken from http://en.wikipedia.org/wiki/Credit_card_number#cite_note-GenCardFeatures-0
var value = $(this).val();
$('#ccCardType').removeClass("unknown");
if ((/^4/).test(value)) {
$('#ccCardType').html("Visa");
return;
}
if ((/^5[1-5]/).test(value)) {
$('#ccCardType').html("Mastercard");
return;
}
if ((/^3[47]/).test(value)) {
$('#ccCardType').html("Mastercard");
return;
}
$('#ccCardType').html("Enter card number above");
$('#ccCardType').addClass("unknown");
});
This is the jQuery to accompany this (ASP.NET MVC):
Card number: <%= Html.TextBox("PaymentDetails.CreditCardDetails.CreditCardNumber")%>
Card Type: <span id="ccCardType" class="unknown">Enter card number above</span>
I have a css rule for .unknown to display grayed out text.
This implementation in Python should work for AmEx, Discover, Master Card, Visa:
def cardType(number):
number = str(number)
cardtype = "Invalid"
if len(number) == 15:
if number[:2] == "34" or number[:2] == "37":
cardtype = "American Express"
if len(number) == 13:
if number[:1] == "4":
cardtype = "Visa"
if len(number) == 16:
if number[:4] == "6011":
cardtype = "Discover"
if int(number[:2]) >= 51 and int(number[:2]) <= 55:
cardtype = "Master Card"
if number[:1] == "4":
cardtype = "Visa"
return cardtype
If all the credit cards that you accept have the same properties then just let the user enter the card number and other properties (expiry date, CVV, etc). However, some card types require different fields to be entered (e.g. start date or issue number for UK Maestro cards). In those cases, you either have to have all fields, thereby confusing the user, or some Javascript to hide/show the relevant fields, again making the user experience a bit weird (fields disappearing/appearing, as they enter the credit card number). In those cases, I recommend asking for the card type first.
Personally I have no problem with picking the card type first. But there are two aspects of credit card number entry that are problematic in my view.
The worst is the inability to enter spaces between groups of numbers. Including the spaces printed on the physical cards would make the digits vastly easier for the user to scan to verify they've entered the information correctly. Every time I encounter this ubiquitous deficiency I feel like I'm being propelled backwards into a stone age when user input couldn't be filtered to remove unnecessary characters.
The second is the need when placing a phone order to listen to the vendor repeat the card number back to you. All the credit card recipient actually needs is a UI that gives them access to the check digit scheme which verifies that a cc number is valid. According to that algorithm the first 15 (or however many) digits calculate the last digit - and is virtually impossible to "fool." For a fat fingered number to "pass" requires at least two mutually canceling errors among the 15 digits. Unless the algorithm suffers from the defect of being dis-proportionally fooled by transposing adjacent numbers (a common entry error) which I doubt, I except it is more reliable than any human double check.
https://binlist.net/ offers a free API. You only need to enter the first 6 or 8 digits of the card number - i.e. the Issuer Identification Numbers (IIN), previously known as Bank Identification Number (BIN).
curl -H "Accept-Version: 3" "https://lookup.binlist.net/45717360"
NPM: https://www.npmjs.com/package/binlookup
Source: https://github.com/paylike/binlookup
(cross-posted from a more specific question: How tell the difference between a Debit Card and a Credit Card )