Scala: for loop until condition - scala

How can I run for until a condition is met? Instead of using scala.util.control.Breaks.break, is it possible to test for a condition within for?
for(line <- source.getLines) {
if (line.equals("")) scala.util.control.Breaks.break
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}
} catch {
case e: IOException =>{

Try takeWhile
for(line <- source.getLines.takeWhile(!_.isEmpty)) {
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}
or
source.getLines.takeWhile(!_.isEmpty).foreach {
line =>
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}

Related

How to read the JSON file from HDFS path and use instead of MAP in Scala code

val airportCodeToTimezoneMap = Map("MAA" -> "Asia/Kolkata" , "SHJ" -> "Asia/Dubai")
val boardPoint = "MAA"
if( airportCodeToTimezoneMap.contains( boardPoint )) {
println("Code exists with value :" + airportCodeToTimezoneMap(boardPoint))
} else {
println("Code Not exist")
}
val tempValue = airportCodeToTimezoneMap(boardPoint)
println(tempValue)
Here instead of
MAP i want to configure in JSON File in HDFS path and use it .
Say For E.G
{
"airportCode": "AAL",
"zoneId": "Europe/Copenhagen"
},
{
"airportCode": "AAM",
"zoneId": "Africa/Johannesburg"
}
Please tell me how to write it .

Gatling print to file if KO

I have an .exec which for some values in my parameter list results in KO (value does not exists in the SUT).
I further have the need to print these values to a file so I later can remove them from the parameter list in order to not get KO`s.
I have a writer defined
val writer = {
val fos = new java.io.FileOutputStream("testresultater.txt")
new java.io.PrintWriter(fos,true)
}
and wonder how I could do this just for KOs inside the .exec resulting in KOs for some values like this:
.exec(http("request_lagDokument")
.post("/proxy/dokumenter/api/v1/SaveDokumentFil?IsDebug=true")
.headers(headers_3)
.body(ElFileBody("magnus/LagDokument.json"))
.check(status.is(expected = 200))
.check(jsonPath("$.DokumentGuid").saveAs("DokumentGuid")))
//if KO then:
.exec((s: Session) => {
writer.println(s.attributes("pnr"))
s
})
Is this possible?
You can do this by having a session function that is always executed with the conditional logic inside
.exec(session = {
if (session.isFailed) {
writer.println(s.attributes("pnr"))
}
session
})
or you can use the dsl's doIf
.doIf(session => session.isFailed) {
exec(session => {
writer.println(s.attributes("pnr"))
session
}
}

How to implement the Lispian cond macro?

Intended usage:
cond! {
x > 5 => 0,
x < 3 => 1,
true => -1
}
Should expand to:
if x > 5 { 0 } else if x < 3 { 1 } else if true { -1 }
Note that it doesn't produce a catch-all else { ... } suffix.
My attempt:
macro_rules! cond(
($pred:expr => $body:expr) => {{
if $pred {$body}
}};
($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => {{
cond! { $pred => $body } else cond! { $($preds => $bodies),+ }
}};
);
However, the compiler complains about the else keyword.
error: expected expression, found keyword `else`
--> src/main.rs:32:34
|
32 | cond! { $pred => $body } else cond! { $($preds => $bodies),+ }
| ^^^^
Macros in Rust don't perform textual substitution like the C preprocessor does. Moreover, the result of a macro is already "parsed", so you can't just append something after the macro invocation that's supposed to be part of what the macro expands to.
In your case, you can't put an else after the first cond! invocation because the compiler has already finished parsing the if expression; you need to put the if and the else together. Likewise, when you invoke cond! again after the else, you need to add braces around the call, because the sequence else if does not begin a nested if expression.
macro_rules! cond {
($pred:expr => $body:expr) => {
if $pred { $body }
};
($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => {
if $pred { $body } else { cond! { $($preds => $bodies),+ } }
};
}
Ultimately though, this macro is pretty much useless. An if expression without an else clause always has its type inferred to be (), so unless all the branches evaluate to () (or diverge), the expanded macro will produce type mismatch errors.

Using Number::Phone to validate and format

I'm trying to use Number::Phone from CPAN to accomplish 2 tasks:
Validate a Phone Number; and
Format the number in E.164 Notation.
However, I'm unable to figure out how it works. My sample code is:
#!/usr/bin/perl -w
use strict;
use warnings;
use Number::Phone;
foreach my $fnum ( '17888888', '97338888888', '00923455555333', '+97366767777' , '38383838') {
my $phone = Number::Phone->new($fnum);
my $norm = "";
eval {
$norm = $phone->format_using('E123'); # or 'Raw'
print "E164 => '$norm'\n";
} or do {
print STDERR "Unable to parse '$fnum'\n";
}
}
Expected output:
E164 => '+97317888888'
E164 => '+97338888888'
E164 => '+923455555333'
E164 => '+97366767777'
E164 => '+97338383838'
But the results were incorrect. I tried using Number::Phone::Normalize, but still not successful:
#!/usr/bin/perl -w
use strict;
use warnings;
use Number::Phone::Normalize;
my %params = (
'CountryCode'=>'973',
'IntlPrefix' =>'00',
'CountryCodeOut'=>'973',
'IntlPrefixOut' => '+',
);
my $nlz = Number::Phone::Normalize->new( %params );
foreach my $number ('17888888', '97338888888', '00923455555333', '+97366767777' , '38383838') {
my $e164 = $nlz->intl( $number );
print "E164 => '$e164'\n";
}
with the same expected output of:
E164 => '+97317888888'
E164 => '+97338888888'
E164 => '+923455555333'
E164 => '+97366767777'
E164 => '+97338383838'
However, this produced the wrong results too. The snippet Java code below works perfectly, and it's what I'm trying to achieve in Perl.
// Uses libphonenumber: http://code.google.com/p/libphonenumber/
// setenv CLASSPATH .:libphonenumber-8.5.2.jar
// libphonenumber
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
public class ValidateList {
public static void main(String[] args) {
try {
if (args.length != 1) {
throw new IllegalArgumentException("Invalid number of arguments.");
}
String file = args[0];
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try (java.io.BufferedReader br = new java.io.BufferedReader(new java.io.FileReader(file))) {
String line = null;
while ((line = br.readLine()) != null) {
try {
PhoneNumber phoneNumber = phoneUtil.parse(line, "BH");
boolean isValid = phoneUtil.isValidNumber(phoneNumber);
if (isValid) {
System.out.println( "E164 => " + phoneUtil.format(phoneNumber, PhoneNumberFormat.E164) );
}
else {
System.err.println( "Invalid => " + line);
}
}
catch (NumberParseException e) {
System.err.println("NumberParseException for ("+line+"): " + e.toString());
}
}
}
}
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java ValidateList <fileNameWithPhoneNumbers>");
}
}
}
% cat input.txt
17888888
97338888888
00923455555333
+97366767777
38383838
% javac -cp libphonenumber-8.5.2.jar ValidateList.java
% java -cp .:libphonenumber-8.5.2.jar ValidateList input.txt
E164 => +97317888888
E164 => +97338888888
E164 => +923455555333
E164 => +97366767777
E164 => +97338383838
Your input is greatly appreciated.
When I run the first example code for the numbers, two of those fail to be parsed:
17888888 - this is obvious, when calling Number::Phone without a country code, this will not be parsed as it's unclear what country this is from
00923455555333 - 923 is, according to a quick google search, the country code for Pakistan. The Wikipedia page for dialing codes in Pakistan shows no 455, leading me to think that this is not a known area code to either Number::Phone or Wikipedia. I suspect it is an invalid number.
So for the first Number: specify which country this is supposed to be from.
If you are certain the other number is correct, you know more about that than the developer of Number::Phone currently and I'm sure he'd be happy to receive your input in the form of a more complete Number::Phone localized package.
The fact that your Java code accepts the (probably) invalid number does not necessarily mean it is more correct, just that it is less picky in what it declares to be a correct number.
Edit:
Asking Phone::Number to parse the input '+923455555333' instead of '00923455555333' leads to the desired output.
Looking at the source of Phone::Number:
# ... processing input arguments
$number = "+$number" unless($number =~ /^\+/);
It becomes clear that the 00 is interpreted as '+00' and then rejected as being an invalid number.
View some discussion on that here
It seems to me you will have to handle this yourself.
One way may be to simply replace leading 00 with '+' - preferably only if parsing failed.
The other number can be parsed if you make it clear what country it should belong to.
Perhaps like so:
my $phone = Number::Phone->new($fnum);
unless ($phone){
$phone = Number::Phone->new('BH',$fnum);
if ( !$phone && $fnum =~ s/^00/+/ ){
# You should probably check the discussion I linked.
# There may well be problems with this approach!
$phone = Number::Phone->new($fnum);
}
}

Show syntax errors in knitr output?

I'm writing a description of R syntax, and I'd like to include some statements that include syntax errors, e.g.
if (n >= 2)
{
# if TRUE
}
else
{
# if FALSE
}
(This is a syntax error at top level because the if is complete before the else is read.) I'm trying to put this into a knitr document, but
even with error=TRUE it fails, because that option only affects run-time errors, not syntax errors. Is there some reasonable way to get this to display what would be shown if I entered it at the console? I.e.
I'd like it to display something like
if (n >= 2)
{
# if TRUE
}
else
Error: unexpected 'else' in "else"
{
# if FALSE
}
Here's a function that does part of what I want: it reproduces the output from a syntax error, but it doesn't do all the markup that knitr would do, so the formatting is wrong.
parse_with_error <- function(text) {
reportError <- function(e) {
msg <- conditionMessage(e)
line <- as.numeric(sub("^text:([[:digit:]]*):.*", "\\1", msg))
col <- as.numeric(sub("^text:[[:digit:]]*:([[:digit:]]*):.*", "\\1", msg))
cat(text[1:line], sep="\n")
if (col > 1)
cat(paste(rep(" ", col-1), collapse=""))
cat("^\n")
err <- sub("^text:[[:digit:]]*:[[:digit:]]*: ([^[:cntrl:]]*)\n.*", "\\1", msg)
parseData <- getParseData(sf)
lastToken <- parseData[nrow(parseData), "text"]
cat(paste0("Error: ", err, ' in "', lastToken, '"'), "\n")
}
text <- unlist(strsplit(text, "\n"))
sf <- srcfile("text")
tryCatch(parse(text = text, keep.source = TRUE, srcfile=sf),
error = reportError)
}
This shows how it would be used:
parse_with_error(
"if (TRUE) {
# do TRUE
}
else {
# do FALSE
}")
You can use a separate R session to evaluate the code, e.g.
```{r, engine='Rscript', error=TRUE}
if (TRUE)
{
# if TRUE
}
else
{
# if FALSE
}
```