Heap sort , about the implementation of method involving range - function

What does the -1, -1 in range(n, -1, -1) do, I have encountered this same pattern and implementation with various sorting algo, and it's confusing me so much. Any answers would be appreciated! thank you in advance - NewCoder
-SAMPLE CODE-
def build_max_heap(A):
n = len(A)
for i in range(n, -1,-1):
max_heapify(A,n, i)
for i in range(n-1,0,-1):
A[0],A[i]=A[i],A[0]
max_heapify(A,i,0)
A=[33,35,42,10,7,8,14,19,48]
build_max_heap(A)
print(A)

The signature for range is range(start, stop[, step]).
The range function in range(n, -1, -1) accept 3 argument:
'n' as the start index of the range object
the first '-1' as the end index of the range object
the second '-1' as the move step of the range object
So range(n, -1, -1) basic means construct a sequence of [n, n-1, ..., 1, 0].
For more you can refer to Python Doc

Related

Why one element of SubString Vector can not be tested into conditional evaluation if (Julia)?

I want to create a function in which, first, it filters one element of a dataframe in Julia. Second, it tests if the element is "missing". If the answer is rue, it return the value "0.0". My issue is that the control evaluation "if" does not work and I don t know why. If the element is "String" the control evaluation works, however, the element is a 1-element Vector{SubString{String}}: after filtering; thus, the control evaluation does not work. I would like to know why and it is possible to turn the vector element into a string object.
Note: "isequal", '==', '===' do not work either.
For example:
example_ped = DataFrame(animal = collect(1:1:11),
sire = [fill(0,5); fill(4,3); fill(5,3)],
dam = [fill(0,4); fill(2,4); fill(3,3)])
CSV.write("ped_example.txt",example_ped, header=true,delim='\t')
pedi = CSV.read("ped_example.txt",delim = '\t', header=true, missingstrings=["0"], DataFrame)
pedi[!,1]=strip.(string.(pedi[!,1]))
pedi[!,2]=strip.(string.(pedi[!,2]))
pedi[!,3]=strip.(string.(pedi[!,3]))
Part of the function
function computAddRel!(ped,animal_1,animal_2)
elder,recent = animal_1 < animal_2 ? (animal_1,animal_2) : (animal_2,animal_1)
sireOfrecent = ped.sire[ped.animal.==recent]
damOfrecent = ped[ped.animal.==recent,"dam"]
if elder==recent
f_inbreed = (sireOfrecent=="missing" || damOfrecent=="missing") ? 0.0 : 0.5*computAddRel!(ped,sireOfrecent,damOfrecent)
adiv = 1.0 + f_inbreed
return adiv
end
end
if the animal_1 and animal_2 are equal to 5
julia> sireOfrecent = pedi.sire[pedi.animal.==recent]
1-element Vector{Union{Missing, Int64}}:
missing
However, the control evaluation is false
julia> sireOfrecent=="missing"
false
julia> isequal(sireOfrecent,"missing")
false
Thank in advance for your time.
You should write:
ismissing(only(sireOfrecent))
The meaning of this:
only checks if you picked exactly one row (if not - you will get an error, as then there is ambiguity; if yes - you extract out the element from an array)
ismissing is a function that you should use to check if some value is missing.
Here are some examples:
julia> x = [missing]
1-element Vector{Missing}:
missing
julia> only(x)
missing
julia> ismissing(only(x))
true
julia> only([1, 2])
ERROR: ArgumentError: Collection has multiple elements, must contain exactly 1 element
julia> ismissing(only([1]))
false

Converting cell coordinates without using a column number to column letter method?

I'm trying to figure out what my options are here when I need to use a column number in a formula, and if I really need to write a column number to column letter method to accomplish what I'm trying to do.
See this method I have here:
createFormulas(lookupField, lookupColumns) {
// Iterate through the lookupColumn array
lookupColumns.forEach(value => {
let columnNumber = this.getColumn(this.headers, value);
let range = this.sheet.getRange(2, columnNumber, this.lastRow - 1, 1);
// range.setFormula('=$A2');
range.setFormula('=' + columnNumber + '2' ); // doesn't work obviously
})
}
I'm trying to add formulas in a column based on the column.
this.getColumn() returns the column number based on the column name being passed in.
let range sets the range I want to set the formula in
range.setFormula('=$A2') pastes this formula into range and updates the reference accordingly (i.e., $A3, $A4, etc.). This isn't the formula I ultimately want to use, just a simplified example.
I need to set the column in the reference dynamically, however.
What I have obviously won't work: range.setFormula('=' + columnNumber + '2' );. That would just result in something like 72 where 7 is the column number.
I know I can write a method that will convert the column number into a letter. I'm just surprised there isn't a built in method for doing that or some other native way of accomplishing this.
For example, in Excel VBA I think you can do something like "=" & Cells(2, columnNumber).Address or something like that (been a while, I could be wrong), which should equate to =A2, =A3, =A4, etc. in the range.
So before writing this column number to letter method, I just wanted to check: is that the only way to accomplish what I'm after or is there a native way of handling this that I'm just not seeing?
Actually, was able to do this using .getA1Notation().
Refactored to the following and it works as expected:
createFormulas(lookupField, lookupColumns) {
// Iterate through the lookupColumn array
lookupColumns.forEach(value => {
let columnNumber = this.getColumn(this.headers, value);
let formulaRange = this.sheet.getRange(2, columnNumber, this.lastRow - 1, 1);
let referenceRange = this.sheet.getRange(2, this.idColumn, this.lastRow - 1, 1);
formulaRange.setFormula("=" + referenceRange.getCell(1, 1).getA1Notation());
})
}
Column To Letters
I followed Yuri's path to the numbers to letter functions and I'm a bit baffled that we have forgotten that there are 26 letters in the alphabet and so after looking at the various functions at that reference none of them seem to have worked for me. So here's my replacement:
function colToletters(num) {
let a = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (num < 27) return a[num % a.length];
if (num > 26) {
num--;
let letters = '';
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters;
num = Math.floor(num / 26) - 1;
}
return letters;
}
}
This will calculate the column letters for 1 to 1000 and I check all the way to 703 where the letters go to AAA and they look good all the way.
Just in case. Based on https://stackoverflow.com/a/64456745/14265469
function numberToLetters(num) {
// num--; // if you need 1 --> A, 2 --> B, 26 --> Z
let letters = '';
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters;
num = (num - num % 26) / 26 - 1;
}
return letters;
}
console.log(numberToLetters(0)); // --> A
console.log(numberToLetters(25)); // --> Z
console.log(numberToLetters(26)); // --> AA

Is there a single Apps Script function equivalent to MATCH() with TRUE?

I need to write some functions that involve the same function as the Sheets function MATCH() with parameter 'sort type' set to TRUE or 1, so that a search for 35 in [10,20,30,40] will yield 2, the index of 30, the next lowest value to 35.
I know I can do this by looping over the array to search, and testing each value against my search value until a value greater than the search value is found, but it seems to me there must be a shorthand way of doing this. We don't have to do this when seeking an exact value; we can just use indexOf(). I was surprised when I first learned that indexOf() does not have a parameter for search type, but can only return a -1 if an exact value is not found.
Is there no function akin to indexOf() that will do this, or is it actually necessary to loop over the array every time you need to do this?
Probably you're looking for the array.find() method. The impelentation could be something like this:
var arr = [10,20,30,40]
// make a copy of the array, reverse it and do find with condition
var value = arr.slice().reverse().find(x => x < 35)
console.log(value) // output --> 30 (first element less than 35 in the reversed array)
var index = arr.indexOf(value)
console.log(index) // output --> 2 (index of the element in the original array)
https://www.w3schools.com/jsref/jsref_find.asp
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
There is another method array.findIndex(). Probably you can use it as well:
var arr = [10,20,30,40]
// find more or equal 35 and return previous index
var index = arr.findIndex(x => x >= 35) - 1
console.log(index) // output --> 2
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
Try this:
function lfunko(tgt = 35) {
Logger.log([10,20,30,40].reduce((a,c,i) => { a.r = (a.x >= c)? i:a.r;return a;},{x:tgt}).r)
}

OCTAVE: Checking existence of an element of a cell array

I am using Octave 4.0.0.
I define A{1, 1} = 'qwe', but when I check existence of A{1, 1}, as in
exist("A{1,1}")
or
exist("A{1,1}", "var")
it returns 0.
How can I check its existence?
To check if an array has element say 3, 5, you need to verify that the array has at least 3 rows and 5 columns:
all(size(A) >= [3, 5])
You can of course check if variable A exists at all before-hand, and also is a cell array. A complete solution might be something like
function b = is_element(name, varargin)
b = false;
if ~evalin(['exists("' name '")'], 'caller')
return;
end
if ~strcmp(evalin(['class(' name ')'], 'caller'), 'cell')
return;
end
if evalin(['ndim(' name ')'], 'caller') ~= nargin - 1
return;
end
b = all(evalin(['size(' name ')'], 'caller') >= cell2mat(varargin))
endfunction
This function accepts a variable name and the multi-dimensional index you are interested in. It returns 1 if the object exists as a cell array of sufficient dimensionality and size to contain the requested element.

Mathematica integrating over set of points to get analytical form of function

I have a following problem - I need to integrate such a function in Mathematica (I couldn't post an image, so I am writing it in latex form):
G(r)= \int_{0}^{\infty} dq f(q)*q*sin(qr)/r
To obtain function G(r) dependable on r.
Nevertheless I don't know the analytical form of f(q), instead I have set of values of f(q) and for q. So I'd like to make a some kind of numerical integration, but to receive not a value afterwards, but a curve of G(r).
In case you know the analytic form of the function f[q] you can do this :
Integrate[f[q] q Sin[q r]/r, {q, 0, Infinity}]
but in case of knowing only values of f[q] you can integrate numerically :
G[r_]:= NIntegrate[ f[q] q Sin[q r]/r, {q, 0, Infinity}]
Assume e.g.
f[q_] := Exp[-q]
Integrate[f[q] q Sin[q r]/r, {q, 0, Infinity}]
yields
ConditionalExpression[2/(1 + r^2)^2, Abs[Im[r]] < 1]
You can make an assumption a priori, e.g. :
Assuming[r > 0, Integrate[f[q] q Sin[q r]/r, {q, 0, Infinity}]]
yields
2/(1 + r^2)^2
Assuming r > 0 you implicitly assume r to be real, so Im[r] == 0.
Having the function G[r] we can plot the appropriate curve, defining f[q] as above :
Plot[ G[r], {r, 0, 10}]