Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialFahri Can
9,921 PointsHow can I verify that only letters or the $ character are used
Is there any other way instead of using regular expressions?
public class Order {
private String itemName;
private int priceInCents;
private String discountCode;
public Order(String itemName, int priceInCents) {
this.itemName = itemName;
this.priceInCents = priceInCents;
}
public String getItemName() {
return itemName;
}
public int getPriceInCents() {
return priceInCents;
}
public String getDiscountCode() {
return discountCode;
}
public void applyDiscountCode(String discountCode) {
this.discountCode = normalizeDiscountCode(discountCode);
}
private String normalizeDiscountCode(String discountCode){
if(!discountCode.matches("[a-zA-Z]($)")){
throw new IllegalArgumentException("Invalid discount code");
}
return discountCode.toUpperCase();
}
}
public class Example {
public static void main(String[] args) {
// This is here just for example use cases.
Order order = new Order(
"Yoda PEZ Dispenser",
600);
// These are valid. They are letters and the $ character only
order.applyDiscountCode("abc");
order.getDiscountCode(); // ABC
order.applyDiscountCode("$ale");
order.getDiscountCode(); // $ALE
try {
// This will throw an exception because it contains numbers
order.applyDiscountCode("ABC123");
} catch (IllegalArgumentException iae) {
System.out.println(iae.getMessage()); // Prints "Invalid discount code"
}
try {
// This will throw as well, because it contains a symbol.
order.applyDiscountCode("w@w");
}catch (IllegalArgumentException iae) {
System.out.println(iae.getMessage()); // Prints "Invalid discount code"
}
}
}
12 Answers
Seth Kroger
56,413 Pointsmatches() has to match an entire line/string, so you need to use + to match one or more, not just a single character . You also need to put the dollar sign inside the character class like this "[a-zA-Z$]+"
Simon Coates
28,694 PointsIn the event it's helpful to anyone in the future, mine was:
private String normalizeDiscountCode(String discountCode){
for(char letter: discountCode.toCharArray()){
if(!Character.isLetter(letter) && letter != 36){
throw new IllegalArgumentException("Invalid discount code.");
}
}
return discountCode.toUpperCase();
}
It only differs from earlier answers in that i used the enhanced for loop, and tried to use the ascii integer code for $. (for whatever reason, i drew a mental blank on representing characters and went straight to ascii. Using '$' is probably a better option, and clearer)
Pedro Cabral
Full Stack JavaScript Techdegree Student 23,916 PointsOne year from now and you will be asking what "36" means, or anyone else reading that code. Google "magic numbers".
Simon Coates
28,694 PointsI mentioned that '$' was clearer. I added my code sample because the for each loop seemed more robust than more manual handling, and didn't feel inclined to correct my code and pretend that I hadn't made a mistake. If nothing else, it gives people an opportunity to see something slightly different that they might see in the wild and (in this case) appreciate why it's a bad idea. I didn't know the 'magic numbers' nomenclature. It should help me remember. thanks. (if you feel inclined to answer, what are the circumstances in which it's useful to know characters are secretly numbers?)
Iheke Iheke-agu
Full Stack JavaScript Techdegree Student 2,307 PointsWhere did you get !=36 is that How you call the $
Arash Abedin
12,107 PointsThis one worked for me: private String normalizeDiscountCode(String discountCode){
for (int i = 0; i < discountCode.length; i++) {
char x = discountCode.charAt(i);
if ((!Character.isLetter(x)) && (x!='$')){
throw new IllegalArgumentException("Invalid discount code");
}
Lonie Messer
4,916 PointsdiscountCode.length; change to discountCode.length();
Pedro Cabral
Full Stack JavaScript Techdegree Student 23,916 PointsIf you don't want to use regex, you can loop through all characters in a String and check if it is a letter with the static method Character.isLetter() or if it's equal to $.
Benjamin Orimoloye
23,328 Pointsyou can change String discountCode toCharArray() and then check if (Character.isLetter() or equal to "$" using the for each loop
Taebin You
4,786 Pointsprivate String normalizeDiscountCode(String discountCode){
for (int i = 0; i < discountCode.length(); i++){
char [] ndc = discountCode.toCharArray();
if (! Character.isLetter(ndc[i]) && ndc[i] != '$'){
throw new IllegalArgumentException("Invalid discount code");
}
}
return discountCode.toUpperCase();
Looks messy, but this worked
Simon Coates
28,694 Pointsyour code creates a lot of redundant character array objects. As you observed, it should work, but the line
char [] ndc = discountCode.toCharArray();
should ideally be outside the loop. (this may be obvious to you, but i though i'd mention it for future users)
lap Nguyen
715 PointsTaebin, your code works and helped me complete the task... to be honest it was a bit confusing and a bit advanced, with the 'ndc' and 'int i = o; 1' first me at first but once I took a closer look it made sense to me. thanks.
Sean M
7,344 PointsQUESTION: Can somebody explain the use of this part? I understand the rest, just not this section. Thank you.
for (char letter: discountCode.toCharArray()) {
Simon Coates
28,694 PointstoCharArray is called on the string, which returns an array of chars (ie char[]). The for loop takes a collection following the : (which should be read as 'in'). Each iteration of the loop, a different value from the collection is loaded into the loop variable (here this is called 'letter' and is type char), allowing you to access it within the loop body ( usually within a set of {}). You read it as "for each value in the collection, do the following".
Sean M
7,344 PointsOkay, that makes more sense. Thanks Simon.
Kourosh Raeen
23,733 PointsIf you want to fix the regex try "[a-zA-Z\$]+". Otherwise, Pedro's answer looks good.
Treehousepl1 Treehousepl1
751 PointsCould you explain me where did "Character" come from?
In this statement from Simon: if(!Character.isLetter(letter)
Simon Coates
28,694 Pointssee https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html . Java has a bunch of wrapper classes for the primitive types (int, char, bool). These classes include static methods related to the particular type. In this example, this is a helper method on the character class to help you determine in your char is a letter.
Treehousepl1 Treehousepl1
751 PointsThank you Simon
Iheke Iheke-agu
Full Stack JavaScript Techdegree Student 2,307 PointsThese answers are too advanced
Richard Min
Courses Plus Student 4,117 PointsHere is my long newb version which still works. Simon Coates' version is much better:
private String normalizeDiscountCode(String discountCode) {
for (char letter : discountCode.toCharArray()) {
if (Character.isLetter(letter)) {
System.out.println("Code is a letter. Valid code."); //this line of code is unnecessary. I just wrote it to make it clear.
} else if(letter == '$') {
System.out.println("Code is a dollar sign. Valid code."); //this line of code is unnecessary.
} else {
throw new IllegalArgumentException("Invalid discount code");
}
}
return discountCode.toUpperCase();
}
Fahri Can
9,921 PointsFahri Can
9,921 PointsThank you very much Seth!