|
Using Delphi and Python together - An ExampleA Delphi app which has all the business logic implemented as Python code. A perfect marriage of two worlds! The Delphi Code
unit mainFrm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, PythonEngine, AtomPythonEngine, StdCtrls, ExtCtrls, PythonGUIInputOutput, uHeartMachine; type TfrmMain = class(TForm) PE: TAtomPythonEngine; PythonInputOutput1: TPythonInputOutput; pdvUser: TPythonDelphiVar; pdvShare: TPythonDelphiVar; pdvOrderManager: TPythonDelphiVar; pdvBankBalance: TPythonDelphiVar; pdvNumShares: TPythonDelphiVar; pdvSharePrice: TPythonDelphiVar; PythonDelphiVar2: TPythonDelphiVar; lblSharePrice: TLabel; bntBuy: TButton; btnForceStockToDrop: TButton; Timer1: TTimer; lblBankBalance: TLabel; lblNumShares: TLabel; btnSell: TButton; Memo1: TMemo; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; lblSharesAreWorth: TLabel; Label5: TLabel; PythonGUIInputOutput1: TPythonGUIInputOutput; btnForceStockToRise: TButton; cbNumShares: TComboBox; Label6: TLabel; cbUserLimit: TComboBox; Label7: TLabel; lblTotalWorth: TLabel; Label8: TLabel; cbNumAttempts: TComboBox; Label9: TLabel; Panel1: TPanel; HeartMachine1: THeartMachine; Panel2: TPanel; HeartMachine2: THeartMachine; Panel3: TPanel; HeartMachine3: THeartMachine; procedure PythonInputOutput1SendData(Sender: TObject; const Data: String); procedure pdvSharePriceSetData(Sender: TObject; Data: Variant); procedure FormShow(Sender: TObject); procedure bntBuyClick(Sender: TObject); procedure btnForceStockToDropClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure btnSellClick(Sender: TObject); procedure btnForceStockToRiseClick(Sender: TObject); procedure cbUserLimitChange(Sender: TObject); procedure cbNumAttemptsChange(Sender: TObject); procedure PEPathInitialization(Sender: TObject; var Path: String); private { Private declarations } public { Public declarations } end; TmgmStockMarketMainForm = class(TObject) // ; // Transformation Interface private LastPrice : integer; public procedure display; procedure repopulateFromGui; end; var frmMain: TfrmMain; implementation uses AndyDelphiPy, ComCtrls, pythonAtom, Math; var Share, User, OrderManager : OleVariant; mgmMainForm : TmgmStockMarketMainForm; {$R *.DFM} procedure TfrmMain.PythonInputOutput1SendData(Sender: TObject; const Data: String); begin PyConsoleOut(Data); end; procedure TfrmMain.pdvSharePriceSetData(Sender: TObject; Data: Variant); begin lblSharePrice.Caption := Data; end; procedure TfrmMain.FormShow(Sender: TObject); begin //PyExeFile('E:\Python20\Boa-0.0.5\AndysTry\Questtest.py', PE); PyExeFile('QuesttestFROZEN.py', PE); User := PyClass('User()', pdvUser, PE); Share := PyClass('Share("Friendly Co.", worth=10)', pdvShare, PE); OrderManager := PyClass('OrderManager()', pdvOrderManager, PE); mgmMainForm := TmgmStockMarketMainForm.Create; timer1.enabled := true; end; procedure TfrmMain.bntBuyClick(Sender: TObject); begin OrderManager.AddOrder(User.myself, strtoint(cbNumShares.text), 'buy', Share.myself); end; procedure TfrmMain.btnSellClick(Sender: TObject); begin OrderManager.AddOrder(User.myself, strtoint(cbNumShares.text), 'sell', Share.myself); end; procedure TfrmMain.Timer1Timer(Sender: TObject); begin try Share.fluxtuate; OrderManager.ProcessOrders; mgmMainForm.display; except timer1.enabled := false; showmessage('Some error cancelled the game.'); end; end; { TmgmStockMarketMainForm } procedure TmgmStockMarketMainForm.display; var f : double; begin if LastPrice = Share.CurrentPrice then with frmMain.lblSharePrice do Caption := Caption + '.' else frmMain.lblSharePrice.Caption := '$ ' + inttostr(Share.CurrentPrice); LastPrice := Share.CurrentPrice; f := User.BankBalance; frmMain.lblBankBalance.Caption := format('%m', [ f ]); frmMain.lblNumShares.Caption := User.NumSharesOwned; f := User.NumSharesOwned * Share.CurrentPrice; frmMain.lblSharesAreWorth.Caption := format('%m', [ f ]); f := f + User.BankBalance; frmMain.lblTotalWorth.Caption := format('%m', [ f ]); frmMain.cbNumAttempts.Text := OrderManager.MaxAttempts; frmMain.cbUserLimit.Text := User.SharePriceLimit; frmMain.HeartMachine1.AddPoint(0, min(Share.CurrentPrice, 100), 'Share Price'); frmMain.HeartMachine2.AddPoint(0, min(User.BankBalance, 50000), 'Bank Balance'); frmMain.HeartMachine3.AddPoint(0, min(User.NumSharesOwned, 1000), 'Num Shares Owned'); end; procedure TmgmStockMarketMainForm.repopulateFromGui; begin User.SharePriceLimit := strtoint( frmMain.cbUserLimit.Text ); OrderManager.MaxAttempts := strtoint( frmMain.cbNumAttempts.Text ); display; end; procedure TfrmMain.cbUserLimitChange(Sender: TObject); begin mgmMainForm.repopulateFromGui; end; procedure TfrmMain.cbNumAttemptsChange(Sender: TObject); begin mgmMainForm.repopulateFromGui; end; procedure TfrmMain.btnForceStockToRiseClick(Sender: TObject); begin Share.CurrentPrice := Share.CurrentPrice + 10 + random(20); end; procedure TfrmMain.btnForceStockToDropClick(Sender: TObject); begin Share.CurrentPrice := random(10); end; procedure TfrmMain.PEPathInitialization(Sender: TObject; var Path: String); begin //path := 'e:\try\deploy;e:\try\deploy\lib'; end; end.
The Python CodeNote: Not all the python code is shown, due to confidentiality issues. # Share trading game simulator. false = 0 ; true = 1 import random, sys def log(s): print s #sys.stdout.flush() class Share: def __init__(self, name, worth=10): self.CurrentPrice = worth self.Name = name def __str__(self): return 'Share ' + self.Name + ' Worth= $' + `self.CurrentPrice` + ' per share.' def fluxtuate(self): if random.randrange(0,2): self.CurrentPrice = self.CurrentPrice + random.randrange(-10,10) if self.CurrentPrice <= 0: self.CurrentPrice = 1 ##log('..time passes.. ' + str(self)) def myself(self): return self class User: def __init__(self, initialBankBalance=1000, initialNumShares=0, initialSharePriceLimit=10): self.BankBalance = initialBankBalance self.NumSharesOwned = initialNumShares self.SharePriceLimit = initialSharePriceLimit def __str__(self): return 'User Bank balance='+`self.BankBalance` + \ ' Number of Shares=' + `self.NumSharesOwned` + \ ' Share Price Limit=' + `self.SharePriceLimit` def myself(self): return self class Order: def candivest(self): return self.NumberOfShares <= self.User.NumSharesOwned def canafford(self): return (self.Share.CurrentPrice*self.NumberOfShares) < self.User.BankBalance def sharepricetoolow(self): return self.Share.CurrentPrice < self.User.SharePriceLimit def sharepricetoohigh(self): return self.Share.CurrentPrice > self.User.SharePriceLimit def __init__(self, user, numshares, buyorsell, share): self.User = user self.Share = share self.NumberOfShares = numshares self.Command = buyorsell #print 'DEBUG - self.Share.CurrentPrice', self.Share.CurrentPrice # debug !!!! def __str__(self): return 'Order to %s %d %s shares' % (self.Command, self.NumberOfShares, self.Share.Name) etc.
Related 'Python for Delphi' Links on this site:
return to main Andy Patterns home page |