I have just started building a webapp in Codeigniter and i can't solve a problem with nested queries in my model.
I have three Tables:
Categories, Links and Topics. Every Link and every Topic can have just one Category, whereas every Category can have multiple Links or Topics.
Every Link can have one Topic (or no Topic at all) and every Topic can have one or more Links.
The Table-Structure looks like this (shortened):
Categories:
- ID
- DESCR
Links:
- ID
- DESCR
- ID_CATEGORY
- ID_TOPIC (either an ID from the Topics-Table or NULL)
Topics:
- ID
- DESCR
- ID_CATEGORY
In my View, i want to display them in the following manner:
- Category 1
- Link 1
- Link 2
- Topic 1
- Topiclink 1
- Topiclink 2
- Link 3
- Category 2
- Topic 2
- Topiclink 3
- Topiclink 4
- Topic 3
- Topiclink 5
- Topiclink 6
- Link 4
So there will be 3 nested queries.
My Model looks like this:
public function get_categories(){
//1. Get the categories
$this->db->select("
ec.ID_CATEGORY,
c.DESCR,
c.VISIBLE,
i.KEYVALUE");
$this->db->from("episode_categories ec");
$this->db->join("categories c", "c.ID = ec.ID_CATEGORY");
$this->db->join("ini i", "i.SETTING = c.VISIBLE");
$this->db->where("i.KEYWORD", "CATEGORY_VISIBLE");
$this->db->where("ec.ID_EPISODE", $_SESSION['cur_episode']);
$categories = $this->db->get()->result_array();
//2. Get the Entries (Topics and Links with NULL as TOPIC_ID)
foreach($categories as $key => $value)
{
$sql_links="SELECT
pf_users.USERNAME,
pf_users.NAME_SHOW,
pf_links.ID AS ID,
pf_links.URL AS URL,
pf_links.ID_USER AS ID_USER,
pf_links.ID_EPISODE,
pf_links.ID_CATEGORY,
pf_links.DESCR,
NULL AS IS_TOPIC,
pf_links.REIHENF,
pf_links.DONE,
pf_links.DONE_TS,
pf_links.INFO AS INFO,
pf_episoden.DONE AS EPISODE_DONE
from pf_links
JOIN pf_users on pf_users.ID = pf_links.ID_USER
JOIN pf_episoden on pf_episoden.ID = pf_links.ID_EPISODE
WHERE ID_EPISODE = ".$_SESSION['cur_episode']." AND ID_CATEGORY = ".$value['ID_CATEGORY']." AND ID_TOPIC IS NULL
UNION ALL SELECT pf_users.USERNAME,
pf_users.NAME_SHOW,
pf_topics.ID AS ID,
NULL AS URL,
pf_topics.ID_USER AS ID_USER,
pf_topics.ID_EPISODE,
pf_topics.ID_CATEGORY,
pf_topics.DESCR,
1 AS IS_TOPIC,
pf_topics.REIHENF,
pf_topics.DONE,
pf_topics.DONE_TS,
pf_topics.INFO AS INFO,
pf_episoden.DONE AS EPISODE_DONE
from pf_topics
JOIN pf_users on pf_users.ID = pf_topics.ID_USER
JOIN pf_episoden on pf_episoden.ID = pf_topics.ID_EPISODE
WHERE ID_EPISODE = ".$_SESSION['cur_episode']." AND ID_CATEGORY = ".$value['ID_CATEGORY']." ORDER BY REIHENF,
ID ASC";
$query_links = $this->db->query($sql_links);
$categories[$key]['link_list'] = $query_links->result_array();
//3. Get the Topiclinks (Links with an ID_TOPIC set)
foreach( $categories[$key]['link_list'] as $key2 => $value2)
{
if($value2['IS_TOPIC'] == 1)
{
$sql_topic_links = "SELECT * FROM pf_links WHERE ID_TOPIC = ".$value2['ID'];
$query_topic_links = $this->db->query($sql_topic_links);
$categories[$key2]['topic_links'] = $query_topic_links->result();
}
}
}
return $categories;
}
Everything works fine until the links of the topics (So Step 3 in the Code). The array i get is the same for every topiclink with the last one of the possible ID_TOPIC. So the links within the topics are all the same.
What do i have to change to get just the links for the specific topics in the third step of the function?
Thank you in advance!
I was able to solve the issue:
In Step 3 the following line
$categories[$key2]['topic_links'] = $query_topic_links->result();
must be changed to:
$categories[$key]['link_list'][$key2]['topic_links'] = $query_topic_links->result_array();
So in my view i can iterate trhough the result-sets.
I am attempting to create a share/stock portfolio based system that will enter at the open and possibly exit on the same day at close if the conditions are met. I have this basicaly working. The thing i cant get going is that I would like my stock system to only ever have 1 open postion in a company at any time.
It seems that if there is both an exit and an entry on the same day, amibroker backtesting is allowing the same company to be purchased on the open, if that same company has a sell order on that same day. Here is an example of this:
Notice at point 1 - we would be entering at the open on the 17th
At point 2, we get a sell signal that day, so we should exit at Close on the 24th.
However at point 3 - we have an entry for the same company on the same day.
To be clear - I would like to allow multiple entries on the same day - this is working. The only thing i would like to figure out is to prevent the backtester from entering the SAME company on the SAME day it exits, as due to the system rules, we would have one day of having 2 positions in the 1 company.
Here is the sample code to replicate this:
SetOption("AllowSameBarExit", True );
SetOption("SettlementDelay", 1 );
Buy = C > MA(C,10);
Sell = C < MA(C,10) OR C > O;
// trade on todays open
SetTradeDelays( 0, 0, 0, 0 );
BuyPrice = Open;
SellPrice = Close;
SetPositionSize( 20, spsPercentOfEquity );
I have read and re-read the page on portfolio timing: here but I still cant figure out how to prevent the entries for the same company on the same day as an exit.
Any help would be greatly appreciated!
UPDATE
It appears that using the OR C > O in the SELL condition is effecting this. If I remove the OR C > O part, I get the correct behaviour. It is entering on the NEXT day. Now Im wondering how to use that exit without reverting back to same bar same company entry and exit...
Thanks to Tomasz from Amibroker for posting the below solution:
SetOption("AllowSameBarExit", True );
BuyPrice = Open;
SellPrice = Close;
Buy = Ref( Close > MA( Close, 10 ), -1 );
Sell = Close > Open OR Close < MA( Close,10);
// removing buys you don't want
intrade = False;
for( i = 0; i < BarCount; i++ )
{
if( NOT intrade )
{
if( Buy[ i ] )
{
intrade = True;
// same bar sell
if( Sell[ i ] ) intrade = False;
}
}
else
{
if( Sell[ i ] )
{
intrade = False;
Buy[ i ] = False; // remove buy if exited this bar
}
}
}
You can find : a detailed discussion here
I Have a SELECT with:
STATUS -1, 0 and 1.
The SELECT Statment:
SQL= "SELECT * FROM MYTABLE ORDER BY STATUS DESC"
SET MYDB = conn.Execute(SQL)
My issue:
Divide the SELECT in two parts with DO WHiLE/LOOP
PART 1:
"NOT EOF" of course
ALL STATUS 1 (priority and overule register limit)
Limit to XX registers (variable - TOTALREG)
NO STATUS -1
** STATUS 1 is the "Approved" status and can overrule the limit of registers.
I have a classroom with 20 students. (limit of registers)
but I can overbook this and make the class with 21, 22, 23 students - with "STATUS 1" = approved.
If I have only 15 approved - I will complete the limit of registers with the first 5 "STATUS 0" (Waiting for approval).
PART 2:
the rest of the SELECT
I Got a PARTIAL solution with this:
DO WHILE (((NOT MYDB.EOF) AND (CINT(COUNTREG) <= CINT(TOTALREG))) OR ((NOT MYDB.EOF) AND (MYDB("STATUS") > 0 ))) AND ((NOT MYDB.EOF) AND (MYDB("STATUS") > -1 ))
IF we have vacancies: (NOT MYDB.EOF) AND (CINT(COUNTREG) <= CINT(TOTALREG))
IF the register is approved: (NOT MYDB.EOF) AND (MYDB("STATUS") > 0 )
Exclude non-approved registers (status -1): (NOT MYDB.EOF) AND (MYDB("STATUS") > -1 )
- COUNTREG = will be incremented for each register inside the LOOP (countreg = countreg + 1)
- TOTALREG = Is a variable (number of person allowed in the classroom)
Its works with all situation.. but when I don't have registers with STATUS = -1 - I got an error '80020009'
why? any idea?
Chemicals have a trade name (which is what it is commonly referred to as) and an actual chemical name. I need to look up a trade name, find its proper chemical name, then get properties of that chemical. For example:
$tradeName = "Voranol"
if $tradeName == "Voranol" then
$productName = "Polyether Polyol"
$flare = "List I"
$bay = "1"
$listPos = 3
EndIf
I have an .au3 file that contains a ton of products. It works fine but it's kind of tedious to do if $tradeName == "Name1" or $tradeName == "Name2" or $tradeName == "Name4" or $tradeName == "Name5". I will also need to be able to edit it programmaticly. This is what I'm using now:
if $product == "dowanol pmb" or $product == "dowanol pma" or $product == "dipropylene glycol" or $product == "dowanol pnp" or $productCheck2 == "dowanol pmb" or $productCheck2 == "dowanol pma" or $productCheck2 == "dipropylene glycol" or $productCheck2 == "dowanol pnp" then
$result = "DIPROPYLENE GLYCOL"
$bay = 4
$useFlare = 1
$listPos = 2
elseif $product == "glycol blend" then
$result = "GLYCOL"
$bay = 3
$useFlare = 2
$listPos = 1
elseif $product == "isopar e" or $product == "isopar c" or $product == "isopar h" or $productCheck2 == "isopar h" then
$result = "PETROLEUM NAPTHA"
$bay = 5
$useFlare = 0
$listPos = 1
EndIf
; Note: 0 = No Flare, 1 = Normal Flare, 2 = CAS Flare
Another alternative to the database option is to use an XML document to store the product (chemical) information.
You could easily query the XML with XPath to get the product name/properties. Maintaining the file would be fairly easy too. You could even create an XML Schema to validate against to be sure your file is still valid after modifications.
The processing of the XML in AutoIt can be done a few different ways:
Creating an MSXML object
Running a command line tool like xmlstarlet
Using a XPath/XQuery/XSLT processor from the command line (i.e. java to run Saxon)
Running something like Saxon is probably overkill for what you need.
MSXML wouldn't be too bad and there should be multiple UDFs that already exist.
Xmlstarlet would be my vote. (Note: I haven't used xmlstarlet in this fashion before. I'm a huge fan of Saxon and use it almost exclusively. Specifically for AutoIt, I've used a combination of MSXML and Saxon; Saxon to do the transforms of complicated data into a smaller, simpler subset and then MSXML to do simple xpath queries on that subset. However, if I was going to do something like this, I'd give xmlstarlet a serious look.)
Also, if your data grows to the point that a single XML file does not make sense, you could always split it into a collection of smaller files; individual products maybe. You might also reach a point that it might make sense to load those files into an actual XML database (eXistdb is an option).
Here's a simple example of what your XML (schema and instance) might look like:
XSD (products.xsd)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="product"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="product">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="tradenames"/>
</xs:sequence>
<xs:attribute name="bay" use="required" type="xs:integer"/>
<xs:attribute name="listpos" use="required" type="xs:integer"/>
<xs:attribute name="useflare" use="required" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="tradenames">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="name" type="xs:string"/>
</xs:schema>
XML (products.xml)
<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="products.xsd">
<product bay="4" useflare="1" listpos="2">
<name>DIPROPYLENE GLYCOL</name>
<tradenames>
<name>dowanol pmb</name>
<name>dowanol pma</name>
<name>dipropylene glycol</name>
<name>dowanol pnp</name>
</tradenames>
</product>
<product bay="3" useflare="2" listpos="1">
<name>GLYCOL</name>
<tradenames>
<name>glycol blend</name>
</tradenames>
</product>
<product bay="5" useflare="0" listpos="1">
<name>PETROLEUM NAPTHA</name>
<tradenames>
<name>isopar e</name>
<name>isopar c</name>
<name>isopar h</name>
</tradenames>
</product>
</products>
Here's a little bit of AutoIt that uses MSXML to demonstrate loading the XML (validates against XSD) and searching for products that have a trade name that contains "glycol".
AutoIt
;~ AutoIt Version: 3.3.14.2
;String to search on.
$searchString = "glycol"
ConsoleWrite("Search string: '" & $searchString & "'" & #CRLF)
;XPath for searching trade names. Search string is injected (code injection; escaping of strings would be a very good idea!).
$xpath_tradename = "/products/product[tradenames/name[contains(.,'" & $searchString & "')]]"
ConsoleWrite("XPath: '" & $xpath_tradename & "'" & #CRLF)
$msxml = ObjCreate('MSXML2.DOMDocument.6.0')
If IsObj($msxml) Then
$msxml.async = False
$msxml.validateOnParse = True
$msxml.resolveExternals = True
$msxml.setProperty("SelectionLanguage", "XPath")
$msxml.load('products.xml')
If $msxml.parseError.errorCode = 0 Then
$prods = $msxml.SelectNodes($xpath_tradename)
If IsObj($prods) And $prods.Length > 0 Then
ConsoleWrite("Number of products found: '" & $prods.Length & "'" & #CRLF)
For $prod In $prods
ConsoleWrite(#CRLF & "------ PRODUCT ------" & #CRLF)
ConsoleWrite("Product name: '" & $prod.SelectSingleNode('name').text & "'" & #CRLF)
ConsoleWrite("Product bay: '" & $prod.getAttribute('bay') & "'" & #CRLF)
Next
ConsoleWrite(#CRLF)
Else
ConsoleWrite("PRODUCT NOT FOUND" & #CRLF)
EndIf
Else
MsgBox(17, 'Error', 'Error opening XML file: ' & #CRLF & #CRLF & $msxml.parseError.reason)
SetError($msxml.parseError.errorCode)
EndIf
EndIf
Console Output
Search string: 'glycol'
XPath: '/products/product[tradenames/name[contains(.,'glycol')]]'
Number of products found: '2'
------ PRODUCT ------
Product name: 'DIPROPYLENE GLYCOL'
Product bay: '4'
------ PRODUCT ------
Product name: 'GLYCOL'
Product bay: '3'
The best database solution in Autoit is SQLite.
If you want to do it like a pro, you should use SQLite.
#include <SQLite.au3>
#include <SQLite.dll.au3>
Local $hQuery, $aRow
_SQLite_Startup()
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & #CRLF)
_SQLite_Open()
; Without $sCallback it's a resultless statement
_SQLite_Exec(-1, "Create table tblTest (a,b int,c single not null);" & _
"Insert into tblTest values ('1',2,3);" & _
"Insert into tblTest values (Null,5,6);")
Local $d = _SQLite_Exec(-1, "Select rowid,* From tblTest", "_cb") ; _cb will be called for each row
Func _cb($aRow)
For $s In $aRow
ConsoleWrite($s & #TAB)
Next
ConsoleWrite(#CRLF)
; Return $SQLITE_ABORT ; Would Abort the process and trigger an #error in _SQLite_Exec()
EndFunc ;==>_cb
_SQLite_Close()
_SQLite_Shutdown()
; Output:
; 1 1 2 3
; 2 5 6
As a simpler solution I would recommend using INI file as database.
[Voranol]
ProductName=Polyether Polyol
Flare=List I
Bay=1
ListPos=3
[Chem2]
ProductName=..
...
And then
; Read the INI section names. This will return a 1 dimensional array.
Local $aArray = IniReadSectionNames($sFilePath)
; Check if an error occurred.
If Not #error Then
; Enumerate through the array displaying the section names.
For $i = 1 To $aArray[0]
MsgBox($MB_SYSTEMMODAL, "", "Section: " & $aArray[$i])
Next
EndIf
Now there is a limit in windows on INI file size(32kb).
That means, certain Autoit INI functions will not work if that limit is breached.
This can be solved by using your own INI functions:
Func _IniReadSectionNamesEx($hFile)
Local $iSize = FileGetSize($hFile) / 1024
If $iSize <= 31 Then
Local $aNameRead = IniReadSectionNames($hFile)
If #error Then Return SetError(#error, 0, '')
Return $aNameRead
EndIf
Local $aSectionNames = StringRegExp(#CRLF & FileRead($hFile) & #CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
Local $nUbound = UBound($aSectionNames)
Local $aNameReturn[$nUbound + 1]
$aNameReturn[0] = $nUbound
For $iCC = 0 To $nUBound - 1
$aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
Next
Return $aNameReturn
EndFunc
Func _IniReadSectionEx($hFile, $vSection)
Local $iSize = FileGetSize($hFile) / 1024
If $iSize <= 31 Then
Local $aSecRead = IniReadSection($hFile, $vSection)
If #error Then Return SetError(#error, 0, '')
Return $aSecRead
EndIf
Local $sFRead = #CRLF & FileRead($hFile) & #CRLF & '['
$vSection = StringStripWS($vSection, 7)
Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
Local $aKey = StringRegExp(#LF & $aData[0], '\n\s*(.*?)\s*=', 3)
Local $aValue = StringRegExp(#LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
Local $nUbound = UBound($aKey)
Local $aSection[$nUBound +1][2]
$aSection[0][0] = $nUBound
For $iCC = 0 To $nUBound - 1
$aSection[$iCC + 1][0] = $aKey[$iCC]
$aSection[$iCC + 1][1] = $aValue[$iCC]
Next
Return $aSection
EndFunc
I need to look up a trade name, find its proper chemical name, then get properties of that chemical.
Relational query (SQLite)
SQL as understood by SQLite.
If requirements are limited to inserts, edits and queries, an SQLite database management tool may suffice. AutoIt SQLite functions are documented as per User-defined function-reference:
(Create and) open database using _SQLite_Open().
Create tables , indexes and view(s) (and insert records) using _SQLite_Exec().
Queries using _SQLite_GetTable2d() return results as two-dimensional array.
Structure
SQLite data types. Inserting records to product and substance table may be automated.
Table product
Defines trade names.
id
name
1
dowanol pmb
2
dowanol pma
3
dipropylene glycol
4
dowanol pnp
5
glycol blend
6
isopar e
7
isopar c
8
isopar h
9
Polyether Polyol
10
Voranol
Creation:
CREATE TABLE IF NOT EXISTS product (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE
);
Insert record:
INSERT INTO product (name) VALUES ('dowanol pmb');
Table substance
Defines chemical names (and properties).
id
name
flare
bay
1
Polyether Polyol
1
1
2
DIPROPYLENE GLYCOL
1
4
3
GLYCOL
2
3
4
PETROLEUM NAPHTA
0
5
Creation:
CREATE TABLE IF NOT EXISTS substance (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE,
flare INTEGER,
bay INTEGER
);
Insert record:
INSERT INTO substance (name, flare, bay) VALUES ('Polyether Polyol', 1, 1);
Table relation
Defines relations between product and substance table's records (using foreign keys).
id
product
substance
1
1
2
2
2
2
3
3
2
4
4
2
5
5
3
6
6
4
7
7
4
8
8
4
9
9
4
10
10
1
Creation:
CREATE TABLE IF NOT EXISTS relation (
id INTEGER PRIMARY KEY,
product INTEGER REFERENCES product(id),
substance INTEGER REFERENCES substance(id),
UNIQUE( /* Constraint applies to *combination* of columns. */
product,
substance
)
);
Insert record:
INSERT INTO relation (
product,
substance
) VALUES (
(SELECT id FROM product WHERE name = 'dowanol pmb'),
(SELECT id FROM substance WHERE name = 'DIPROPYLENE GLYCOL')
);
Or just:
INSERT INTO relation (product, substance) VALUES (0, 1);
View view_relation
View (stored query), joining (combines) product and substance tables' fields, as per relation table's records (acting as virtual table, negating need to include underlying JOIN operators every query).
name_product
name_substance
flare
bay
dowanol pmb
DIPROPYLENE GLYCOL
1
4
dowanol pma
DIPROPYLENE GLYCOL
1
4
dipropylene glycol
DIPROPYLENE GLYCOL
1
4
dowanol pnp
DIPROPYLENE GLYCOL
1
4
glycol blend
GLYCOL
2
3
isopar e
PETROLEUM NAPTHA
0
5
isopar c
PETROLEUM NAPTHA
0
5
isopar h
PETROLEUM NAPTHA
0
5
Polyether Polyol
PETROLEUM NAPTHA
0
5
Voranol
Polyether Polyol
1
1
Creation:
CREATE VIEW IF NOT EXISTS view_relation AS
SELECT
product.name AS name_product,
substance.name AS name_substance,
substance.flare,
substance.bay
FROM
relation
LEFT OUTER JOIN product ON relation.product = product.id
LEFT OUTER JOIN substance ON relation.substance = substance.id
ORDER BY
product.id ASC
;
Query by trade name
name_product
name_substance
flare
bay
Voranol
Polyether Polyol
1
1
Query:
SELECT
*
FROM
view_relation
WHERE
name_product = 'Voranol'
;
Or (without view):
SELECT
product.name AS name_product,
substance.name AS name_substance,
substance.flare,
substance.bay
FROM
relation
WHERE
product.name = 'Voranol'
LEFT OUTER JOIN product ON relation.product = product.id
LEFT OUTER JOIN substance ON relation.substance = substance.id
;
Query by substance
name_product
name_substance
flare
bay
dowanol pmb
DIPROPYLENE GLYCOL
1
4
dowanol pma
DIPROPYLENE GLYCOL
1
4
dipropylene glycol
DIPROPYLENE GLYCOL
1
4
dowanol pnp
DIPROPYLENE GLYCOL
1
4
Query:
SELECT
*
FROM
view_relation
WHERE
name_substance = 'DIPROPYLENE GLYCOL'
;
Or (without view):
SELECT
product.name AS name_product,
substance.name AS name_substance,
substance.flare,
substance.bay
FROM
relation
WHERE
substance.name = 'DIPROPYLENE GLYCOL'
LEFT OUTER JOIN product ON relation.product = product.id
LEFT OUTER JOIN substance ON relation.substance = substance.id
;
AutoIt
Example creating (and inserting records to) a single table and query it:
#include <SQLite.au3>
#include <SQLite.dll.au3>
#include <Array.au3>
Global Const $g_iRecords = 50
Global Const $g_sFileDb = #ScriptDir & '\example.sqlite'
Global $g_aCreate = [ _
'CREATE TABLE IF NOT EXISTS example (id INTEGER PRIMARY KEY, name TEXT UNIQUE);' & #LF, _
'--CREATE INDEX IF NOT EXISTS index_example_name ON example(name);' & #LF _
]
Global Const $g_sInsert = 'INSERT INTO example (name) VALUES (%i);\n'
Global Const $g_sTransact1 = 'BEGIN TRANSACTION;' & #LF
Global Const $g_sTransact2 = 'END TRANSACTION;' & #LF
Global Const $g_sQuery = 'SELECT * FROM example ORDER BY id ASC;'
Global Const $g_sMsgError = 'sqlite.dll not found.' & #LF
Global $g_hDb = 0
Main()
Func Main()
Local $sQuery = ''
Local $iResultCol = 0
Local $iResultRow = 0
Local $aResult
For $i1 = 0 To UBound($g_aCreate, 1) -1
$sQuery &= $g_aCreate[$i1]
Next
For $i1 = 1 To $g_iRecords
$sQuery &= StringFormat($g_sInsert, _SQLite_FastEscape('example' & $i1))
Next
$sQuery = $g_sTransact1 & $sQuery & $g_sTransact2
ConsoleWrite($sQuery)
_SQLite_Startup()
If #error Then
ConsoleWrite($g_sMsgError)
Exit
EndIf
_SQLite_Open($g_sFileDb)
_SQLite_Exec($g_hDb, $sQuery)
_SQLite_GetTable2d($g_hDb, $g_sQuery, $aResult, $iResultRow, $iResultCol)
_SQLite_Close($g_hDb)
_SQLite_Shutdown()
_ArrayDisplay($aResult)
Exit
EndFunc
So I am using a gift certificate module with satchmo store and in order to send multiple gift certificate codes equal to the number of items purchased I need to add a loop doing
"while quantity is greater than zero loop"
Here is the code, the loop is being added to right before "price=order_item.unit_price"
def order_success(self, order,
order_item):
log.debug("Order success called, creating gift certs on order:
%s", order)
message = ""
email = ""
for detl in order_item.orderitemdetail_set.all():
if detl.name == "email":
email = detl.value
elif detl.name == "message":
message = detl.value
price=order_item.unit_price
log.debug("Creating gc for %s", price)
gc = GiftCertificate(
order = order,
start_balance= price,
purchased_by = order.contact,
valid=True,
message=message,
recipient_email=email
)
gc.save()
I am not sure I understand the question, but maybe something like
for ix in range(0, order_item.quantity):
... do stuff
might do the trick. You don't have to use the ix anywhere inside the loop, it is just (arguably) the standard way to do something n times in Python.