forked from jtlowery/Coursera-Stanford-ML-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
447 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
from urllib import urlencode | ||
from urllib2 import urlopen | ||
from json import loads, dumps | ||
from collections import OrderedDict | ||
import numpy as np | ||
import os | ||
|
||
|
||
|
||
class Submission(): | ||
|
||
def __init__(self, homework, part_names, srcs, output): | ||
self.__homework = homework | ||
self.__part_names = part_names | ||
self.__srcs = srcs | ||
self.__output = output | ||
self.__submit_url = 'https://www-origin.coursera.org/api/onDemandProgrammingImmediateFormSubmissions.v1' | ||
self.__login = None | ||
self.__password = None | ||
|
||
def __init__(self): | ||
self.__submit_url = 'https://www-origin.coursera.org/api/onDemandProgrammingImmediateFormSubmissions.v1' | ||
|
||
|
||
def submit(self): | ||
print '==\n== Submitting Solutions | Programming Exercise %s\n==' % self.__homework | ||
self.login_prompt() | ||
|
||
parts = OrderedDict() | ||
for part_id, _ in enumerate(self.__srcs,1): | ||
parts[str(part_id)] = {'output': self.__output(part_id)} | ||
|
||
result, response = self.request(parts) | ||
response = loads(response) | ||
try: | ||
print response['errorMessage'] | ||
return | ||
except: | ||
pass | ||
print '==' | ||
print '== %43s | %9s | %-s' % ('Part Name', 'Score', 'Feedback') | ||
print '== %43s | %9s | %-s' % ('---------', '-----', '--------') | ||
|
||
|
||
for part in parts: | ||
partFeedback = response['partFeedbacks'][part] | ||
partEvaluation = response['partEvaluations'][part] | ||
score = '%d / %3d' % (partEvaluation['score'], partEvaluation['maxScore']) | ||
print '== %43s | %9s | %-s' % (self.__part_names[int(part)-1], score, partFeedback) | ||
|
||
evaluation = response['evaluation'] | ||
|
||
|
||
totalScore = '%d / %d' % (evaluation['score'], evaluation['maxScore']) | ||
print '== --------------------------------' | ||
print '== %43s | %9s | %-s\n' % (' ', totalScore, ' ') | ||
print '==' | ||
|
||
if not os.path.isfile('token.txt'): | ||
with open('token.txt', 'w') as f: | ||
f.write(self.__login + '\n') | ||
f.writelines(self.__password) | ||
return response | ||
|
||
def login_prompt(self): | ||
try: | ||
with open('token.txt', 'r') as f: | ||
self.__login = f.readline().strip() | ||
self.__password = f.readline().strip() | ||
except IOError: | ||
pass | ||
|
||
if self.__login is not None and self.__password is not None: | ||
reenter = raw_input('Use token from last successful submission (%s)? (Y/n): ' % self.__login) | ||
|
||
if reenter == '' or reenter[0] == 'Y' or reenter[0] == 'y': | ||
return | ||
|
||
if os.path.isfile('token.txt'): | ||
os.remove('token.txt') | ||
self.__login = raw_input('Login (email address): ') | ||
self.__password = raw_input('Token: ') | ||
|
||
def request(self, parts): | ||
|
||
params = { | ||
'assignmentSlug': self.__homework, | ||
'secret': self.__password, | ||
'parts': parts, | ||
'submitterEmail': self.__login} | ||
|
||
params = urlencode({'jsonBody': dumps(params)}) | ||
f = urlopen(self.__submit_url, params) | ||
try: | ||
return 0, f.read() | ||
finally: | ||
f.close() | ||
|
||
def sprintf(fmt, arg): | ||
"emulates (part of) Octave sprintf function" | ||
if isinstance(arg, tuple): | ||
# for multiple return values, only use the first one | ||
arg = arg[0] | ||
|
||
if isinstance(arg, (np.ndarray, list)): | ||
# concatenates all elements, column by column | ||
return ' '.join(fmt % e for e in np.asarray(arg).ravel('F')) | ||
else: | ||
return fmt % arg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
import os | ||
import pypandoc | ||
from kivy.app import App | ||
from kivy.uix.boxlayout import BoxLayout | ||
from kivy.uix.gridlayout import GridLayout | ||
from kivy.uix.floatlayout import FloatLayout | ||
from kivy.uix.button import Button | ||
from kivy.uix.codeinput import CodeInput | ||
from kivy.uix.label import Label | ||
from kivy.uix.rst import RstDocument | ||
from kivy.uix.textinput import TextInput | ||
from kivy.uix.spinner import Spinner | ||
from kivy.uix.togglebutton import ToggleButton | ||
from kivy.uix.splitter import Splitter | ||
from kivy.uix.scrollview import ScrollView | ||
from kivy.uix.popup import Popup | ||
from kivy.clock import Clock | ||
from functools import partial | ||
from kivy.animation import Animation | ||
from Submission import Submission | ||
|
||
|
||
class resourceHandler(): | ||
def __init__(self, **args): | ||
pass | ||
|
||
|
||
def read_token(self,instance): | ||
path = '../'+instance.current_ex+'/token.txt' | ||
try: | ||
credentials = open(path) | ||
instance.email = credentials.readline().strip() | ||
instance.token = credentials.readline().strip() | ||
return True | ||
except Exception, e: | ||
return False | ||
|
||
|
||
|
||
def files(self,excercise): | ||
path = 'res/'+excercise+'/sources.txt' | ||
filehandler = open(path) | ||
filelist=[] | ||
while True: | ||
try: | ||
filelist.append(filehandler.next()) | ||
except Exception, e: | ||
return filelist | ||
def manual(self, excercise): | ||
path = 'res/'+excercise+'/manual.md' | ||
return pypandoc.convert(path,'rst') | ||
|
||
def writeFile(self,excercise,filename): | ||
path = '../'+excercise+'/'+filename | ||
f=open(path,'w') | ||
return f | ||
|
||
def readFile(self,excercise,filename): | ||
path = '../'+excercise+'/'+filename | ||
#print 'Opening ',path | ||
f=open(path,'r') | ||
return f.read() | ||
|
||
class MainScreen(BoxLayout): | ||
|
||
def __init__(self, welcome=False, **kwargs): | ||
super(MainScreen, self).__init__(**kwargs) | ||
self.orientation='vertical' | ||
self.current_ex = 'ex1' | ||
self.current_file = 'warmUpExercise.py' | ||
self.submit_ob = Submission() | ||
self.element=resourceHandler() | ||
|
||
if welcome: | ||
welcome_popup = Popup(title='Coursera ML in Python', content=Label(text='Hello World'),size_hint=(1, 1)) | ||
self.add_widget(welcome_popup) | ||
welcome_popup.open() | ||
Clock.schedule_once(self.start_app,3) | ||
else: | ||
self.bind(size=self.draw_screen) | ||
|
||
def start_app(self,*args): | ||
self.draw_screen() | ||
self.bind(size=self.draw_screen) | ||
|
||
def draw_screen(self,*args): | ||
self.clear_widgets() | ||
self.add_widget(self.titlebar()) | ||
self.add_widget(self.maineditor()) | ||
scrollbar = ScrollView(size_hint=(1,None)) | ||
#TODO: Make filebar scrollable for smaller screens and many files | ||
#scrollbar.add_widget(self.filebar()) | ||
#self.add_widget(scrollbar) | ||
self.add_widget(self.filebar()) | ||
self.add_widget(self.console()) | ||
|
||
def titlebar(self): | ||
layout=BoxLayout(padding='2sp',size_hint=(1,None),height='65sp') | ||
layout.orientation='horizontal' | ||
|
||
#credentials = self.accept_credentials() | ||
self.submit_popup = Popup(title='Enter credentials',content=self.accept_credentials(),size_hint=(0.6, 0.35)) | ||
#credentials.children[1].bind(on_press=self.submit_popup.dismiss) | ||
|
||
submit = Button(text='Submit',size_hint=(0.4,1)) | ||
if self.element.read_token(self): | ||
submit.bind(on_press=partial(self.submit_assignment)) | ||
else: | ||
submit.bind(on_press=self.submit_popup.open) | ||
|
||
run = Button(text='Run',size_hint=(0.4,1)) | ||
run.bind(on_press=self.run) | ||
|
||
ex_dropdown = Spinner(text=self.current_ex,size_hint=(1,1)) | ||
ex_dropdown.values = os.listdir('./res/') | ||
ex_dropdown.bind(text=self.updateExercise) | ||
|
||
layout.add_widget(run) | ||
layout.add_widget(ex_dropdown) | ||
layout.add_widget(submit) | ||
|
||
return layout | ||
|
||
|
||
def console(self): | ||
layout = FloatLayout(size_hint=(1,None),height=100) | ||
self.info_label = TextInput(size_hint=(1,None),readonly=True,background_color=(0,0,0,1),foreground_color=(1,1,1,1),opacity=0) | ||
self.info_label.text_size = self.size | ||
self.info_label.text = 'console' | ||
self.info_label.height = '150pt' | ||
self.info_label.top = 0 | ||
layout.add_widget(self.info_label) | ||
return layout | ||
|
||
|
||
def accept_credentials(self): | ||
main_layout= BoxLayout(padding='2sp') | ||
main_layout.orientation='vertical' | ||
layout=GridLayout(padding='2sp') | ||
layout.cols=2 | ||
layout.add_widget(Label(text='Email id:')) | ||
email = TextInput(multiline=False) | ||
layout.add_widget(email) | ||
token = TextInput(multiline=False) | ||
layout.add_widget(Label(text='Submission Token:')) | ||
layout.add_widget(token) | ||
main_layout.add_widget(layout) | ||
submit = Button(text='Submit',size_hint=(1,0.4)) | ||
submit.bind(on_press=partial(self.submit_assignment,email,token)) | ||
main_layout.add_widget(submit) | ||
return main_layout | ||
|
||
def submit_assignment(self,*largs): | ||
#Make submit_ob local if not used anywhere else | ||
if len(largs)>1: | ||
self.submit_ob.__login = largs[0].text | ||
self.submit_ob.__password = largs[1].text | ||
else: | ||
self.submit_ob.__login=self.email | ||
self.submit_ob.__password=self.token | ||
|
||
print 'Email',self.submit_ob.__login | ||
print 'Token', self.submit_ob.__password | ||
self.submit_popup.dismiss() | ||
#TODO:submission call | ||
#self.show_error(self.submit_ob.submit()) | ||
|
||
|
||
def updateExercise(self,spinner,text): | ||
self.current_ex=text | ||
current_file = self.element.files(self.current_ex)[0] | ||
if current_file.endswith('\n'): | ||
current_file=current_file[:-1] | ||
self.current_file= current_file | ||
self.draw_screen() | ||
print 'Current Exercise changed to: ', self.current_ex | ||
|
||
|
||
|
||
def run(self,instance): | ||
#TODO: Display output in popup | ||
self.show_error('Cannot run') | ||
print('The button <%s> is being pressed' % instance.text) | ||
|
||
|
||
|
||
|
||
def maineditor(self): | ||
layout=BoxLayout() | ||
if self.width < self.height: | ||
layout.orientation='vertical' | ||
else: | ||
layout.orientation='horizontal' | ||
#self.bind(self.current_ex=self.update_currentFile) | ||
man = self.element.manual(self.current_ex) | ||
codeFile = self.element.readFile(self.current_ex,self.current_file) | ||
code = CodeInput(text=codeFile) | ||
code.bind(focus =self.schedule_reload) | ||
splitter = Splitter() | ||
if layout.orientation == 'vertical': | ||
splitter.sizable_from='bottom' | ||
else: | ||
splitter.sizable_from='right' | ||
splitter.add_widget(code) | ||
layout.add_widget(splitter) | ||
|
||
layout.add_widget(RstDocument(text=man)) | ||
return layout | ||
|
||
def saveAssignment(self,assignment,*largs): | ||
print 'callback called' | ||
try: | ||
if not self.element.readFile(self.current_ex,self.current_file)==assignment.text: | ||
filehandler = self.element.writeFile(self.current_ex,self.current_file) | ||
filehandler.write(assignment.text) | ||
print 'INFO: Autosaved file' | ||
except Exception, e: | ||
raise e | ||
self.show_error(e) | ||
|
||
|
||
def schedule_reload(self,instance,value): | ||
if value: | ||
#Schedule Update | ||
self.callback = partial(self.saveAssignment,instance) | ||
Clock.schedule_interval(self.callback,5) | ||
else: | ||
#TODO:When clicking on another file, both focus=False and filebar button callbacks are executed simultaneously leading to deadlock | ||
Clock.unschedule(self.callback) | ||
#self.saveAssignment(instance) | ||
#Update now | ||
|
||
|
||
def filebar(self): | ||
layout=BoxLayout(padding='2sp',size_hint=(1,None),height='100sp') | ||
layout.orientation='horizontal' | ||
files = self.element.files(self.current_ex) | ||
for f in files: | ||
if f.strip() == self.current_file: | ||
button = ToggleButton(text=f,group = self.current_ex,state='down') | ||
else: | ||
button = ToggleButton(text=f,group = self.current_ex,state='normal') | ||
button.bind(on_press=self.update_currentFile) | ||
layout.add_widget(button) | ||
return layout | ||
|
||
def update_currentFile(self,instance): | ||
if instance.text.endswith('\n'): | ||
instance.text=instance.text[:-1] | ||
self.current_file = instance.text | ||
self.draw_screen() | ||
print 'Current file changed to: ', self.current_file | ||
|
||
def show_error(self, e): | ||
self.info_label.text = str(e) | ||
duration = len(self.info_label.text)/10 | ||
anim = Animation(top=190.0, opacity=1, d=0.5) +\ | ||
Animation(top=190.0, d=duration) +\ | ||
Animation(top=0, opacity=0, d=2) | ||
anim.start(self.info_label) | ||
|
||
|
||
|
||
class CourseraApp(App): | ||
|
||
def build(self): | ||
return MainScreen(welcome=True) | ||
def on_pause(self): | ||
return True | ||
|
||
|
||
if __name__ == '__main__': | ||
CourseraApp().run() |
Oops, something went wrong.