No calls to throwing functions occur within 'try' expression - error-handling

` enum outofBound: Error
{
case NegativeNumber
case OutOfLimit
}
func sqareRoot(Number: Int) throws -> String
{
if Number < 10
{
throw outofBound.NegativeNumber
}
if Number > 100
{
throw outofBound.OutOfLimit
}
else
{
let number1 = Double (Number / 4)
print(number1)
let number2 = Double (number1 / 2)
print(number2)
return "number2"
}
}
do
{
let Result = try sqareRoot(Number: 3600)
}
catch outofBound.NegativeNumber
{
print("Please provide positive number")
}
catch outofBound.OutOfLimit
{
print("please provide less than 1000 number")
}
catch
{
print("unkonw errors occured")
}
print(squareRoot(Number: 2500))
print(squareRoot(Number: 3600))
print(squareRoot(Number: 4))
`
it gives this suggestion I am not getting it please help me.
{
No calls to throwing functions occur within 'try' expression
'catch' block is unreachable because no errors are thrown in 'do' block
}

try something like this:
func test() {
do {
let result = try sqareRoot(Number: 3600)
print("result: \(result)")
}
catch (let error) {
switch error {
case outofBound.NegativeNumber:
print("Please provide >= 10 number")
case outofBound.OutOfLimit:
print("please provide <= 100 number")
default:
print("error: \(error)")
}
}
// test print
print(try? sqareRoot(Number: 25))
}
func sqareRoot(Number: Int) throws -> String {
if Number < 10 {
throw outofBound.NegativeNumber
}
if Number > 100 {
throw outofBound.OutOfLimit
}
else {
let number1 = Double (Number / 4)
print("number1 \(number1)")
let number2 = Double (number1 / 2)
print("number2 \(number2)")
return String(number2)
}
}

Related

Function don't exit with return kotlin

I wrote this function with recursion in Kotlin, it's just for academic purposes.
But I have a problem, when the condition is true, the execution is not interrupted. It's as if it ignores the return command and keeps iterating.
I have seen it in debug, that when the condition is true it goes through there and then continues.
Anyone knows how to solve this?
In this capture, see the debugger in the return true statement, but the function don't exit.
Here is the function:
// The inputArray must be sorted in order to apply the binary search.
fun binarySearch(inputArray: Array<Int>, itemToSearch: Int) : Boolean {
// This print is for see the interactions in the search
println()
inputArray.forEach {
print("$it,")
}
if (inputArray.size > 1) {
if (itemToSearch == inputArray[(inputArray.size / 2) - 1]) {
return true
}
if (itemToSearch > inputArray[(inputArray.size / 2) - 1]) {
binarySearch(inputArray.copyOfRange(inputArray.size / 2, inputArray.size), itemToSearch)
} else {
binarySearch(inputArray.copyOfRange(0, inputArray.size / 2), itemToSearch)
}
}
return false
}
Here is the call:
val result = binarySearch(arrayOf(1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23), 16)
You need to return the result of the recursion, like
return binarySearch(inputArray.copyOfRange(inputArray.size / 2, inputArray.size), itemToSearch)
so in total:
// The inputArray must be sorted in order to apply the binary search.
fun binarySearch(inputArray: Array<Int>, itemToSearch: Int) : Boolean {
// This print is for see the interactions in the search
println()
inputArray.forEach {
print("$it,")
}
if (inputArray.size > 1) {
if (itemToSearch == inputArray[(inputArray.size / 2) - 1]) {
return true
}
if (itemToSearch > inputArray[(inputArray.size / 2) - 1]) {
return binarySearch(inputArray.copyOfRange(inputArray.size / 2, inputArray.size), itemToSearch)
} else {
return binarySearch(inputArray.copyOfRange(0, inputArray.size / 2), itemToSearch)
}
}
return false
}

Problem creating user with email and password with Firebase

i'm new to android dev and Kotlin, the code was working fine till i added some validations. I don't know if i have too many if statements or i'm dong the validations all wrong even though they seems to be working. Any help would be appreciated
reg.setOnClickListener {
val eml = email.text.toString()
val passwr = password.text.toString()
val confirmPsw = confirmPsswrd.text.toString()
val fName = findViewById<EditText>(R.id.f_name).text.toString()
val lName = findViewById<EditText>(R.id.l_name).text.toString()
if (Patterns.EMAIL_ADDRESS.matcher(eml).matches()) {
if (passwr == confirmPsw && passwr.length >= 4) {
if (fName != "" || lName != "") {
auth.createUserWithEmailAndPassword(eml, passwr)
.addOnCompleteListener (this) { task ->
//if task isn't successful
if (task.isSuccessful) {
Toast.makeText(
this#Register,
" Successfully Registered, Login to continue",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
this#Register,
" Registration error",
Toast.LENGTH_SHORT
).show()
}
}
} else {
val builder = AlertDialog.Builder(this)
with(builder)
{
setTitle("Some Fields Were Left Empty!!")
setMessage("*Please Enter Your First and Last Name(s)")
setPositiveButton(
"OK",
DialogInterface.OnClickListener(function = buttonClick)
)
show()
}
}
} else if (passwr.length < 4) {
password.error = "Password must be at least 4 characters long"
password.requestFocus()
} else {
confirmPsswrd.error = "Passwords don't match"
confirmPsswrd.requestFocus()
}
} else {
email.error = "Please enter a valid Email Address"
email.requestFocus()
}
}
Better do it with your addTextChangedListener
private fun passwordchanged(){
binding.passwordTextForSignUp.addTextChangedListener(object: TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val pass = binding.passwordTextForSignUp.text.toString().trim()
try {
if (PASSWORD_PATTERN.matcher(pass).matches()){
}
else{
binding.passwordTextForSignUp.setError("Invalid Password!")
binding.passwordTextForSignUpLayout.helperText = "Must be at least one number, at least one special character and at least 8 characters."
}
}catch (e : Exception){
Toast.makeText(this#SignUpActivity,e.localizedMessage,Toast.LENGTH_LONG).show()
}
}
and
private val PASSWORD_PATTERN: Pattern = Pattern.compile(
"^" + "(?=.*[0-9])" + //at least 1 digit
//"(?=.*[a-z])" + //at least 1 lower case letter
//"(?=.*[A-Z])" + //at least 1 upper case letter
"(?=.*[a-zA-Z])" + //any letter
"(?=.*[##$%^&+=.])" + //at least 1 special character
"(?=\\S+$)" + //no white spaces
".{8,}" + //at least 8 characters
"$"
)
Add Regex under "class SignUpActivity : AppCompatActivity() {"
If you want to check them again later, you can add an if to the button and query whether it is empty.

Roman Numerals. Could you point out my mistakes further down the road?

Beginner here. This piece of code converts number into roman numerals in multiples of 50 if not 10 if not 9 and down to 0. Methods are so intertwined. Is there something (just at a glance) you could suggest I should avoid doing? Thank You.
public static void main(String[] args) {
System.out.println(fiftyAndAbove(37));
}
public static String nineAndDown(int number) {
String one = "I", five = "V", ten = "X", sum = "";
if(number == 5) {
return five;
} else if(number == 9) {
return one + ten;
}
else if(number > 5) {
for(int i=1; i<=number-5; i++) {
sum += one;
}
return five + sum;
} else {
if(number == 4 ) {
return one + five;
} else
for(int i=1; i <=number; i++) {
sum += one;
}
} return sum;
}
public static String tenAndAbove(int number) {
int remainder = number % 10, numberOftens = number/10;
String ten = "X", sum = "";
if(numberOftens > 0) {
while(numberOftens > 0) {
sum += ten;
numberOftens -= 1;
}
}
return sum + nineAndDown(remainder);
}
public static String fiftyAndAbove(int number) {
int remainder = number % 50, numberOfFifty = number/50;
String fifty = "L", sum = "";
if(numberOfFifty > 0) {
while(numberOfFifty > 0) {
sum += fifty;
numberOfFifty -= 1;
}
}
return sum + tenAndAbove(remainder);
}
Is there something (just at a glance) you could suggest I should avoid doing?
I'd not unnecessarily complicate the logic as with
if(numberOfFifty > 0) {
while(numberOfFifty > 0) {
…
}
}
which is equivalent to
while (numberOfFifty > 0)
{
…
}
You could also have a look at this implementation and see what you prefer:
import java.util.Arrays;
…
public static String fiftyAndAbove(int number)
{
int remainder = number%50, numberOfFifty = number/50;
char [] Ls = new char [numberOfFifty];
Arrays.fill(Ls, 'L');
return new String(Ls) + tenAndAbove(remainder);
}
You have four places like this in your program where you need a string of a character repeated. If you're willing to require a certain Java version or above, you can also use one of the methods described at Java: String - add character n-times; otherwise I'd suggest to use a function to do it.
You could also think about whether you find
String one = "I", five = "V", ten = "X", sum = "";
if(number == 5) {
return five;
} else if(number == 9) {
return one + ten;
}
really better than
if (number == 5) return "V";
if (number == 9) return "IX";

Return Option inside Loop

The program aims to use a loop to check if the index of a iterator variable meets certain criteria (i.g., index == 3). If find the desired index, return Some(123), else return None.
fn main() {
fn foo() -> Option<i32> {
let mut x = 5;
let mut done = false;
while !done {
x += x - 3;
if x % 5 == 0 {
done = true;
}
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
return None; //capture all other other possibility. So the while loop would surely return either a Some or a None
}
}
}
The compiler gives this error:
error[E0308]: mismatched types
--> <anon>:7:9
|
7 | while !done {
| ^ expected enum `std::option::Option`, found ()
|
= note: expected type `std::option::Option<i32>`
= note: found type `()`
I think the error source might be that a while loop evaluates to a (), thus it would return a () instead of Some(123). I don't know how to return a valid Some type inside a loop.
The value of any while true { ... } expression is always (). So the compiler expects your foo to return an Option<i32> but finds the last value in your foo body is ().
To fix this, you can add a return None outside the original while loop. You can also use the loop construct like this:
fn main() {
// run the code
foo();
fn foo() -> Option<i32> {
let mut x = 5;
loop {
x += x - 3;
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
if x % 5 == 0 {
return None;
}
}
}
}
The behaviour of while true { ... } statements is maybe a bit quirky and there have been a few requests to change it.

Conversion from NonStrictExceptions to Expectations

I have test cases using NonStrictExpectations in jMockit v 1.22 as follows:
#Mocked Scanner mockScanner;
#Test
public void getNumber496() {
new NonStrictExpectations() {{
mockScanner.nextLine(); result = "496";
}};
int val = PrimeOrPerfect.getNumber(); // calls Scanner.nextLine() for a number
assertEquals(496, val);
}
The mocking works fine.
After upgrading to jMockit v. 1.25 I changed to Expectations (since NonStrictExceptions is deprecated) as shown below:
#Mocked Scanner mockScanner;
#Test
public void getNumber496() {
new Expectations() {{
mockScanner.nextLine(); result = "496";
}};
int val = PrimeOrPerfect.getNumber(); // calls Scanner.nextLine() for a number
assertEquals(496, val);
}
The mocked method always returns null. What's wrong with the new code?
Here is the code for getNumber():
protected static int getNumber() {
logger.info(">>getNumber()");
Scanner scanner = new Scanner(System.in);
boolean validInput = false;
int number;
System.out.println("Enter a whole positive number (0 to quit):");
do {
String line = scanner.nextLine();
logger.info("input number: {}", line);
number = 0;
try {
number = Integer.parseInt(line);
} catch (NumberFormatException e) {
logger.debug("input is invalid: {}", e.toString());
System.err.println("Please enter a positive integer less than 1001.");
continue;
}
if (number < 0 || number > 1000 ) {
logger.debug("input is out of range 1..1000.");
System.err.println("Please enter a valid number between 1 and 1,000 inclusive.");
} else {
validInput = true;
}
} while (!validInput);
// Don't close the scanner because doing so also closes System.in. Do NOT uncomment the line below.
//scanner.close();
logger.info("<<getNumber()");
return number;
}