I am using ReadConsoleInputW to read Windows 10 console input. I want to be able to detect when Ctrl+S is pressed. Using the code I have, I can detect Ctrl+Q without issue, but I'm not seeing anything for Ctrl+S. Is Ctrl+S even detectable?
The below is the sequence of INPUT_RECORD I read when pressing Ctrl+S a few times, followed by Ctrl+Q.
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 17, scan_code: 29, wide_char: 0, control_key_state: 40 }
Key { key_down: true, repeat_count: 1, key_code: 81, scan_code: 16, wide_char: 17, control_key_state: 40 }
If it matters, this is in Rust using wio.
Calling SetConsoleMode with ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS as the second argument (thus disabling ENABLE_PROCESSED_INPUT) did the trick.
oconnor0's answer helped me find the solution.
However, I could not get ctrl-s event by disabling ENABLE_PROCESSED_INPUT, so I tried using only ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS as suggested by oconnor0. This worked, but this means ENABLE_PROCESSED_INPUT is not the culrpit!
So I tried:
//This didn't work
if (!GetConsoleMode(hConsoleInput, &lpMode)) Error();
lpMode &= ~(ENABLE_PROCESSED_INPUT);
if (!SetConsoleMode(hConsoleInput, lpMode)) Error();
//This worked
if (!GetConsoleMode(hConsoleInput, &lpMode)) Error();
lpMode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
if (!SetConsoleMode(hConsoleInput, lpMode)) Error();
Disabling ENABLE_ECHO_INPUT forces you to disable ENABLE_ECHO_INPUT (see msdn), but it isn't the culprit because:
//This didn't work either
if (!GetConsoleMode(hConsoleInput, &lpMode)) Error();
lpMode &= ~(ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT);
if (!SetConsoleMode(hConsoleInput, lpMode)) Error();
So this means that ENABLE_LINE_INPUT is the culprit!
It's not clear why though:
ENABLE_LINE_INPUT 0x0002 The ReadFile or ReadConsole function returns
only when a carriage return character is read. If this mode is
disabled, the functions return when one or more characters are
available.
Related
I am trying to write some somewhat complicated ReQL that deletes a single value from an array in a field, or deletes the record entirely if that value is the only one in the array.
I thought I had worked it out using branch/do/offsetAt, but then I ran into this "Argument 1 to deleteAt may not be undefined." error and I'm at a loss as to what the fix is.
r.branch(
r.db('db').table('table').get('uuid').eq(null),
{"deleted": 0, "errors": 0, "inserted": 0, "replaced": 0, "skipped": 0, "unchanged": 1},
r.db('db').table('table').get('uuid').getField('array_field').eq(['value']),
r.db('db').table('table').get('uuid').delete(),
r.do(
r.db('db').table('table').get('uuid').getField('array_field').offsetsOf('value'),
function(index) {
return r.branch(
index.eq([]),
{"deleted": 0, "errors": 0, "inserted": 0, "replaced": 0, "skipped": 0, "unchanged": 1},
r.db('db').table('table').get('uuid').update({
"array_field": r.row('array_field').deleteAt(index[0])
})
)
}
)
)
Also, as a side question, is there a more efficient way to do this without constantly fetching the record over and over calling .get()
So it turns out the issue here was in thinking I could use [] on the index.
Switching to .deleteAt(index.nth(0)) at line 16 solved the problem, or at least changed the error to "Cannot use r.row in nested queries"
So I rewrote the code to also solve my secondary issue, of constantly fetching the data using .get()
My new code is now
r.do(
r.db('db').table('table').get('uuid'),
function(record) {
return r.branch(
record.eq(null),
{"deleted": 0, "errors": 0, "inserted": 0, "replaced": 0, "skipped": 0, "unchanged": 1, "result": "no record"},
record.getField('array_field').eq(['array_value']),
r.db('db').table('table').get('uuid').delete(),
r.do(
record.getField('array_field').offsetsOf('array_value'),
function(index) {
return r.branch(
index.eq([ ]),
{"deleted": 0, "errors": 0, "inserted": 0, "replaced": 0, "skipped": 0, "unchanged": 1, "result": "no index"},
r.db('db').table('table').get('uuid').update({
"array_field": record.getField('array_field').deleteAt(index.nth(0))
})
)
}
)
)
}
)
I'm trying to iterate trough the results of this variable created from an API with a for loop (here commented or it will give an error):
let create_account_instruction: Instruction = solana_sdk::system_instruction::create_account(
&wallet_pubkey,
&mint_account_pubkey,
minimum_balance_for_rent_exemption,
Mint::LEN as u64,
&spl_token::id(),
);
println!("Creating the following instructions: {:?}", create_account_instruction);
// for x in create_account_instruction {
// println!("{:?}", x)
// }
Here is the results I would like to iterate trough (FYI: Those private and public keys are just for test on devnet):
Creating the following instructions: Instruction { program_id: 11111111111111111111111111111111, accounts: [AccountMeta { pubkey: ESCkgk5AfDC8cXd4KYjkUda1psCL8otfu8NvniUBiGhX, is_signer: true, is_writable: true }, AccountMeta { pubkey: Ah63GoKnnBicTELvfz2F9YvF9vaR51HR2BK3hJWwWE8x, is_signer: true, is_writable: true }], data: [0, 0, 0, 0, 96, 77, 22, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, 245, 133, 126, 255, 0, 169] }
If I try to iterate trough it via for loop (uncommenting the above), I get this error:
Compiling AmatoRaptor v0.1.0 (/home/joomjoo/Desktop/Tester)
error[E0277]: `Instruction` is not an iterator
--> src/main.rs:89:14
|
89 | for x in create_account_instruction {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `Instruction` is not an iterator
|
= help: the trait `Iterator` is not implemented for `Instruction`
= note: required because of the requirements on the impl of `IntoIterator` for `Instruction`
note: required by `into_iter`
--> /home/joomjoo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:234:5
|
234 | fn into_iter(self) -> Self::IntoIter;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain
My question is what is the easiest way to iterate trough the results?
From the Solana documentation, Instruction is a struct:
pub struct Instruction {
pub program_id: Pubkey,
pub accounts: Vec<AccountMeta, Global>,
pub data: Vec<u8, Global>,
}
You can access its attributes, and iterate over them:
for x in create_account_instruction.data {
...
}
or
for x in create_account_instruction.accounts {
...
}
I'm looking to add an Attrition Rate % graph to my Dashboard but I'm having difficulty in working out how I would do this using the complex calculation.
Basically the attrition rate % needs to look back at the previous 12 periods - for each period.
Calculation (for each Period) -
Total Starters in Previous 12 Periods (including current) / (Total Heads for Period 13 months ago + Leavers in Previous 12 Periods (including current)).
For example, if the Period is 201710 [YYYYMM], then the calculation would be:
(Total Starters in Periods 201611 to 201710) / Heads in Period 201610 + Total Leavers in Periods 201611 to 201710)
And within the line chart, you'd have the same calculation above for each period.
So, if I have the following data:
{ ... }
{ "Period": 201601, "Heads": 100, "Starters": 10, "Leavers": 8 },
{ "Period": 201602, "Heads": 102, "Starters": 8, "Leavers": 8 },
{ "Period": 201603, "Heads": 102, "Starters": 3, "Leavers": 0 },
{ "Period": 201604, "Heads": 105, "Starters": 8, "Leavers": 12 },
{ "Period": 201605, "Heads": 101, "Starters": 2, "Leavers": 5 },
{ "Period": 201606, "Heads": 98, "Starters": 8, "Leavers": 11 },
{ "Period": 201607, "Heads": 101, "Starters": 6, "Leavers": 5 },
{ "Period": 201608, "Heads": 102, "Starters": 4, "Leavers": 1 },
{ "Period": 201609, "Heads": 105, "Starters": 11, "Leavers": 17 },
{ "Period": 201610, "Heads": 99, "Starters": 8, "Leavers": 11 },
{ "Period": 201611, "Heads": 96, "Starters": 5, "Leavers": 8 },
{ "Period": 201612, "Heads": 95, "Starters": 4, "Leavers": 5 },
{ "Period": 201701, "Heads": 91, "Starters": 1, "Leavers": 5 },
The calculation and attrition rate % for Period 201701 would be:
Starters (Period 201602-201701): 68 / (Heads (Period 201601): 100 + Leavers (Period 201602-201701): 88
Attrition Rate for 201701 is: 36.17%
I would also like to have a number display that shows the attrition rate for the most recent Period.
I have some sample data and a Period chart to work with in a jsfiddle here: https://jsfiddle.net/kevinelphick/nh34aknn/
And a custom reduce function for the group like this:
attritionGroup = dimPeriod.group().reduce(
function (p, d) {
p.heads += d.Heads;
p.starters += d.Starters;
p.leavers += d.Leavers;
return p;
},
function (p, d) {
p.heads -= d.Heads;
p.starters -= d.Starters;
p.leavers -= d.Leavers;
return p;
},
function () {
return {heads: 0, starters: 0, leavers: 0};
});
I appreciate this may be a long shot due to its complex nature and I hope I've described my problem without confusion. I've tried in the past but I can't find any solutions that would work due to my limited knowledge. I can only guess that it would have to loop through the arrays dynamically to sum up starters, leavers that I need for the required Periods? Would I need to get a count of unique Periods to reference the correct periods I need for the calculation?
The reduce sets up the groups for you, then you can use a dummy group that calculates the attrition rates.
(UPDATED code)
function calcAttritionGroup (group) {
return {
all() {
var groupAll = group.all()
groupAll.forEach((p) => {
let elevenMonthsAgo = d3.time.month.offset(p.key, -11)
let twelveMonthsAgo = d3.time.month.offset(p.key, -12)
let twelveMonthsAgoGroup = groupAll.find(function(g){
return g.key.getTime() === twelveMonthsAgo.getTime()
})
let attrHeads = null
if (twelveMonthsAgoGroup) {
attrHeads = twelveMonthsAgoGroup.value.heads;
}
p.attrition = null
if (attrHeads) {
let subgroup = groupAll.filter(function(g) {
return g.key <= p.key && g.key >= elevenMonthsAgo;
})
let attrStarters = subgroup.reduce(function(sum, n) {
return sum + n.value.starters
}, 0)
let attrLeavers = subgroup.reduce(function(sum, n) {
return sum + n.value.leavers
}, 0)
let attrRate = (attrStarters / (attrHeads + attrLeavers))
p.attrition = attrRate || null
})
return groupAll
}
};
}
Here are modifications to your fiddle: https://jsfiddle.net/ga7x1p8m/ (UPDATED)
(Note, the values and formula in your question are different from in the fiddle.)
Some points...
1 - Formatting your period like that is not going to get you far because it won't give you a smooth range for your x scale, and makes it hard to do the comparisons you'll need for getting previous periods. So easiest is probably to cast as date object.
var format = d3.time.format("%Y%m");
data.forEach(function (d) {
d.date = format.parse(d.Period + '')
})
2 - You will have to manage edge cases. What happens if the 12 months previous period can't be found? If the earliest available period is used then this will add some more logic to the calculation.
I get a bit confused and frustrated when it comes to using NEST to querying, as it seems very hit and miss. I have no trouble querying when using standard JSON, so I was wondering if there was some way to query using a JSON object, I have code below
var query = "bkala";
var q = new
{
query = new
{
text = new
{
_all = "jane"
}
}
};
var qJson = JsonConvert.SerializeObject(q);
var hits = client.Search<Users>(qJson);
However, I get the error "Cannot convert from type string to System.Func, Nest.ISearchRequest"
If anyone knows how I can simply query using a JSON object, that would be fantastic, cheers in advance.
NEST and Elasticsearch.Net, the low level client that NEST uses under the covers, are flexible in how you wish to query. With NEST you have a couple of different ways:
NEST - High level client
1.Fluent API
var query = "bkala";
var searchResult = client.Search<MyDocument>(s => s
.Query(q => q
.Match(m => m
.Field("_all")
.Query(query)
)
)
);
Laid out as above, this API uses lambda expressions to define a fluent interface that mimics the structure of the Elasticsearch json API and query DSL.
2.Object Initializer Syntax
var query = "bkala";
var request = new SearchRequest<MyDocument>
{
Query = new MatchQuery
{
Field = "_all",
Query = query
}
};
var searchResult = client.Search<MyDocument>(request);
If lambda expressions are not your thing, then you can always define your searches using specific search types.
Elasticsearch.Net - Low level client
In cases where you would like to query with anonymous types (as per your question), json strings or a byte representation of a query, then you can use the low level client, Elasticsearch.Net, to achieve this. The low level client is exposed on the high level client through the .LowLevel property
1.Anonymous types
var query = new
{
query = new
{
match = new
{
_all = new
{
query = "bkala"
}
}
}
};
var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(query);
Using the low level client on the high level client means that you can still take advantage of using Json.NET to deserialize search results; in this example, the search response can be accessed through searchResult.Body
2.Json string
var query = #"
{
""query"": {
""match"": {
""_all"": {
""query"": ""bkala""
}
}
}
}";
var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(query);
3.Byte array
var bytes = new byte[] { 123, 13, 10, 32, 32, 34, 113, 117, 101, 114, 121, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 34, 109, 97, 116, 99, 104, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 34, 95, 97, 108, 108, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 34, 113, 117, 101, 114, 121, 34, 58, 32, 34, 98, 107, 97, 108, 97, 34, 13, 10, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 125, 13, 10, 125 };
var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(bytes);
All of the above methods produce the following query
{
"query": {
"match": {
"_all": {
"query": "bkala"
}
}
}
}
Check out the Getting started guide on the github repo as well as the documentation on the Elastic website. We are continually working to improve documentation and PRs are more than welcome for areas where you feel we are lacking :)
One iPhone is used to transmit ibeacon using locate app (the proximity uuid is 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6). The android phone is used to detect the ibeacon.
When I debugļ¼ I can get the following message:
08-30 15:33:57.051 D/BluetoothLeScanner(27939): onScanResult() - ScanResult{mDevice=6D:CC:9D:8D:3A:F3, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[2, 21, 47, 35, 68, 84, -49, 109, 74, 15, -83, -14, -12, -111, 27, -87, -1, -90, 0, 0, 0, 0, -59]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-31, mTimestampNanos=58705755631306}
However in function RangingBeaconsInRegion, there is no beacon.
void RangingBeaconsInRegion(object sender, RangeEventArgs e)
{
await ClearData();
var allBeacons = new List<Beacon>();
if (e.Beacons.Count > 0)
{
foreach (var b in e.Beacons)
{
allBeacons.Add(b);
int rssi = b.Rssi;
System.Diagnostics.Debug.WriteLine(rssi.ToString());
}
var orderedBeacons = allBeacons.OrderBy(b => b.Distance).ToList();
await UpdateData(orderedBeacons);
}
else
{
// unknown
await ClearData();
}
}
The following is my implementation:
public class MainActivity : XFormsApplicationDroid, IBeaconConsumer
{
public MainActivity()
{
}
protected override void OnCreate(Bundle bundle)
{
BeaconManager beaconManager = BeaconManager.GetInstanceForApplication(this);
var iBeaconParser = new BeaconParser();
iBeaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
var parser = new BeaconParser();
parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
beaconManager.BeaconParsers.Add(parser);
beaconManager.Bind(this);
}
public void OnBeaconServiceConnect()
{
//obtain the beaconservie object of android
var beaconService = Xamarin.Forms.DependencyService.Get<IbeaconService>();
beaconService.InitializeService();
//beaconService.StartTransmitting();
beaconService.StartMonitoring();
beaconService.StartRanging();
}
public void InitializeService()
{
m_beaconManager = InitializeBeaconManager();
}
private BeaconManager InitializeBeaconManager()
{
BeaconManager bm = BeaconManager.GetInstanceForApplication(Xamarin.Forms.Forms.Context);
//set the scan window
bm.SetForegroundScanPeriod(1100L);
//subscribe to the events;
m_monitorNotifier.EnterRegionComplete += EnteredRegion;
m_monitorNotifier.ExitRegionComplete += ExitedRegion;
m_monitorNotifier.DetermineStateForRegionComplete += DeterminedStateForRegionComplete;
m_rangeNotifier.DidRangeBeaconsInRegionComplete += RangingBeaconsInRegion;
// constructs a new region object to be used for ranging or monitoring
m_tagRegion = new Region("myUniqueBeaconId", Identifier.Parse("E4C8A4FC-F68B-470D-959F-29382AF72CE7"), null, null);
m_tagRegion = new Region("myUniqueBeaconId", Identifier.Parse("B9407F30-F5F8-466E-AFF9-25556B57FE6D"), null, null);
m_tagRegion = new Region("myUniqueBeaconId", Identifier.Parse("2F234454-CF6d-4A0F-ADF2-F4911BA9FFA6"), null, null);
m_emptyRegion = new Region("myEmptyBeaconId", null, null, null);
bm.SetBackgroundMode(false);
//
//bm.Bind((IBeaconConsumer)Xamarin.Forms.Forms.Context);
return bm;
}
public void StartRanging()
{
BeaconManagerInstance.SetForegroundBetweenScanPeriod(0L);
m_beaconManager.AddRangeNotifier(m_rangeNotifier);
m_beaconManager.StartRangingBeaconsInRegion(m_tagRegion);
m_beaconManager.StartRangingBeaconsInRegion(m_emptyRegion);
}
If you look closely at the code that sets up the beaconParsers, you'll see that two are constructed, but only one is added like this:
beaconManager.BeaconParsers.Add(parser);
Adding a second call to add the other beacon parser should solve the problem.
Thanks, that's my mistake! After I add a second call to add the other beacon parser! there is still some strange situation: I did not launch any beacon transmitter, but when I debug, I got the following output: D/BluetoothLeScanner( 6864): onScanResult() - ScanResult{mDevice=58:D6:74:3A:34:C5, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={76=[12, 14, 0, 126, 81, 116, -16, 10, 52, 84, 15, 98, 113, 29, -15, 34]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-89, mTimestampNanos=122142418198514}
08-31 09:11:13.943 D/BluetoothLeScanner( 6864): onScanResult() - ScanResult{mDevice=58:D6:74:3A:34:C5, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={76=[12, 14, 0, 126, 81, 116, -16, 10, 52, 84, 15, 98, 113, 29, -15, 34]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-89, mTimestampNanos=122142560625598}. It seems that one beacon is detected.