We are working on a project where we are translating javaScript code into python. Everything is going pretty smoothly, except for this one line of code that has given us errors on multiple translations:
"primes" is an empty array BTW.
JavaScript:
var primes = [];
if(primes[primes.length - 1] > 3){...}
Python:
primes = []
if primes[len(primes) - 1] > 3:
......
This code works in javascript, however in Python we get an error. It seems as though we are trying to access an index of the list that doesn't exist.
This is the error:
TypeError: object of type 'int' has no len()
Does anyone have a workaround?
Python hasn't a safe get so you should change your code this way:
primes = []
if primes and primes[len(primes) - 1] > 3:
...
Even better, to get the last of the list you can use primes[-1]
primes = []
if primes and primes[-1] > 3:
...
Related
I'm trying to develop a javascript code using opencv.js, I have python code with the same requirement, I converted many lines but some are very hard to find, please guide me.
last 3 lines from python code unable to find for javascript opencv.js.
def find_marker(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts) //these three line are unable to find for javascript.
c = max(cnts, key = cv2.contourArea)
return cv2.minAreaRect(c)
In the first line, the code is using the function in imutils python package. If you see the grab_contours method in imutils.convenience file located at https://github.com/jrosebr1/imutils/blob/master/imutils/convenience.py, you can see how it is implemented.
This is very simple to implement as a one liner in js.
cnts = (cnts.length == 2) ? cnts[0] : (cnts.length == 3) ? cnts[1] : cnts
In second line, max is the inbuilt function of python for iterating through an iterable and to find the maximum based on the key.
This same functionality can be achieved in js as follows
c = cnts.reduce(function(max, cur) {
// here key is the cv2.contourArea function,
// we apply that on the cnts[i] and finds the cnts[i]
// such that cv2.contourArea(cnts[i]) is maximum
if(cv2.contourArea(max) < cv2.countourArea(cur)) {
return cur
} else {
return max
}
});
Now for the third line I assume cv2.minAreaRect function is present in the js version too. I'm not sure though. But hope the above code works for you. Thank you.
I have a uncyclic directed graph, represented by a dictionnary (example {1: [2,3] , 2:[], 3: [4], 4:[]} ).
I want to find the size of the longest branch from a given source vertex, let say 1 for this example.
I wrote following javascript recursive function:
function computeLongest(graph, node){
if (graph[node].length === 0){
return 1;
}
else{
var l = [];
for (var i=0; i < graph[node].length; i++){
l.push(computeLongest(graph, graph[node][i]));
}
return 1+Math.max(l);
}
}
If I test this function with previous example, simple tree which looks like :
1
/ \
2 3
\
4
My result is 2 and not 3. It looks like my list l is beeing modified in the recursive calls of the function.
If I write the same function in Python, it works fine.
Are there any differences between Python and Javascript in the way we handle recursion and associated variables ? I don't understand why the behaviour is not the same.
Python code:
def c(graph, number):
if len(graph[number]) == 0:
return 1
l = []
for child in graph[number]:
l.append(c(graph, child))
return 1+max(l)
Your issue is probably from a difference in max implementation.
The max function in python doesn't behave like Math.max in javascript. If given an array, Python will find a way to get the maximum value out of it. Javascript will not. In javascript, the expected input is a list of arguments, e.g Math.max(1,4,3,2).
Ex:
Python
max([1,4,3,2]) # returns 4
Javascript
Math.max([1,4,3,2]) # returns NaN
In fact, I am surprised that your javascript code works.
Update
As stated in the comments, you may use the spread operator ... to use Math.max with an array and still, provide the expected input.
Math.max(...[1,4,3,2]) is equivalent to Math.max(1,4,3,2), hence Math.max(...l) will expand in Math.max(l[0], l[1]... l[N]).
I am working on a Django app. I need to pass back a few parameters from the server, which I do with this code:
num_periods = 25
num_traces = 2
opacities = [0.5, .99]
ys = [[1,2,3,4,5],[7,6,5,4,3]]
response = {'text' : request.POST['value'],
'num_periods' : num_periods,
'num_traces' : num_traces,
'opacity': opacities,
'ys': ys
}
return JsonResponse(response)
On the client side, in the Ajax callback, I have code that looks like this:
success : function(data) {
console.log('num traces = ' + data.num_traces);
console.log('opacitiees = ' + data.opacity);
console.log('data = ' + data.ys);
but, console.log(ys) gives data = 1,2,3,4,5,7,6,5,4,3, which looks flattened.
However, if I do console.log(ys[1]), it 'looks like' an array: 7,6,5,4,3, though with no brackets. So, JS is aware of the nested list structure.
But any attempt to get it into a list of lists of numbers fails. for example this code:
z=[]
z.push(ys[0])
z.push(ys[1])
gives me back z = 1,2,3,4,5,7,6,5,4,3 when I do console.log("z = " + z)
Something deeply confusing is happening here. I also tried Object.values(ys[0]), but still this does not give a list. Other ideas I have seen are a clever use of slice like so :
var ys=[];
while(list.length) ys.push(list.splice(0,5));
console.log("ys[0]="+ys[0]);
which gives
ys[0]=1,2,3,4,5,7,6,5,4,3
How do you take the JSON that was received from Python and get it to look like the basic list of lists that I clearly need? Stuffing '[' and ']' around things before assigning does no good...
What seems very confusing is that if I do a 'loopback' within Javascript by doing something like
var foo = JSON.parse(JSON.stringify( { 'ys' : [[1,2,3],[4,5,6]]))
then things look better: the type of foo.ys is now Array[ Array[5], Array[5] ]. But the type of what I am getting with the actual Python-JS transfer is just that list of numbers, with type 'Object'.
(1) use the development tools of your browser to see what is sent back and forth between the server and the browser (F12 on all browsers).
(2) you can use commas in console.log('ys=', ys);
I'd be very surprised if it isn't in fact a list of lists with the same values you sent.
The problem is that here it (implicitly) calls toString, which you can see doesn't put any square brackets around the array. That means it doesn't put brackets around smaller arrays either - so it looks like it's flat. To make it look like the object in your code, you can convert it to JSON:
JSON.stringify([[1, 2, 3], [4, 5, 6]])
will be
"[[1,2,3],[4,5,6]]"
which you can then log or do more with. (while [[1, 2, 3], [4, 5, 6]].toString() is "1,2,3,4,5,6"). All of your actual data structures are entirely as you expected, the problem is just in the step of turning them into strings for output - so you don't need to do any more processing on the variables themselves, until you need to represent them as strings.
I am trying to understand the relationship between C++ dll and JavaScript.
There is a js code:
cert = CERT_FindUserCertByUsage(certDB, certName.nickname,certUsageEmailSigner, true, null);
where cert is defined as
let cert = null;
However in C++, cert is a struct
CERTCertificateStr {
char *subjectName;
char *issuerName;
SECItem derCert; /* original DER for the cert */
.... }
I am trying to get the subject name in javascript and I continue the code with
let a = cert.contents.subjectName;
It is unsuccessful. It logs error as "cannot get content of undefined size"
Anything that i have missed in between C++ and javascript?
How can i print the subjectName in javascript?
I think you are doing jsctypes and you are on the right track. To get the js string though you have to tag on a readString() after casting it to an array with a certain length, its ok to go past the actual length as readString() will read up till the first null char which is \x00. Although if you know the exact length that's always best (you dont have to do the length + 1 for null term) because then you save memory as you dont have to unnecessarily allocate a buffer (array in jsctypes case) more then the length needed.
So try this:
let a = ctypes.cast(cert.contents.subjectName, ctypes.char.array(100).ptr).contents.readString();
console.log('a:', a);
The error cannot get contents of undefined size happens in situations like this:
var a = ctypes.voidptr_t(ctypes.char.array()('rawr'))
console.log('a:', a.contents);
this spits out
Error: cannot get contents of undefined size
So in order to fix that what we do is this:
var b = ctypes.cast(a, ctypes.char.array(5).ptr)
console.log('b:', b.contents);
and this succesfully accesses contents, it gives us (by the way, i used 5 for length which is 4 for the length of rawr + 1 for null terminator but i really didnt have to do that i could have used length of just 4)
CData { length: 5 }
so now we can read the contents as a js string like this:
console.log('b:', b.contents.readString());
and this spits out:
rawr
ALSO, you said the functions returns a struct, does it return a pointer to the struct? Or actually the struct? I would think it returns a pointer to the struct no? so in that case you would do this:
let certPtr = CERT_FindUserCertByUsage(certDB, certName.nickname,certUsageEmailSigner, true, null);
let certStruct = ctypes.StructType('CERTCertificateStr', [
{'subjectName': ctypes.char.ptr},
{issuerName: ctypes.char.ptr},
{derCert: ctypes.voidptr_t}
]);
let cert = ctypes.cast(certPtr, certStruct.ptr).contents;
let a = cert.contents.subjectName.readString();
Well, turns out camp_amount wasn't setup properly and returned "NaN"... Thanks anyway! You guys made me look past the array syntax, which turns out to be fine. Sometimes I just get a bit lost in code.
For use with highcharts I have the following array:
dashboardData = [[tableData[1], parseFloat(tableData[12])],[tableData[14], parseFloat(tableData[25])]];
I can literally just paste that as highcharts series data:
data: dashboardData
However, I need to build the array in a for loop because the length of the array will vary. So I need to build an array that ends up with the same structure as above, which would be something like:
0: Array[2]
0: "a string"
1: 312
1: Array[2]
0: "another string"
1: 1668
How do I build this up? I tried the following but it doesn't work...
var dashboardData = [];
for (var i = 1; i <= camp_amount.length; i++) {
dashboardData.push([tableData[i], tableData[i + 1]]);
}