---
# System prepended metadata

title: Labs
tags: [34-CC]

---

---
tags: 34-CC
---

# Labs
https://cw-cc-386316.nw.r.appspot.com

API: https://7efuv9rcv7.execute-api.us-east-1.amazonaws.com/default/cw_func

## Lab 1 - GAE with Python

#### Host Python website on GAE
https://myproject0504-385716.nw.r.appspot.com

## Lab 2 - EC2

#### launch EC2 instance and SSH into it, with given security group (PEM file).

AWS Details:
aws_access_key_id
aws_secret_access_key
aws_session_token

## Lab 3 - Lambda "Function as a Service"
npydxv5ta2.execute-api.us-east-1.amazonaws.com
- lambda functions
- API gateway

function_one:
```python=
import json
import random

def lambda_handler(event, context):
    simulate = int(event['key1']) # using the number in a string here.
    # simulate = event['key1'] # an int cast is not always needed, e.g. 10000 vs "10000"
    vals = [random.gauss(0.002,0.04) for i in range(simulate)]
    vals.sort()
    return str(vals[10])
```

test_event:
```json=
{
  "key1": 1000,
  "key2": "value2",
  "key3": "value3"
}
```

Use POST method to get result:
```bash=
$ curl -d '{"key1":"1000"}' https://npydxv5ta2.execute-api.us-east-1.amazonaws.com/default/function_one
"-0.09062159312871101"
```

Then host the website on GAE, and the API is called by using Lambda.

serial vs. parallel

Function URL:
https://dhvpocaeuywabidbrhipaw6le40daqos.lambda-url.us-east-1.on.aws/

```pyton=
import json
jsonString = '{"result":[{"a":54, "b":28}, {"a":21, "b":29}]}'
aDict = json.loads(jsonString)
aDict
{'result': [{'a': 54, 'b': 28}, {'a': 21, 'b': 29}]}

aDict['result']
# [{'a': 54, 'b': 28}, {'a': 21, 'b': 29}]

aDict['result'][1]
# {'a': 21, 'b': 29}

aDict['result'][1]['a']
# 21

aDict['result'][1]['b']
# 29

[i['a'] for i in aDict['result']]
# [54, 21]
```

## Lab 4 - Replicating VMs 
1. Create a simple java and python website on the AWS instance and access it via the DNS URL
2. Create an image from an instance.
3. Launch another instance from the image.
4. Launch instance from code.
5. Find out, document, and – preferably – work out how to use the “aws cli” command-line calls for 
    a. Launching an AMI.
        b. Creating and attaching an EBS volume to a running instance (VM).
        c. Detaching an EBS volume from a running instance.
        d. Attaching the EBS volume in ( c ) to another instance [must be in the same AZ]
        e. Deleting an EBS volume.
        f. Terminating a running instance.
        
## Lab 5
- Use S3 bucket to host static webiste (expensive)
1. Ensure that you know how to access values of different parameters, using Python, from a web form via GET or POST. 
2. Alter your code to run 2 instances with cgitest.py and postform.py but with httpd instead of Apache (and without the LB).
3. Create a Lambda function that, simply, logs all of the times that calls were made to it in a single file in S3 – you will need to be able to write (and overwrite – read, add, write) a file in an S3 bucket via boto3.
4. Create another App Engine page that uses the above function; test this by making multiple page requests that will make the Lambda function execute, but which displays only the full log file. Consider how such data could be stored in a Google Cloud capability instead. 

```
def calculate_pct_change(prices):
    pct_changes = []
    for i in range(1, len(prices)):
        pct_changes.append((prices[i] - prices[i - 1]) / prices[i - 1])
    return pct_changes


def calculate_std(pct_changes, mean):
    squared_diff = [(x - mean) ** 2 for x in pct_changes]
    variance = sum(squared_diff) / len(squared_diff)
    return math.sqrt(variance)
```
```
for i in range(minhistory, len(data_list)): 
    if data_list[i][6] == 1:  # if we're interested in Buy signals
        close_prices = [row[4] for row in data_list[i - minhistory:i]]
        pct_changes = calculate_pct_change(close_prices)
        mean = sum(pct_changes) / len(pct_changes)
        std = calculate_std(pct_changes, mean)
        
        # generate much larger random number series with the same broad characteristics 
        simulated = [random.gauss(mean, std) for x in range(shots)]
        
        # sort and pick 95% and 99%  - not distinguishing long/short risks here
        simulated.sort(reverse=True)
        var95 = simulated[int(len(simulated) * 0.95)]
        var99 = simulated[int(len(simulated) * 0.99)]

        print(var95, var99)  # so you can see what is being produced
```

print(data.Buy[0:2])
mean=data.Close[101-minhistory:101].pct_change(1).mean()
std=data.Close[101-minhistory:101].pct_change(1).std()
print(data.Close[101-minhistory:101].pct_change(1), mean, std)

def calculate_pct_change(prices):
    pct_changes = []
    for i in range(1, len(prices)):
        pct_changes.append((prices[i] - prices[i - 1]) / prices[i - 1])
    return pct_changes


def calculate_std(pct_changes, mean):
    squared_diff = [(x - mean) ** 2 for x in pct_changes]
    variance = sum(squared_diff) / len(squared_diff)
    return math.sqrt(variance)

close_prices = [row[4] for row in data_list[101 - minhistory:101]]
pct_changes = calculate_pct_change(close_prices)
mean = sum(pct_changes) / len(pct_changes)
std = calculate_std(pct_changes, mean)
print(mean, std)

```
#!/usr/bin/env python3

import math
import random
import yfinance as yf
import pandas as pd
from datetime import date, timedelta
from pandas_datareader import data as pdr
# override yfinance with pandas – seems to be a common step
yf.pdr_override()

# Get stock data from Yahoo Finance – here, asking for about 3 years
today = date.today()
decadeAgo = today - timedelta(days=1095)
# print(today)
# print(decadeAgo)

# Get stock data from Yahoo Finance – here, Gamestop which had an interesting 
#time in 2021: https://en.wikipedia.org/wiki/GameStop_short_squeeze 
# data_GME = pdr.get_data_yahoo('GME', start=decadeAgo, end=today) 

# Other symbols: TSLA – Tesla, AMZN – Amazon, ZM – Zoom, ETH-USD – Ethereum-Dollar etc.
data_ZM = pdr.get_data_yahoo('ZM', start=decadeAgo, end=today)

data = data_ZM
# print(data)

# Add two columns to this to allow for Buy and Sell signals
# fill with zero
data['Buy']=0
data['Sell']=0
# print(data)

# Find the signals – uncomment print statements if you want to 
# look at the data these pick out in some another way
# e.g. check that the date given is the end of the pattern claimed
# print(data.Close[0:2])

for i in range(2, len(data)): 

    body = 0.01

    # Three Soldiers
    if (data.Close[i] - data.Open[i]) >= body  and data.Close[i] > data.Close[i-1]  \
and (data.Close[i-1] - data.Open[i-1]) >= body and data.Close[i-1] > data.Close[i-2]  \
and (data.Close[i-2] - data.Open[i-2]) >= body:
        data.at[data.index[i], 'Buy'] = 1
        # print("Buy at ", data.index[i])
        # print(data.Open[i-2:i+1], data.Close[i-2:i+1])

    # Three Crows
    if (data.Open[i] - data.Close[i]) >= body  \
and data.Close[i] < data.Close[i-1] \
and (data.Open[i-1] - data.Close[i-1]) >= body  \
and data.Close[i-1] < data.Close[i-2]  \
and (data.Open[i-2] - data.Close[i-2]) >= body:
        data.at[data.index[i], 'Sell'] = 1
        # print("Sell at ", data.index[i])
        # print(data.Open[i-2:i+1], data.Close[i-2:i+1])
print(data)
data_list = data.values.tolist()

# Data now contains signals, so we can pick signals with a minimum amount
# of historic data, and use shots for the amount of simulated values
# to be generated based on the mean and standard deviation of the recent history

minhistory = 101    # (H)
shots = 80000       # (D)
print(len(data))
for i in range(minhistory, len(data)): 
    if data.Buy[i]==1: # if we’re interested in Buy signals
        mean=data.Close[i-minhistory:i].pct_change(1).mean()
        std=data.Close[i-minhistory:i].pct_change(1).std()
        # print(mean, std)
        # generate much larger random number series with same broad characteristics 
        simulated = [random.gauss(mean,std) for x in range(shots)]
        # sort and pick 95% and 99%  - not distinguishing long/short risks here
        simulated.sort(reverse=True)
        # print(simulated )
        var95 = simulated[int(len(simulated)*0.95)]
        var99 = simulated[int(len(simulated)*0.99)]
        # print(var95, var99) # so you can see what is being produced
```
```
buy_col_index = data.columns.get_loc('Buy')
close_col_index = data.columns.get_loc('Close')

if data_list[i][buy_col_index] == 1:  # if we're interested in Buy signals
        close_prices = [row[close_col_index] for row in data_list[i-minhistory:i]]
        # Calculate percentage change using list comprehension
        pct_changes = [(close_prices[j] - close_prices[j-1]) / close_prices[j-1] for j in range(1, len(close_prices))]
        mean = sum(pct_changes) / len(pct_changes)
        std = math.sqrt(sum((x - mean)**2 for x in pct_changes) / len(pct_changes))
```
[-0.059337424448963505, -0.08116459002475124]

json = '{"key1":"'+str(SHOTS)+'", "key2":"'+js_mean+'", "key3":"'+js_std+'"}'

<table>
    <thead>
        <tr>
            {% for column in dataframe.columns %}
            <th>{{ column }}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for index, row in dataframe.iterrows() %}
        <tr>
            {% for value in row %}
            <td>{{ value }}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </tbody>
</table>

import requests

# Define the URL parameters
chart_type = "lc"  # Line chart
chart_size = "700x300"  # Width x height
chart_data = "t:10,20,30,40,50|15,25,35,45,55"  # Two sets of data
chart_colors = "FF0000,00FF00"  # Red and green lines
chart_title = "My%20Line%20Chart"  # URL-encoded title

# Construct the URL
url = f"https://image-charts.com/chart?cht={chart_type}&chs={chart_size}&chd={chart_data}&chco={chart_colors}&chtt={chart_title}"

# Get the chart image
response = requests.get(url)

# Save the image
with open("chart.png", "wb") as f:
    f.write(response.content)
    
x_data = ','.join(df['x'].astype(str))
chart_data = f"t:{x_data}|{y_data}"  # Two sets of data

df = pd.DataFrame({
    'x': [1.0, 2.1, 3.2, 4.3, 5.4],
    'y': [10.5, -20.6, 30.7, -40.8, 50.9]  # y contains negative values
})
# Round the data to 2 decimal places
df_rounded = df.round(2)

# Convert the data to strings with values separated by commas
x_data = ','.join(df_rounded['x'].astype(str))
y_data = ','.join(df_rounded['y'].astype(str))

chart_data = f"t:{x_data}|{y_data}"  # Two sets of data
chart_markers = "o,FF0000,0,-1,10|o,00FF00,1,-1,10"

chart_data = f"chd=a:{','.join(map(str, series1))}|{','.join(map(str, series2))}"

df = pd.DataFrame({
    'x': [1.0, 2.1, 3.2, 4.3, -5.4],
    'y': [1.5, -2.6, 3.7, -4.8, 5.9]  # y contains negative values
    })
    
base_url = "https://image-charts.com/chart"
    chart_type = "lc"  # Line chart
    chart_data = f"chd=a:{','.join(map(str, df['x']))}|{','.join(map(str, df['y']))}"
    chart_size = "chs=700x300"
    chart_markers = "chm=o,FF0000,0,-1,5|o,0000FF,1,-1,5"
    chart_url = f"{base_url}?cht={chart_type}&{chart_data}&{chart_size}&{chart_markers}"

import pandas as pd
import requests

def draw_chart(df, filename):
    base_url = "https://image-charts.com/chart"
    chart_type = "lc"  # Line chart
    avg_x = df['x'].mean()
    chart_data = f"chd=a:{','.join(map(str, df['x']))}|{','.join(map(str, df['y']))}|{avg_x},{avg_x}"
    chart_size = "chs=700x300"
    chart_markers = f"chm=o,FF0000,0,-1,5|o,00FF00,1,-1,5|l,FFA500,2,0,{avg_x},{avg_x}"  # Use "l" for straight line with average value of x
    chart_url = f"{base_url}?cht={chart_type}&{chart_data}&{chart_size}&{chart_markers}"

    response = requests.get(chart_url)

    with open(filename, 'wb') as f:
        f.write(response.content)

df = pd.DataFrame({
    'x': [1.0, 2.1, 3.2, 4.3, -5.4],
    'y': [1.5, -2.6, 3.7, -4.8, 5.9]  # y contains negative values
})

draw_chart(df, 'chart.png')

chart_grid = f"chg=0,20,1,5"  # Grid pattern: "0" disables vertical gridlines, "20" sets the spacing between horizontal gridlines, "1" sets the thickness of the gridlines, "5" is the length of each dash
    chart_avg_line = f"chm=d,FFA500,0,{avg_x},0.5"  # Add a dashed line for the average value of x
    chart_url = f"{base_url}?cht={chart_type}&{chart_data}&{chart_size}&{chart_grid}&{chart_avg_line}"

chart_markers = f"chm=o,FF0000,0,-1,5|o,00FF00,1,-1,5|l,FFA500,2,0,{avg_x},1"  # Use "l" for straight line with average value of x

import pandas as pd
import requests

def draw_chart(df, filename):
    base_url = "https://image-charts.com/chart"
    chart_type = "lc"  # Line chart
    avg_x = df['x'].mean()
    chart_data = f"chd=a:{','.join(map(str, df['x']))}|{','.join(map(str, df['y']))}|0,0|10,10"  # Add two additional data points for drawing the line
    chart_size = "chs=700x300"
    chart_markers = f"chm=o,FF0000,0,-1,5|o,00FF00,1,-1,5|l,FFA500,2,0,{avg_x},1"  # Use "l" for straight line with average value of x
    chart_url = f"{base_url}?cht={chart_type}&{chart_data}&{chart_size}&{chart_markers}"

    response = requests.get(chart_url)

    with open(filename, 'wb') as f:
        f.write(response.content)

df = pd.DataFrame({
    'x': [1.0, 2.1, 3.2, 4.3, -5.4],
    'y': [1.5, -2.6, 3.7, -4.8, 5.9]  # y contains negative values
})

draw_chart(df, 'chart.png')

avg_x = df['x'].mean()
df_with_avg_x = df.assign(avg_x=avg_x)

base_url = "https://image-charts.com/chart"
    chart_type = "lc"  # Line chart
    chart_data = f"chd=a:{','.join(map(str, TABLE['Avg_95']))}|{','.join(map(str, TABLE['Avg_99']))}|{','.join(map(str, TABLE['a_95']))}|{','.join(map(str, TABLE['a_99']))}"
    chart_size = "chs=700x300"
    chart_markers = "chm=o,FF0000,0,-1,5|o,00FF00,1,-1,5|o,FF0000,0,-1,5|o,00FF00,1,-1,5"
    chart_url = f"{base_url}?cht={chart_type}&{chart_data}&{chart_size}&{chart_markers}"

    # Get the chart image
    response = requests.get(chart_url)

    # Save the image
    with open("./static/img/chart.png", "wb") as f:
        f.write(response.content)
        
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/process', methods=['POST'])
def process():
    data = request.json  # Assuming you are sending JSON data in the request body
    # Perform your processing logic here based on the received data
    # For example, you can access a specific variable: received_var = data['var']
    result = {'response': 'Processed data'}
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)
    
import requests

data = {'var': 'your_variable_value'}
response = requests.post('http://your-instance-ip/process', json=data)
result = response.json()
print(result)  # Processed result received from the AWS Linux instance

# Create a simple DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
})

# Convert the DataFrame to a JSON string
df_json = df.to_json(orient='split')

import concurrent.futures
import time

def print_line(line, refresh_rate):
    while True:
        print(line, end='\r', flush=True)
        time.sleep(refresh_rate)

# Example usage:
line1_refresh_rate = 1.0  # Refresh rate for line 1 (seconds)
line2_refresh_rate = 0.5  # Refresh rate for line 2 (seconds)

with concurrent.futures.ThreadPoolExecutor() as executor:
    executor.submit(print_line, "Line 1", line1_refresh_rate)
    executor.submit(print_line, "Line 2", line2_refresh_rate)


import time

start_time = time.time()  # save start time
elapsed_time = 0
i = 0

while elapsed_time < 5:
    # ... your code here ...
    i += 1

    current_time = time.time()
    elapsed_time = current_time - start_time
    print(f"Elapsed time: {elapsed_time} seconds")

print(f"Performed {i} iterations in {elapsed_time} seconds")

ec2 	3 	110 	1700 	Buy 	19 	-320.0099792480469 	-0.06503956791519112 	-0.09135093877463582 	55
ec2 	1 	101 	800 	Buy 	10 	-230.7299041748047 	-0.06540002967782159 	-0.09242949383809729 	55
ec2 	5 	110 	1700 	Sell 	19 	580.0199432373047 	-0.06549014511847924 	-0.09269913260396263 	55