How to evaluate without unnecessary parentheses in Julia? - julia

I have a case struct which holds an expression with the type of SymbolicUtils.Term{Bool}. Also I have defined rules from SymbolicUtils library which takes these cases as input and simplifies them. In order to simplify these cases the form should be like: (i == j) & (i == 3) & (j == 3) & (i == 3) & (j == 3) without unnecessary parentheses. For example it's not good to have this one: ((i == j) & ((i == 3) & (j == 3))) & ((i == 3) & (j == 3))
In order to solve this, I thought I can convert the expression with extra parentheses to string then I can process this string to get the desired form. I did this actually:
function reduce_parentheses(case::Case)
main_exp_string = ""
exp_to_str = repr(case.condition) #Convert case's condition into a string.
condition_list = split(exp_to_str, "&") #Split cases to subcases into a list.
for i in 1:length(condition_list) # Iterate cases list one by one.
stripped = lstrip(condition_list[i], [' ']) #Remove the whitespace at the beginning of the expression.
stripped = rstrip(stripped, [' ']) #Remove the whitespace at the end of the expression.
stripped = lstrip(stripped, ['(']) #Add opening parentheses at the beginning of the expression.
stripped = rstrip(stripped, [')']) #Add closing parentheses at the end of the expression.
#Get the desired form.
if i != 1
main_exp_string = main_exp_string * ' ' * '(' *stripped * ')'
elseif i == 1
main_exp_string = main_exp_string * '(' *stripped * ')'
end
if i != length(condition_list)
main_exp_string = main_exp_string * ' ' * '&'
end
end
println(main_exp_string)
exp = (Meta.parse(main_exp_string)) #Convert string back to an expression.
println(typeof(eval(exp))) #Convert expression back to SymbolicUtils.Term{Bool} type.
end
I can get the string in the desired form but when I try to turn it back into an expression I'm getting unnecessary parentheses with the different form because it's evaluating left to right I think.
Example:
The case with unnecessary parentheses: ((i == j) & ((i == 3) & (j == 3))) & ((i == 3) & (j == 3))
The processed string(desired form): (i == j) & (i == 3) & (j == 3) & (i == 3) & (j == 3)
Evaluated case: ((((i == j) & (i == 3)) & (j == 3)) & (i == 3)) & (j == 3)
How can I solve this? Maybe instead of converting it into a string can I do it in a smarter way?

Related

paste0 not printing the message inside else statement

I don't get any error but I was expecting that when I type an integer that is not 1,2,3,4 the code should enter in else statement and print what is in paste0 function. What is wrong?
escolha <- as.integer(readline(prompt="Enter your choice: "))
if(escolha == 1){
print("Cool you choose addition!")
} else if (escolha == 2) {
print("Cool, you choose subtraction!")
} else if (escolha == 3) {
print("Cool, you choose multiplication!")
} else if (escolha == 4){
print("Cool, you choose division!")
} else{
paste0("It's not possible to use ", escolha," as input.")
escolha<- as.integer(readline(prompt="Choose a valid number (1 a 4): "))
}
num1 <- as.double(readline(prompt="What is the first number? "))
num2 <- as.double(readline(prompt="What is the second number? "))
resultado <- switch (escolha, (num1+num2), (num1-num2), (num1*num2), (num1/num2))
cat("The result is: ", resultado)
paste0() (and paste()) assemble a string and return it. You still need to print the result to the screen with print() or cat(), like this:
cat(paste0("It's not possible to use ", escolha," as input.\n"))
(added the \n at the end, so the readline() prompt that follows will be on a separate line)

Julia: Console Input Validation

How do you guys handle console input validation? In C++, case/switch is my goto...
I was trying a recursive function but was getting locked in lower levels. Plus that might be overdoing it. I did manage a while loop with an "exclusive or" but, that is not really scalable.
function prob6()
println("Pick a number; any number:")
x = readline(stdin)
y = parse(Int64, x)
z = 0
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
while xor((p2 == 1), (p2 == 2)) == false
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
end
if select == 1
for i in 1:y
print("$i ")
z = z + i
end
else
z = 1
for i in 1:y
print("$i ")
z = z * i
end
end
println(z)
end
Any alternatives?
There are many ways. I usually create a validation loop to check the type of the input item, and will use tryparse instead of parse, since it will not throw an error if input is malformed:
function queryprompt(query, typ)
while true
print(query, ": ")
choice = uppercase(strip(readline(stdin)))
if (ret = tryparse(typ, choice)) != nothing
return ret
end
println()
end
end
n = queryprompt("Integer please", Int64)
println(n)
x = queryprompt("Float please", Float64)
println(x)

Expected type 'int' but returned type 'NoneType'."

I have to write a python function that takes two single-line strings as inputs and returns the index where the first difference between the two occurs (and a negative number in the case they're identical). This is the code I wrote so far:
def singleline_diff(line1, line2):
len1 = len(line1)
len2 = len(line2)
if len1 < len2:
min_len = len1
elif len1 > len2:
min_len = len2
else:
min_len = len1
indx1 = 0
indx2 = 0
if line1 == line2:
return IDENTICAL
elif line1 != line2:
if min_len == len1:
for word2 in line2:
word2 = line2 [indx2]
indx2 = indx2+1
if word2 not in line1:
diff_idx_2 = int(indx2)
print (diff_idx_2)
elif min_len == len2:
for word1 in line1:
word1 = line1 [indx1]
indx1=indx1+1
if word1 not in line2:
diff_idx_1 = int(indx1)
print (diff_idx_1)
In the event that line1 != line2, your code prints the integer to the console instead of returning the value, which is what it should be doing according to the documentation. Try return diff_idx_2 instead of print(diff_idx_2) (and the same for diff_idx_1).
def singleline_diff(line1, line2):
min_len = min(len(line1), len(line2))
for i in range(min_len):
if line1[i] != line2[i]:
return i
if min_len == len(line1) and min_len == len(line2):
return -1 # they're identical
return min_len # one of the two lines has terminated, hence they differ

function to convert amount into Indian words (Crores, Lakhs, Thousands ...) in R language

I need a function in R language to convert amount into Indian words in crore, lakh, thousand etc...
For example:
function(3257) should generate: Three Thousand Two Hundred and Fifty Seven;
function(473257) should generate: Four Lakh Seventy Three Thousand Two Hundred and Fifty Seven;
function(12473257) should generate: One Crore Twenty Four Lakh Seventy Three Thousand Two Hundred and Fifty Seven
Plenty of working VBA functions can be found on the internet for use with Microsoft Excel and Access but I was unable to find a similar function in R language.
Edit: Example how to do it in English words: https://github.com/ateucher/useful_code/blob/master/R/numbers2words.r
Seems that I have figured it out myself. Interested users may test and report bugs, if any.
# function to convert number to words in Indian counting system
# https://en.wikipedia.org/wiki/Indian_numbering_system#Names_of_numbers
# number always rounded; multiple numbers also accepted as vector
# currently handles numbers upto 15 digits but can be easily extended
# Credit: A big THANKS to Mr. John Fox.
# His function to convert number to English words can be found at:
# http://tolstoy.newcastle.edu.au/R/help/05/04/2715.html
SpellIndianNumber <- function(x){
helper <- function(x){
digits <- rev(strsplit(as.character(x), "")[[1]])
nDigits <- length(digits)
# function meant to handle numbers upto 15 digits only
if(nDigits > 15) stop("Number is too large!")
# single digit cases: 1 to 9
if (nDigits == 1) as.vector(ones[digits])
# two digits cases: 10 to 99
else if (nDigits == 2)
if (x <= 19) as.vector(teens[digits[1]]) # for 10 to 19
else trim(paste(tens[digits[2]], # for 20 to 99
Recall(as.numeric(digits[1]))))
# three digits cases: 100 to 999
else if (nDigits == 3) trim(paste(ones[digits[3]], "Hundred",
Recall(makeNumber(digits[2:1]))))
# four & five digits cases: handling thousands
else if (nDigits <= 5){
thousands <- x %/% 1e3
remainder <- x %% 1e3
trim(paste(Recall(thousands), "Thousand", Recall(remainder)))
}
# six & seven digits cases: handling lakhs
else if (nDigits <= 7){
lakhs <- x %/% 1e5
remainder <- x %% 1e5
trim(paste(Recall(lakhs), "Lakh", Recall(remainder)))
}
# eight & nine digits cases: handling crores
else if (nDigits <= 9){
crores <- x %/% 1e7
remainder <- x %% 1e7
trim(paste(Recall(crores), "Crore", Recall(remainder)))
}
# ten & eleven digits cases: handling arabs
else if (nDigits <= 11){
arabs <- x %/% 1e9
remainder <- x %% 1e9
trim(paste(Recall(arabs), "Arab", Recall(remainder)))
}
# twelve & thirteen digits cases: handling kharabs
else if (nDigits <= 13){
kharabs <- x %/% 1e11
remainder <- x %% 1e11
trim(paste(Recall(kharabs), "Kharab", Recall(remainder)))
}
# fourteen & fifteen digits cases: handling neels
else if (nDigits <= 15){
neels <- x %/% 1e13
remainder <- x %% 1e13
trim(paste(Recall(neels), "Neel", Recall(remainder)))
}
}
trim <- function(text){
gsub("^\ ", "", gsub("\ *$", "", text))
}
makeNumber <- function(...) as.numeric(paste(..., collapse=""))
opts <- options(scipen=100)
on.exit(options(opts))
ones <- c("", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine")
names(ones) <- 0:9
teens <- c("Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen",
"Sixteen", " Seventeen", "Eighteen", "Nineteen")
names(teens) <- 0:9
tens <- c("Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety")
names(tens) <- 2:9
x <- round(x)
if (length(x) > 1) return(sapply(x, helper))
helper(x)
}
# Examples:
# > SpellIndianNumber(83720834)
# [1] "Eight Crore Thirty Seven Lakh Twenty Thousand Eight Hundred Thirty Four"
# > SpellIndianNumber(1283720834)
# [1] "One Arab Twenty Eight Crore Thirty Seven Lakh Twenty Thousand Eight Hundred Thirty Four"
# > SpellIndianNumber(653234532342345)
# [1] "Sixty Five Neel Thirty Two Kharab Thirty Four Arab Fifty Three Crore Twenty Three Lakh Forty Two Thousand Three Hundred Forty Five"
# > SpellIndianNumber(c(5,10,87))
# [1] "Five" "Ten" "Eighty Seven"
# > SpellIndianNumber(11:15)
# [1] "Eleven" "Twelve" "Thirteen" "Fourteen" "Fifteen"
# Number Zero will appear as a zero length string
# > SpellIndianNumber(0)
# [1] ""
# > SpellIndianNumber(c(12,0,87))
# [1] "Twelve" "" "Eighty Seven"
Function to Convert Amount in Number to Digits in Indian Standard upto 12 digits
function GetAmountInWords(Amount) {
var nums = parseFloat(Amount).toFixed(2).toString().split('.');
var AmountInWords = '';
if (nums.length > 0 && parseInt(nums[0]) > 0) {
AmountInWords += ReturnAmountInWords(nums[0]) + 'Rupees '
}
if (nums.length == 2 && parseInt(nums[1]) > 0) {
var Paisa = ReturnAmountInWords(nums[1]);
AmountInWords += ((AmountInWords.trim().length > 0) ? 'and ' : '') + Paisa + 'Paisa ';
}
return (AmountInWords.length > 0) ? AmountInWords + 'Only.' : '';
}
var a = ['', 'One ', 'Two ', 'Three ', 'Four ', 'Five ', 'Six ', 'Seven ', 'Eight ', 'Nine ', 'Ten ', 'Eleven ', 'Twelve ', 'Thirteen ', 'Fourteen ', 'Fifteen ', 'Sixteen ', 'Seventeen ', 'Eighteen ', 'Nineteen '];
var b = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
function ReturnAmountInWords(num) {
if ((num = num.toString()).length > 12) return 'overflow';
n = ('000000000000' + num).substr(-12).match(/^(\d{2})(\d{1})(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
if (!n) return;
var AmountStr = '';
AmountStr += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'Thousand ' : '';
AmountStr += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'Hundred ' : '';
AmountStr += (n[1] != 0 || n[2] != 0 || n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'Crore ' : '';
AmountStr += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'Lakh ' : '';
AmountStr += (n[5] != 0) ? (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) + 'Thousand ' : '';
AmountStr += (n[6] != 0) ? (a[Number(n[6])] || b[n[6][0]] + ' ' + a[n[6][1]]) + 'Hundred ' : '';
AmountStr += (n[7] != 0) ? ((AmountStr != '') ? 'and ' : '') + (a[Number(n[7])] || b[n[7][0]] + ' ' + a[n[7][1]]) + '' : '';
return AmountStr;
}

Should Generic URL Decoding Functions Handle "+" Chars or Just "%20" etc. Chars?

I am wondering if a generic URL Decoding function should handle the "+" character (space) in addition to all of the e.g. "%20" etc. encodings?
There is no specific use case as of yet.
Is there any spec that would be appropriate to reference here?
I am doing it in VBScript (but that is not relevant to my question I believe) and I have two versions, one which would handle the "+" by replacing it with a "" (space) ...
Public Function decode(s)
s = replace(s, "+", " ")
For i = 1 To Len(s)
If Mid(s, i, 1) = "%" Then
decode = decode & Chr("&H" & Mid(s, i+1, 2))
i = i + 2
Else
decode = decode & Mid(s, i, 1)
End If
Next
End Function
...and one which does not:
Public Function decode(s)
For i = 1 To Len(s)
If Mid(s, i, 1) = "%" Then
decode = decode & Chr("&H" & Mid(s, i+1, 2))
i = i + 2
Else
decode = decode & Mid(s, i, 1)
End If
Next
End Function
If it's supposed to be generic: no. The role of "+" is very specific to HTML forms and has nothing to do with generic URI handling.

Resources