I have basically something such as :
var escape = function ( x ) {
if ( ! x ) return '\\N';
return '"' + x.replace( /\r\n/g, '\n' ) + '"';
};
array.forEach( function ( item ) {
process.stdout.write( 'foo:' + [ a, b, d ].map( escape ).join( '\t' ) + '\n' );
item.child.forEach( function ( sub ) {
process.stdout.write( 'bar:' + [ e, f, g ].map( escape ).join( '\t' ) + '\n' );
} );
} );
However, the output file contains, at apparently random locations, strings such as :
bar:\N "1981258" "Can't Get N^#^#^#^#^#^#^#^#^#^#Her Bones In Thefoo:"1981259" "164264"
bar:\N ^# Left" \N \N
bar:^#^#^# \N
It does not make sense for me, since the program should not be able to print anything without wrapping it into double quotes.
I think it's a Node.js bug, due to this line, but I just want to know if there is a workaround.
b^#^#^#^#^#^#^#^#^#x 1 root root 1,5G 17 d\303\251c. 19:14 /D/Release.cs
You don't have to escape crlf sequences.
$ node
> var crlf = '\n';
undefined
> process.stdout.write( 'foo:' + crlf + 'bar:');
foo:
bar:true
> process.stdout.write( 'foo:' + crlf + 'bar:' + crlf + '\\n' + 'foobar?');
foo:
bar:
\nfoobar?true
>
(The "true" at the end of both line is the return value from process.stdout.write in the REPL)
That said, could you post a gist with a sample input and more code (I don't know what a, b, d, e, f, g,... refer to).
Also, depending on your input (and seeing your output), it may make more sense for you to use Buffers instead of raw strings.
It was probably an issue related to the filesystem were the file was wrote (vmhgfs). The second generated file did not have this garbage.
Related
I am new to Perl and I'm trying to create a simple calculator program, but the rules are different from normal maths. All operations have the same power and the math problem must be solved from left to right.
Here is an example:
123 - 10 + 4 * 10 = ((123 - 10) + 4) * 10 = 1170
8 * 7 / 3 + 2 = ((8 * 7) / 3) + 2 = 20.666
So in the first case the user needs to enter one string: 123 - 10 + 4 * 10.
How do i approach this task?
I'm sorry if it's too much of a general question, but i'm not sure how to even begin. Do i need a counter? Like - every second character of the string is an operator, while the two on the sides are digits.
I'm afraid I'm lazy so I'll parse with a regex and process as I parse.
#!/usr/bin/env perl
#use Data::Dumper;
use Params::Validate (':all');
use 5.01800;
use warnings;
my $string=q{123 - 10 + 4 * 10};
my $result;
sub fee {
my ($a)=validate_pos(#_,{ type=>SCALAR });
#warn Data::Dumper->Dump([\$a],[qw(*a)]),' ';
$result=$a;
};
sub fi {
my ($op,$b)=validate_pos(#_,{ type=>SCALAR},{ type=>SCALAR });
#warn Data::Dumper->Dump([\$op,\$b],[qw(*op *b)]),' ';
$result = $op eq '+' ? $result+$b :
$op eq '-' ? $result-$b :
$op eq '*' ? $result*$b :
$op eq '/' ? $result/$b :
undef;
#warn Data::Dumper->Dump([\$result],[qw(*result)]),' ';
};
$string=~ m{^(\d+)(?{ fee($1) })(?:(?: *([-+/*]) *)(\d+)(?{ fi($2,$3) }))*$};
say $result;
Note the use of (?{...}) 1
To be clear, you are not looking for a regular calculator. You are looking for a calculator that bends the rules of math.
What you want is to extract the operands and operators, then handle them 3 at the time, with the first one being the rolling "sum", the second an operator and the third an operand.
A simple way to handle it is to just eval the strings. But since eval is a dangerous operation, we need to de-taint the input. We do this with a regex match: /\d+|[+\-*\/]+/g. This matches either 1 or more + digits \d or |, 1 or more + of either +-*/. And we do this match as many times as we can /g.
use strict;
use warnings;
use feature 'say';
while (<>) { # while we get input
my ($main, #ops) = /\d+|[+\-*\/]+/g; # extract the ops
while (#ops) { # while the list is not empty
$main = calc($main, splice #ops, 0, 2); # take 2 items off the list and process
}
say $main; # print result
}
sub calc {
eval "#_"; # simply eval a string of 3 ops, e.g. eval("1 + 2")
}
You may wish to add some input checking, to count the args and make sure they are the correct number.
A more sensible solution is to use a calling table, using the operator as the key from a hash of subs designed to handle each math operation:
sub calc {
my %proc = (
"+" => sub { $_[0] + $_[1] },
"-" => sub { $_[0] - $_[1] },
"/" => sub { $_[0] / $_[1] },
"*" => sub { $_[0] * $_[1] }
);
return $proc{$_[1]}($_[0], $_[2]);
}
As long as the middle argument is an operator, this will perform the required operation without the need for eval. This will also allow you to add other math operations that you might want for the future.
Just to read raw input from the user you would simply read the STDIN file handle.
$input = <STDIN>;
This will give you a string, say "123 + 234 - 345" which will have a end of line marker. You can remove this safely with the chomp command.
After that you will want to parse your string to get your appropriate variables. You can brute force this with a stream scanner that looks at each character as you read it and processes it accordingly. For example:
#input = split //, $input;
for $ch (#input) {
if ($ch > 0 and $ch <= 9) {
$tVal = ($tVal * 10) + $ch;
} elsif ($ch eq " ") {
$newVal = $oldVal
} elsif ($ch eq "+") {
# Do addition stuff
}...
}
Another approach would be to split it into words so you can just deal with whole terms.
#input = split /\s+/, $input;
Instead of a stream of characters, as you process the array values will be 123, +, 234, -, and 345...
Hope this points you in the right direction...
I am looking for a way to read numerical expressions in Fortran.
With numerical expression I mean dsqrt(0.5d0)/3.d0+1.d0 or something rather then the translated 1.235... real version.
With reading I mean
open(unit=UnitNumber,file="FileName")
read(UnitNumber, *) ....
I try to define in the reading statement the format, for instanceread(unitNumber,"(15F24.17)") but it does not help. I am
I am wondering if I can do it only internally, defining real(8), parameter :: dsqrt(0.5d0)/3.d0+1.d0 .
Maybe the use of FORMAT syntax could help?
As suggested by #agentp, interpreted languages like Python and Julia can parse a string directly as a piece of code, so utilizing such a feature may be convenient for your purpose. But if you definitely need to achieve the same goal in Fortran, another approach (with least effort!) may be simply to call eval() in such languages, for example:
module util
use iso_fortran_env, only: dp => real64
implicit none
contains
subroutine eval( expr, ans, x, y )
character(*), intent(in) :: expr
real(dp), intent(out) :: ans
real(dp), intent(in), optional :: x, y
character(len(expr)+200) cmd, sx, sy
integer u
sx = "" ; sy = ""
if ( present(x) ) write( sx, "(' x = ', es25.15, ' ; ')" ) x
if ( present(y) ) write( sy, "(' y = ', es25.15, ' ; ')" ) y
write( cmd, "(a)" ) &
"python -c ""from __future__ import print_function, division ; " // &
"from math import * ; " // trim(sx) // trim(sy) // &
"print( eval( '" // trim(expr) // "' ))"" > tmp.dat"
call system( trim( cmd ) )
open( newunit=u, file="tmp.dat", status="old" )
read( u, * ) ans
close( u )
call system( "rm -f tmp.dat" )
end subroutine
end module
program main
use util, only: dp, eval
implicit none
character(200) str
real(dp) ans
str = "sqrt( 2.0 ) + 1000.0"
call eval( str, ans )
print *, "ans = ", ans
str = "acos( x ) + 2000.0"
call eval( str, ans, x= -1.0_dp )
print *, "ans = ", ans
str = "10 * x + y"
call eval( str, ans, x= 1.0_dp, y= 2.0_dp )
print *, "ans = ", ans
end program
Results:
$ gfortran test.f90 # gfortran >=5 is recommended
$ ./a.out
ans = 1001.4142135623731
ans = 2003.1415926535899
ans = 12.000000000000000
More specifically, the above code simply invokes the built-in eval() function in Python via system(). But it is not very efficient because the resulting value is once written to an external file (and also the overhead to call Python itself). So if efficiency matters, it may be better to use more specific 3rd-party libraries, or for handiness, work with interpreted languages directly. (I suggest the latter approach if the calculation is not too demanding, because it saves much time for coding...)
Python:
from __future__ import print_function, division
from math import *
str = input( "Input an expression: " )
x = 1.0
y = 2.0
print( eval( str ) ) # if you type "x + 10 * y" in the prompt, you get 21
Julia:
println( "Input an expression: " )
str = readline()
x = 1.0
y = 2.0
println( eval( parse( str ) ) )
[ EDIT ]
If it is OK to use system() and write external files, another option may be to simply write a small Fortran code that contains the expression to be evaluated, compile and run it via system(), get the result via an external file. For example, if we replace the two lines in the above code (write( cmd, "(a)" ) ... and system( trim( cmd ) )) by the following, it gives the same result. This might be useful if we want to keep the code entirely written in Fortran, with minimal effort for modification.
open( newunit=u, file="tmp.f90" )
write( u, "(a)" ) "implicit none"
write( u, "(a)" ) "real :: x, y"
write( u, "(a)" ) trim(sx)
write( u, "(a)" ) trim(sy)
write( u, "(a)" ) "write(*,'(e30.20)') " // trim(expr)
write( u, "(a)" ) "end"
close( u )
call system( "gfortran -fdefault-real-8 -ffree-line-length-none tmp.f90 && ./a.out > tmp.dat" )
! Assuming bash on Linux or Mac (x86_64).
! -fdefault-real-8 is attached to promote 1.0 etc to 8-byte floating-point values.
call system( "rm -f tmp.f90" )
For the record, the library fparser allows you to do precisely what you asked for: evaluate a string as a mathematical expression within Fortran, without requiring any other programming languages.
No, there is nothing like this built in Fortran or any related programming languages. There are specific libraries for similar purposes (not necessarily too many in Fortran).
It is not clear at all to me why do you want that and how do you intend to use such an expression. It would have to be some specific type and you would need specific subroutines to evaluate such an expression.
I have a need to convert log messages into JSON, so I decided to write a groovy script to try and accomplish the task. The log messages look like:
InvoiceAdjustment{invoiceAdjustmentId=null, invoiceAdjustmentType='REFUND', invoiceId=20231189, currencyCode='USD', shippingRefundAmount=0.00, shippingRefundAmountUsd=0.00, taxTariffRefundAmount=0.00, taxTariffRefundAmountUsd=0.00, salesTaxTotalRefundAmount=0.00, salesTaxTotalRefundAmountUsd=0.00, vatRefundAmount=0.00, vatRefundAmountUsd=0.00, invoiceAdjustmentItems=[InvoiceAdjustmentItem{invoiceAdjustmentItemId=null, invoiceLineItemId=411729, refundAmount=3.82, refundAmountUsd=3.82, salesTaxRefundAmount=0.00, salesTaxRefundAmountUsd=0.00, returnQuantityExpected=0, returnQuantityActual=0, keptEnrolled=false, cancelShip=true, cancellationSuccessful=true, reshipQuantity=0, relativeLineNumber=4, sku='NTN-CHCK-339CV-NS163880', created=null, createdBy=null}], billingType='BRAINTREE', externalTransactionId='c3rvz7bv', refundTransactionId='null', reason='WAREHOUSE_CANCELLED', reshipmentInvoiceId=null, created=null, createdBy=null, refundedOn=null, notes='Cancelled by warehouse', createdByName='null', createdByEmail='null'}
When iterating through these (using String... args) it appears all single quotes (which I want to key off to know if a field is a string) are gone! For example, the SKU field which is surrounded with single quotes in the input, prints as "sku=NTN-CHCK-339CV-NS163880," -- no quotes!
Is there a way to keep the single quotes from the input so I can replace them in my script?
Here is the script in its entirety:
class LogToJson
{
static void main( String... args )
{
if ( args.length == 0 )
{
println( "Error, you must provide a string." )
}
StringBuilder jsonBuilder = new StringBuilder()
for ( String token : args )
{
if ( token.contains( "{" ) )
{
token = token.contains( "[" ) ? "\"" + token.substring( 0, token.indexOf( '[' ) - 1 ) + "\"=[{"
: "" +
"{\"" + token.substring( token.indexOf( "{" ) + 1, token.indexOf( "=" ) ) + "\"" + token.substring( token.indexOf( "=" ) )
}
else if ( token.contains( '=' ) )
{
token = "\"" + token.substring( 0, token.indexOf( '=' ) ) + "\"" + token.substring( token.indexOf( '=' ) )
}
token = token.replaceAll( '=', ':' ).replaceAll( "\'", "\"" )
jsonBuilder.append( token + ' ' )
}
println( jsonBuilder.toString() )
}
}
Edited to add: It appears if I escape all the single quotes in the input (i.e. replace ' with \' before using it as input) the script works as expected. Ideally, I'd rather not have to do this.
I am trying to create a way in UltiSnip to take a list of variable names and transform them into a line delimited list of strings (like
you would see in AngularJS). So you type each arg, jump to next placeholder, and above the function is filled in with what you want.
Start with this:
function(FirstArg, SecondArg, ThirdArg)
Hit the CTRL-J (next placeholder)
And Final Result:
[
'FirstArg',
'SecondArg',
'ThridArg',
function(FirstArg, SecondArg, ThirdArg) {
// ... cursor here after hitting CTRL-J
// this would be $0
}
]
Any hints would be great!
Simpler then I thought. This is the function
global !p
def varDeps(args):
result = ""
argList = args.split(",")
for arg in argList:
dep = " " + "'" + arg.strip() + "',\n"
result = result + dep
return result.rstrip()
endglobal
Then use something like this (where this is the third placeholder)
`!p snip.rv = varDeps(t[3])`
function($scope, ${3:deps}) {
//....
}
I'm looking for a boolean interpolation character for string.format(as the title says).
I want something that will work this way:
print(string.format("nil == false: %b",(nil==false))
%b is just a placeholder, you'll get an error with that. I'm looking for 'b'. I can't
just do:
print("nil == false: " .. (nil==false))
because booleans can't be concatenated with strings. I could do:
val=(nil==false)
if val==false then truth="false" else truth="true" end
print("nil==false: ".. truth)
But it's too much work.
If you're wondering how to modify string.format so it supports bools, here's one way you can do it:
do
local format = string.format
function string.format(str, ...)
local args = {...}
local boolargs = {}
str = str:gsub("%%b", "%%%%b")
for i = #args, 1, -1 do
if type(args[i]) == "boolean" then
table.insert(boolargs, 1, args[i])
table.remove(args, i)
end
end
str = format(str, unpack(args))
local j = 0
return (str:gsub("%%b", function(spec) j = j + 1; return tostring(boolargs[j]) end))
end
end
print(string.format("%s is %b", "nil == false", nil==false))
It might be a bit confusing to follow. The idea is to gsub all "%b" in the string and replace it with double escape %%b so format doesn't try to interpret it. We let string.format do its stuff and we take the result and handle %b manually ourselves.
Well, first you should try reading the relevant section of the manual. That will let you discover that there is no format specifier for booleans.
What greatwolf suggests is a solution, i.e. converting the value explicitly to a string. If there is a possibility that your truth value may be nil, but you want to output it as false, this trick is useful:
truth = nil
print("nil==false: ".. tostring( not not truth ))
In this way both nil and false will be displayed as false.
Edit (to answer a comment)
In Lua 5.2 the %s specifier automatically convert the arguments to strings using tostring internally. Thus:
print( string.format( "%s %s %s", true, nil, {} ) )
prints:
true nil table: 00462400
otherwise you can create your own formatting function wrapping string.format:
local function myformat( fmt, ... )
local buf = {}
for i = 1, select( '#', ... ) do
local a = select( i, ... )
if type( a ) ~= 'string' and type( a ) ~= 'number' then
a = tostring( a )
end
buf[i] = a
end
return string.format( fmt, unpack( buf ) )
end
print( myformat( "%s %s %s", true, nil, {} ) )