コード例 #1
0
ファイル: main.py プロジェクト: samoretc/Workout-Timer
	def post(self):
		workout_title = self.request.get("workout")
		new_workout = Workout(parent = PARENT_KEY, title = workout_title)
		new_workout.put()
		arguments = self.request.arguments()
		exercises = [ {} for i in range( utils.findLength(arguments) ) ]
		print exercises
		for argu in arguments:
			if str(argu) != 'workout':
				num = utils.findPosition(argu)
				if utils.is_time(argu):
					exercises[num]['time'] = int(self.request.get(argu))
				if utils.is_rest(argu):
					exercises[num]['rest'] = int(self.request.get(argu))
				if utils.is_name(argu): 
					exercises[num]['name'] = str(self.request.get(argu))
		print exercises
		for counter, exercise in enumerate(exercises): ## Needs to be ordered
			print counter
			print exercise
			new_exercise = Exercise(parent = PARENT_KEY, 
									name = exercise['name'],
									time = exercise['time'],
									rest = exercise['rest'],
									workout_title =  workout_title,
									order =  counter)
			new_exercise.put()

		self.redirect('/home') 
コード例 #2
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def get_json_response(self):
        # Currently accepts: { "buckets", "all", "newest" }
        to_show = self.request_string('show', 'buckets')
        past_days = self.request_int('past_days', 7)
        refresh_secs = self.request_int('rsecs', 30)

        today = dt.date.today()
        # We don't use App Engine Query filters so as to avoid adding entries to index.yaml
        days = [ today - dt.timedelta(days=i) for i in range(0, past_days) ]

        if to_show == 'all':
            exercise_names = [ex.name for ex in Exercise.get_all_use_cache()]
            return self.exercise_over_time_for_highcharts(exercise_names, days, 'All Exercises', showLegend=True)

        if to_show == 'newest':
            exercises = Exercise.get_all_use_cache()
            exercises.sort(key=lambda ex: ex.creation_date, reverse=True)
            exercise_names = [ex.name for ex in exercises]

            num_newest = self.request_int('newest', 5)
            exid = exercise_names[get_bucket_cursor(refresh_secs, num_newest)]

            title = 'Newest Exercises - %s' % Exercise.to_display_name(exid)

            return self.exercise_over_time_for_highcharts([exid], days, title, showLegend=True)

        num_buckets = self.request_int('buckets', NUM_BUCKETS)
        bucket_index = self.request_int('ix', 0)
        bucket_size = get_bucket_size(num_buckets, bucket_index)
        bucket_cursor = get_bucket_cursor(refresh_secs, bucket_size)

        exercise_names = exercises_in_bucket(num_buckets, bucket_index)
        exid = exercise_names[bucket_cursor]

        return self.exercise_over_time_for_highcharts([exid], days, Exercise.to_display_name(exid))
コード例 #3
0
def exercise_progress_graph_context(user_data_student):

    if not user_data_student:
        return {}
    
    exercise_data = {}
    
    exercises = Exercise.get_all_use_cache()
    user_exercise_graph = UserExerciseGraph.get(user_data_student)

    review_exercise_names = user_exercise_graph.review_exercise_names()

    for exercise in exercises:
        chart_link =""
        status = ""
        color = "transparent"
        exercise_display = Exercise.to_display_name(exercise.name)
        hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, "Not Started", '0%', 0)

        chart_link = "/profile/graph/exerciseproblems?student_email=%s&exercise_name=%s" % (user_data_student.email, exercise.name) 
                
        graph_dict = user_exercise_graph.graph_dict(exercise.name)

        if graph_dict["proficient"]:

            if exercise.name in review_exercise_names:
                status = "Review"
                color = "review light"
            else:
                status = "Proficient"
                color = "proficient"
                if not graph_dict["explicitly_proficient"]:
                    status = "Proficient (due to proficiency in a more advanced module)"

        elif graph_dict["struggling"]:
            status = "Struggling"
            color = "struggling"
        elif graph_dict["total_done"] > 0:
            status = "Started"
            color = "started"

        if len(status) > 0:
            hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % (exercise_display, 
                        status, 
                        UserExercise.to_progress_display(graph_dict["progress"]),
                        graph_dict["total_done"])

        exercise_data[exercise.name] = {
                "short_name": exercise.short_name(),
                "chart_link": chart_link,
                "ex_link": exercise.relative_url,
                "hover": hover,
                "color": color
                }
                
    return { 'exercises': exercises, 'exercise_data': exercise_data, }
コード例 #4
0
def exercise_progress_graph_context(user_data_student):

    if not user_data_student:
        return {}
    
    user = user_data_student.user

    exercise_data = {}
    
    exercises = Exercise.get_all_use_cache()
    user_exercises = UserExercise.get_for_user_use_cache(user)

    dict_user_exercises = {}
    for user_exercise in user_exercises:
        dict_user_exercises[user_exercise.exercise] = user_exercise

    for exercise in exercises:
        chart_link =""
        status = ""
        color = "transparent"
        exercise_display = Exercise.to_display_name(exercise.name)
        ex_link = "/exercises?exid="+exercise.name
        hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, "Not Started", 0, 0)

        chart_link = "/profile/graph/exerciseproblems?student_email=%s&exercise_name=%s" % (user.email(), exercise.name) 
                
        user_exercise = dict_user_exercises[exercise.name] if dict_user_exercises.has_key(exercise.name) else None

        if user_data_student.is_proficient_at(exercise.name):
            status = "Proficient"
            color = "proficient"
            if not user_data_student.is_explicitly_proficient_at(exercise.name):
                status = "Proficient (due to proficiency in a more advanced module)"

        elif user_exercise is not None and UserExercise.is_struggling_with(user_exercise, exercise):
            status = "Struggling"
            color = "struggling"
        elif user_exercise is not None and user_exercise.total_done > 0:
            status = "Started"
            color = "started"

        if len(status) > 0:
            hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % (exercise_display, 
                        status, 
                        user_exercise.streak if user_exercise is not None else 0, 
                        user_exercise.total_done if user_exercise is not None else 0)

        exercise_data[exercise.name] = {
                "short_name": exercise.short_name(),
                "chart_link": chart_link,
                "ex_link": ex_link, 
                "hover": hover,
                "color": color
                }
                
    return { 'exercises': exercises, 'exercise_data': exercise_data, }
コード例 #5
0
ファイル: views.py プロジェクト: jurka/training_builder
def load_csv(self):
    # import codecs
    # reader = codecs.getreader('utf-8')
    reader = csv.reader(open('./data/base_ex_women.csv', 'r'))

    print(repr(reader))
    print(dir(reader))

    try:
        i = True
        while True:
            row = reader.next()
            row = [unicode(s, "utf-8") for s in row]
        # for row in reader.next():
            if i:
                i = False
                continue
            logging.error(row)

            c = Exercise()
            # row = map(str, row)
            row = row + ([''] * 5)
            logging.error(row)

            c.title = row[0]
            c.description = row[1]
            c.image_link = row[2]
            c.link_to = row[3]
            c.video_link = row[4]
            c.for_women = True

            c.save()
    except Exception, e:
        pass
コード例 #6
0
ファイル: serializers.py プロジェクト: amd1250x/MyWorkouts
 def create(self, validated_data):
     e = Exercise(name=validated_data['name'],
                  order=validated_data['order'],
                  repsStart=validated_data['repsStart'],
                  repsEnd=validated_data['repsEnd'],
                  setsStart=validated_data['setsStart'],
                  setsEnd=validated_data['setsEnd'],
                  workout_id=validated_data['workout_id'],
                  owner=validated_data['owner'])
     e.save()
     return e
コード例 #7
0
def demo_exercise():
    from models import Exercise
    run = Exercise.query.filter(Exercise._name=='Run').first()
    walk = Exercise.query.filter(Exercise._name=='Walk').first()
    if run is None:
        run = Exercise('Run', '4 mph')
        db.session.add(run)
        db.session.commit()
    if walk is None:
        walk = Exercise('Walk', '2 mph')
        db.session.add(walk)
        db.session.commit()
    return run, walk
コード例 #8
0
    def get_use_cache(self):
        params = self.get_request_params()

        # Get the maximum so we know how the data label circles should be scaled
        most_new_users = 1
        ex_stat_dict = {}
        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name,
                                                 params['interested_day'])
            ex_stat_dict[ex.name] = stat
            if stat:
                most_new_users = max(most_new_users, stat.num_new_users())

        data_points = []
        min_y, max_y = -1, 1
        for ex in Exercise.get_all_use_cache():
            stat = ex_stat_dict[ex.name]

            y, x = -int(ex.h_position), int(ex.v_position)

            min_y, max_y = min(y, min_y), max(y, max_y)

            # Set the area of the circle proportional to the data value
            radius = 1
            if stat:
                radius = math.sqrt(
                    float(stat.num_new_users()) /
                    most_new_users) * MAX_POINT_RADIUS

            point = {
                'x': x,
                'y': y,
                'name': ex.display_name,
                'marker': {
                    'radius': max(radius, 1)
                },
            }
            data_points.append(point)

        context = {
            'title': 'Exercises map - First attempts',
            'series': {
                'name': 'First attempts',
                'data_values': json.dumps(data_points),
            },
            'minYValue': min_y - 1,
            'maxYValue': max_y + 1,
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_scatter_map.json', context)
コード例 #9
0
def delete_exercise(id):
    if request.method == 'OPTIONS':
        return Response()

    user_id = session.get('user_id', None)
    if user_id is None:
        return jsonify({'success': False}), 403

    ex = Exercise.get(id)
    if ex.day.workout.user.id != user_id:
        return jsonify({'success': False}), 403

    Exercise.delete(ex.id)
    return jsonify({'success': True})
コード例 #10
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def get_use_cache(self):
        params = self.get_request_params()

        # Get the maximum so we know how the data label circles should be scaled
        most_new_users = 1
        ex_stat_dict = {}
        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, params['interested_day'])
            ex_stat_dict[ex.name] = stat
            if stat:
                most_new_users = max(most_new_users, stat.num_new_users())

        data_points = []
        min_y, max_y = -1, 1
        for ex in Exercise.get_all_use_cache():
            stat = ex_stat_dict[ex.name]

            y, x = -int(ex.h_position), int(ex.v_position)

            min_y, max_y = min(y, min_y), max(y, max_y)

            # Set the area of the circle proportional to the data value
            radius = 1
            if stat:
                radius = math.sqrt(float(stat.num_new_users()) / most_new_users) * MAX_POINT_RADIUS

            point = {
                'x': x,
                'y': y,
                'name': ex.display_name,
                'marker': {
                    'radius': max(radius, 1)
                },
            }
            data_points.append(point)

        context = {
            'title': 'Exercises map - First attempts',
            'series': {
                'name': 'First attempts',
                'data_values': json.dumps(data_points),
            },
            'minYValue': min_y - 1,
            'maxYValue': max_y + 1,
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_scatter_map.json', context)
コード例 #11
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def exercise_counter_for_geckoboard_rag():
        exercises = Exercise.get_all_use_cache()
        exercises.sort(key=lambda ex: ex.creation_date, reverse=True)

        last_exercise = exercises[0]
        num_exercises = len(exercises)
        last_exercise_author = last_exercise.author.nickname() if last_exercise.author else 'random person'

        text = "Thanks %s for %s!" % (last_exercise_author, last_exercise.display_name)

        return {
            'item': [
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': num_exercises,
                    'text': text,
                },
            ]
        }
コード例 #12
0
    def exercise_counter_for_geckoboard_rag():
        exercises = Exercise.get_all_use_cache()
        exercises.sort(key=lambda ex: ex.creation_date, reverse=True)

        last_exercise = exercises[0]
        num_exercises = len(exercises)
        last_exercise_author = last_exercise.author.nickname(
        ) if last_exercise.author else 'random person'

        text = "Thanks %s for %s!" % (last_exercise_author,
                                      last_exercise.display_name)

        return {
            'item': [
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': num_exercises,
                    'text': text,
                },
            ]
        }
コード例 #13
0
ファイル: autocomplete.py プロジェクト: johnfelipe/server
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]
コード例 #14
0
ファイル: views.py プロジェクト: chrisuehlinger/sg-study-c
	def user_get(self, *args):
		pagename = args[0]
		if pagename is None:
			exercise_list = Exercise.query().order('name')
			page = {'url':'exercises', 'topic_name':'Practice Exercises'}
			self.render_with_user("exerciseindex.html", {'page':page,
														 'exercises':exercise_list})
		else:
			exercise = Exercise.query().filter("url = ",pagename).get()
			if exercise is None:
				self.write("No Exercise named '%s'" % pagename)
			else:
				logging.info("Serving exercise: " + repr(exercise.name))
				logging.info("Serving exercise: " + repr(exercise.start_code))
				logging.info("Serving exercise: " + repr(exercise.description))
				self.render_with_user("exercise.html", {'page':exercise})
コード例 #15
0
ファイル: views.py プロジェクト: chrisuehlinger/sg-study-c
	def user_post(self, *args):
		pagename = args[0]
		if args[0] is None:
			pagename=""

		exercise = Exercise.query().filter("url = ",pagename).get()
		submission = self.request.get('code')
		program = exercise.outside_code.format(submission)
		action = self.request.get('action')


		response = dict()
		if action == 'check':
			response = exercise.checker.checkWork(program, self.username)
			if response['passed']:
				user = User.query().filter('username = '******'test':
			message = ''
			logging.info(self.request.get('input'))
			response = exercise.checker.submit(program, self.username, self.request.get('input'))
			
			if (response['error'] != "OK" or 
				int(response['result']) != 15 or 
				response['output'] is None):
					message = response['error_message']

			response['message'] = message

		self.write_json(response);
コード例 #16
0
def add_workout():
    if request.method == 'POST':
        user = User.query.filter_by(name=session['username']).first()
        workout = Workout(date=datetime.utcnow(), user_id=user.id)

        exercise_count = int(request.form['exercise_count'])
        for exercise_num in range(1, exercise_count + 1):
            exercise = Exercise(order=1,
                                exercise_id=request.form['exercise' +
                                                         str(exercise_num)],
                                workout=workout)
            weights = request.form.getlist('weight' + str(exercise_num))
            reps = request.form.getlist('reps' + str(exercise_num))

            set_order = 1
            for weight, rep in zip(weights, reps):
                work_set = Set(order=set_order,
                               exercise=exercise,
                               weight=weight,
                               reps=reps)
                set_order += 1

        db.session.add(workout)
        db.session.commit()
        return redirect(url_for('index'))

    exercises = Exercises.query.all()
    return render_template('add_workout.html', exercises=exercises)
コード例 #17
0
ファイル: autocomplete.py プロジェクト: johnfelipe/server
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]
コード例 #18
0
    def post(self):
        # create a new day
        data = request.get_json()
        if not data:
            ret = {
                'message': 'Provide data.',
            }
            return jsonify(ret), 422
        exercises = []
        if data.get('exercises'):
            exercises = [
                Exercise.get(each_exercise)
                for each_exercise in data.get('exercises')
            ]

        day = Day(name=data['name'], exercises=filter(None, exercises))
        db.session.add(day)
        db.session.commit()
        db.session.refresh(day)
        ret = {
            'message': 'Day created successfully.',
            'id': day.id,
            'name': data['name']
        }
        return jsonify(ret), 200
コード例 #19
0
ファイル: app.py プロジェクト: alexgenc/healthy-living
def get_exercises():
    """Get exercises from API and place them in db."""
    request = requests.get(
        'https://wger.de/api/v2/exercise?language=2&limit=250')

    result = request.json()

    # Find all exercises currently stored in database
    exercises = Exercise.query.all()

    exercise_ids = []

    for exercise in exercises:
        exercise_ids.append(exercise.id)

    for item in result['results']:
        if item['id'] not in exercise_ids:
            exercise = Exercise(id=item['id'],
                                name=item['name'],
                                description=item['description'],
                                category_id=item['category'])

            db.session.add(exercise)

            db.session.commit()
コード例 #20
0
def handle_average(argv, Class, class_str, call_print_averages=True):
    '''Pass the appropriate data to get the corresponding averages.

    Keyword arguments:
    argv -- An array of command line arguments.
    Class -- The class in which to find the averages.
    class_str -- The stringified Classname (e.g., a Student class would be
    "Student").
    call_print_averages -- Boolean value to optionally print the averages
    '''
    arr = []
    for i in mean:
        i["pts_total"] = 0.0
        i["mean"] = 0.0
        i["num"] = 0
    for exercise in Exercise.select():
        compare = {"Student": exercise.student.id,
                   "Batch": exercise.student.batch.id,
                   "School": exercise.student.batch.school.id}
        if str(compare.get(class_str)) == str(argv[2]):
            get_average(exercise, argv)
    for i in range(0, len(mean)):
        if call_print_averages is True:
            print_averages(i)
        else:
            if print_averages(i, False) is not None:
                arr.append(print_averages(i, False))
    for student in Class.select():
        if str(student.id) == str(argv[2]):
            return arr
    print class_str + " not found"
コード例 #21
0
ファイル: main.py プロジェクト: samoretc/Workout-Timer
	def get(self):
		workouts_query = Workout.query(ancestor = PARENT_KEY)
		exercise_query = Exercise.query(ancestor = PARENT_KEY).order( Exercise.order )
		template = jinja_env.get_template("templates/index.html")
		print 'self response'
		print self.response
		self.response.write(template.render( {"workouts_query": workouts_query, "exercise_query" : exercise_query} ))
コード例 #22
0
def process_exercise(name, starting_path, clone_dir, blob_prefix, mapper,
                     bucket, user):
    tqdm.write(f"Processing exercise:{name}")
    exercise_path = f"{starting_path}/{name}"
    with tarfile.open(f"{exercise_path}/{name}.tar.gz", "w:gz") as f:
        f.add(f"{exercise_path}/", arcname=name, recursive=True)

    upload_folder(exercise_path, starting_path, mapper.language, bucket)

    has_hint = mapper.hint_exists(exercise_path)
    mappings = mapper.get_files_mappings(blob_prefix, name, has_hint=has_hint)
    metadata = mapper.get_metadata(clone_dir)
    topics, difficulty = next(
        iter([(ex["topics"], ex["difficulty"]) for ex in metadata
              if ex["slug"] == name]), (None, None))
    exercise = Exercise(name=name,
                        language=mapper.language,
                        description=mapper.pluck_readme(exercise_path),
                        topics=topics,
                        difficulty=difficulty,
                        creator=user.email)

    files = Artifact(readme=mappings["readme"],
                     solution=mappings["solution"],
                     starting_point=mappings["starting_point"],
                     test=mappings["test"],
                     hint=mappings["hint"],
                     compressed=mappings["compressed"],
                     exercise=exercise)

    return (exercise, files)
コード例 #23
0
ファイル: library.py プロジェクト: di445/server
def library_content_html(mobile=False, version_number=None):

    if version_number:
        version = TopicVersion.get_by_number(version_number)
    else:
        version = TopicVersion.get_default_version()

    tree = Topic.get_root(version).make_tree(types = ["Topics", "Video", "Exercise", "Url"])

    videos = [item for item in walk_children(tree) if item.kind()=="Video"]

    root, = prepare(tree)
    topics = root.subtopics

    timestamp = time.time()

    template_values = {
        'topics': topics,
        'is_mobile': mobile,
        # convert timestamp to a nice integer for the JS
        'timestamp': int(round(timestamp * 1000)),
        'version_date': str(version.made_default_on),
        'version_id': version.number,
        'approx_vid_count': Video.approx_count(),
        'exercise_count': Exercise.get_count(),
    }

    html = shared_jinja.get().render_template("library_content_template.html", **template_values)

    return html
コード例 #24
0
def get_all_exercises():

    response = requests.get('https://curric.rithmschool.com/r13/exercises/')
    soup = BeautifulSoup(response.text)
    links = []

    # Drop Exercise table
    engine = create_engine(ProductionConfig.SQLALCHEMY_DATABASE_URI)
    Exercise.__table__.drop(engine)
    db.create_all()

    # Set up current exercises to test for duplicates
    current_exercises = []
    for exercise in Exercise.query.all():
        current_exercises.append(exercise.title)

    for link in soup.find_all('a'):
        links.append('https://curric.rithmschool.com/r13/exercises/' +
                     link.get('href'))

    for link in links:
        if 'zip' in link:
            continue

        response = requests.get(link)
        soup = BeautifulSoup(response.text)
        if (soup.title is None):
            continue
        if (soup.title.string == 'Rithm Curriculum'):
            continue
        else:
            new_exercise = Exercise(title=soup.title.string, url=link)
            db.session.add(new_exercise)

    db.session.commit()
コード例 #25
0
def insert_item(argv):
    '''Takes the system arguments as parameter and then inserts the item.

    Keyword arguments:
    argv -- An array of command line arguments passed to the program.
    '''
    if argv[2] == "school":
        school = School.create(name=argv[3])
        print "New school: " + str(School.get(School.name == argv[3]))
    elif argv[2] == "batch":
        batch = Batch.create(school=argv[3], name=argv[4])
        print "New batch: " + str(Batch.get(Batch.name == argv[4]))
    elif argv[2] == "student":
        print "New student:",
        if len(argv) > 6:
            student = Student.create(batch=argv[3],
                                     age=argv[4],
                                     last_name=argv[5],
                                     first_name=argv[6])
            print str(Student.get(Student.age == argv[4] and
                                  Student.last_name == argv[5] and
                                  Student.first_name == argv[6]))
        else:
            student = Student.create(batch=argv[3],
                                     age=argv[4],
                                     last_name=argv[5])
            print str(Student.get(Student.age == argv[4] and
                                  Student.last_name == argv[5]))
    elif argv[2] == "exercise":
        exercise = Exercise.create(student=argv[3],
                                   subject=argv[4],
                                   note=argv[5])
        print "New Exercise: " + str(exercise)
コード例 #26
0
ファイル: main.py プロジェクト: colinfrankb/math-pomodoro
def generate_percentage_exercise():
    percentage_equations_factory = PercentageEquationsFactory()

    exercise = Exercise()

    percentage_equations_factory.appendTo(exercise)

    return render_template('exercise.html', exercise=exercise)
コード例 #27
0
 def update_exercise(self, exercise_name):
     ex = Exercise.all().filter('name =', exercise_name).get()
     if ex is not None:
         if ex.key() not in self.exercises:
             self.exercises.append(ex.key())
             return True
     else:
         logging.debug("Exercise %s not in datastore" % exercise_name)
コード例 #28
0
def test_delete():
    entry = ExerciseEntry.ExerciseEntry()
    entry.delete(TEST_ENTRY_DATA["user_id"],
                 TEST_ENTRY_DATA["exercise_entry_id"])
    exercise = Exercise.Exercise()
    exercise.delete(TEST_EXERCISE_DATA["user_id"],
                    TEST_EXERCISE_DATA["exercise_id"])
    assert entry.get_one(TEST_ENTRY_DATA["exercise_entry_id"]) is None
コード例 #29
0
ファイル: views.py プロジェクト: amd1250x/MyWorkouts
def add_exercise(request, workout):
    if not request.user.is_authenticated():
        return redirect(index)
    elif request.method == 'POST':
        form = ExerciseForm(request.POST)
        name = request.POST['name']
        if form.is_valid():
            e = Exercise(name=name,
                         owner=request.user,
                         workout=Workout.objects.get(id=workout))
            e.save()
            return redirect(index)
        else:
            print(form.errors)
    else:
        form = ExerciseForm()
    return render(request, 'add_exercise.html', {'form': form})
コード例 #30
0
ファイル: templatetags.py プロジェクト: johnfelipe/server
def exercise_message(exercise, user_exercise_graph, sees_graph=False,
        review_mode=False):
    """Render UserExercise html for APIActionResults["exercise_message_html"] listener in khan-exercise.js.

    This is called **each time** a problem is either attempted or a hint is called (via /api/v1.py)
    returns nothing unless a user is struggling, proficient, etc. then it returns the appropriat template

    See Also: APIActionResults

    sees_graph is part of an ab_test to see if a small graph will help
    """

    # TODO(david): Should we show a message if the user gets a problem wrong
    #     after proficiency, to explain that this exercise needs to be reviewed?

    exercise_states = user_exercise_graph.states(exercise.name)

    if review_mode and user_exercise_graph.has_completed_review():
        filename = 'exercise_message_review_finished.html'

    elif (exercise_states['proficient'] and not exercise_states['reviewing'] and
            not review_mode):
        if sees_graph:
            filename = 'exercise_message_proficient_withgraph.html'
        else:
            filename = 'exercise_message_proficient.html'

    elif exercise_states['struggling']:
        filename = 'exercise_message_struggling.html'
        suggested_prereqs = []
        if exercise.prerequisites:
            proficient_exercises = user_exercise_graph.proficient_exercise_names()
            for prereq in exercise.prerequisites:
                if prereq not in proficient_exercises:
                    suggested_prereqs.append({
                          'ka_url': Exercise.get_relative_url(prereq),
                          'display_name': Exercise.to_display_name(prereq),
                          })
        exercise_states['suggested_prereqs'] = apijsonify.jsonify(
                suggested_prereqs)

    else:
        return None

    return shared_jinja.get().render_template(filename, **exercise_states)
コード例 #31
0
def test_update_invalid_data_types():
    exercise = Exercise.Exercise()
    copy = dict(TEST_EXERCISE_DATA)
    copy.update({
        "amount": "this is not an int",
        "description": 123,
    })
    res = exercise.update(copy)
    assert res is None
コード例 #32
0
ファイル: main.py プロジェクト: colinfrankb/math-pomodoro
def generate_division_exercise():
    three_digit_rounded_division_equations_factory = RoundedDivisionEquationsFactory(
    )

    exercise = Exercise()

    three_digit_rounded_division_equations_factory.appendTo(exercise)

    return render_template('exercise.html', exercise=exercise)
コード例 #33
0
def update_exercise(id):

    if request.method == 'OPTIONS':
        return Response()

    user_id = session.get('user_id', None)
    if user_id is None:
        return jsonify({'success': False}), 403

    ex = Exercise.get(id)
    if ex.day.workout.user.id != user_id:
        return jsonify({'success': False}), 403

    sets = request.get_json().get('sets')
    reps = request.get_json().get('reps')
    Exercise.update(id, sets=sets, reps=reps)

    return jsonify({'success': True})
コード例 #34
0
ファイル: main.py プロジェクト: colinfrankb/math-pomodoro
def generate_multiplication_exercise():
    two_digit_multiplication_equations_factory = TwoDigitMultiplicationEquationsFactory(
    )

    exercise = Exercise()

    two_digit_multiplication_equations_factory.appendTo(exercise)

    return render_template('exercise.html', exercise=exercise)
コード例 #35
0
ファイル: main.py プロジェクト: colinfrankb/math-pomodoro
def generate_exercise():
    subtraction_equations_factory = SubtractionEquationsFactory()
    multiplication_equations_factory = MultiplicationEquationsFactory()

    exercise = Exercise()

    subtraction_equations_factory.appendTo(exercise)
    multiplication_equations_factory.appendTo(exercise)

    return render_template('exercise.html', exercise=exercise)
コード例 #36
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def get(self):
        date_to_set = self.request_date('date', "%Y/%m/%d")

        exercises = Exercise.get_all_use_cache()
        updated = []
        for ex in exercises:
            ex.creation_date = date_to_set
            updated.append(ex)

        db.put(updated)
コード例 #37
0
    def get_ip_addresses_for_geckoboard_map(date):
        ip_addresses = []

        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, date)

            if stat:
                ip_addresses += stat.histogram.get('ip_addresses', [])

        return {'points': {'point': [{'ip': addr} for addr in ip_addresses]}}
コード例 #38
0
    def get(self):
        date_to_set = self.request_date('date', "%Y/%m/%d")

        exercises = Exercise.get_all_use_cache()
        updated = []
        for ex in exercises:
            ex.creation_date = date_to_set
            updated.append(ex)

        db.put(updated)
コード例 #39
0
    def get_json_response(self):
        # Currently accepts: { "buckets", "all", "newest" }
        to_show = self.request_string('show', 'buckets')
        past_days = self.request_int('past_days', 7)
        refresh_secs = self.request_int('rsecs', 30)

        today = dt.date.today()
        # We don't use App Engine Query filters so as to avoid adding entries to index.yaml
        days = [today - dt.timedelta(days=i) for i in range(0, past_days)]

        if to_show == 'all':
            exercise_names = [ex.name for ex in Exercise.get_all_use_cache()]
            return self.exercise_over_time_for_highcharts(exercise_names,
                                                          days,
                                                          'All Exercises',
                                                          showLegend=True)

        if to_show == 'newest':
            exercises = Exercise.get_all_use_cache()
            exercises.sort(key=lambda ex: ex.creation_date, reverse=True)
            exercise_names = [ex.name for ex in exercises]

            num_newest = self.request_int('newest', 5)
            exid = exercise_names[get_bucket_cursor(refresh_secs, num_newest)]

            title = 'Newest Exercises - %s' % Exercise.to_display_name(exid)

            return self.exercise_over_time_for_highcharts([exid],
                                                          days,
                                                          title,
                                                          showLegend=True)

        num_buckets = self.request_int('buckets', NUM_BUCKETS)
        bucket_index = self.request_int('ix', 0)
        bucket_size = get_bucket_size(num_buckets, bucket_index)
        bucket_cursor = get_bucket_cursor(refresh_secs, bucket_size)

        exercise_names = exercises_in_bucket(num_buckets, bucket_index)
        exid = exercise_names[bucket_cursor]

        return self.exercise_over_time_for_highcharts(
            [exid], days, Exercise.to_display_name(exid))
コード例 #40
0
ファイル: views.py プロジェクト: chrisuehlinger/sg-study-c
	def post(self):
		upload_files = self.get_uploads()
		used_methods = list()
		for method in test_methods:
			if self.request.get(method):
				used_methods.append(method)

		inputs = list()
		for i in string.replace(self.request.get('test_input'), '\r', '').split(';'):
			inputs.append(db.Text(i))

		outputs = list()
		for o in string.replace(self.request.get('output'), '\r', '').split(';'):
			outputs.append(db.Text(o))

		if len(inputs) != len(outputs):
			self.write("Error: Number of inputs did not match number of outputs.")
		else:
			keywords = string.replace(self.request.get('keywords'), '\r', '').split(';')
			checker = ExerciseChecker(	test_methods=used_methods,
										inputs=inputs,
										outputs=outputs,
										keywords=keywords)
			checker.put()

			start_code=string.replace(self.request.get('start_code'), '\r', '')

			description = self.request.get('description')
			description = string.replace(description, '\r', '')
			description = string.replace(description, '\n', '<br>')

			exercise = Exercise(name=self.request.get('name'), 
								url=self.request.get('url'), 
								description=description,
								start_code=start_code,
								checker=checker)

			if len(upload_files):
				exercise.flowchart = upload_files[0].key()
			exercise.put()
			time.sleep(5)
			self.redirect('/exercises/'+exercise.url)
コード例 #41
0
def test_create():
    entry = ExerciseEntry.ExerciseEntry()
    exercise = Exercise.Exercise()
    exercise_id = exercise.create(TEST_EXERCISE_DATA["user_id"],
                                  TEST_EXERCISE_DATA)["exercise_id"]
    TEST_ENTRY_DATA["exercise_id"] = exercise_id
    TEST_EXERCISE_DATA["exercise_id"] = exercise_id
    res = entry.create(TEST_ENTRY_DATA["user_id"],
                       TEST_ENTRY_DATA["exercise_id"], TEST_ENTRY_DATA)
    TEST_ENTRY_DATA.update({"exercise_entry_id": res["exercise_entry_id"]})
    assert res is not None
コード例 #42
0
def add_exercise(id):
    if 'user_id' not in session:
        return redirect('/')

    day = WorkoutDay.get(id)
    if session.get('user_id') != day.workout.user_id:
        return redirect('/')

    prior_data = None
    if request.method == 'POST':
        exercise = request.form.get('exercise')
        sets = request.form.get('sets')
        reps = request.form.get('reps')
        exerciseName = request.form.get('exerciseName')
        results = Exercise.add(day.id, exercise, reps, sets, exerciseName)
        if results is not None:
            return redirect(f'/workouts/{day.workout_id}/days/{day.id}')
        prior_data = {
            'exercise': {
                'value': exercise,
                'error': None
            },
            'sets': {
                'value': sets,
                'error': None
            },
            'reps': {
                'value': reps,
                'error': None
            },
            'exerciseName': {
                'value': exerciseName,
                'error': None
            }
        }
    exercises = Exercise.all_for(id)
    return render_template('add_exercise.html',
                           workout_id=day.workout_id,
                           id=day.id,
                           prior_data=prior_data,
                           exercises=exercises)
コード例 #43
0
ファイル: app.py プロジェクト: Dcrdn/GrayCare-API
def agregarExercise(idPersona, exerciseTime, date):
    try:
        query=Exercise(
                idPersona=idPersona,
                exerciseTime=exerciseTime,
                date=date
            )
        db.session.add(query)
        db.session.commit()
        return "exercise added. exercise id={}".format(query.id)
    except Exception as e:
        return(str(e))
コード例 #44
0
def move_exercise(id):

    if request.method == 'OPTIONS':
        return Response()

    user_id = session.get('user_id', None)
    if user_id is None:
        return jsonify({'success': False}), 403

    ex = Exercise.get(id)
    user = ex.day.workout.user
    if user_id != user.id:
        return jsonify({'success': False}), 403

    direction = request.get_json().get('direction')
    if (direction == 'up'):
        Exercise.move_up(id)
    else:
        Exercise.move_down(id)

    return jsonify({'success': True})
コード例 #45
0
def test_update():
    exercise = Exercise.Exercise()
    copy = dict(TEST_EXERCISE_DATA)
    copy.update({
        "amount": 255,
        "sets": 5,
        "reps": 5,
        "units": "lbs",
        "description": "Update"
    })
    res = exercise.update(copy)
    assert res is not None
コード例 #46
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
def exercises_in_bucket(num_buckets, bucket_index):
    exercise_names = [ex.name for ex in Exercise.get_all_use_cache()]
    exercise_names.sort()

    # These calculations evenly distribute exercises among buckets, with excess
    # going to the first few buckets.
    # In particular, max_capacity(buckets) - min_capacity(buckets) <= 1.
    num_exercises = len(exercise_names)
    min_bucket_size = num_exercises / num_buckets
    bucket_rem = num_exercises % num_buckets

    first = bucket_index * min_bucket_size + min(bucket_rem, bucket_index)
    return exercise_names[ first : first + get_bucket_size(num_buckets, bucket_index) ]
コード例 #47
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def get_ip_addresses_for_geckoboard_map(date):
        ip_addresses = []

        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, date)

            if stat:
                ip_addresses += stat.histogram.get('ip_addresses', [])

        return {
            'points': {
                'point': [{'ip': addr} for addr in ip_addresses]
            }
        }
コード例 #48
0
def export_json(argv):
    '''Export all data in JSON format.

    Keyword arguments:
    argv -- An array of command line arguments.
    '''
    data = []
    for school in School.select():
        dict = {"name": school.name}
        data.append(dict)

    '''Add the batches.'''
    for dict in data:
        batches = []
        for batch in Batch.select():
            if batch.school.name == dict["name"]:
                batch_dict = {}
                dict["batches"] = batches
                batch_dict["name"] = batch.name
                batches.append(batch_dict)

    '''Add the students in their batch.'''
    for dict in data:
        if dict.get("batches") is not None:
            for batch in dict.get("batches"):
                students = []
                for student in Student.select():
                    if str(student.batch.name) == str(batch["name"]):
                        student_dict = {}
                        batch["students"] = students
                        student_dict["first_name"] = student.first_name
                        student_dict["last_name"] = student.last_name
                        student_dict["age"] = student.age
                        students.append(student_dict)

    '''Add the exercises to the corresponding student.'''
    for dict in data:
        if dict.get("batches") is not None:
            for batch in dict.get("batches"):
                for student in batch["students"]:
                    exercises = []
                    for e in Exercise.select():
                        if e.student.first_name == student.get("first_name"):
                            exercsie_dict = {}
                            student["exercises"] = exercises
                            exercsie_dict["note"] = e.note
                            exercsie_dict["subject"] = e.subject
                            exercises.append(exercsie_dict)

    print json.dumps(data)
コード例 #49
0
ファイル: __init__.py プロジェクト: KhanWorld/KhanAcademy
    def get(self):
        # task name token
        uid = self.request_string('uid', uuid.uuid4())

        yesterday = dt.date.today() - dt.timedelta(days=1)
        yesterday_dt = dt.datetime.combine(yesterday, dt.time())
        date = self.request_date('date', "%Y/%m/%d", yesterday_dt)
        start_dt, end_dt = ExerciseStatistic.date_to_bounds(date)

        exercises = self.request_string('exercises', '')
        exercises = [e for e in exercises.split(',') if e]
        if not exercises:
            exercises = [e.name for e in Exercise.all()]

        for exercise in exercises:
            logging.info("Creating task chain for %s", exercise)
            enqueue_task(exercise, start_dt, end_dt, None, uid, 0)
コード例 #50
0
def print_all(argv):
    '''Print all data in database, ordered with tab heirarchy.

    Keyword arguments:
    argv -- An array of command line arguments passed to the program.
    '''
    for school in School.select():
        print school
        for batch in Batch.select():
            if batch.school.id == school.id:
                print "\t" + str(batch)
                for student in Student.select():
                    if student.batch.id == batch.id:
                        print "\t\t" + str(student)
                        for exercise in Exercise.select():
                            if exercise.student.id == student.id:
                                print "\t\t\t" + str(exercise)
コード例 #51
0
ファイル: api.py プロジェクト: adamwulf/old-khan
   def get(self):
       exid = self.request.get('exid')
       exercise = Exercise.all().filter('name =', exid).get()

       exercise_videos = []
       for exercise_video in ExerciseVideo.all().filter('exercise =', exercise):
            v = exercise_video.video
            video_dict = {'youtube_id':  v.youtube_id,
                          'youtube_url': v.url,
                          'title': v.title, 
                          'description': v.description,
                          'keywords': v.keywords,                         
                          'readable_id': v.readable_id,
                          'ka_url': "http://www.khanacademy.org/video/%s" % (v.readable_id,)
                         }         
            exercise_videos.append(video_dict)

       self.response.out.write(json.dumps(exercise_videos, indent=4))
コード例 #52
0
ファイル: library.py プロジェクト: johnfelipe/server
def add_related_exercises(videos):
    logging.info("%s videos", len(videos))

    exercises = {e.key():e for e in Exercise.get_all_use_cache()}
    relations = {}
    logging.info("%s exercises", len(exercises))
    for exvid in ExerciseVideo.all().run():
        ex = exercises.get(exvid.key_for_exercise())
        if ex:
            relations.setdefault(exvid.key_for_video(),[]).append(ex)

    for exs in relations.itervalues():
        exs.sort(key=lambda e: (e.v_position, e.h_position))

    logging.info("%s related videos", len(relations))
    for vid in videos:
        exs = relations.get(vid.key()) or []
        vid.cached_related_exercises = exs
コード例 #53
0
ファイル: classtime.py プロジェクト: adamwulf/old-khan
    def description(self):
        dict_videos = {}
        dict_exercises = {}

        for activity in self.activities:

            dict_target = None
            name_activity = None

            if type(activity) == ProblemLog:
                name_activity = activity.exercise
                dict_target = dict_exercises
            elif type(activity) == VideoLog:
                name_activity = activity.video_title
                dict_target = dict_videos

            if dict_target is not None:

                # For older data that doesn't have video titles recorded
                if name_activity is None:
                    name_activity = "Unknown"

                if not dict_target.has_key(name_activity):
                    dict_target[name_activity] = True

        desc_videos = ""
        for key in dict_videos:
            if len(desc_videos) > 0:
                desc_videos += "<br/>"
            desc_videos += " - <em>%s</em>" % key
        if len(desc_videos) > 0:
            desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos

        desc_exercises = ""
        for key in dict_exercises:
            if len(desc_exercises) > 0:
                desc_exercises += "<br/>"
            desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key)
        if len(desc_exercises) > 0:
            desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises

        desc = ("<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises

        return desc
コード例 #54
0
def get_content_data():
    topics = {str(t.key()):(idx, t) for idx, t in enumerate(Topic.get_visible_topics())}
    topic_names = {}
    def get_topics_of(item):
        def g():
            if not item.topic_string_keys:
                return
            seen = set()
            for tk in item.topic_string_keys:
                try:
                    idx, topic = topics[tk]
                except KeyError:
                    continue
                for depth, tk2 in enumerate(topic.ancestor_keys[:-1][::-1]):
                    try:
                        idx2, topic2 = topics[str(tk2)]
                    except KeyError:
                        continue
                    if idx2 in seen:
                        continue
                    seen.add(idx2)
                    topic_names[idx2] = topic2.title
                    # use depth for sorting by topic level
                    yield depth, idx2
        return [idx for _, idx in sorted(g())]

    videos = {video.key().id():
        dict(
            key_id=video.key().id(),
            name=video.readable_id,
            display_name=video.title,
            topics=get_topics_of(video)
        ) for video in Video.get_all()}

    exercises = {exercise.name:
        dict(
            name=exercise.name,
            display_name=exercise.display_name,
            topics=get_topics_of(exercise),
        ) for exercise in Exercise.get_all_use_cache()}

    return topic_names, videos, exercises
コード例 #55
0
ファイル: report_json.py プロジェクト: avh4/khan-academy
    def get_histogram_spline_for_highcharts(self, earliest_dt=dt.datetime.min):
        histogram = {}
        for ex in Exercise.get_all_use_cache():
            if ex.creation_date:
                creation_day = dt.datetime.combine(ex.creation_date, dt.time())
                timestamp = to_unix_secs(creation_day) * 1000
                histogram[timestamp] = histogram.get(timestamp, 0) + 1

        total_exercises = {}
        prev_value = 0
        for day, value in sorted(histogram.items()):
            prev_value = total_exercises[day] = prev_value + value

        # Only retain recent dates
        earliest_unix = to_unix_secs(earliest_dt) * 1000
        histogram = [[k,v] for k,v in histogram.items() if k >= earliest_unix]
        total_exercises = [[k,v] for k,v in total_exercises.items() if k >= earliest_unix]

        context = {
            'series': [
                {
                    'name': 'Histogram (created per day)',
                    'type': 'column',
                    'data_values': json.dumps(histogram),
                    'axis': 0,
                },
                {
                    'name': 'Total exercises',
                    'type': 'spline',
                    'data_values': json.dumps(total_exercises),
                    'axis': 1,
                }
            ],
            # Let highcharts determine the scales for now.
            'axes': [
                { 'max': 'null' },
                { 'max': 'null' },
            ],
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_exercises_created_histogram.json', context)
コード例 #56
0
ファイル: classtime.py プロジェクト: KhanWorld/KhanAcademy
    def description(self):
        desc_videos = ""
        for key in self.dict_videos:
            if len(desc_videos) > 0:
                desc_videos += "<br/>"
            desc_videos += " - <em>%s</em>" % key
        if len(desc_videos) > 0:
            desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos

        desc_exercises = ""
        for key in self.dict_exercises:
            if len(desc_exercises) > 0:
                desc_exercises += "<br/>"
            desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key)
        if len(desc_exercises) > 0:
            desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises
 
        desc = ("<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises

        return desc
コード例 #57
0
ファイル: handlers.py プロジェクト: johnfelipe/server
    def get(self):
        from exercises import attempt_problem

        login_user = UserData.current()
        exercises_list = [exercise for exercise in Exercise.all()]
        videos_list = [video for video in Video.all()]

        user_count = self.request_int('users', 5)
        for user_id in xrange(0, user_count):
            # Create a new user
            first_name = random.choice(CreateRandomGoalData.first_names)
            last_name = random.choice(CreateRandomGoalData.last_names)
            nickname = "%s %s" % (first_name, last_name)
            email = 'test_%i@automatedrandomdata' % user_id
            user = users.User(email)

            logging.info("Creating user %s: (%i/%i)"
                % (nickname, user_id + 1, user_count))

            user_data = UserData.get_or_insert(
                key_name="test_user_%i" % user_id,
                user=user,
                current_user=user,
                user_id=str(user_id),
                moderator=False,
                last_login=datetime.now(),
                proficient_exercises=[],
                suggested_exercises=[],
                need_to_reassess=True,
                points=0,
                coaches=[login_user.user_email],
                user_email=email,
                user_nickname=nickname,
                )
            user_data.put()

            # Delete user exercise & video progress
            query = UserExercise.all()
            query.filter('user = '******'user = '******'type': 'GoalObjectiveExerciseProficiency',
                        'exercise': random.choice(exercises_list)})

                for objective in xrange(1, random.randint(2, 4)):
                    obj_descriptors.append({
                        'type': 'GoalObjectiveWatchVideo',
                        'video': random.choice(videos_list)})

                title = first_name + "'s Goal #" + str(goal_idx)
                logging.info("Creating goal " + title)

                objectives = GoalObjective.from_descriptors(obj_descriptors,
                    user_data)
                goal = Goal(parent=user_data, title=title,
                    objectives=objectives)
                user_data.save_goal(goal)

                for objective in obj_descriptors:
                    if objective['type'] == 'GoalObjectiveExerciseProficiency':
                        user_exercise = user_data.get_or_insert_exercise(
                            objective['exercise'])
                        chooser = random.randint(1, 120)
                        if chooser >= 60:
                            continue
                        elif chooser > 15:
                            count = 1
                            hints = 0
                        elif chooser < 7:
                            count = 20
                            hints = 0
                        else:
                            count = 25
                            hints = 1
                        logging.info(
                            "Starting exercise: %s (%i problems, %i hints)" %
                            (objective['exercise'].name, count, hints * count))
                        for i in xrange(1, count):
                            attempt_problem(user_data, user_exercise, i, 1,
                                'TEST', 'TEST', 'TEST', True, hints, 0, False,
                                "TEST", 'TEST', '0.0.0.0')

                    elif objective['type'] == 'GoalObjectiveWatchVideo':
                        seconds = random.randint(1, 1200)
                        logging.info("Watching %i seconds of video %s"
                            % (seconds, objective['video'].title))
                        VideoLog.add_entry(user_data, objective['video'],
                            seconds, 0, detect_cheat=False)

        self.response.out.write('OK')
コード例 #58
0
ファイル: models.py プロジェクト: johnfelipe/server
 def url(self):
     if self.exercise_name:
         return Exercise.get_relative_url(self.exercise_name)
     else:
         return "/exercisedashboard"