I'm stuck with this logic proble.m - php

WHAT I HAVE:
-I have a file with various products ( Flag "P" mean reserved, without "P" mean sold but not reserved)
ELEMENTS
PRODOTTO Quantita Terminale
TAMOXIFENE EG*20CPR RIV 20MG 00002n 04
FERRITIN COMPLEX*OS 10FL 8ML 00001 P 01
VOLTADOL*10CER MEDIC 140MG 00001n 05
LEDERFOLIN*10CPR 7,5MG 00002 P 03
-From this file,through a regular php expression (that search only strings with "P" flag), I extract products and insert it into mysql db.
insericineldb.php
$txt = file_get_contents('./FILE', true);
$specialChars = preg_quote( '#$%^&*()+=-[]\';,./{}|\":<>?~', '#' );
preg_match_all('#([0-9]{4,9}\s+[A-Z]{1}\s+([' . $specialChars . 'A-Z0-9 ]+)\s+([0-9]{3,7})n?\s+P\s+([0-9]+))#', $txt, $match);
$products = [];
foreach (array_keys($match[2]) as $idx) {
$tagliaprodotto = rtrim(substr($match[2][$idx],1));
$tagliaquantita = ltrim($match[3][$idx],'0');
$products[] = [
'prodotto' => $tagliaprodotto,
'quantita' => $tagliaquantita,
'terminale' => $match[4][$idx]
];
}
$query = $pdo->prepare('INSERT INTO tabella (prodotto, quantita, terminale, data) VALUES (:prodotto, :quantita, :terminale, NOW()) ON DUPLICATE KEY UPDATE quantita = VALUES(quantita), terminale = VALUES(terminale)');
foreach ($products as $product) {
$query->execute($product);
}
-I extract products automatically thanks to the use of a batch (which monitors the variation of the file).
BATCH
#echo off
:loop
timeout -t 1 >nul
for %%i in (c:\file) do echo %%~ai|find "a">nul || goto :loop
"c:\xampp\php\php.exe" -f c:\xampp\htdocs\inseriscineldb.php
rem do workload
attrib -a c:\file
goto :loop
The file:
-At a certain time NOT REGULAR (when they make the final order, 2 times a day) is emptied NOT COMPLETELY (some strings with and without "P" remain in the file but they aren't important, are important only for logic because I can't use an if as: when P=0 don't start the query).
-Furthermore sometimes some products (ES. FERRITIN COMPLEX*OS 10FL 8ML 00001 P 01) is eliminated VOLUNTARILY (Suppose a customer wants a 50-milliliter product, i reserve it but after he wants a 8-milliliter product, the old 50 milliliters order will not be deleted from the database)
PROBLEM:
1)So if I enter products into the database through INSERT INTO when one of the elements is removed voluntarily, it isn't removed from the database.
2)However, if I use REPLACE instead of INSERT, when the file is emptied, the other elements inside the database will also be deleted and now I'm stuck.

A way to to this in a pretty simple manner, is to read all the elements from the Database ( with a "select * from tabella) then check which one is present into the file and delete / insert / update what you need.

Related

Parse strings of numbers and domain/subdomain strings, group, then sum numbers in each group

In PHP, I have an array that shows how many times user clicked on each individual domain like this:
$counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk"
];
How can i use this input as a parameter to a function and returns a data structure containing the number of clicks that were recorded on each domain AND each subdomain under it. For example, a click on "mail.yahoo.com" counts toward the totals for "mail.yahoo.com", "yahoo.com", and "com". (Subdomains are added to the left of their parent domain. So "mail" and "mail.yahoo" are not valid domains. Note that "mobile.sports" appears as a separate domain near the bottom of the input.)
Sample output (in any order/format):
calculateClicksByDomain($counts) =>
com: 1345
google.com: 900
stackoverflow.com: 10
overflow.com: 20
yahoo.com: 410
mail.yahoo.com: 60
mobile.sports.yahoo.com: 10
sports.yahoo.com: 50
com.com: 5
org: 3
wikipedia.org: 3
en.wikipedia.org: 2
m.wikipedia.org: 1
mobile.sports: 1
sports: 1
uk: 1
co.uk: 1
google.co.uk: 1
The first step I am stuck at is how can to get subdomains from for example
"mobile.sports.yahoo.com"
such that result is
[com, yahoo.com, sports.yahoo.com, mobile.sports.yahoo.com]
This code would work:
$counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk"
];
function calculateClicksByDomain($dataLines)
{
$output = [];
foreach ($dataLines as $dataLine) {
[$count, $domain] = explode(',', $dataLine);
$nameParts = [];
foreach (array_reverse(explode('.', $domain)) as $namePart) {
array_unshift($nameParts, $namePart);
$domain = implode('.', $nameParts);
$output[$domain] = ($output[$domain] ?? 0) + $count;
}
}
return $output;
}
print_r(calculateClicksByDomain($counts));
See: https://3v4l.org/o5VgJ#v8.0.26
This function walks over each line of the data and explodes it into a count and a domain. After that it explodes the domain by the dots, reverses it, and walks over those name parts. In that loop it reconstructs the various subdomains and counts them into the output.

filter data with php or sql?

I'm not sure if this is an anti-pattern or not, but it feels a bit convoluted, so I'd like to get your opinion on how these cases should be handled:
Let's say we have this data:
$sofas[0]['color'] = 'green';
$sofas[0]['pillows'] = 8;
$sofas[0]['pattern'] = 'moons';
$sofas[1]['color'] = 'green';
$sofas[1]['pillows'] = 8;
$sofas[1]['pattern'] = 'ducks';
$sofas[1]['footrest'] = 'small';
$sofas[2]['color'] = 'green';
$sofas[2]['pillows'] = 8;
$sofas[2]['pattern'] = 'stripes';
$sofas[2]['speakers'] = 'badass';
color, pillows and pattern comes from the database, whilst "footrest" and "speakers" have been added on by an api.
We can say for the sake of argument that there are 1250 different attributes that can be added by the api like "footrest" and "speakers".
We now want to load an some data from the database based on these attributes, like an image for example.
So we have a table that looks like this:
ID , attribute_value, image
1 , 'color_green' 'img0023',
2 , 'pillows_8' 'img003',
3 , 'pattern_moons' 'img002',
6 , 'pattern_ducks' 'img0083',
7 , 'footrest_small' 'img0058',
10 , 'pattern_stripes''img0073',
11 , 'speakers_badass''img00pluto'
etc , etc , etc;
So, the way I figure I can approach this two ways:
$sofaSQL="'color_green',
'pillows_8',
'pattern_moons',
'pattern_ducks',
'footrest_small',
'pattern_stripes',
'speakers_badass'";
$sql = "SELECT ID, attribute_value, image
FROM `example`
WHERE attribute_value IN ($sofaSQL)"
and then loop through the array and check if the key + '_' + value matches the rows in the recordset to see what images should be used for sofas[0], sofas[1] and sofas[2].
The other option I see would be to prep each sofa with a different sql statement, ie:
$sofaSQL="'color_green',
'pillows_8',
'pattern_moons';
-add images-
$sofaSQL="'color_green',
'pillows_8',
'pattern_ducks',
'footrest_small';
-add images-
$sofaSQL="'color_green',
'pillows_8',
'pattern_stripes',
'speakers_badass'";
-add images-
That seems simpler, but it doesn't feel right to hammer the database with a seperate request for each item in the array.
So, what would you recommend in this case? IS there a better way of dealing with attributes that are selected randomly/from an api?

PHP: "While" loop returns same value for each iteration of the variable

Thanks in advance for any help offered.
I'm performing a query that returns something like this:
route | busnumber
2 300
4 123
2 455
12 934
My goal is to print/echo a list of all "busnumber" were "route" = 2.
I know I can do a query on the DB to do this but I don't want to run this query for each and every route. The result set is actually part of one master, complex query so I need to accomplish my goal using the array.
The query works correctly and does display the appropriate info. I also return the results into an array. i.e ...
$query=("SELECT * from foo")
$result=mysql_fetch_assoc($query);
My current code looks like this (note my comments):
mysql_data_seek( $result,0); // because I'm previously iterating through $result
while ($i2=mysql_fetch_assoc($result)) {
$busnumber=$i2['busnumber'];
$busroute=$i2['route'];
echo "<div class='businfo'>";
if ($busroute='2'){ // I only want this to happen if $busroute=2
echo "Current Route = $busroute</br>";
echo "Bus Number : $busnumber </br>";
}
echo "</div>";
}
What I'm getting, however, it is echoing the same '$busroute' (2) but different '$busnumber' for each row as such:
Current Route = 2
Bus Number : 194
Current Route = 2
Bus Number : 196
Current Route = 2
Bus Number : 2002
Current Route = 2
Bus Number : 2010
Current Route = 2
Bus Number : 2013
The problem is that all of those bus numbers are not part of route 2. It is a listing of bus numbers from all routes. I only want it to perform the foreach loop if $routenumber=2.
Thanks again for the help :)
if ($busroute='2'){
The problem is that you're not checking whether it's equal to 2 here, you're assigning it to equal 2. Change it to this and you'll be fine:
if ($busroute=='2'){
$query = "SELECT * from foo";
$result = mysql_query($query);
while($row = mysql_fetch_assoc($result)) {
if ($row['route'] == 2) {
// do your stuff
}
}

Making the leap from PhP to Python

I am a fairly comfortable PHP programmer, and have very little Python experience. I am trying to help a buddy with his project, the code is easy enough to write in Php, I have most of it ported over, but need a bit of help completing the translation if possible.
The target is to:
Generate a list of basic objects with uid's
Randomly select a few Items to create a second list keyed to the uid containing new
properties.
Test for intersections between the two lists to alter response accordingly.
The following is a working example of what I am trying to code in Python
<?php
srand(3234);
class Object{ // Basic item description
public $x =null;
public $y =null;
public $name =null;
public $uid =null;
}
class Trace{ // Used to update status or move position
# public $x =null;
# public $y =null;
# public $floor =null;
public $display =null; // Currently all we care about is controlling display
}
##########################################################
$objects = array();
$dirtyItems = array();
#CREATION OF ITEMS########################################
for($i = 0; $i < 10; $i++){
$objects[] = new Object();
$objects[$i]->uid = rand();
$objects[$i]->x = rand(1,30);
$objects[$i]->y = rand(1,30);
$objects[$i]->name = "Item$i";
}
##########################################################
#RANDOM ITEM REMOVAL######################################
foreach( $objects as $item )
if( rand(1,10) <= 2 ){ // Simulate full code with 20% chance to remove an item.
$derp = new Trace();
$derp->display = false;
$dirtyItems[$item->uid] = $derp; //# <- THIS IS WHERE I NEED THE PYTHON HELP
}
##########################################################
display();
function display(){
global $objects, $dirtyItems;
foreach( $objects as $key => $value ){ // Iterate object list
if( #is_null($dirtyItems[$value->uid]) ) // Print description
echo "<br />$value->name is at ($value->x, $value->y) ";
else // or Skip if on second list.
echo "<br />Player took item $value->uid";
}
}
?>
So, really I have most of it sorted I am just having trouble with Python's version of an Associative array, to have a list whose keys match the Unique number of Items in the main list.
The output from the above code should look similar to:
Player took item 27955
Player took item 20718
Player took item 10277
Item3 is at (8, 4)
Item4 is at (11, 13)
Item5 is at (3, 15)
Item6 is at (20, 5)
Item7 is at (24, 25)
Item8 is at (12, 13)
Player took item 30326
My Python skills are still course, but this is roughly the same code block as above.
I've been looking at and trying to use list functions .insert( ) or .setitem( ) but it is not quite working as expected.
This is my current Python code, not yet fully functional
import random
import math
# Begin New Globals
dirtyItems = {} # This is where we store the object info
class SimpleClass: # This is what we store the object info as
pass
# End New Globals
# Existing deffinitions
objects = []
class Object:
def __init__(self,x,y,name,uid):
self.x = x # X and Y positioning
self.y = y #
self.name = name #What will display on a 'look' command.
self.uid = uid
def do_items():
global dirtyItems, objects
for count in xrange(10):
X=random.randrange(1,20)
Y=random.randrange(1,20)
UID = int(math.floor(random.random()*10000))
item = Object(X,Y,'Item'+str(count),UID)
try: #This is the new part, we defined the item, now we see if the player has moved it
if dirtyItems[UID]:
print 'Player took ', UID
except KeyError:
objects.append(item) # Back to existing code after this
pass # Any error generated attempting to access means that the item is untouched by the player.
# place_items( )
random.seed(1234)
do_items()
for key in objects:
print "%s at %s %s." % (key.name, key.x, key.y)
if random.randint(1, 10) <= 1:
print key.name, 'should be missing below'
x = SimpleClass()
x.display = False
dirtyItems[key.uid]=x
print ' '
objects = []
random.seed(1234)
do_items()
for key in objects:
print "%s at %s %s." % (key.name, key.x, key.y)
print 'Done.'
So, sorry for the long post, but I wanted to be through and provide both sets of full code. The PhP works perfectly, and the Python is close. If anyone can point me in the correct direction it would be a huge help.
dirtyItems.insert(key.uid,x) is what i tried to use to make a list work as an Assoc array
Edit: minor correction.
You're declaring dirtyItems as an array instead of a dictionary. In python they're distinct types.
Do dirtyItems = {} instead.
Make a dictionary instead of an array:
import random
import math
dirtyItems = {}
Then you can use like:
dirtyItems[key.uid] = x

How to retrieve 1 record at a time from db

I have a table comment as follow:
Comment
comment_id cmt followupid
1 Hello 3
2 hi 4
3 Hey 2
4 wassup 1
My query is that I want to echo "Hello", "hi", "hey" , "Wassup" and other (the record continues) individualy, I have used
$comment = mysql_result($runQuery, $i,"cmt");
echo $comment;
which works fine but the problem is that it echoes all the comments at once, what I want is to echo all the comment but one at a time. the comment are in a div tag such that each the div appears only after 1 second the page is loaded. I want each comment to appear after different time interval
for e.g:
Hello to appear at 5pm (not necessarily the corect time it can be just an int)
hi 5.10 pm
hey 6.30 pm
Please Help!
The following code should give you some hints.
$result = mysql_query($runquery);
while($row=mysql_fetch_assoc($result)){
// $row contains a single row.
echo $row['cmt'], $row['comment_id']
}
Create another variable storing time divisions(or number of rows). So that different output at different time can be fetched. For eg. If your table has 24 rows(or items), then this variable shall have a value 24. Use it to divide you output times(As in 24 hours, each hour a different value).
Now, the PHP part(I am not much familiar with date and time functions in PHP, so you can totally ignore the paragraph above.
$result = mysql_query($runquery);
$j = 0;
$i = rand( 0, mysql_num_rows($result) );
while($row=mysql_fetch_assoc($result)){
// $row contains a single row.
if( $j++ = $i )
echo $row['cmt'], $row['comment_id'];
}
This will fetch one random row from the table, but not depending upon the server time.

Categories