Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 63 additions & 57 deletions application/code_generator.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,78 @@
from model import code_blocks
class CodeGenerator:
def __init__(self, template_mapping, parse_template):
self.blocks = code_blocks.AllBlocks()
self.function_mapping = template_mapping
self.parse_template = parse_template
self.data = {}
def __init__(self, template_mapping, parse_template):
self.blocks = code_blocks.AllBlocks()
self.function_mapping = template_mapping
self.parse_template = parse_template
self.data = {}

def get_data(self):
return self.data['dataframe']
#call to resetAll() function in clas AllBblocks of code_blocks.py
def resetone(self):
self.blocks.reset_all()
self.data = {}

def load_data(self, csv_file):
dataframe = self._parse_and_execute('read_csv', [csv_file])
self._save('dataframe', dataframe)
self._save('X', dataframe)
return self.data['dataframe'].shape
def get_data(self):
return self.data['dataframe']

def describe_data(self):
output = self._parse_and_execute('describe_data', ['dataframe'])
return output
def load_data(self, csv_file):
dataframe = self._parse_and_execute('read_csv', [csv_file])
self._save('dataframe', dataframe)
self._save('X', dataframe)
return self.data['dataframe'].shape

def clean_data(self):
self._parse_and_execute('clean_data', ['dataframe'])
return self.data['dataframe'].shape
def describe_data(self):
output = self._parse_and_execute('describe_data', ['dataframe'])
return output

def get_labels(self):
keys = self._parse_and_execute('get_keys', ['X'])
return keys.values.tolist()
def clean_data(self):
self._parse_and_execute('clean_data', ['dataframe'])
return self.data['dataframe'].shape

def drop_x(self, input_labels):
x_values = self._parse_and_execute('drop_x', ['X', input_labels])
self._save('X', x_values)
def get_labels(self):
keys = self._parse_and_execute('get_keys', ['X'])
return keys.values.tolist()

def select_y(self, output_label):
x_values, y_values = self._parse_and_execute('select_y', ['X', output_label])
self._save('X', x_values)
self._save('Y', y_values)
def drop_x(self, input_labels):
x_values = self._parse_and_execute('drop_x', ['X', input_labels])
self._save('X', x_values)

def split_data(self, train_ratio = 0.8, seed = 200):
(train, test) = self._parse_and_execute('split',['X',train_ratio,seed])
self.data['train'] = train
self.data['test'] = test
return self.data['train'].shape
def select_y(self, output_label):
x_values, y_values = self._parse_and_execute(
'select_y', ['X', output_label])
self._save('X', x_values)
self._save('Y', y_values)

def download_code(self):
return self.blocks.to_text()
def split_data(self, train_ratio=1, seed=200):
(train, test) = self._parse_and_execute(
'split', ['X', train_ratio, seed])
self.data['train'] = train
self.data['test'] = test
return self.data['train'].shape

def _create_new_block(self, comment, statements):
block = code_blocks.CodeBlock(comment, statements)
self.blocks.add_next_block(block)
def download_code(self):
return self.blocks.to_text()

def _parse_and_execute(self, template, args):
replaced_args = []
string_args = []
for arg in args:
if isinstance(arg, str) and arg in self.data:
replaced_args.append(self.data[arg])
string_args.append(arg)
else:
replaced_args.append(arg)
if isinstance(arg, str):
string_args.append('\"'+arg+'\"')
else:
string_args.append(str(arg))
def _create_new_block(self, comment, statements):
block = code_blocks.CodeBlock(comment, statements)
self.blocks.add_next_block(block)

(comments, code) = self.parse_template(template, string_args)
self._create_new_block(comments[0], code)
output = self.function_mapping[template](replaced_args)
return output
def _parse_and_execute(self, template, args):
replaced_args = []
string_args = []
for arg in args:
if isinstance(arg, str) and arg in self.data:
replaced_args.append(self.data[arg])
string_args.append(arg)
else:
replaced_args.append(arg)
if isinstance(arg, str):
string_args.append('\"'+arg+'\"')
else:
string_args.append(str(arg))
(comments, code) = self.parse_template(template, string_args)
self._create_new_block(comments[0], code)
output = self.function_mapping[template](replaced_args)
return output

def _save(self, key, value):
self.data[key] = value
def _save(self, key, value):
self.data[key] = value
111 changes: 57 additions & 54 deletions flask_app/flask_main.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import os

from flask import g
from flask import Flask
from flask import render_template
from flask import request, redirect, flash
from werkzeug.utils import secure_filename

from application import code_generator
from pandas_code.mapping import template_mapping
from pandas_code.parse_template import parse_template


ALLOWED_EXTENSIONS = {'csv'}

app = Flask(__name__, template_folder='templates')
Expand All @@ -20,85 +17,91 @@

@app.route('/')
def welcome():
return render_template('home.html')
return render_template('home.html')

def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/download', methods=['GET'])
def download_code():
code = generator.download_code()
return render_template('info/code.html', text=code)
code = generator.download_code()
return render_template('info/code.html', text=code)

@app.route('/describe', methods=['GET'])
def describe_data():
description = generator.describe_data()
return render_template('info/description.html',table=description.to_html())
description = generator.describe_data()
return render_template('info/description.html',table=description.to_html())

#added start over option in base.html to clear the previous block of code
@app.route('/start_over', methods=['GET'])
def start_over():
generator.resetone()
return render_template('home.html')

@app.route('/clean', methods=['GET'])
def clean_data():
original_data_size = generator.get_data().shape
cleaned_data_size = generator.clean_data()
num_rows_removed = original_data_size[0]-cleaned_data_size[0]
return render_template('info/cleaning_summary.html', removed_rows=num_rows_removed)
original_data_size = generator.get_data().shape
cleaned_data_size = generator.clean_data()
num_rows_removed = original_data_size[0]-cleaned_data_size[0]
return render_template('info/cleaning_summary.html', removed_rows=num_rows_removed)

@app.route('/split', methods=['GET'])
def split_data():
train_data_size = generator.split_data()
return render_template('info/splitting_summary.html', num_rows_train=train_data_size[0])
train_data_size = generator.split_data()
return render_template('info/splitting_summary.html', num_rows_train=train_data_size[0])

@app.route('/input_labels', methods=['GET', 'POST'])
def get_input_labels():
if request.method == 'POST':
request_dict = request.form.to_dict(flat=False)
generator.drop_x(request_dict['drop_labels'])
return render_template('actions/actions.html')
if request.method == 'POST':
request_dict = request.form.to_dict()
generator.drop_x(request_dict['drop_labels'])
return render_template('actions/actions.html')

keys = generator.get_labels()
return render_template('actions/select_input_values.html', labels=keys)
keys = generator.get_labels()
return render_template('actions/select_input_values.html', labels=keys)

@app.route('/labels', methods=['GET', 'POST'])
def get_data_labels():
if request.method == 'POST':
request_dict = request.form.to_dict()
generator.select_y(request_dict['label'])
return redirect('/input_labels')

keys = generator.get_labels()
return render_template('actions/select_output_value.html', labels=keys)
if request.method == 'POST':
request_dict = request.form.to_dict()
generator.select_y(request_dict['label'])
return redirect('/input_labels')
keys = generator.get_labels()
return render_template('actions/select_output_value.html', labels=keys)
# return render_template('labels.html', labels=keys)

@app.route('/data', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)

file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# return redirect(url_for('download_file', name=filename))
print(g)
with app.app_context():
generator.load_data(app.config['UPLOAD_FOLDER']+'/'+filename)
return render_template('actions/actions.html')

return render_template('actions/upload_data.html')
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# return redirect(url_for('download_file', name=filename))
print(g)
#call to resetone() in class CodeGenerator in code_generator.py
generator.resetone()
with app.app_context():
generator.load_data(app.config['UPLOAD_FOLDER']+'/'+filename)
return render_template('actions/actions.html')
return render_template('actions/upload_data.html')

@app.route('/actions')
def next_actions():
return render_template('actions/actions.html')
return render_template('actions/actions.html')

# main driver function
if __name__ == '__main__':
# run() method of Flask class runs the application
# on the local development server.
app.run()
# run() method of Flask class runs the application
# on the local development server.
app.run()

2 changes: 1 addition & 1 deletion flask_app/templates/actions/select_input_values.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h2> Select your input values</h2>
<form action="/input_labels" method="post">
<div>
{% for label in labels %}
<input type="checkbox" name="drop_labels" value="{{label}}">{{label}}</input>"
<input type="checkbox" name="drop_labels" value= "{{label}}" SELECTED>{{label}}</option>"
{% endfor %}
</div>

Expand Down
4 changes: 2 additions & 2 deletions flask_app/templates/actions/split_data.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<h2>Split Data</h2>
<p>
If this is the only dataset you have with these values, you need to split it into
a training and testing datasets.
a training and testing datasets.
</p>
<form action="/split" method="get">
<input class="action" type="submit" value="Split Data"/>
</form>
</div>
</div>
1 change: 1 addition & 0 deletions flask_app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<li><a href="/download">Show Code</a>
<li><a href="/data">Upload Data</a>
<li><a href="/actions">Next Actions</a>
<li><a href="/start_over">Start Over</a>
</ul>
</nav>
<section class="content">
Expand Down
26 changes: 13 additions & 13 deletions flask_app/templates/info/code.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@
{% endfor %}
</div>
<div class="action">
<button class="action">Copy Code</button>
<button class="action">Copy Code</button>
<div>
<script>
var copyBtn = document.querySelector('.action');
copyBtn.addEventListener('click', function(event) {
var copyBtn = document.querySelector('.action');
copyBtn.addEventListener('click', function(event) {
// Select the email link anchor text
var code = document.querySelector('.information');
var range = document.createRange();
range.selectNode(code);
window.getSelection().addRange(range);
try {
var code = document.querySelector('.information');
var range = document.createRange();
range.selectNode(code);
window.getSelection().addRange(range);
try {
// Now that we've selected the anchor text, execute the copy command
var successful = document.execCommand('copy');
var msg = successful ? 'Code copied to your clipboard' : 'Unable to copy';
var successful = document.execCommand('copy');
var msg = successful ? 'Code copied to your clipboard' : 'Unable to copy';
alert(msg);
} catch(err) {
alert('Unable to copy');
} catch(err) {
alert('Unable to copy');
}
// Remove the selections
window.getSelection().removeAllRanges();
window.getSelection().removeAllRanges();
});
</script>
{% endblock %}
2 changes: 1 addition & 1 deletion flask_app/templates/info/splitting_summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
<div class="information">
<p>Training data contains {{num_rows_train}} rows</p>
</div>
{% endblock %}
{% endblock %}
Loading