Breaking 2 nested loops "at once" [duplicate] - java

This question already has answers here:
How do I break out of nested loops in Java?
(37 answers)
Closed 8 years ago.
Please have a look at the following code (Java)
while((str=br.readLine())!=null)
{
int tempCounter=0;
for(int i=0;i<str.length();i=i+3)
{
String word = str.substring(i, i+3);
// System.out.println(word);
int insert = db.insert(index, word);
if(insert<0)
{
break;
}
tempCounter++;
}
index++;
System.out.println("Index Updated: "+index);
System.out.println(String.valueOf("Total words in this run: "+tempCounter));
if(index==5)
{
break;
}
}
if insert is less than 0, the I need to break both for and while loops. How can I do this?
Problem here is I need to break "both" loops if insert is less than 0. And you can't add 2 break commands one after another, even with labels.

You may try this simple example to see how a labeled loop works:
public static void main(String[] args) {
int i = 0; int j = 0;
EXIT: for (; i < 10; i++) {
for (; j < 10; j++) {
if (i * j > 50) {
break EXIT;
}
}
j = 0;
}
System.out.printf("Finished with i=%s and j=%s\n", i, j);
}
OUTPUT:
Finished with i=6 and j=9

+1.. #AntonH.. label is an first option.. if you are confused how to use label.. you can use a boolean variable like below..
while (...) {
boolean brk = false;
for (...) {
if(insert<0)
{ brk = true;
break;
}
}
if(brk)
{
break;
}
}

while((str=br.readLine())!=null)
{
int tempCounter=0;
boolean check = false;
for(int i=0;i<str.length();i=i+3)
{
String word = str.substring(i, i+3);
// System.out.println(word);
int insert = db.insert(index, word);
if(insert<0)
{
check = true;
break;
}
tempCounter++;
}
index++;
if(check)
break;
System.out.println("Index Updated: "+index);
System.out.println(String.valueOf("Total words in this run: "+tempCounter));
if(index==5)
{
break;
}
}
You can do by this way

Your question is already partly answered here. Use the label in front of the line of the while loop, e.g. OUTMOST, then when the insert is less than 0, 'break OUTMOST'. For example:
OUTMOST:
while(someCondition) {
for(int i = 0; i < someInteger; i++) {
if (someOtherCondition)
break OUTMOST;
}
}

IMO, an exception is inappropriate; a label is rare and not likely to be understood by future readers.
Invoking KISS principle, why not just use an extra flag and augment the expression used in each loop:
boolean isInsertFail = false;
while((! isInsertFail) && (str=br.readLine())!=null))
{
int tempCounter=0;
for(int i=0;(! isInsertFail) && i<str.length();i=i+3)
{
String word = str.substring(i, i+3);
// System.out.println(word);
int insert = db.insert(index, word);
if(insert<0)
{
isInsertFail = true;
}
tempCounter++;
}
if (!isInsertFail) {
index++;
System.out.println("Index Updated: "+index);
System.out.println(String.valueOf("Total words in this run: "+tempCounter));
if(index==5)
{
break;
}
}
}
Note that in Eclipse, one could click on isInsertFail, and the syntax highlighting should illustrate its use.

One approach is to use an exception, depending on the expected result of the db.insert routine.
In short, create a new EDBInsertionException exception (a class extending Exception) and raise the exception in your for loop.
try
{
while((str=br.readLine())!=null)
{
int tempCounter=0;
for(int i=0;i<str.length();i=i+3)
{
String word = str.substring(i, i+3);
// System.out.println(word);
int insert = db.insert(index, word);
if(insert<0)
{
throw new EDBInsertionException("No record inserted: " + insert);
}
tempCounter++;
}
index++;
System.out.println("Index Updated: "+index);
System.out.println(String.valueOf("Total words in this run: "+tempCounter));
if(index==5)
{
break;
}
}
}
catch (EDBInsertionException e)
{
// MZ: The database insertion has failed
log.error(e.getMessage(), e);
// MZ: Supplemental action: Delegate, escalate, rollback, etc
}
EDIT
Expanded the example to illustrate a potential usage of an (user) exception.

Related

Exception in thread "main" java.lang.StringIndexOutOfBoundsException

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 7
at java.lang.String.charAt(Unknown Source)
at DNAmatch.findFirstMatchingPosition(DNAmatch.java:100)
at DNAmatch.run(DNAmatch.java:82)
at acm.program.Program.runHook(Program.java:1568)
at acm.program.Program.startRun(Program.java:1557)
at acm.program.Program.start(Program.java:808)
at acm.program.Program.start(Program.java:1279)
at acm.program.Program.main(Program.java:1360)
I got this weird error and I don't know what is causing it. I googled for a solution to my problem but nothing helped me solve it.
If you try as inputs for chain1 atcg and for chain2 tagaagtc, it works fine
but for inputs chain1 atcg and chain2 tagaagct then i got this error.
If anyone could help i'd appreciate it.
=================================================
import acm.program.*;
public class DNAmatch extends Program
{
public void run()
{
//The chains must only contain the characters A,T,C or G so we check the string for any irregularities.
String current, chain2; Boolean flag=true; int errorCount;
String chain1 = readLine("Please type in the first chain of DNA code: ");
for (int i=0; i<chain1.length(); i++)
{
current = chain1.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g"))))
{
flag=false; break;
}
}
while (flag==false)
{
errorCount=0;
println("The DNA code you insert must only contain the characters A, T, C and G");
chain1 = readLine("Please type again in the first chain of DNA code: ");
for (int i=0; i<chain1.length(); i++)
{
current=chain1.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g"))))
{
errorCount =1; break;
}
}
if (errorCount==0)
{
flag=true; break;
}
}
chain2 = readLine("Please type in the second chain of DNA code: ");
flag=true;
for (int i=0; i<chain2.length(); i++)
{
current = chain2.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g")))&&(chain1.length()>chain2.length()))
{
flag= false; break;
}
}
while ((flag==false)&&(chain1.length()>chain2.length()))
{
errorCount=0;
if (chain1.length()>chain2.length())
println("The second DNA chain must be longer or equal to the first one at the most!");
else
println("The DNA code you insert must only contain the characters A, T, C and G");
chain2 = readLine("Please type again the second chain of DNA code: ");
for (int i=0; i<chain2.length(); i++)
{
current = chain2.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g")))&&(chain1.length()>chain2.length()))
{
errorCount =1; break;
}
}
if (errorCount==0)
{
flag=true;
}
}
int match=findFirstMatchingPosition(chain1,chain2);
if (match==-1)
println("Not match found! "+ match);
else
println("Match has been found at point "+ match+ "!");
}
public int findFirstMatchingPosition(String shortDNA, String longDNA)
{
String currentCharShort=""; String currentCharLong="";
int match=0; int ans=-1; int a;
for (int i=0; i < longDNA.length(); i++)
{
a = i;
match = 0;
for (int j=0; j < shortDNA.length(); j++)
{
currentCharLong=longDNA.charAt(a)+ "";
currentCharShort=shortDNA.charAt(j)+ "";
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
else break;
}
if (match == shortDNA.length())
{
ans=i;
break;
}
}
return ans;
}
}
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
This is where your problem is, since you nested the loop, 'a' has the opportunity to increment greater than the total length of longDNA.
When you enter this for loop
for (int j=0; j < shortDNA.length(); j++)
{
currentCharLong=longDNA.charAt(a)+ "";
currentCharShort=shortDNA.charAt(j)+ "";
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
else break;
}
with "a" that is the index of your last character in longDNA (say 5 if longDNA has six characters), when you enter the if branch and put a+=1 you now have an index that is greater than longDNA size. So when you iterate again and search for charAt(a) the exception will be thrown. This could also happen with lesser "a" if you execute the a+=1 statement different times in the internal for loop.

How do I sort an array of strings alphabetically in java?

I'm new to programming/coding and have been stuck on a project in school for a few days now. The goal is to take an array full of words (each position is a different word) and sort it alphabetically. I've tried doing some research on stack overflow already, but I'm having a bit of trouble following some of the examples I've found. The class and driver (I'm using a two part setup if you will) both compile fine, no problems there. The problem occurs when I try to use alphaSort from my driver. I receive a null pointer exception for the line marked below. I've had some trouble with these exceptions in the past, so I'm sure it's something small I'm overlooking. As stated however, I'm not yet fluent enough in the java syntax to catch a small error like that.
I figured I should just include the entire method in-case my error is something in the beginning, before the sorting part. What I have so far (i found this on Stack overflow):
public void alphaSort()
{
String alphaList[] = new String[wordList.size()];
int count=0;
//puts wordList into alphaList for easier sorting
while(count<wordList.size()-1)
{
alphaList[count]=wordList.get(count);
count++;
}
int shortestStringIndex;
//sort begins here
for(int j=0; j<alphaList.length -1; j++)
{
shortestStringIndex = j;
for(int i=j+1; i<alphaList.length; i++)
{
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim())<0) //null pointer exception points here
{
shortestStringIndex = i;
}
}
if(shortestStringIndex !=j)
{
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]=temp;
}
}
//prints out results
count=0;
while(count<alphaList.length)
{
System.out.println(alphaList[count]);
alphaOut.print(alphaList[count]);
count++;
}
}
Any help would be greatly appreciated. Please be as thorough as possible in giving an answer (as i said, I'm a bit of a java newbie). Thanks :)
edit: to test for null values (which i assume are spots in my array list that are blank) i made the following method:
public void isNull()
{
int count=0;
while(count<wordList.size()-1)
{
if((wordList.get(count)).equals(""))
{
System.out.println("null");
break;
}
else
{
System.out.println("nothing yet");
}
count++;
}
}
the while loop never broke early, my method ran to completion.
You need to update the first while loop to match:
while(count < wordList.size()) {
alphaList[count] = wordList.get(count);
count++;
}
You aren't copying over every index of the list to the array, which means that when it goes to check the last index, it cannot find a value (NullPointerException).
Edit:
Here's my full test class that works:
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
new Test();
}
private ArrayList<String> wordList = new ArrayList<String>();
public Test() {
wordList.add("Test");
wordList.add("Bee");
wordList.add("Pig");
wordList.add("Dog");
alphaSort();
}
public void alphaSort() {
String[] alphaList = new String[wordList.size()];
int count = 0;
while(count < wordList.size()) {
alphaList[count] = wordList.get(count);
count++;
}
int shortestStringIndex;
for(int j = 0; j < alphaList.length - 1; j++) {
shortestStringIndex = j;
for(int i = j + 1; i < alphaList.length; i++) {
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim()) < 0) {
shortestStringIndex = i;
}
}
if(shortestStringIndex != j) {
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]= temp;
}
}
count = 0;
while(count < alphaList.length) {
System.out.println(alphaList[count++]);
}
}
}
Output:
Bee
Dog
Pig
Test
Try this...
// sorting array
if(wordList.size()>0){
String alphaList[] = new String[wordList.size()];
//convert list to String array
alphaList= wordList.toArray(alphaList);
//sorting
Arrays.sort(alphaList);
}
........
// let us print all the elements available in wordList
if(wordList.size()>0){
for (String word: alphaList) {
System.out.println("word= " + word);
}
}
There is an error when you are copying your List to an array. It is inserting a null at the end of the list which is causing your NullPointerException. Here is the revised version that works. Instead of looping through the List and copying each item to the array(which is buggy) I just use the standard java method that is on a List to convert the List to an array.
public static void alphaSort()
{
String alphaList[] = wordList.toArray(new String[]{});
int shortestStringIndex;
//sort begins here
for(int j=0; j<alphaList.length -1; j++)
{
shortestStringIndex = j;
for(int i=j+1; i<alphaList.length; i++)
{
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim())<0) //null pointer exception points here
{
shortestStringIndex = i;
}
}
if(shortestStringIndex !=j)
{
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]=temp;
}
}
//prints out results
int count=0;
while(count<alphaList.length)
{
System.out.println(alphaList[count]);
alphaOut.print(alphaList[count]);
count++;
}
}
The problem is that you're adding wordList.size()-1 number of items into the array and the array size is wordList.size() which means that the last value in the array is null
For this while loop:
while (count<wordList.size()-1)
{
alphaList[count]=wordList.get(count);
count++;
}
you don't need to loop to wordList.size()-1 since you already do < instead of <=. You are stopping your loop at the second to last index and are thus not assigning a value to the last place in the array. Instead do while (count < wordList.size()) or while (count <= wordList.size()-1)

What am I doing Wrong here [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I made a program to search for a certain string in another string and print Word found if the condition is true or print word not found if condition is false
The logic is as follows
enter word
length of word
for searching for letter [1]
if true
then for till length of word match with string to be searched
else continue loop
But I always get word not found no matter what the input, please help me over here!!!
The code is as follows :-
import java.util.Scanner;
class Search_i_String
{
public static void main(String args[])
{
int flag=0;
Scanner Prakhar=new Scanner(System.in);
System.out.println("Enter a String");
String ori=Prakhar.nextLine();
System.out.println("Enter the String to be Searched");
String x=Prakhar.nextLine();
char a[]=new char[ori.length()];
char b[]=new char[x.length()];
for(int i=0;i<ori.length();i++)
{
a[i]=ori.charAt(i);
}
for(int i=0;i<x.length();i++)
{
b[i]=x.charAt(i);
}
for(int i=0;i<a.length;i++)
{
if (a[i]==b[0])
{
for(int j=0;j<b.length;j++)
{
while(flag==0)
{
if(b[j]==a[i])
{
flag=0;
}
else if(b[j] != a[i])
{
flag=1;
}
i++;
}
}
}
}
if (flag==0)
{
System.out.println("Word Found !!!");
}
else
System.out.println("Word not Found");
}
}
P.S. : I know I can use the contains() function but I can as my professor suggests against it and could someone please correct the program I have written, because I could have scavenged off a program from the internet too if I had to, I just wanted to use my own logic
Thank You(again)
while(flag==0)
{
if(b[j]==a[i])
{
flag=0;
}
else if(b[j] != a[i])
{
flag=1;
}
i++;
j++; //add this and try once
}
If you are comparing strings in Java, you have to use equals();
So, stringA.equals(stringB);
Cheers!
Let me get this straight. You're looking for b array inside of a array? "Enter the string to be searched" means that you are searching the other way around, but I'll go with the logic your code seems to follow... Here's a naive way to do it:
if (a[i]==b[0])
{
flag = 0;
for(int j=0;j<b.length;j++)
{
if(b[j] != a[i+j]) // will array index out of bounds when its not foud
{
flag++; // you should probably break out of a named loop here
}
}
if(flag == 0){/*win*/}
}
You're modifying your first search loop with variable i when you don't have to. You can just add i to j. Also, you don't need the while loop inside if i'm understanding your problem. Like others have said, functions exist to do this already. This algorithm isn't even as efficient as it could be.
I know of an algorithm where you check starting in the last character in b instead of the first character in b to begin with. Then you can use that information to move your search along faster. Without resorting to full pseudo code, anyone know what that's called?
The simple way(but not the fastest way) is use double loop to check the chars in strings one by one, pls ref to my code and comments:
public class SearchString {
public static void main(String[] args) {
String a = "1234567890";
String b = "456";
// Use toCharArray() instead of loop to get chars.
search(a.toCharArray(), b.toCharArray());
}
public static void search(char[] a, char[] b) {
if (a == null || b == null || a.length == 0 || b.length == 0) {
System.out.println("Error: Empty Input!");
return;
}
int lenA = a.length, lenB = b.length;
if (lenA < lenB) {
System.out
.println("Error: search key word is larger than source string!");
return;
}
// Begin to use double loop to search key word in source string
for (int i = 0; i < lenA; i++) {
if (lenA - i < lenB) { // If the remaining source string is shorter than key word.
// Means the key word is impossible to be found.
System.out.println("Not found!");
return;
}
// Check the char one by one.
for (int j = 0; j < lenB; j++) {
if (a[i + j] == b[j]) {
if (j == lenB - 1) { // If this char is the last one of key word, means it's found!
System.out.println("Found!");
return;
}
} else {
// If any char mismatch, then right shift 1 char in the source string and restart the search
break;
}
}
}
}
}
You can just use String.contains();
If you really want to implement a method, try this one:
public static void main(String[] args) {
// Initialize values searchedWord and original by user
String original = [get original word from user] ;
String searchedWord = [get searched for word from user];
boolean containsWord = false;
int comparePosition = 0;
for(int i = 0; i < original.length() - searchedWord.length(); i++) {
if(original.charAt(i) == searchedWord.charAt(comparePosition)) {
comparePosition += 1;
} else {
comparePosition = 0;
}
if(comparePosition == searchedWord.length()) {
containsWord = true;
break;
}
}
return containsWord? "Word found!!" : "Word not found.";
}

How do I do palindromes in java? [duplicate]

This question already has answers here:
Check string for palindrome
(42 answers)
What's the simplest way to print a Java array?
(37 answers)
Closed 9 years ago.
First time posting here! Yeah I kind of just need some help with this assignment. We had to read an input file, go through a loop for each character in a line of the input file, and store that info in a char array, and then finally write an isPalindrome method and call it to determine if that line is a palindrome and print it to the console.
This is what I have so far, sorry if I didn't format correctly, it was kind of confusing.
I'm still kind of a beginner and I'm not sure where I'm going wrong. My output is essentially "[C#91bee48 is not a palindrome!" over and over again with some variation on whether or not its a palindrome.
public class Palindromes {
public static void main(String[] args) {
int k = 0;
try {
Scanner inF = new Scanner(new File("palindromes.txt"));
String aString;
while (inF.hasNextLine()) {
aString = inF.nextLine();
k++;
for (int i = 0; i < k; i++) {
char[] phrases = new char[aString.length()];
if (Character.isLetter(aString.charAt(k))) {
phrases[i] = aString.charAt(i);
}
isPalindrome(phrases);
}
}
}
catch (FileNotFoundException e) {
System.err.println("palindromes.txt not found!");
}
}
public static void isPalindrome(char[] phrases) {
boolean isPalindrome = false;
int i1 = 0;
int i2 = phrases.length - 1;
while (i2 > i1) {
if (phrases[i1] != phrases[i2]) {
isPalindrome = false;
System.out.println(phrases + " is not a palindrome!");
} else {
isPalindrome = true;
System.out.println(phrases + " is a palindrome!");
}
i1++;
i2--;
}
}
}
Use Arrays.toString() to get the string representing the array.
For example:
System.out.println(Arrays.toString(phrases) + " is not a palindrome!");
Otherwise you get the default toString() for an array object - which is not what you are after.
The logic of your while loop is faulty. This kind of loop is a common idiom: you have to check a number of things, and if any check fails, you want the result to be false. If no check fails, you want the result to be true. The thing is, you can't tell if the result is true until the loop is completely finished. Your code is:
while (i2 > i1)
{
if(phrases[i1] != phrases[i2])
{
isPalindrome = false;
System.out.println(phrases + " is not a palindrome!");
}
else
{
isPalindrome = true;
System.out.println(phrases + " is a palindrome!");
}
i1++;
i2--;
}
The problem is that you're printing "is a palindrome" before you've checked all the characters, and you can't possibly know that. The way to write this kind of loop is something like this:
isPalindrome = true;
while (i2 > i1)
{
if(phrases[i1] != phrases[i2])
{
isPalindrome = false;
break; // get out of the loop, it's pointless to continue
}
i1++;
i2--;
}
// *** NOW you can check isPalindrome and display your output

Palindrome Program

I'm trying to write a program which will output what Palindromes will work from entering in a string and how many there are. I keep getting a lot of errors and I'm still trying to get my head around some of the harder topics in Java!
Here's what I have already, as always, all answers are greatly appreciated!
public static boolean Palindrome(String text) {
int index;
int palindrome;
System.out.println("Please enter your text ");
text = EasyIn.getString();
for(index = 0; index < amount.length() / 2; index++) {
if(text.charAt(index) != text.charAt(text.length() - index - 1)) {
return false;
}
}
System.out.println("The number of valid palindrome(s) is " + amount);
amount = EasyIn.getString();
}
I think the problem is in amount.length(), you should use text.length(), since you are looping over the half of text. The algorithm works fine. Here is a reduced example:
public static boolean palindrome(String text)
{
for (int index = 0; index < text.length() / 2; index++) {
if (text.charAt(index) != text.charAt(text.length() - index - 1)) {
return false;
}
}
return true;
}
Note:
You forgot to add a return true statement, if you don't add one, is possible that the for loop finishes and no return statement is reached, which will cause an error.
I would recommend you to follow Java naming conventions. You method should be called like someMethodName instead of SomeMethodName. This last is used for class names.
Edit:
As #bobbel commented, you could improve this code by assigning text.length() to a variable and using it inside the for.
There can be two things:
ammount variable that you used either it could be a string array that you are maintaining strings inside it, if this is the case than you have to loop first through array of strings and then maintain one nested loop to check that strings inside it are palindrom or not
or second case is that you have used the variable incorrect it may be text instead of ammount
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("enter string to check for palidrome");
String orginal = in.next();
int start = 0;
int middle = orginal.length()/2;
int end = orginal.length() - 1;
int i;
for(i=start; i<=middle; i++) {
if(orginal.charAt(start) == orginal.charAt(end)) {
start++;
end--;
} else {
break;
}
}
if(i == middle+1) {
System.out.println("palidrome");
} else {
System.out.println("not palidrome");
}
}
This is the Simplest way of Checking Palindrom number.
package testapi;
public class PalindromNumber {
public static void checkPalindrom(Object number) {
StringBuilder strNumber = new StringBuilder(number.toString());
String reverseNumber = strNumber.reverse().toString();
if (number.toString().equals(reverseNumber)) {
System.out.println(number + " is palindrom number");
} else {
System.out.println(number + " is not palindrom number");
}
}
public static void main(String[] args) {
checkPalindrom(101);
checkPalindrom(10.01);
checkPalindrom("aanaa");
}
}

Categories

Resources