Update hash indexed keys separately with a for loop - perl

I have a %parallel_hash with indexed key names 0-2:
%parallel_hash
(function_name_0 => "sharp_mpi_steps::run_mpirun",
params_name_0 => ("reporter","xml_obj",$hash{value}),
function_name_1 => "sharp_mpi_steps::run_mpirun",
params_name_1 => ("reporter","xml_obj",$hash{value}),
(function_name_2 => "sharp_mpi_steps::run_mpirun",
params_name_2 => ("reporter","xml_obj",$hash{value})
I would like to update the $hash{value} content with an indexed text. To each $hash{value} inside params_name_$i, simply add another key and value: reporter_message => "process_$i"
my code is:
package delete;
use strict;
use warnings FATAL => 'all';
my %parallel_hash;
my %hash_mpi;
$hash_mpi{value}->{bind_to} = "none";
for (my $i=0;$i<=2;$i++)
{
my %hash;
$hash{value} = $hash_mpi{value};
$parallel_hash{"function_name_$i"} = "sharp_mpi_steps::run_mpirun";
#{$parallel_hash{"params_name_$i"}} = ("reporter","xml_obj",$hash{value});
$parallel_hash{"params_name_$i"}->[2]->{reporter_message} = "process_$i";
}
print ("Done");
1;
I would like to get:
%parallel_hash
'function_name_0' = "sharp_mpi_steps::run_mpirun"
'params_name_0' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_0"
'function_name_1' = "sharp_mpi_steps::run_mpirun"
'params_name_1' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_1"
'function_name_2' = "sharp_mpi_steps::run_mpirun"
'params_name_2' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
The problem is that after the "reporter_message" key is added, it updates all the previous "params_name_$i" as well:
%parallel_hash
'function_name_0' = "sharp_mpi_steps::run_mpirun"
'params_name_0' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
'function_name_1' = "sharp_mpi_steps::run_mpirun"
'params_name_1' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
'function_name_2' = "sharp_mpi_steps::run_mpirun"
'params_name_2' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
How can I avoid this updating?

my %hash_mpi;
$hash_mpi{value}->{bind_to} = "none";
my %hash;
$hash{value} = $hash_mpi{value};
#{$parallel_hash{"params_name_$i"}} = ("reporter","xml_obj",$hash{value});
is a weird way of doing
my $value = { bind_to => "none" };
$parallel_hash{ "params_name_$i" } = [ "reporter", "xml_obj", $value ];
You're adding a reference to same hash to every array.
You want
my %parallel_hash;
for my $i ( 0 .. 2 ) {
$parallel_hash{ "function_name_$i" } = "sharp_mpi_steps::run_mpirun";
my %hash = ( # Create a new hash.
bind_to => "none",
reporter_message => "process_$i",
);
$parallel_hash{ "params_name_$i" } = [
"reporter",
"xml_obj",
\%hash, # Create a reference to that hash.
];
}
{} does those two things at once.
my %parallel_hash;
for my $i ( 0 .. 2 ) {
$parallel_hash{ "function_name_$i" } = "sharp_mpi_steps::run_mpirun";
$parallel_hash{ "params_name_$i" } = [
"reporter",
"xml_obj",
{
bind_to => "none",
reporter_message => "process_$i",
}
];
}
That's a very weird data structure, by the way. Using an array would make more sense.
my #data;
for my $i ( 0 .. 2 ) {
push #data, {
function => "sharp_mpi_steps::run_mpirun",
params => [
"reporter",
"xml_obj",
{
bind_to => "none",
reporter_message => "process_$i",
}
],
};
}

Related

Perl Issue trying to add static text by IP address

I have a script that has an exact count of IP address' being compared to an expected count of IP address going though a specific port.
Code:
my %minimum = (
'10.10.10.10' => 2,
'10.10.10.11' => 3,
'10.10.10.12' => 6,
'10.10.10.13' => 7,
);
my %count;
open my $fh, '-|', 'netstat -an |grep 1111 ' or die "could not run netstat: $!";
while(<$fh>) {
next unless /^\s*............(regex) /;
$count{$1}++;
}
close $fh;
while(my ($ip, $expected) = each %minimum) {
$count{$ip} ||= 0;
next if $count{$ip} == $expected && print color("green"), "$ip: OK! Expected = $expected count = $count{$ip}\n", color("reset");
print color("red"), "$ip: BAD! Expected = $expected count = $count{$ip}\n", color("reset");
}
I'm trying to add a static hostname. Currently an example output looks like:
10.10.10.10: OK! Expected = 2 Actual = 2
10.10.10.11: OK! Expected = 3 Actual = 3
10.10.10.12: OK! Expected = 6 Actual = 6
10.10.10.13: BAD! Expected = 7 Actual = 5
But I want to include a static hostname to look like below:
10.10.10.10: aaaa#aa.com OK! Expected = 2 Actual = 2
10.10.10.11: bbb#aa.com OK! Expected = 3 Actual = 3
10.10.10.12: ccc#aa.com OK! Expected = 6 Actual = 6
10.10.10.13: ddd#aa.com BAD! Expected = 7 Actual = 5
Thank you all for any recommendations/tips.
You could create a second hash to keep the info, keyed on the ip addresses, or you could create a nested data structure like so:
my %minimum = (
'10.10.10.10' => { label => 'hotdog', count => 2 },
'10.10.10.11' => { label => 'burger', count => 3 },
'10.10.10.12' => { label => 'steak', count => 6 },
'10.10.10.13' => { label => 'pizza', count => 7 },
);
and then later, when you need the info, you can retrieve it:
while(my ($ip, $data) = each %minimum) {
$count{$ip} ||= 0;
my $label = $data->{label};
my $expected = $data->{count};
# ... rest of code here ...
}
my %notes = (
'10.10.10.10' => 'cheeseburger',
'10.10.10.11' => 'hotdog',
'10.10.10.12' => '...',
'10.10.10.13' => '...',
);
s{^([^:]*):\K}{ defined($notes{$1}) ? " $notes{$1}" : "" }e;

Add several records in moodle

I've been having trouble adding items in my table in moodle, this is what I've trying with no success.
$totalrec = array();
$rec2 = $DB->get_records('table1', null, '', '*', 0, 0);
$rec4 = $DB->get_records('table2', array('x' => 'y') , '', '*', 0, 0);
foreach ($rec2 as $records2) {
$rec3 = $DB->get_records('z', array('m' => 'n') , '', '*', 0, 0);
foreach ($rec3 as $records3) {
if (isset($_REQUEST['a']) && isset($_REQUEST['b'])) {
$ca = $_REQUEST['a'];
$co = $_REQUEST['b'];
$pi = $records2->idp;
$recorsh = new class ();
$recorsh->id = $records2->id;
$recorsh->te = $co;
$recorsh->idt = $ti;
$recorsh->res = $ca;
$recorsh->ida = $idaud;
$totalrec[$n] = array($recorsh);
$n++;
}
}
}
$lastinsertid2 = $DB->insert_records('table4', $totalrec);
and, this one:
$rec2 = $DB->get_records('table1', null, '', '*', 0, 0);
$rec4 = $DB->get_records('table2', array('x' => 'y') , '', '*', 0, 0);
foreach($rec2 as $records2) {
$rec3 = $DB->get_records('z', array('m' => 'n') , '', '*', 0, 0);
foreach($rec3 as $records3) {
if (isset($_REQUEST['a']) && isset($_REQUEST['b'])) {
$ca = $_REQUEST['a'];
$co = $_REQUEST['b'];
$pi = $records2->idp;
$recorsh = new class ();
$recorsh->id = $records2->id;
$recorsh->te = $co;
$recorsh->idt = $ti;
$recorsh->res = $ca;
$recorsh->ida = $idaud;
$lastinsertid = $DB->insert_record('table4', $recorsh, false);
}
}
}
Both of them gives me a "Error writing to database" but doesn't say anything specific, I know that I'm not doing the inserting "in the right way" but I don't know how to do it, what am I doing wrong?
It's probably because the ID is added to each object before inserting.
$recorsh->id = $records2->id;
Like davosmith says, during development always have debugging set to developer level.
In your config.php have this
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 0);
$CFG->debug = E_ALL | E_STRICT; // 32767;
$CFG->debugdisplay = true;
Also never ever use $_REQUEST or $_GET or $_POST directly. This can introduce SQL injection.
Use
$a = optional_param('a', null, PARAM_XXX);
$b = optional_param('b', null, PARAM_XXX);
or
$a = required_param('a', PARAM_XXX);
$b = required_param('b', PARAM_XXX);
Change PARAM_XXX to the type of parameter you are expecting. eg PARAM_INT, PARAM_BOOL etc.

Hash reference - Reuse inner hash to store and retrieve next values

I am new to Perl programming and have to work on Hash of Hashes. I am trying to reuse innerHash variables to be dynamic in nature. And I expect the inner items to be stored in outerHash how ever many I have added. Below is my test program snippet.
use warnings;
sub testHash {
my %outerHash = ();
my %innerHash1 = ();
my %innerHash2 = ();
$innerHash1{"key1"} = "value1";
$innerHash1{"key2"} = "value2";
$innerHash1{"key3"} = "value3";
$outerHash{"Master1"} = \%innerHash1;
$innerHash2{"key4"} = "value4";
$innerHash2{"key5"} = "value5";
$innerHash2{"key6"} = "value6";
$outerHash{"Master2"} = \%innerHash2;
#delete $innerHash1{$_};
%innerHash1 = ();
#undef %innerHash1;
$innerHash1{"key7"} = "value7";
$innerHash1{"key8"} = "value8";
$innerHash1{"key9"} = "value9";
$outerHash{"Master3"} = \%innerHash1;
foreach $outerItem (keys %outerHash){
print "\n$outerItem: ";
foreach $innerItem (keys %{$outerHash{$outerItem}}){
print "\t $innerItem = $outerHash{$outerItem}{$innerItem}";
}
print "\n-------------------------------------------------------";
}
print "\n";
}
testHash;
Output:
Master3: key8 = value8 key7 = value7 key9 = value9
-----------------------------------------------------------------
Master2: key5 = value5 key6 = value6 key4 = value4
-----------------------------------------------------------------
Master1: key8 = value8 key7 = value7 key9 = value9
-----------------------------------------------------------------
I understand it's taking the newer reference of innerHash1 while printing the items. What is the right way to have all the right elements in outerHash? In a real programming scenario I cannot declare n variables in advance.
You may be new to perl, but you understand the concept of pointers don't you? The code $outerHash{"Master1"} = \%innerHash1; means that "$outerHash{"Master1"} is assigned a pointer to %innerHash1". So what you're observing is correct and expected.
If you want to keep recreating %innerHash and adding it to %outerHash, you will need to do one of two things:
Assign by value. $outerHash{"Master1"} = {}; %{$outerHash{"Master1"}} = %innerHash1;
Only add %innerHash to %outerHash once per loop. Since %innerHash is redeclared within the loop, not outside of it, it goes out of scope every loop, but its contents will be kept in outerHash due to perl's reference counting. Depending on your perspective, this could be considered "trying to be too clever and potentially dangerous", but I think it's fine.
The "right" way, at least in my opinion, is by never declaring any intermediary "innerhashes" at all. Just use references directly:
my %outerHash;
$outerHash{Master1} = { key1 => 'value1', key2 => 'value2', key3 => 'value3'};
$outerHash{Master2} = { key4 => 'value4', key5 => 'value5', key6 => 'value6'};
$outerHash{Master3} = { key7 => 'value7', key8 => 'value8', key9 => 'value9'};
# or....
my %outerHash2;
$outerHash2{Master1}{key1} = 'value1';
$outerHash2{Master1}{key2} = 'value2';
$outerHash2{Master1}{key3} = 'value3';
$outerHash2{Master2}{key4} = 'value4';
$outerHash2{Master2}{key5} = 'value5';
$outerHash2{Master2}{key6} = 'value6';
$outerHash2{Master3}{key7} = 'value7';
$outerHash2{Master3}{key8} = 'value8';
$outerHash2{Master3}{key9} = 'value9';
# or...
my %outerHash3 = (
Master1 => {
key1 => 'value1',
key2 => 'value2',
key3 => 'value3'
}
Master2 => {
key4 => 'value4',
key5 => 'value5',
key6 => 'value6'
}
Master3 => {
key7 => 'value7',
key8 => 'value8',
key9 => 'value9'
}
);

Uncaught exception 'MongoCursorException' with message .... duplicate key error index:

Here's my code:
When i try to work it, there's an error as it:
"Fatal error: Uncaught exception 'MongoCursorException' with message
'localhost:27017: E11000 duplicate key error index:
futbol_db.maclar.$kod_1_link_1 dup key:
{ : null, : null }' in /var/www/html/cagkansokmen/futbol/db/maclar.php:182
Stack trace: #0 /var/www/html/cagkansokmen/futbol/db/maclar.php(182):
MongoCollection->insert(Array) #1 {main} thrown in
/var/www/html/cagkansokmen/futbol/db/maclar.php on line 182"
The problem is about insert. Because, when i drop insert code, there's no problem about this code. But if i try to insert data, there's an error just as i said.
How can i fix it?
$collection1 = $db->lig_kod;
$collection_maclar = $db->maclar;
$collection1->ensureIndex(array("kod" => 1, "link" => 1), array("unique" => true, "dropDups" => true));
$a = $collection1->find(array())->limit(15)->skip(0);
foreach($a as $b){
$kod = $b["kod"];
$link = $b["link"];
$parc = explode(',', $link);
$ligkoduson = $parc[0].",".$parc[1];
$url2 = "http://www.stats.betradar.com/s4/gismo.php?&html=1&id=1424&language=tr&clientid=35&state=".$ligkoduson.",5_".$kod.",9_fixtures,231_fixtures,23_1,242_21&child=0";
$url2 = curl($url2);
$url2 = str_replace("\t","",$url2);
$url2 = str_replace("\n","",$url2);
$url2 = str_replace("\r","",$url2);
$bul = ara("<![CDATA[", "]]>", $url2);
$sonuc = ara("setState('", ",", $bul[0]);
$say = count($sonuc);
for($i = 0; $i<$say; $i++){
$sezonbul = $sonuc[$i];
$lonk = "http://www.stats.betradar.com/s4/gismo.php?&html=1&id=2127&language=tr&clientid=35&state=".$ligkoduson.",".$sezonbul.",9_fixtures,231_full,23_1&child=2";
$fiksturlink = curl("http://www.stats.betradar.com/s4/gismo.php?&html=1&id=2127&language=tr&clientid=35&state=".$ligkoduson.",".$sezonbul.",9_fixtures,231_full,23_1&child=2");
$fiksturlink = str_replace("\t","",$fiksturlink);
$fiksturlink = str_replace("\n","",$fiksturlink);
$fiksturlink = str_replace("\r","",$fiksturlink);
$kategori = ara('title="', '"', $fiksturlink);
$kategori_parcala = explode(' > ', $kategori[0]);
$tur = trim($kategori_parcala[0]);
$ulke = trim($kategori_parcala[1]);
$lig = $kategori_parcala[2];
$lig_parcala = explode(' ', $lig);
$lig_bosluk = count($lig_parcala)-1;
$sezon = trim($lig_parcala[$lig_bosluk]);
$lig_son = trim(str_replace($sezon, "", $lig));
$takimlar = ara('<span class="teams">', '</a>', $fiksturlink);
$timebul = ara('<td class="datetime">', '</td>', $fiksturlink);
$fhbul = ara('<td class="p1 ">', '</td>', $fiksturlink);
$ftbul = ara('<td class="nt ftx ">', '</td>', $fiksturlink);
$dongusay = count($takimlar);
echo $dongusay."<br>";
for($dongu = 0; $dongu<$dongusay; $dongu++){
$takimlarbul = ara('">', '</span>', $takimlar[$dongu]);
$home = trim($takimlarbul[0]);
$away = trim($takimlarbul[2]);
$time = trim($timebul[$dongu]);
$time_ayir = explode(' ', $time);
$yil_ayir = explode('/', $time_ayir[0]);
$gun = $yil_ayir[0];
$ay = $yil_ayir[1];
$yil = $yil_ayir[2];
$saat_ayir = explode(':', $time_ayir[1]);
$saat = $saat_ayir[0];
$dk = $saat_ayir[1];
$time_sonuc = mktime($saat, $dk, 0, $ay, $gun, $yil);
$fh = trim($fhbul[$dongu]);
if(empty($fh)){
$fh1 = null;
$fh2 = null;
}else{
$fh_ayir = explode(':', $fh);
$fh1 = $fh_ayir[0];
$fh2 = $fh_ayir[1];
}
$ft = trim($ftbul[$dongu]);
if(empty($ft)){
$ft1 = null;
$ft2 = null;
}else{
if(strpos($ft, '(')){
$parcala1 = explode('(', $ft);
$ft_ayir = explode(':', $parcala1[0]);
$ft1 = $ft_ayir[0];
$ft2 = $ft_ayir[1];
}else{
$ft_ayir = explode(':', $ft);
$ft1 = $ft_ayir[0];
$ft2 = $ft_ayir[1];
}
}
echo $ligkoduson."-".$sezonbul."-".$tur."-".$ulke."-".$lig_son."-".$sezon."-".$home."-".$away."-".$time_sonuc."-".$fh1."-".$fh2."-".$ft1."-".$ft2."<br>";
$collection_maclar->insert(array(
'ulke_kodu'=>$ligkoduson,
'sezon_kodu'=>$sezonbul,
'tur'=>$tur,
'ulke'=>$ulke,
'lig'=>$lig_son,
'sezon'=>$sezon,
'home'=>$home,
'away'=>$away,
'tarih'=>$time_sonuc,
'fh1'=>$fh1,
'fh2'=>$fh2,
'ft1'=>$ft1,
'ft2'=>$ft2
));
}
}
}
You have an unique index on "kod" and "link", but the document you are inserting doesn't include either of these fieldnames.
That means the first document you insert will have these values as null, and the second one will too.. but fails as it violoates the unique index you created.
Note that the "dropDupe" flag you provide with the ensureIndex() command only means "drop existing duplicates", not "if I try to use that key again, drop the previous document".
Your current code seems to be ensuring this index on the "lig_kod" collection, but I suspect you may have previously (maybe accidentally) used the $collection_maclar variable, rather then the $collection1 variable and executed the code, resulting in creating the index on the maclar collection.
-Hannes

Php Notice: Use of undefined constant

What am i doing wrong ?
echo try_add("test","2562782");
echo try_add("test","25627826");
function try_add($ct,$tankid){
$file = 'testFile_'.$ct.'.txt';
$pizza = file_get_contents($file);
preg_match_all("/Tankid:(?P.*?);/", $pizza, $pie);
//print_r($pie);
//outputs
//Array
//(
// [0] => Array
// (
// [0] => Tankid:2562782;
// [1] => Tankid:25627826;
// [2] => Tankid:2562782;
// [3] => Tankid:25627826;
// )
//
// [this] => Array
// (
// [0] => 2562782
// [1] => 25627826
// [2] => 2562782
// [3] => 25627826
// )
//
// [1] => Array
// (
// [0] => 2562782
// [1] => 25627826
// [2] => 2562782
// [3] => 25627826
// )
//
//)
foreach($pie[this] as $thi){
if($thi == $tankid){
$inthis = "yes";
}
else{
$inthis = "no";
}
}
if($inthis == "no"){
$myFile = "testFile_$ct.txt";
$fh = fopen($myFile, 'a');
$stringData = "Tankid:$tankid;\n";
fwrite($fh, $stringData);
fclose($fh);
return "This '$tankid' has been added in this file '$myFile' \n";
}
else{
return "This '$tankid' is already in this file '$myFile' \n";
}
}
//Code outputs
//Notice: Use of undefined constant this - assumed 'this' in \xampp\htdocs\new.php on line 39
//This '2562782' has been added in this file 'testFile_test.txt'
//Notice: Use of undefined constant this - assumed 'this' in \xampp\htdocs\new.php on line 39
//This '25627826' has been added in this file 'testFile_test.txt'
Change
foreach($pie[this] as $thi){
Into
foreach($pie['this'] as $thi){
You just need to rewrite
foreach($pie[this] as $thi){
into
foreach($pie[$this] as $thi){
You could even use
foreach($pie as $thi){