perl null or empty detection - string

I have a hash containing results of matching substrings. I want to print a message if there is no matching between the string. I've tried the following and it didn't work.
foreach (keys %d) {
if ($_ eq "") {
print "no matches"; # and i've tried (if defined $_
} else {
print "$_\n";
}
}
the % d is filled this way (it contains matched substrings) :
foreach (my $i=0;$i<length($seq1)-$k;$i+=1) {
my $common=substr($seq1,$i,$k);
if ($seq2=~/$common/) {
$d{$common}++;
}
}

I think I finally see what you are trying to accomplish. You think that checking if the keys in %d equal the empty string, then there were no matches in your loop. This is false. If there are no matches, then there are no keys, and the loop will never execute.
Unfortunately, you cannot check if %d contains no values that way. You need something like:
unless (%d) {
print "No matches\n";
} else {
print "$_\n" for keys %d;
}

You have an iteration over all existing keys and check if the are an empty string, that's I guess not what you want.
Try
if (defined $d{$_})
or if it is set to "" then
if ($d{$_} eq "")
To be more helpfull, one would have to know how your hash is filled.
You need to initialize also the non matching values. In your code you can add an
if ($seq2=~/$common/) {
$d{$common}++;
}
else
{ $d{$common} = 0 unless (exists($d{common})); }
and then check
if ($d{$_} > 0)

Related

How to set an empty or not empty entry for a switch case statement?

I'd like to know to set an entry to validate if a String is empty or not empty in a switch-case statement. Let me show you:
String str = 'value'
switch(str){
case str == '':
println('Entered an empty value')
break
case str != '':
println('Entered value '+str)
break
case 'CoDe':
println('Entered special code '+str)
break
default:
println('Incorrect entry')
break
}
I know how to set an entry with a value (case 3) but I don't know how to set a entry with an empty or not empty string value.
Any help?
I tested it, and I think I have the answer for you.
switch(str) {
case "": // empty
println("Entered an empty value")
break
case "CoDe": // str == CoDe
println("Entered special code "+str)
break
default: // String not empty and not "CoDe"
println("Not empty")
break
}
It works because you have case "" which is the empty string. Meaning that everithing else is not empty. everything else is the default:
If you are not convinced, I'll give you a different example with the same meaning.
if (str.isEmpty()) {
// do something
} else if (!str.isEmpty()) { // <- this if is redundant
// do something else
}
You don't need the second if, because, you enter the else branch only if str is not empty! I appleid the same logic to the case. And it works because case "": in Java is valid.
As commented, what you need in Java is a series of if tests.
In the String class, you can test either:
The string has no characters at all (isEmpty)
The string has no characters OR has only whitespace characters (isBlank)
if ( str.isEmpty() ) { System.out.println( "ERROR - String has no characters." ); }
else if ( str.isBlank() ) { System.out.println( "ERROR - String has only whitespace." ); }
else if ( str.equals( "CoDe" ) ) { System.out.println( "Code received." ); }
else { System.out.println( "ERROR - Incorrect entry." ); }
See that code run live at Ideone.com.
Before that code block, I would add a null-check.
Objects.requireNonNull( str ); // Throw exception if null.
I find the if - else if - else construct in Java to be awkward in terms of readability. The switch syntax is much better at making obvious that a series of possibilities is being tested, mutually-exclusive, with a single result.
I do wish Java offered a cascading test for a series of boolean expressions. I have used such a feature in another language. There I found the cascading-boolean-tests to be quite practical for handling a series of business rules. But, alas, no such feature in Java. If only Brian Goetz were taking my calls.
I do not know Groovy. Perhaps Groovy provides another facility.
Your code has a smell, as str != '' would block all further cases.
I would re-organize it and use straight-forward basic Groovy switch-statement:
String str = 'value'
switch(str){
case 'CoDe':
println "Entered special code $str"
break
case '':
println 'Entered an empty value'
break
case { str != '' && str != null }:
println "Entered value $str"
break
default:
println 'Incorrect entry'
}
prints
Entered value value

TextField.text is assigned with a multi-line string, but they're not equal right after the assignment

I have an Array of strings:
private var phrase:Array = ["You will be given a series of questions like this:\n2 + 2 =\n(click or press ENTER to continue)","You can use the Keyboard or Mouse\nto deliver the answer\n\"ENTER\" locks it in.\n(click or press ENTER to continue)","\nClick Here\n to start."];
I have a conditional later in the script to see if the phrase[0] is equal to the instructText.text, so I put a "test" directly after the assignment as below:
instructText.text = phrase[0];
if (instructText.text == phrase[0]) {
trace("phrase zero");
}
else {
trace("nottttttttt");
}
//OUTPUT: nottttttttt
I've tried various combinations of phrase[0] as String and String(phrase[0]), but haven't had any luck.
What am I missing?
Turns out that the text property of the TextField class converts the "Line Feed" characters (the "\n", ASCII code of 1010=A16) to the character of "Carriage Return" (the ASCII code of 1310=D16).
So, you need a LF to CR conversion (or vise-versa) to make a homogeneous comparison of what is stored in the property against what you have in the array element:
function replaceLFwithCR(s:String):String {
return s.replace(/\n/g, String.fromCharCode(13));
}
if (instructText.text == replaceCRwithLF(phrase[0])) {
trace("They are equal :)");
}
else {
trace("They are NOT equal :(");
}
// Output: They are equal :)
P.S. To get the code of a character, you may utilize the charCodeAt() method of the String class:
trace("\n".charCodeAt(0)); // 10

Remove function from file using sed or awk

I want to remove the function engine "map" { ... "foobar" ... }.
I tried in so many ways, it's so hard because it has empty lines and '}' at the end, delimiters doesn't work
mainfunc {
var = "baz"
engine "map" {
func {
var0 = "foo"
border = { 1, 1, 1, 1 }
var1 = "bar"
}
}
}
mainfunc {
var = "baz"
engine "map" {
func {
var0 = "foo"
border = { 1, 1, 1, 1 }
var1 = "foobar"
}
}
}
... # more functions like 'mainfunc'
I tried
sed '/engine/,/^\s\s}$/d' file
but removes every engine function, I just need the one containing "foobar", maybe a pattern match everything even newlines until foobar something like this:
sed '/engine(.*)foobar/,/^\s\s}$/d' file
Is it possible?
Try:
sed '/engine/{:a;N;/foobar/{N;N;d};/ }/b;ba}' filename
or:
awk '/engine/{c=1}c{b=b?b"\n"$0:$0;if(/{/)a++;if(/}/)a--;if(!a){if(b!~/foobar/)print b;c=0;b="";next}}!c' filename
I would simple count the numbers of open / close brackets when you match engine "map", cannot say if this only works in gawk
awk '
/^[ \t]*engine "map"/ {
ship=1; # ship is used as a boolean
b=0 # The factor between open / close brackets
}
ship {
b += split($0, tmp, "{"); # Count numbers of { in line
b -= split($0, tmp, "}"); # Count numbers of } in line
# If open / close brackets are equal the function ends
if(b==0) {
ship = 0;
}
# Ship the rest (printing)
next;
}
1 # Print line
' file
Split returns the number of matches: split(string, array [, fieldsep [, seps ] ]):
Divide
string into pieces defined by fieldpat
and store the pieces in array and the separator strings in the
seps array. The first piece is stored in
array[1], the second piece in array[2], and so
forth. The third argument, fieldpat, is
a regexp describing the fields in string (just as FPAT is
a regexp describing the fields in input records).
It may be either a regexp constant or a string.
If fieldpat is omitted, the value of FPAT is used.
patsplit() returns the number of elements created.

Using loops to go through string and check char as a dict key

so I want to kind of build a "Decrypter", I have a dictionary with the keys being the symbol, and the value the respective value for the symbol, then I have this string that the code is suppose to look into, the translate will be saved in a other string, in this case called output. This is the way I did the loop part, but is not working:
var outputText = " "
for character in textForScan{
for key in gematriaToLetters{
if (gematriaToLetters.keys == textForScan[character]){
outputText.insert(gematriaToLetters.values, atIndex: outputText.endIndex)
}
}
}
You could also consider using map:
let outputText = "".join(map(textForScan) { gematriaToLetters[String($0)] ?? String($0) })
If you don't specify a specific letter in the dictionary it returns the current letter without "converting".
I think you are looking for something like this:
for aCharacter in textForScan {
let newChar = gematrialToLetters["\(aCharacter)"]
outputText += newChar
}
print(outputText)

Joining two strings by matching positions of alphabet in both strings in Perl

I am trying to write a Perl script where a string get fragmented at every occurrence of 'E' and when user enters positions of 'C' through command line (say 3-8 or 3-8,13-18 or any comma separated such positions of 'C' according to the string in such format if the string is long), the fragments containing 'C' (say at 3 and 8 positions) should be joined and shown in the output. Suppose string is
"ABCDEABCDEABCDEABCDEABCDE" and user enters 3-8 then program oputput should be-
ABCDEABCDE
ABCDE
ABCDE
ABCDE
I wrote a script where user enters 'C' positions through command line and string get cut at every position of 'E' but after that I'm not able to write it properly. Please help!
Code (edited) that I've written so far is:
use strict;
use warnings;
my $s = 'ABCDEABCDEABCDEABCDEABCDE';
my $i=0;
my #where;
my #array;
my #bond;
my #pos;
my #s_array;
my #s_array2;
for ($i=0; $i<=4; $i++) {
$where[$i] = index($s,"C",$where[$i-1])+1;
push(#array,$where[$i]);
}
print "All Positions of C: #array\n\n";
print "Enter C positions:\n";
my #join_C = <STDIN>;
foreach (#join_C) {
#bond = split (',',$_);
}
foreach (#bond) {
#pos = split ('-', $_);
}
print "entered C positions:#pos\n";
print "Resulting disulfide linked peptides\n\n";
my #a = split(/E/, $s);
my $result = join ("E,", #a);
my #final = split(/,/, $result);
foreach my $final (#final) {
foreach my $pos(#pos) {
my #source = split //, $final[#final];
my $length = #source;
for ($i=0; $i<=$length; $i++) {
if (index($final[$i], "C") == $pos[$i]) {
push (#s_array, $final[$i]);
}
else {
push (#s_array2, $final[$i]);
}
}
}
}
my $lastly_joined = join (',', #s_array);
print "Joined Fragments= #s_array\n";
print "Remaining fragments= #s_array2\n";
I will try to understand what you want to do.
I am trying to write a Perl script where a string get fragmented at every
occurrence of 'E'
Okay, first create the input. Lets use an array to make access to the
elements easier.
my #s = split ('', 'ABCDE' x 5);
I'm not sure how that string will look in your case. Can you please provide an
real world example.
and when user enters c_pos of 'C' through command line (say 3-8
or 3-8,13-18 or any comma separated such c_pos of 'C' according to
the string in such format if the string is long)
I would suggest to use commandline arguments. That makes it easier to use the
script later in a chain with other tools. Pass the arguments to the script:
script.pl 3-8,13-18
So we get a list of pairs:
my #pairs = split (',', join('', #ARGV));
Now you should check that the passed values point to 'C's. Valid combinations
are stored in a hash where the key is the start index and the value is the end
index.
my %c_pos;
foreach my $pair (#pairs) {
my ($from, $to) = split('-', $pair);
if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
$c_pos{$from-1} = $to-1;
} else {
warn "position ${from}-${to} not valid => ignored!\n";
}
}
the fragments containing 'C' (say at 3 and 8 positions) should be joined
and shown in the output.
Now we can iterate on the elements of #s. When we hit a start index
a 'connecion' starts and this connection is active until the end is
reached.
We store all values to the current entry.
When we hit an 'E' and we are not in a 'connection' the current entry is
pushed to our result and we start with the next empty entry.
for (my $i=0; $i<#string; $i++) {
if ($c_pos{$i}) {
$inside_connection = 1;
$end = $c_pos{$i};
} elsif ($i == $end) {
$inside_connection = 0;
$end = 0;
}
$entry.=$string[$i];
if ($inside_connection) {
# do not split on 'E'
} elsif ($string[$i] eq 'E') {
# split on 'E'
push #result, $entry;
$entry = '';
}
}
Because I do not know better I assumed that a chaind connection like
3-8, 8-13 will cause that it works like you would have said 3-13. Hope
that fits. Here is the complete script:
use strict;
use warnings;
my #string = split ('', 'ABCDE' x 5);
my #pairs = split (',', join('', #ARGV));
my %c_pos;
foreach my $pair (#pairs) {
my ($from, $to) = split('-', $pair);
if (($string[$from-1] eq 'C') && ($string[$to-1] eq 'C')) {
$c_pos{$from-1} = $to-1;
} else {
warn "position ${from}-${to} not valid => ignored!\n";
}
}
my #result;
my $entry = '';
my $inside_connection = 0;
my $end=0;
for (my $i=0; $i<#string; $i++) {
if ($c_pos{$i}) {
$inside_connection = 1;
$end = $c_pos{$i};
} elsif ($i == $end) {
$inside_connection = 0;
$end = 0;
}
$entry.=$string[$i];
if ($inside_connection) {
# do not split on 'E'
} elsif ($string[$i] eq 'E') {
# split on 'E'
push #result, $entry;
$entry = '';
}
}
print join ("\n", #result);

Resources