Ruby array sort without changing position of nils - arrays
I am working with an array of arrays. I need to sort the rows, and the sort criteria is the value of each column (starting with the 2nd column) successively from left to right. Nil values must be pushed to the bottom. Once pushed to the bottom, I need to leave nil columns as they are without successive searches changing their position relative to each other. Starting with this array:
sort_array =
[[297, 100, 101, 235, 253, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil],
[256, 105, 111, 212, 216, 264, nil, nil],
[276, 108, 111, 204, 207, 257, 259, 367],
[274, 66, 66, 120, 121, nil, 150, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[283, 102, 106, 193, 199, 247, 248, 343]]
I iterate across the array with these lines of code:
(1..sort_array[0].size - 1).each do |i|
sort_array.sort_by! { |e| [e[i] ? 0 : 1, e[i]] }
end
The idea is to ignore the first column, but sort the second through nth column in ascending order pushing nil values to the bottom. This gives the following result:
=> [[283, 102, 106, 193, 199, 247, 248, 343],
[276, 108, 111, 204, 207, 257, 259, 367],
[256, 105, 111, 212, 216, 264, nil, nil],
[297, 100, 101, 235, 253, nil, nil, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[274, 66, 66, 120, 121, nil, 150, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil]]
This is close to what I need, but not quite right. The problem is that the nil values once pushed to the bottom don't stay put. For example, after sorting the column whose first value is 247, the array would have looked like this:
=> [[283, ... 247, ...]
[276, ... 257, ...]
[256, ... 264, ...]
[296, ... 324, ...]
[297, ... nil, ...]
[274, ... nil, ...]
[298, ... nil, ...]
[286, ... nil, ...]
But further sorting on columns to the right results in the nil values being reordered, which messes up the sort. Nil values need to stay put unless a cell to the right is non-nil, in which case it should be sorted as usual.
The table should look like this when the sort is finished:
=> [[283, 102, 106, 193, 199, 247, 248, 343],
[276, 108, 111, 204, 207, 257, 259, 367],
[274, 66, 66, 120, 121, nil, 150, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[256, 105, 111, 212, 216, 264, nil, nil],
[297, 100, 101, 235, 253, nil, nil, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil]]
Could someone please help me write a method that will achieve this result?
It may be helpful to see the real-life example of what I am trying to achieve. Here is a link to a spreadsheet:
https://github.com/SplitTime/OpenSplitTime/blob/master/hardrock2015test.xlsx
Each row is a runner effort. Runners are ranked by final finish time of course. But those who do not finish are ranked by how far they made it and what time they made it to their last waypoint.
Though the linked spreadsheet does not show it, the sort also needs to deal with nil values with time data to the right, representing times that didn't get recorded for whatever reason.
I think that you want to sort the rows by its 2nd to last elements in reverse order (with nil being treated as Infinity):
arrays = [[297, 100, 101, 235, 253, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil],
[256, 105, 111, 212, 216, 264, nil, nil],
[276, 108, 111, 204, 207, 257, 259, 367],
[274, 66, 66, 120, 121, nil, 150, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[283, 102, 106, 193, 199, 247, 248, 343]]
arrays.sort_by { |a| a[1..-1].reverse.map { |e| e || Float::INFINITY } }
#=> [[283, 102, 106, 193, 199, 247, 248, 343],
# [276, 108, 111, 204, 207, 257, 259, 367],
# [274, 66, 66, 120, 121, nil, 150, nil],
# [296, 127, 130, 259, 264, 324, 332, nil],
# [256, 105, 111, 212, 216, 264, nil, nil],
# [297, 100, 101, 235, 253, nil, nil, nil],
# [298, 114, 117, 270, 270, nil, nil, nil],
# [286, 116, 116, 213, nil, nil, nil, nil]]
At least, this produces the expected result.
Since the first row consists of keys, you could take advantage of Ruby's array decomposition abilities and use |_, *vs| vs.reverse... instead of |a| a[1..-1].reverse.... Here, _ refers to the (unused) key and *vs collects the remaining elements.
Related
How can I convert arraybuffer to visible data in python?
I have API that work with JS perfect as showsn as(response typ is arraybuffer ): hrOverride.responseType = 'arraybuffer'; My_request = $.ajax({ url: 'my url api ', method: 'GET' My_request.done(function(data) { Rcv_data = { buffer: data, }; myFunction(Rcv_data ); } ... when I reqquest to API in python: My_request = requests.get('my url api') print(My_request .text) output:�0�Ɗ���$����Fp�#�Uk�K�u�jq,� How can I convert arraybuffer to visible data in python? I try convert response to base64 then to string and convert response to byteArray then to string that but data was not visible yet. OutPut base64: 7MovzZ2UtYi97OovzNGpDbz46OW9+OhKqvhOdvEHsokJ+CaqtZXofTbM6Ym+6Ogd54aFlA== OutPut ByteArray: [ 236, 202, 47, 205, 157, 148, 181, 136, 189, 236, 234, 47, 204, 209, 169, 13, 188, 248, 232, 229, 189, 248, 232, 74, 170, 248, 78, 118, 241, 7, 178, 137, 9, 248, 38, 170, 181, 149, 232, 125, 54, 204, 233, 137, 190, 232, 232, 29, 231, 134,133, 148 ]
Validate credentials against AD with Elixir/Erlang
I'm trying to achieve simple AD Credential Validation with Elixir/Erlang. My code in C# works fine. C# private static void Main(string[] args) { try { using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "132.10.100.156")) { bool isValid = pc.ValidateCredentials("my-username", "my-password"); Console.WriteLine(isValid); } } catch (Exception e) { Console.WriteLine(e); } Console.ReadLine(); } Elixir defmodule AD do #moduledoc false require Logger #format [ limit: :infinity, pretty: true, structs: true, width: 210, syntax_colors: [number: :yellow, atom: :cyan, string: :green, boolean: :magenta, nil: :magenta] ] def test do {:ok, pid} = :eldap.open(['132.10.100.156'], log: &log/3) :eldap.simple_bind(pid, 'my-username', 'my-password') end def log(_, format_string, format_args) do Logger.debug(inspect({format_string, format_args}, #format)) end end Console: iex> AD.test [2019-11-16 18:23:53.354] {'bind request = ~p~n', [{:BindRequest, 3, 'my-username', {:simple, 'my-password'}}]} {:error, :invalidCredentials} [2019-11-16 18:23:53.511] {'bind reply = ~p~n', [ ok: {:LDAPMessage, 1, {:bindResponse, {:BindResponse, :invalidCredentials, [], [56, 48, 48, 57, 48, 51, 48, 56, 58, 32, 76, 100, 97, 112, 69, 114, 114, 58, 32, 68, 83, 73, 68, 45, 48, 67, 48, 57, 48, 51, 67, 56, 44, 32, 99, 111, 109, 109, 101, 110, 116, 58, 32, 65, 99, 99, 101, 112, 116, 83, 101, 99, 117, 114, 105, 116, 121, 67, 111, 110, 116, 101, 120, 116, 32, 101, 114, 114, 111, 114, 44, 32, 100, 97, 116, 97, 32, 53, 50, 101, 44, 32, 118, 50, 53, 56, 48, 0], :asn1_NOVALUE, :asn1_NOVALUE}}, :asn1_NOVALUE} ]} iex>
:erldap requires my-username#somedomain or a full DN in order to work correctly.
appIdentityService.signForApp (Java) and app_identity.sign_blob (Python) results are different
I need to sign JWT using Google Cloud appIdentity. I tried using python agent and it is working. But the Java client gives signature error. So I run test code to get signature of same input from Java and Python. It returns different result. python code import array from google.appengine.api import app_identity header_and_payload = "test" (key_name, signature) = app_identity.sign_blob(header_and_payload) print array.array('B', signature) java code import com.google.appengine.api.appidentity.AppIdentityService; import com.google.appengine.api.appidentity.AppIdentityServiceFactory; headerAndPayload = "test"; AppIdentityService appIdentityService = AppIdentityServiceFactory.getAppIdentityService(); AppIdentityService.SigningResult signingResult = appIdentityService.signForApp(headerAndPayload.getBytes()); System.out.println(Arrays.toString(signingResult.getSignature())); Python output [205, 130, 214, 28, 19, 7, 233, 69, 92, 161, 8, 160, 36, 162, 149, 125, 5, 100, 8, 219, 244, 235, 188, 126, 118, 45, 176, 63, 61, 88, 91, 151, 151, 114, 228, 31, 85, 209, 117, 134, 66, 120, 13, 159, 10, 155, 70, 16, 110, 56, 212, 79, 165, 40, 222, 46, 26, 74, 182, 80, 223, 57, 244, 44, 224, 122, 230, 184, 114, 236, 158, 204, 145, 152, 133, 131, 115, 43, 224, 132, 219, 232, 186, 237, 82, 86, 243, 194, 155, 127, 26, 227, 19, 165, 142, 216, 238, 163, 99, 251, 41, 191, 164, 206, 85, 239, 64, 133, 41, 49, 120, 235, 120, 226, 96, 224, 105, 68, 81, 186, 184, 65, 233, 129, 211, 231, 211, 135, 15, 88, 35, 20, 217, 95, 56, 215, 134, 71, 210, 28, 43, 22, 231, 69, 134, 116, 227, 161, 202, 94, 54, 222, 132, 158, 108, 45, 73, 68, 240, 90, 59, 139, 222, 118, 6, 82, 162, 198, 143, 7, 233, 148, 233, 232, 101, 135, 182, 71, 148, 136, 246, 168, 5, 28, 94, 11, 10, 78, 147, 4, 200, 36, 79, 244, 117, 223, 114, 33, 2, 206, 13, 66, 204, 201, 102, 147, 237, 83, 83, 17, 221, 16, 136, 206, 115, 141, 32, 149, 131, 136, 183, 96, 51, 31, 212, 174, 245, 120, 18, 120, 191, 174, 90, 111, 122, 136, 96, 152, 81, 8, 72, 52, 33, 46, 227, 241, 41, 77, 40, 176, 97, 189, 195, 197, 202, 71] java output [10, -64, 92, 105, 15, 35, -32, -101, 47, 111, -1, -72, 110, 105, -77, -117, 23, 69, 113, -49, -14, -104, 110, 78, 84, -78, 30, 26, 38, -43, 36, 112, 33, -10, -5, -63, -11, 47, -53, -116, -71, 2, -64, -16, 36, 122, 45, 79, 3, 49, -7, 120, -10, 125, 92, 43, -43, -34, 100, 75, -54, -36, 5, 106, -128, 106, -120, 36, 59, -31, -2, 100, 79, 65, -118, -50, -83, 11, -19, -28, -80, -125, -8, 59, -94, -125, 91, -104, -96, -12, 14, 31, -108, 61, 12, 6, 90, -6, -24, -47, -57, 55, -64, -50, 41, 26, -46, -81, -124, 122, 82, -120, 31, 19, 85, -7, -17, 40, -18, -118, -64, 114, -76, -60, 116, -12, -16, 12, -91, 55, -57, -61, 108, 88, -13, 80, -38, 100, 121, -11, -20, -5, -105, 20, 87, 60, -125, 33, -11, 111, -115, -69, 24, 0, -113, -24, 49, 21, -27, 96, 27, 12, 72, 50, 12, 15, -61, -40, -52, -76, -63, 29, -99, 114, 88, 41, 111, 9, 127, 96, -123, 58, 92, -91, 17, 114, -11, -105, -79, -110, -100, -35, 16, 103, 27, -21, -50, 7, -28, 117, 119, -124, -127, -115, -116, 86, 74, 57, -46, 114, 102, -18, -73, 97, 10, -113, 119, -1, -68, -18, -16, -119, 49, -120, 104, 121, 113, -82, -42, -119, -81, 95, -114, 16, -11, -58, 36, -24, 58, -50, 101, -117, -55, -101, -19, 62, -53, 30, -59, 106, 37, 98, 102, 75, -9, 91] What is the issue in Java code? Thank you.
In the line: print array.array('B', signature) you are using the option 'B' for unsigned char according to the docs. If you use the option 'b' (for signed char) like in print array.array('b', signature) you will get the same results for both the Java and the python versions. I performed tests with the sample codes for Python and Java. In the Python example I set the message variable to the same value as in Java: message = "abcdefg" and added this line: self.response.write('Signature Array: {}\n'.format(array.array('b', signature))) Hope this helps.
Swift - Array filtering values in between two numbers
i have a small problem. I have an array with a integer of value: let array = [99, 42, 34, 19, 167, 30, 49, 39, 75, 175, 270, 540] How do I get all the values between 19 and 167 for example? There has to be a better way than a for iteration through all the integer value ? this is on swift. so i am looking for answer on swift. thanks in advance
In Swift, you can still do this using filter let array = [99, 42, 34, 19, 167, 30, 49, 39, 75, 175, 270, 540] let newArray = array.filter{$0 > 19 && $0 < 167} print(newArray)
You can use filter and the pattern matching operator ~= which is able to filter a range. let array = [99, 42, 34, 19, 167, 30, 49, 39, 75, 175, 270, 540] let range = 19...167 let filteredArray = array.filter{ range ~= $0 } Consider that this operator does not filter the edges 19 and 167. The result is // [99, 42, 34, 19, 167, 30, 49, 39, 75] To exclude the edges write 20...168 or 20..<167, then the result is // [99, 42, 34, 30, 49, 39, 75]
let filtered = array.filter { (20..<167).contains($0) }
sine function on 16-bit microcontroller
I need to generate a sine wave to fill a char table of size 1024. The word size on the microcontroller is 16-bit and floating-point operations are not available. The sine wave itself will oscillate between the value of 0 to 255, with 127 being the center point. Any ideas?
You only actually need to store one quarter of the sine wave -- you can lookup the other three quarters from the first quadrant. So you only need 256 bytes. To generate the values on the micro controller, implement CORDIC. You can store one value, and generate the whole sine wave from that.
Create a precomputed array on your PC. You only have to create a fourth of the array if ROM (or equivalent, such as flash or code segment) space is at a premium, then mirror this part out to the other 768 bytes of the array.
Write a sin table generator in your favorite language using float. Scale and round the results to desired ranges 1024/-127..+128 (you may do that right away). From the table, generate a source file in ASM or C, what ever works better for you. Make sure the generated table in marked "const" in C or make go to a approbiate section in ASM so it goes to FLASH rather than RAM. Include the file in your project. Now intsin(x)1 is: int intsin(int x) limit x // 0..360° or 2PI scale to 1024 read table at x return x You can improve resolution by using the table for the first quadrant only. You can than use positive values only, too (0..255). Then your intsin(x) would need to determine the quadrant and mirror the first quadrant results.
You just generate table on your PC and use it on your MCU. As somebody said you just need a quater period, but to answer your question fully, here are all 1024 chars: for k := 0 to 1023 do buffer[k] := (round(128+127*sin(2*pi*k/1024))); 128, 129, 130, 130, 131, 132, 133, 133, 134, 135, 136, 137, 137, 138, 139, 140, 140, 141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 166, 167, 168, 169, 169, 170, 171, 172, 172, 173, 174, 174, 175, 176, 177, 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, 186, 186, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 206, 207, 207, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238, 239, 239, 239, 240, 240, 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, 246, 246, 246, 246, 247, 247, 247, 248, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 249, 249, 249, 249, 248, 248, 248, 248, 247, 247, 247, 246, 246, 246, 246, 245, 245, 245, 244, 244, 244, 243, 243, 243, 242, 242, 242, 241, 241, 241, 240, 240, 240, 239, 239, 239, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234, 234, 234, 233, 233, 232, 232, 231, 231, 230, 230, 230, 229, 229, 228, 228, 227, 227, 226, 226, 225, 225, 224, 224, 223, 223, 222, 222, 221, 221, 220, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214, 213, 213, 212, 212, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205, 204, 204, 203, 202, 202, 201, 200, 200, 199, 199, 198, 197, 197, 196, 195, 195, 194, 193, 193, 192, 191, 191, 190, 189, 189, 188, 187, 186, 186, 185, 184, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, 172, 171, 170, 169, 169, 168, 167, 166, 166, 165, 164, 163, 163, 162, 161, 160, 160, 159, 158, 157, 157, 156, 155, 154, 154, 153, 152, 151, 150, 150, 149, 148, 147, 147, 146, 145, 144, 144, 143, 142, 141, 140, 140, 139, 138, 137, 137, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129, 128, 127, 126, 126, 125, 124, 123, 123, 122, 121, 120, 119, 119, 118, 117, 116, 116, 115, 114, 113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103, 102, 102, 101, 100, 99, 99, 98, 97, 96, 96, 95, 94, 93, 93, 92, 91, 90, 90, 89, 88, 87, 87, 86, 85, 84, 84, 83, 82, 82, 81, 80, 79, 79, 78, 77, 77, 76, 75, 74, 74, 73, 72, 72, 71, 70, 70, 69, 68, 67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 57, 57, 56, 56, 55, 54, 54, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47, 47, 46, 46, 45, 44, 44, 43, 43, 42, 42, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 22, 21, 21, 20, 20, 19, 19, 19, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 46, 46, 47, 47, 48, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 55, 56, 56, 57, 57, 58, 59, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79, 80, 81, 82, 82, 83, 84, 84, 85, 86, 87, 87, 88, 89, 90, 90, 91, 92, 93, 93, 94, 95, 96, 96, 97, 98, 99, 99, 100, 101, 102, 102, 103, 104, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 114, 115, 116, 116, 117, 118, 119, 119, 120, 121, 122, 123, 123, 124, 125, 126, 126, 127