7
\$\begingroup\$

True Story: Several years ago while interviewing at an investment advisory firm that managed over a billion dollars in client funds, I was asked a collection of reasonable and bizarre questions by a partner in the firm. An example of a reasonable question would be "What can go wrong with a linear fit?".

But then, things devolved....

Interviewer: "Have you ever written code that modifies itself?"

Job Candidate: "No, can't say that I have"

Interviewer: "We have one guy who writes programs that modify themselves, I think he uses awk"

Job Candidate: "Wow. That's pretty incredible. AWK? "

Now it is your turn to be that one guy that financial houses would kill to hire...

Challenge: Write a self-modifying script of some kind that performs a "useful financial function".

Rules:

  1. Use a scripting language, not a language requiring compilation such as C or Java. Perl, Python and the like that will work from a #! are OK. Of course, heroes use awk, but awk is not a requirement.
  2. Self-modifying means that the script modifies its own source code. The script must be reusable after it has modified itself. The script might also generate useful user output to STDOUT or some other interface.
  3. The definition of "useful financial function" is left to the voters and can be as intriguing or dysfunctional as you prefer. If you need examples for inspiration, here are a few ideas: stock picking, stock trading, prediction and/or fitting, future value of account, Ponzi scheme generator, risk analysis of Nigerian email deals, salary bonus calculator for partners vs employees, etc.
  4. Most upvotes wins.

EDIT: I agree with one participant who notes that it is not obvious how to read the current gawk script from within gawk. Here is a solution for Linux-based systems and other O/S that have a /proc filesystem.

#!/usr/bin/gawk -f
BEGIN { 
pid = PROCINFO["pid"]
commfile = "/proc/"pid"/comm"
print "I will look here for the script file name: " commfile
print "Here is what is in that file:"
getline scriptfilename < commfile
print scriptfilename
print "Here is my script:"
while (getline line < scriptfilename){
      print line
      }
}
\$\endgroup\$

closed as too broad by Sriotchilism O'Zaic, Toto, Stephen, Titus, DJMcMayhem Aug 3 '17 at 19:23

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Removed code-challenge tag because it would require an objective winning criterion. \$\endgroup\$ – Howard Dec 30 '13 at 12:27
  • \$\begingroup\$ Wait, rule 2 disallows the self-modify Befunge. :-( \$\endgroup\$ – Justin Dec 30 '13 at 16:58
  • \$\begingroup\$ @Quincunx How would you modify the rule? \$\endgroup\$ – Paul Dec 30 '13 at 20:04
  • 1
    \$\begingroup\$ In PERL, special variable $0 contains the full pathname to the running script. Just goes to show you shouldn't bring gawk to a perl fight. \$\endgroup\$ – Paul Jan 1 '14 at 10:19
  • 1
    \$\begingroup\$ What! You disallow Java eh! Well, I'm going to write a self modifying Java program, complete with compilation. Challenge accepted. \$\endgroup\$ – Justin Jan 22 '14 at 4:30
8
\$\begingroup\$

Pseudocode

// Set up a cron job to run this script (only) once a day

yesterdays_stock_price = '46.48'

todays_stock_price = curl_google_finance('VTSMX')

print "Difference between yesterday's stock price and today's: "

print todays_stock_price

self = open('self.file')

self.replace( /yesterdays_stock_price = '[0-9\.]+'/, todays_stock_price)

self.save()
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice. I like how it doesn't work if you use it too much or at the wrong interval. \$\endgroup\$ – Paul Dec 30 '13 at 20:03
  • \$\begingroup\$ Maybe it should have a wait and loop in it too so it can self run, I love it. \$\endgroup\$ – alan2here Jan 2 '14 at 1:37
  • \$\begingroup\$ Funny how you call it pseudocode where it's actually nearly Python. \$\endgroup\$ – Turion Mar 19 '14 at 16:26
3
\$\begingroup\$

gawk (1224 characters, as this is not code golf)

One of reasons why awk shouldn't be used for self-modifying scripts.

#!/usr/bin/gawk -f
function download(name,     url, service, host, old_rs, old_ors) {
    old_rs = RS
    old_ors = ORS
    RS = ORS = "\r\n"

    host = "download.finance.yahoo.com"
    url = "http://"host"/d/quotes.csv?s="name"&f=l1"
    service = "/inet/tcp/0/"host"/80"
    print "GET", url |& service
    service |& getline
    close(service)

    RS = old_rs
    ORS = old_ors

    return $0
}

function update(value,       file, self, result) {
    # Do complex stuff in order to find the program itself.
    file = "/proc/"PROCINFO["pid"]"/comm"
    if (getline < file <= 0) {
        print "/proc filesystem not supported." > "/dev/stderr"
        exit
    }
    close(file)
    if ($0 ~ /^g?awk$/) {
        print "You need to run program directly." > "/dev/stderr"
        exit
    }
    self = $0
    result = ""
    while (getline < self > 0) {
        # Avoid finding this line.
        if (/[y]esterday/) gsub(/[0-9]+(\.[0-9]+)?/, value)
        result = result $0"\n"
    }
    printf "%s", result > self
    close(self)
}

BEGIN {
    yesterday = 1120.71
    today = download("GOOG")
    update(today)
    print "Yesterday:", yesterday
    print "Today:", today
    print "Difference:", today - yesterday
}
\$\endgroup\$
  • \$\begingroup\$ Wow, an HTTP client in GAWK. \$\endgroup\$ – Paul Jan 1 '14 at 10:31
2
\$\begingroup\$

Using @jawns317 psueudocode:

BASH

#!/bin/bash
set -e;
google_price_last=1118.79;
current_google_price=`wget -qO- "http://finance.yahoo.com/d/quotes.csv?s=GOOG&f=l1"|tr -d "\r\n"`;
echo "Current Price: $current_google_price";
echo "Last Price: $google_price_last";
echo "Price change: "`echo $current_google_price - $google_price_last | bc -l`;
sed -ri 's/last=[0-9\.]+\;/last='"$current_google_price"';/g' $0;
\$\endgroup\$
1
\$\begingroup\$

Back at uni I discovered (ah-hem) a system which I though would prove fool-proof at the local casino. Bet on red on the roulette wheel, and if you lost double the bet, and so on ...See Martingale System

VBS

Dim objFSO
Dim objTF
Dim strFile
Dim lngBet

lngBet = 5
strFile = "boss.txt"
'spin roulette wheel
Randomize

'18 blacks, 18 reds, 1 green    
intnumber = Int(36 * Rnd + 1)

'mofify code to double-down losing bets
Do While intnumber < 18 
intnumber = Int(36 * Rnd + 1)
bfound = True
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.createtextfile(strFile, 2)
objTF.writeline "lngbet=lngbet*2"
objTF.Close
Set objTF = objFSO.opentextfile(strFile, 1)
Execute objTF.ReadAll()
objTF.Close
Loop

If bfound Then objFSO.deletefile (strFile)    
wscript.echo "final bet was " & lngBet
\$\endgroup\$
0
\$\begingroup\$

I have some pseudo code for someone to develop. All it really needs are some functions built to do the text replacement. I feel the function names give a sufficient description that the actual code is probably trivial.

Write "You should really give him back his stapler."
Write "No one has noticed an account with $0 ."
Write "Your TPS reports are complete."
Write "You should throw that Piece of * out the window."

$event = Random 1..3
$fireStarter = Random 1..100
$fractions = Random 1..100

switch $event
    {
    1 - $stapler = $false
    2 - $TPSreports = $false
    3 - $printerJam = $true
    }

if ($stapler = false)
    { Write "I think you have my stapler"

           if ( ($times + $fireStarter ) -GreaterThan 100 ) { Function Burn }
    $times + 1
    $stapler = $true
    Function SelfModifyLine1
    Function SelfModifyTimes
    }

if ( $Fractions -LessThan 50 )
    { $account = $account + $fractions 
    Function SelfModifyLine2 }

if ( $TPSreports = $false ) {  Function SelfModifyLine3  }

Function YellAtPrinter
Out-file $scriptPath
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.