How do you print an associative array in DTrace? - arrays

The question pretty much sums it up. "dtrace 'print an associative array'" has exactly one google hit and the similar searches are equally useless.
EDIT:
If I were to use an aggregation, I'm not aware that I'd still be able to remove entries. My application requires that I be able to do things like:
file_descriptors[0] = "stdin"
file_descriptors[3] = "service.log"
...
...
file_descriptors[3] = 0
...
...
# should print only those entries that have not been cleared.
print_array(file_descriptors)
I know that you can clear an entire aggregation, but what about a single entry?
UPDATE:
Since I'm doing this in OS X and my application is to track all of the file descriptors that have been opened by a particular process, I was able to have an array of 256 pathnames, thusly:
syscall::open*:entry
/execname == $1/
{
self->path = copyinstr(arg0);
}
syscall::open*:return
/execname == $1/
{
opened[arg0] = self->path;
}
syscall::close*:entry
/execname == $1/
{
opened[arg0] = 0;
}
tick-10sec
{
printf(" 0: %s\n", opened[0]);
}
The above probe repeated 255 more times...
It sucks. I'd really like to have something better.

Is this the link Google found? Because the advice seems pretty sound:
I think the effect you're looking for should be achieved by using an
aggregation rather than an array. So you'd actually do something like:
#requests[remote_ip,request] = count();
... and then:
profile:::tick-10sec
{
/* print all of the requests */
printa(#requests);
/* Nuke the requests aggregation */
trunc(#requests);
}

Use an associative array and sum(1) and sum(-1) instead of count().

Related

QS5026 - The variable cannot be reassigned here

I'm following tutorial from the official Microsoft learning page (https://learn.microsoft.com/en-us/azure/quantum/tutorial-qdk-explore-entanglement?pivots=ide-azure-portal) about quantum entanglement.
Basically, I copied an example posted there and I am getting error:
QS5026 The variable "numOnesQ1" cannot be reassigned here. In conditional blocks that depend on a measurement result, the target QuantinuumProcessor only supports reassigning variables that were declared within the block.
I understand what it says but it's just a copy from the official Microsoft tutorial. Am I missing something simple like imports, wrong settings? If not, how can I in other way set variables declared outside conditional blocks that depend on a measurement result?
Here is my code:
namespace Quantum.QuantumDream {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
operation GetRandomResult() : Result {
use q = Qubit();
H(q);
return M(q);
}
#EntryPoint()
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones':
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return number of |0> states, number of |1> states
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
}
This tutorial code is only supposed to run on a local simulator (using %simulate magic commands in a Jupyter Notebook). From the error message, it looks like you've tried to run it on one of Quantinuum targets, which have some limitations on the kinds of things you can do in the code. To run equivalent code on Quantinuum, you'd need to define an operation for just the body of the loop (preparing a state and measuring it) and run it as a job - the cloud targets will take care of the loop themselves, running your code multiple times and returning to you a histogram of the results. For an example, you can see the QRNG sample in the samples gallery in Azure Portal.

How to make what function I use in c be controlled by a variable

This is my first year of vex. I am taking on the role of programmer.
I have had this idea for rapid autonomous creation, recording the driver. Instead of the usual array/debugger dump of raw streams of power levels, I had the idea of extracting functions from driver movement.
I wont go into the details, and I can code it myself, but I need some help.
There is one thing I am unable to do simply because of my lack of coding experience.
I want to create a for loop that checks every joystick button one by one.
For example:
struct button
{
bool pressed;
}
for(int i = 0; i>12; i++) //12 is number of buttons on the joystick
{
struct button button<cycle through buttons>;
}
I want there to then be:
struct button button6U;
struct button button6D;
struct button button6R;
etc.
Then, I want this:
for(int i = 0; i>12; i++) // 12 is number of buttons on the joystick
{
if(VexRT[<currentButton>])
{
button<currentButton>.pressed = true;
}
}
I have no idea how to do this, with a wildcard modifing the actual variable name I am writing to.
A couple thoughts:
A for statement would have no idea how to advance the order of joystick buttons. So something I think I might need is:
orderOfButtons
{
VexRT[6U];
VexRT[6D];
VexRT[6R];
// etc.
}
I just cant seem to figure out how to have a variable defining what VexRT[]button I am reading from.
Any help would be appreciated!
Thanks.
Sounds like you want an array:
#define NUMBER_OF_BUTTONS 12
...
struct button VexRT[NUMBER_OF_BUTTONS];
If you want to use symbolic constants to refer to specific buttons in the array, you can use an enumeration:
enum btn_id { BTN_6U, // maps to 0
BTN_6D, // maps to 1
BTN_6R, // maps to 2
...
}
Enumeration constants are represented as integers, and by default they start at 0 and increment by 1. You can initialize them to different values if you want, and multiple enumeration constants can map to the same value. I take advantage of this when I want to identify a "first" and "last" enumeration for looping, like so:
enum btn_id {
BTN_6U,
BTN_FIRST = BTN_6U, // both BTN_FIRST and BTN_6U will map to 0
BTN_6D,
BTN_6R,
...
BTN_whatever,
BTN_LAST
};
Thus, VexRT[BTN_6U] maps to VexRT[0], VexRT[BTN_6D] maps to VexRT[1], etc.
Note that this way, you don't have to loop through all the buttons just to set one:
enum btn_id currentButton = BTN_6D;
...
VexRT[currentButton].pressed = true;
If you do want to loop through the whole set, you can use
for ( enum btn_id i = BTN_FIRST; i < BTN_LAST; i++ )
{
VexRT[i].pressed = false;
}
So, what you want is to sample the user input (at some specified rate), then record it into an array, then play that back at a later time? If you have functions that drive the VEX (I'm not familiar with that), each of which are associated with an input, you can use an array of function pointers to create your output.
#define MAX_ACTION 12
#define MAX_RECORDED 200
// Declare your array of function pointers
int (*action[MAX_ACTION])(void);
// Declare your stored array of recorded actions
int recorded[MAX_RECORDED];
...
// Assign function pointers to associated functions
action[0] = go_forward;
action[1] = turn_right;
...
// Record your actions into some array
while (...)
{
// Record the action
recorded[i++] = get_action();
// Sample delay
}
...
// Playback the actions
for (i=0;i<RECORDED;i++)
{
(*action[recorded[i]])();
// delay here
}
P.S. Your for loop is backward (i<12 not i>12).
I think you are trying to access the events coming from the joystick. You can just loop through the array of values and record them. I think the channels on the joystick are simply accessed like: vexRT[x] where x is 1-12. If you just want to store the latest value from each channel you could do this:
int value[12];
for(i=0; i<12; i++)
{
value[i] = vexRT[i];
}
If you want to store all of the values so that you can map them or play them back or something then you will need a more complex data structure to store them, like a list of the value arrays.
I also have found documentation that says the values are accessed by like vexRT[Chx] where x is 1-12, so you could alternatively create a string and use it to access the joystick channels inside your loop:
string *s = (char *)malloc(5*sizeof(char)); //5 is the max length of the null terminated string
for() . . . {
sprintf(s,"Ch%d", i);
value[i] = vertRT[s];
}

how to get a particular block in an array get copied in perl

I have details like below in an array. There will be plenty of testbed details in actual case. I want to grep a particular testbed(TESTBED = vApp_eprapot_icr) and an infomation like below should get copied to another array. How can I do it using perl ? End of Testbed info can be understood by a closing flower bracket }.
TESTBED = vApp_eprapot_icr {
DEVICE = vApp_eprapot_icr-ipos1
DEVICE = vApp_eprapot_icr-ipos2
DEVICE = vApp_eprapot_icr-ipos3
DEVICE = vApp_eprapot_icr-ipos5
CARDS=1GIGE,ETHFAST
CARDS=3GIGE,ETHFAST
CARDS=10PGIGE,ETHFAST
CARDS=20PGIGE,ETHFAST
CARDS=40PGIGE,ETHFAST
CARDS=ETHFAST,ETHFAST
CARDS=10GIGE,ETHFAST
CARDS=ETH,ETHFAST
CARDS=10P10GIGE,ETHFAST
CARDS=PPA2GIGE,ETHFAST
CARDS=ETH,ETHFAST,ETHGIGE
}
I will make it simpler, please see the below array
#array("
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
");
Consider an array like this. Where such entries are plenty. I need to grep, for an example student=Akshaya's data. from the opening '{' to closing '}' all info should get copied to another array. This is what I'm looking for.
while (<>) {
print if /TESTBED = vApp_eprapot_icr/../\}/;
}
as a sidenote <> will capture the filename you use on cmdline. So if the data is stored in a file you will run from commandline
perl scriptname.pl filename.txt
Ok. We finally have enough information to come up with an answer. Or, at least, to produce two answers which will work on slightly different versions of your input file.
In a comment you say that you are creating your array like this:
#array = `cat $file`;
That's not a very good idea for a couple of reasons. Firstly, why run an external command like cat when Perl will read the file for you. And secondly, this gives you one element in your array for each line in your input file. Things become far easier if you arrange it so that each of your TESTBED = foo { ... } records is a single array element.
Let's get rid of the cat first. The easiest way to read a single file into an array is to use the file input operator - <>. That will read data from the file whose name is given on the command line. So if you call your program filter_records, you can call it like this:
$ ./filter_records your_input_data.txt
And then read it into an array like this:
#array = <>;
That's good, but we still have each line of the input file in its own array element. How we fix that depends on the exact format of your input file. It's easiest if there's a blank line between each record in the input file, so it looks like this:
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
Perl has a special variable called $/ which controls how it reads records from input files. If we set it to be an empty string then Perl goes into "paragraph" mode and it uses blank lines to delimit records. So we can write code like this:
{
local $/ = '';
#array = <>;
}
Note that it's always a good idea to localise changes to Perl's special variables, which is why I have enclosed the whole thing in a naked block.
If there are no blank lines, then things get slightly harder. We'll read the whole file in and then split it.
Here's our example file with no blank lines:
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
And here's the code we use to read that data into an array.
{
local $/;
$data = <>;
}
#array = split /(?<=^})\n/m, $data;
This time, we've set $/ to undef which means that all of the data has been read from the file. We then split the data wherever we find a newline that is preceded by a } on a line by itself.
Whichever of the two solutions above that we use, we end up with an array which (for our sample data) has three elements - one for each of the records in our data file. It's then simple to use Perl's grep to filter that array in various ways:
# All students whose names start with 'Ak'
#filtered_array = grep { /student=Ak/ } #array;
If you use similar techniques on your original data file, then you can get the records that you are interested in with code like this:
#filtered_array = grep { /TESTBED = vApp_eprapot_icr/ } #array;

Proper way to parse a file and build output

I'm trying to learn D and I thought after doing the hello world stuff, I could try something I wanted to do in Java before, where it was a big pain because of the way the Regex API worked: A little template engine.
So, I started with some simple code to read through a file, character by character:
import std.stdio, std.file, std.uni, std.array;
void main(string [] args) {
File f = File("src/res/test.dtl", "r");
bool escape = false;
char [] result;
Appender!(char[]) appender = appender(result);
foreach(c; f.rawRead(new char[f.size])) {
if(c == '\\') {
escape = true;
continue;
}
if(escape) {
escape = false;
// do something special
}
if(c == '#') {
// start of scope
}
appender.put(c);
}
writeln(appender.data());
}
The contents of my file could be something like this:
<h1>#{hello}</h1>
The goal is to replace the #{hello} part with some value passed to the engine.
So, I actually have two questions:
1. Is that a good way to process characters from file in D? I hacked this together after searching through all the imported modules and picking what sounded like it might do the job.
2. Sometimes, I would want to access more than one character (to improve checking for escape-sequences, find a whole scope, etc. Should I slice the array for that? Or are D's regex functions up to that challenge? So far, I only found matchFirst and matchAll methods, but I would like to match, replace and return to that position. How could that be done?
D standard library does not provide what you require. What you need is called "string interpolation", and here is a very nice implementation in D that you can use the way you describe: https://github.com/Abscissa/scriptlike/blob/4350eb745531720764861c82e0c4e689861bb17e/src/scriptlike/core.d#L139
Here is a blog post about this library: https://p0nce.github.io/d-idioms/#String-interpolation-as-a-library

How to change the elements of an array in perl when the order of the array changes depending on where the program is run?

EDIT: Figured it out using a subroutine and a whole lot of if statements. I've appended the working code to the bottom of the question (since it won't let me post an answer) in case someone comes across a similar issue, with the disclaimer that I'm a mega-novice and the code probably isn't good, just functional.
Thanks for the help, guys!
Original Question:
I'm currently banging my head against an assignment that requires we use the Win32::DriveInfo module to create a list of drives, followed by the drive type. Using an array, we have to take the supplied drive type number and convert it into a descriptive string.
I can get the program to return the appropriate drive type, the problem is converting those numbers into strings. The array is populated based on the drives it finds on the user's system, which means the program has to be able read the array, determine each number, and then (probably?) compare it against some kind of predetermined 'conversion chart' and convert the provided numbers to the appropriate string.
I've been at this for hours, and so far my best option seems like it might be the map function, although we haven't gone over that in class (and my teacher is not fond of googling) so I'm not entirely sure that's what we're supposed to use. And even so, the only information I've been able to find has either been completely over my head, or assumes that the contents of the array are static.
The entire program is longer, but here's the relevant code:
use Win32::DriveInfo;
my #DrivesInUse = Win32::DriveInfo::DrivesInUse();
my #DriveType;
my %DrivesHash;
foreach $DrivesInUse (#DrivesInUse)
{
print "$DrivesInUse: ";
push (#DriveType, Win32::DriveInfo::DriveType($DrivesInUse));
foreach $DriveType (#DriveType)
{
$DrivesHash{$DrivesInUse} = $DriveType;
}
print $DrivesHash{$DrivesInUse} . "\n";
}
And the output is:
A: 2
C: 3
D: 5
E: 5
F: 5
G: 2
Now I just have to figure out a way to convert all potential numbers (0-6) to the appropriate strings and print those instead. We can't use any additional modules, and considering I'm still very much a newbie, the more basic the solution the better.
Edit:
For clarification, the numbers come from the Win32::DriveInfo module, and each of them represent a drive type, description from CPAN below:
0 - the drive type cannot be determined.
1 - the root directory does not exist.
2 - the drive can be removed from the drive (removable).
3 - the disk cannot be removed from the drive (fixed).
4 - the drive is a remote (network) drive.
5 - the drive is a CD-ROM drive.
6 - the drive is a RAM disk.
In my program, I need those numbers to return as descriptive strings instead, so the desired output on my system would be something like:
A: Removable Drive
C: Fixed Drive
D: CD-ROM Drive
E: CD-ROM Drive
F: CD-ROM Drive
G: Removable Drive
My problem is I can't figure out how to convert the numbers in #DriveType to the corresponding strings, since the elements in #DriveType change depending on the system.
I hope that cleared things up?
Working Code
use Win32::SystemInfo;
use Win32::DriveInfo;
my #DrivesInUse = Win32::DriveInfo::DrivesInUse();
my #DriveType;
my %DrivesHash;
foreach $DrivesInUse (#DrivesInUse)
{
print "$DrivesInUse: ";
push (#DriveType, Win32::DriveInfo::DriveType($DrivesInUse));
foreach $DriveType (#DriveType)
{
$DriveString = conversion($DriveType);
$DrivesHash{$DrivesInUse} = $DriveString;
}
print $DrivesHash{$DrivesInUse} . "\n";
}
sub conversion
{
if ($_[0] == 0)
{
$StringContent = "Undetermined";
}
if ($_[0] == 1)
{
$StringContent = "Does not exist";
}
if ($_[0] == 2)
{
$StringContent = "Removable";
}
if ($_[0] == 3)
{
$StringContent = "Fixed";
}
if ($_[0] == 4)
{
$StringContent = "Network";
}
if ($_[0] == 5)
{
$StringContent = "CD-ROM";
}
if ($_[0] == 6)
{
$StringContent = "RAM";
}
return $StringContent;
}
I hope this may help you
use Win32::DriveInfo;
my #DrivesInUse = Win32::DriveInfo::DrivesInUse();
my %DriveType = (
'0' => 'Undetermined',
'1' => 'Does not exist',
'2' => 'Removable',
'3' => 'Fixed',
'4' => 'Network',
'5' => 'CD-ROM',
'6' => 'RAM',
);
for $DrivesInUse ( #DrivesInUse ) {
print "$DrivesInUse: "
. $DriveType{ Win32::DriveInfo::DriveType($DrivesInUse) } . "\n";
}
One way to go could be a types hash like
my %typesHash;
$typesHash{0} = "the drive type cannot be determined.";
$typesHash{1} = "the root directory does not exist.";
.
.
.
edit: In an earlier version i had butchered these lines. Another way to assign the hash would be the following, i just tried to use the version above because i thought it would be clearer and consequently managed to make everything less clear. \o/
my %typesHash = (0 => "the drive type cannot be determined.",
1 => "the root directory does not exist.",
...);
end edit
And later use
print $typesHash{$DrivesHash{$DrivesInUse}} . "\n";
Not necessarily the most elegant solution but a proper use for a hash.
edit:
By the way:
push (#DriveType, Win32::DriveInfo::DriveType($DrivesInUse));
foreach $DriveType (#DriveType)
{
$DrivesHash{$DrivesInUse} = $DriveType;
}
is a completely useless loop. It just assigns all the drive types encountered so far to $DrivesHash{$DrivesInUse} one after the other. It does work because you pushed the most recent one into the array last and so it will end up with the correct one but there is no reason to assign all the others before. If you do not need the array of drive types (they are in the hash as well anyways), the whole stuff pasted above could be replaced with:
$DrivesHash{$DrivesInUse} = Win32::DriveInfo::DriveType($DrivesInUse);

Resources