I am writing a simple SRMS, and I need to validate the input from the user if it matches some criteria depending on the field, e.g. an email field or a phone field. The app is to run in a featured phone and so I am using the Java ME SDK with a virtual machine for testing.
What is the best way to do so, what would be the best way to validate the input and if the input does not meet some criteria, should the user be notified or the value she has entered to be set to null again.
public void name() {
boolean nameValid = false;
display = Display.getDisplay(this);
nameForm = new Form("Student Record Management (1/4");
TextField firstName = new TextField("First Name(s)", "", 20, TextField.ANY);
TextField lastName = new TextField("Last Name", "", 20, TextField.ANY);
TextField personNumber = new TextField("Person Number", "", 10, TextField.NUMERIC);
back = new Command("BACK", Command.BACK, 1);
next = new Command("Continue", Command.ITEM, 2);
nameForm.append(firstName);
nameForm.append(lastName);
nameForm.append(personNumber);
nameForm.addCommand(back);
nameForm.addCommand(next);
nameForm.setItemStateListener(this);
nameForm.setCommandListener(this);
display.setCurrent(nameForm);
if (firstName.toString().length() > 0) {
nameValid = true;
}
}
The person who started the code has implemented the CommandListener and ItestStateListener.
I am not sure what is the second one does and it has an abstract method to be filled which is called itemStateChanged(Item item) am I supposed to check for changes and validate in here ?
The ItemStateListener notifies the application of changes in Form items. The item itemStateChanged(Item item) method is called when an item in your form is changed by the user or when Item.notifyStateChanged() is called in an Item. The argument is the Item (Textfield, DateField, ect) that changed value.
I would recommend that you call your validation method inside both the CommandAction and ItemStateListener. In the itemStateChanged only the current Item (the one received in the argument) should be checked. In the CommandAction every field should be checked. This way every Item is validated in every situation.
public static boolean validateEmailID(String email) {
email = email.trim();
String reverse = new StringBuffer(email).reverse().toString();
if (email == null || email.length() == 0 || email.indexOf("#") == -1) {
return false;
}
int emailLength = email.length();
int atPosition = email.indexOf("#");
int atDot = reverse.indexOf(".");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLength);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
for (int i = 0; email.length() - 1 > i; i++) {
char i1 = email.charAt(i);
char i2 = email.charAt(i + 1);
if (i1 == '.' && i2 == '.') {
return false;
}
}
if (email.charAt(atPosition - 1) == '.' || email.charAt(0) == '.' || email.charAt(atPosition + 1) == '.' || afterAt.indexOf("#") != -1 || atDot < 2) {
return false;
}
return true;
}
Related
I have this method which validates a string.
In my assignment I can't have more than 1 return in a method.
How can I make this method in a way to return only one value at the end after the do while loop ?
public final static String CHOIX_MENUS_VALIDES = "1234";
public static String validateMenu() {
String choice;
String choice1 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(0));
String choice2 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(1));
String choice3 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(2));
String choice4 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(3));
do {
choice = validateString(MSG_SOLL_MENU, MSG_ERR_MENU, 1, 4, true);
if (choice.trim().equals(choice1) || choice.trim().equals(choice2) || choice.trim().equals(choice3) || choice.trim().equals(choice4)) {
return choice; //Here I don't want to return the choice
}
if (!choice.equals(choice1) || !choice.equals(choice2) || !choice.equals(choice3) || !choice.equals(choice4)) {
System.out.println(MSG_ERR_MENU);
}
} while(!choice.trim().equals(choice1) || !choice.trim().equals(choice2) || !choice.trim().equals(choice3) || !choice.trim().equals(choice4));
return choice;
}
I would appreciate if someone could help me rebuild that method for returning only one value at the end.
The simples solution is to replace the first return
return choice; //Here I don't want to return the choice
by a break;
Another solution is to use a boolean variable (lets named stay)
do{
boolean stay = true;
choice = validateString(MSG_SOLL_MENU, MSG_ERR_MENU, 1, 4, true);
if (...){
stay = false;
}
else if(...) {...}
while(stay && ...);
return choice;
In every loop iteration you set the variable to true (i.e., boolean stay = true;) so that you only get out of the loop due to that variable being set to false. Because we removed the first return from the first if(..) and added now the variable we had to change the second if to an else if so that it does not get executed if the first if evaluates to true. Finally, you add the new variable as part of your while condition.
I have a constructor ID3 and I need to start by executing it from the main. Is it possible?
I tried doing this:
public class ID3
{
public static void main(String[] args) throws Exception
{
System.out.print("\f"); //clears the screen
ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);
instance.ID3("data.txt", 3 , 5 , " ", 2); //error given here since this line had to be removed
}
public ID3(String fName, int numAttributes, int testCases, String delimiter, int limitSplits) throws IOException, FileNotFoundException
{
fileName = fName;
n = numAttributes;
t = testCases;
numSplits = limitSplits;
FileInputStream fstream = new FileInputStream(fileName);
DataInputStream in = new DataInputStream(fstream);
//Parse the first line to see if continuous or discrete attributes.
firstLine = new String[n];
firstLine = in.readLine().split(delimiter);
int i, j, lineCount = 0;
for(i=0; i<n; i++)
unusedAttr.add(new Integer(i));
input = new String[t][n+1];
String line;
int invalidLines = 0;
while((lineCount + invalidLines)<t)
{
try
{
input[lineCount] = (in.readLine()).split(delimiter);
}
catch(NullPointerException e)
{
invalidLines++;continue;
}
if (Array.getLength(input[lineCount]) != n+1 || (Array.get(input[lineCount],n).toString().compareTo("?") == 0)) //number of attributes provided in the line is incorrect.
{
invalidLines++;continue;
}
lineCount++;
}
if(invalidLines == t)
{
System.out.println("All lines invalid - Check the supplied attribute number");
System.exit(0);
}
if (invalidLines > 0)
System.out.println("Not Considering "+invalidLines+" invalid training cases");
if(numSplits > maxSplits || numSplits > (t/2))
{
System.out.println("numSplits should be less than or equal to "+Math.min(t/2,limitSplits));
System.exit(1);
}
t = testCases - invalidLines;
thresholdVal = new String[n][numSplits - 1];
boolean allCont = false;
if(Array.getLength(firstLine) == 1)
{
if(firstLine[0].compareTo("c") == 0)
allCont = true;
else if(firstLine[0].compareTo("d") == 0)
return;
else
{
System.out.println("Invalid first line - it should be c or d");
System.exit(1);
}
}
for(i=0; i<n; i++)
{
if(allCont || firstLine[i].compareTo("c") == 0) //Continuous Attribute
{
for(j=0; j<numSplits-1; j++)
thresholdVal[i][j] = calculateThreshold(i,j);
}
else if(firstLine[i].compareTo("d") != 0)
{
System.out.println("Invalid first line - Training data (it should specify if the attributes are c or d)");
System.exit(1);
}
}
for(i=0; i<t; i++)
{
for(j=0; j<n; j++)
{
if(allCont || firstLine[j].compareTo("c") == 0)
input[i][j] = makeContinuous(input[i][j], j);
}
}
}
The code for the constructor is shown above, however it finds the file but doesn't process the data and prints the errors out. How should the file be exactly?
Used text file has:
d
Span Shape Slab
long square waffle
long rectangle waffle
short square two-way
short rectangle one-way
You are already calling the constructor here - ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);. You can't call it as a regular method. Just remove the instance.ID3("data.txt", 5 , 14 , "", 5); line.
You cannot call constructors like regular methods. The constructor is automatically called when you create an instance of a class,i.e,when you do
ID3 instance = new ID3("data.txt", 5 , 14 , "", 5);
Contructors are not methods. One of the key feature of a method is that it should have a return type (event if it is 'void').
Here, you do not need to explicitly call the constructor again. The functionality you implement in the constructor will be executed at instantiation itself. However, this is not recommended and is bug-prone. You should only be instantiating any variables. The actual functionality should be defined in another method.
I was wondering if it would be possible to make the code below any smaller, basically its if else statement and each time only 3 things are changing and I was think I am just repeating my self, so I though if there is any way to make it any smaller.
if (text1.getText == "1" && text2.text == "2"){
text3.setText("3");
}
else if(text3.getText == "1" && text4.text == "2"){
text7.setText("3");
}
else if(text5.getText == "1" && text6.text == "2"){
text4.setText("3");
}
else if(text7.getText == "1" && text8.text == "2"){
text5.setText("3");
}
else if(text9.getText == "1" && text10.text == "2"){
text6.setText("3");
}
else if(text11.getText == "1" && text12.text == "2"){
text2.setText("3");
}
else if(text13.getText == "1" && text14.text == "2"){
text14.setText("3");
}
......
else{
Statement here
}
boolean didIt = false;
ArrayList<JTextField[]> listOfStuff = new ArrayList<JTextField[]>();
listOfStuff.add({ text1, text2, text3 });
listOfStuff.add({ text3, text4, text7 });
....
listOfStuff.add({ text13, text44, text14 });
for (JTextField[] fields : listOfStuff) {
didIt = didIt || setToThree(fields[2], fields[0], fields[1]);
}
if (!didIt) {
Statement here
}
Function:
boolean setToThree(JTextField target, JTextField first, JTextField second) {
if ("1".equals(first.getText()) && "2".equals(second.getText()) {
target.setText("3");
return true;
}
return false;
}
The pattern looks like for every pair of textN and textN+1, you set some other textM to 3 if the two aforementioned are labelled 1 and 2 respectively. I don't see the pattern connecting pairs to their target texts, so I suggest this:
Assuming these text variables are of the type Text, store them using one of the following:
Text[] texts = new Text[N];
ArrayList<Text> texts = new ArrayList<Text>();
Put all of your Text instances in the array or ArrayList
Set up a map or method that takes the odd number of some pair of consecutive Texts and returns the target Text to modify (look up HashMap)
Use a for loop to iterate through every other Text instance
Here's an example, if you're using an array and some method findTarget:
for (int i = 0; i+1 < texts.length; i+=2) {
if texts[i].getText().equals("1") && texts[i+1].getText().equals("2") {
texts[findTarget(i)].setText("3");
break;
}
}
You can create a function to do that.
function CheckValues (a, b, c){
if (a.getText().equals("1") && (b.getText().equals("2")){
c.setText("3");
}
}
And then run it with:
CheckValues(text1,text2,text3);
CheckValues(text3,text4,text7);
CheckValues(text5,text6,text11);
Like the title says. I want to find out if a given java String contains an emoticon.
I can't use Character.UnicodeBlock.of(char) == Character.UnicodeBlock.EMOTICONS since that requires API level 19.
I found this code for iOS but it isn't really applicable since it looks like java and objective-c handle surrogate pairs in different manners.
The documentations I've looked through tell me that:
A char value, therefore, represents Basic Multilingual Plane (BMP) code points, including the surrogate code points, or code units of the UTF-16 encoding
I'm not quite sure what that means. Does that simply mean that they also include the BMP point as their first number?
According to Wikipedia the emoticon set lies between 0x1f600 and 0x1f64f but I don't know how to check if the char is in that range.
I had hoped that something like this would work but it didn't
if (0x1f600 <= a && a <= 0x1f64f)
{
Print.d("Unicode", "groovy!");
}
So how do I go about this?
Four years later...
At this time, it might make more sense to take advantage of EmojiCompat. This code presumes you initialized EmojiCompat when your app was starting up. The basic idea here is to have EmojiCompat process your CharSequence, inserting instances of EmojiSpan wherever any emoji appear, and then examine the results.
public static boolean containsEmoji(CharSequence charSequence) {
boolean result = false;
CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL);
if (processed instanceof Spannable) {
Spannable spannable = (Spannable) processed;
result = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class).length > 0;
}
return result;
}
If you want to collect a list of the unique emoji that appear within a given CharSequence, you could do something like this, iterating over the results of getSpans() and finding the start and end of each span to capture the emoji discovered by EmojiCompat:
#NonNull
public static List<String> getUniqueEmoji(CharSequence charSequence) {
Set<String> emojiList = new HashSet<>();
CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL);
if (processed instanceof Spannable) {
Spannable spannable = (Spannable) processed;
EmojiSpan[] emojiSpans = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class);
for (EmojiSpan emojiSpan : emojiSpans) {
int spanStart = spannable.getSpanStart(emojiSpan);
int spanEnd = spannable.getSpanEnd(emojiSpan);
CharSequence emojiCharSequence = spannable.subSequence(spanStart, spanEnd);
emojiList.add(String.valueOf(emojiCharSequence));
}
}
return emojiList.size() > 0 ? new ArrayList<>(emojiList) : new ArrayList<String>();
}
UPDATE: Here's an example of EmojiCompat initialization. This static method can be called from your Application onCreate() method, passing in the Application itself as the Context param.
#JvmStatic
fun initEmojiCompat(context: Context) {
if (emojiCompatConfig != null) {
// alternatively, EmojiCompat.reset() could be called here
logger().w(LOGTAG, "EmojiCompat already initialized.")
return
}
// "Noto Color Emoji Compat" doesn't have graphics for the following emojis:
// U+1F5E3 "speaking head" (required)
// U+1F441 "eye" (required)
// U+1F575 "detective" (nice to have)
val fontRequest = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
"Noto Color Emoji Compat",
R.array.com_google_android_gms_fonts_certs
)
emojiCompatConfig = FontRequestEmojiCompatConfig(context, fontRequest)
.setReplaceAll(false)
.setEmojiSpanIndicatorEnabled(false)
.registerInitCallback(initCallback)
.also {
EmojiCompat.init(it)
}
}
I was in fact able to use the linked iOS code to create the following function. I didn't realize that a String that contains, for example, a single emoticon will have a length of 2. So you can check if a character is in fact a surrogate.
I'm not entirely sure how to handle else if (substring.length > 1) from the iOS code but I think Character.isHighSurrogate(myChar) does the same job in that instance.
private boolean containsIllegalCharacters(String displayName)
{
final int nameLength = displayName.length();
for (int i = 0; i < nameLength; i++)
{
final char hs = displayName.charAt(i);
if (0xd800 <= hs && hs <= 0xdbff)
{
final char ls = displayName.charAt(i + 1);
final int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f)
{
return true;
}
}
else if (Character.isHighSurrogate(hs))
{
final char ls = displayName.charAt(i + 1);
if (ls == 0x20e3)
{
return true;
}
}
else
{
// non surrogate
if (0x2100 <= hs && hs <= 0x27ff)
{
return true;
}
else if (0x2B05 <= hs && hs <= 0x2b07)
{
return true;
}
else if (0x2934 <= hs && hs <= 0x2935)
{
return true;
}
else if (0x3297 <= hs && hs <= 0x3299)
{
return true;
}
else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50)
{
return true;
}
}
}
return false;
}
This is how Telegram does it:
private static boolean isEmoji(String message){
return message.matches("(?:[\uD83C\uDF00-\uD83D\uDDFF]|[\uD83E\uDD00-\uD83E\uDDFF]|" +
"[\uD83D\uDE00-\uD83D\uDE4F]|[\uD83D\uDE80-\uD83D\uDEFF]|" +
"[\u2600-\u26FF]\uFE0F?|[\u2700-\u27BF]\uFE0F?|\u24C2\uFE0F?|" +
"[\uD83C\uDDE6-\uD83C\uDDFF]{1,2}|" +
"[\uD83C\uDD70\uD83C\uDD71\uD83C\uDD7E\uD83C\uDD7F\uD83C\uDD8E\uD83C\uDD91-\uD83C\uDD9A]\uFE0F?|" +
"[\u0023\u002A\u0030-\u0039]\uFE0F?\u20E3|[\u2194-\u2199\u21A9-\u21AA]\uFE0F?|[\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55]\uFE0F?|" +
"[\u2934\u2935]\uFE0F?|[\u3030\u303D]\uFE0F?|[\u3297\u3299]\uFE0F?|" +
"[\uD83C\uDE01\uD83C\uDE02\uD83C\uDE1A\uD83C\uDE2F\uD83C\uDE32-\uD83C\uDE3A\uD83C\uDE50\uD83C\uDE51]\uFE0F?|" +
"[\u203C\u2049]\uFE0F?|[\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE]\uFE0F?|" +
"[\u00A9\u00AE]\uFE0F?|[\u2122\u2139]\uFE0F?|\uD83C\uDC04\uFE0F?|\uD83C\uDCCF\uFE0F?|" +
"[\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA]\uFE0F?)+");
}
It is Line 21,026.
Try this...
if (Integer.parseInt("1f600", 16) <= (int)'☺' && (int)'☺' <= Integer.parseInt("1f64f", 16)) {
Print.d("Unicode", "groovy!");
}
This might work because the hexidecimal value and the char value are both being converted to ints.
Here's some Kotlin that relies on java.lang.Character api (granted the original poster can't use this). I have found it pretty reliably tells apart an emoji from 'special characters' and non-latin alphabets etc. Try it.
import java.lang.Character.*
import java.lang.Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL
import java.lang.Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS
import java.lang.Character.UnicodeBlock.VARIATION_SELECTORS
fun isStringEmoji(someString: String): Boolean {
if (someString.isNotEmpty() && someString.length < 5) {
val firstCodePoint = codePointAt(someString, 0)
val lastCodePoint = codePointBefore(someString, someString.length)
if (isValidCodePoint(firstCodePoint) && isValidCodePoint(lastCodePoint)) {
if (isSupplementaryCodePoint(firstCodePoint) ||
isSupplementaryCodePoint(lastCodePoint) ||
UnicodeBlock.of(firstCodePoint) == MISCELLANEOUS_SYMBOLS ||
UnicodeBlock.of(firstCodePoint) == MISCELLANEOUS_TECHNICAL ||
UnicodeBlock.of(lastCodePoint) == VARIATION_SELECTORS
) {
return true
}
}
}
return false
}
In my program, I have a while loop that will display a list of shops and asks for an input, which corresponds with the shop ID. If the user enters an integer outside the array of shops, created with a Shop class, it will exit the loop and continue. Inside this loop is another while loop which calls the sellItem method of my Shop class below:
public Item sellItem()
{
displayItems();
int indexID = Shop.getInput();
if (indexID <= -1 || indexID >= wares.length)
{
System.out.println("Null"); // Testing purposes
return null;
}
else
{
return wares[indexID];
}
}
private void displayItems()
{
System.out.println("Name\t\t\t\tWeight\t\t\t\tPrice");
System.out.println("0. Return to Shops");
for(int i = 0; i < wares.length; i++)
{
System.out.print(i + 1 + ". ");
System.out.println(wares[i].getName() + "\t\t\t\t" + wares[i].getWeight() + "\t\t\t\t" + wares[i].getPrice());
}
}
private static int getInput()
{
Scanner scanInput = new Scanner(System.in);
int itemID = scanInput.nextInt();
int indexID = itemID - 1;
return indexID;
}
The while loop in my main class method is as follows:
boolean exitAllShops = true;
while(exitAllShops)
{
System.out.println("Where would you like to go?\nEnter the number which corresponds with the shop.\n1. Pete's Produce\n2. Moore's Meats\n3. Howards Hunting\n4. Foster's Farming\n5. Leighton's Liquor\n6. Carter's Clothing\n7. Hill's Household Products\n8. Lewis' Livery, Animals, and Wagon supplies\n9. Dr. Miller's Medicine\n10. Leave Shops (YOU WILL NOT BE ABLE TO RETURN)");
int shopInput = scan.nextInt();
if(shopInput >= 1 && shopInput <= allShops.length)
{
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
}
else
{
System.out.println("Are you sure you want to leave?\n1. Yes\n2. No");
int confirm = scan.nextInt();
if(confirm == 1)
{
exitAllShops = false;
}
}
The problem is here:
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
No matter what I do, I can't get "still null" to print to confirm that I'm correctly calling the return statement of the method sellItem of the class Shop. What am I doing wrong?
After calling allShops[...].sellItem(), allShops is still a valid array reference -- there's no way it could be null! You probably want to test the return value from sellItem:
if(allShops[shopInput-1].sellItem() == null)