Ejemplo n.º 1
0
def run_suite (suite):
    # We use a random username so that if a test fails, we don't have to do a cleaning of the DB so that the test suite can run again
    # This also allows us to run concurrent tests without having username conflicts.
    username = '******' + str (random.randint (10000, 100000))
    tests = suite (username)
    state = {'headers': {}}
    t0 = timems ()

    if not type_check (tests, 'list'):
        return print ('Invalid test suite, must be a list.')
    counter = 1

    def run_test (test, counter):
        result = request (state, test, counter, username)

    for test in tests:
        # If test is nested, run a nested loop
        if not (type_check (test[0], 'str')):
            for subtest in test:
                run_test (subtest, counter)
                counter += 1
        else:
           run_test (test, counter)
           counter += 1

    if isinstance (threading.current_thread (), threading._MainThread):
        print ('Test suite successful! (' + str (timems () - t0) + 'ms)')
    else:
        return timems () - t0
Ejemplo n.º 2
0
def retrieveProgramsBefore (state, response, username):
    if not type_check (response ['body'], 'dict'):
        raise Exception ('Invalid response body')
    if not 'programs' in response ['body'] or not type_check (response ['body'] ['programs'], 'list'):
        raise Exception ('Invalid programs list')
    if len (response ['body'] ['programs']) != 0:
        raise Exception ('Programs list should be empty')
Ejemplo n.º 3
0
def request (state, test, counter, username):

    start = timems ()

    if isinstance (threading.current_thread (), threading._MainThread):
        print ('Start #' + str (counter) + ': ' + test [0])

    # If no explicit cookie passed, use the one from the state
    if not 'cookie' in test [3] and 'cookie' in state ['headers']:
        test [3] ['cookie'] = state ['headers'] ['cookie']

    # If path, headers or body are functions, invoke them passing them the current state
    if type_check (test[2], 'fun'):
        test[2] = test[2] (state)

    if type_check (test[3], 'fun'):
        test[3] = test[3] (state)

    if type_check (test[4], 'fun'):
        test[4] = test[4] (state)

    if type_check (test[4], 'dict'):
        test[3] ['content-type'] = 'application/json'
        test[4] = json.dumps (test [4])

    # We pass the X-Testing header to let the server know that this is a request coming from an E2E test, thus no transactional emails should be sent.
    test [3] ['X-Testing'] = '1'

    r = getattr (requests, test [1]) (host + test [2], headers=test[3], data=test[4])

    if 'Content-Type' in r.headers and r.headers ['Content-Type'] == 'application/json':
        body = r.json ()
    else:
        body = r.text

    if r.history and r.history [0]:
        # This will be the case if there's a redirect
        code = r.history [0].status_code
    else:
        code = r.status_code

    output = {
        'code':    code,
        'headers': r.headers,
        'body':    body
    }

    if (code != test[5]):
        print (output)
        raise Exception ('A test failed!')

    if len (test) == 7:
        test [6] (state, output, username)

    if isinstance (threading.current_thread (), threading._MainThread):
        print ('Done  #' + str (counter) + ': ' + test [0] + ' - ' + str (r.status_code) + ' (' + str (timems () - start) + 'ms)')

    return output
Ejemplo n.º 4
0
def request(test, counter):

    start = timems()

    print('Start #' + str(counter) + ': ' + test[0])

    # If no explicit cookie passed, use the one from the state
    if not 'cookie' in test[3] and 'cookie' in state['headers']:
        test[3]['cookie'] = state['headers']['cookie']

    # If path, headers or body are functions, invoke them passing them the current state
    if type_check(test[2], 'fun'):
        test[2] = test[2](state)

    if type_check(test[3], 'fun'):
        test[3] = test[3](state)

    if type_check(test[4], 'fun'):
        test[4] = test[4](state)

    if type_check(test[4], 'dict'):
        test[3]['content-type'] = 'application/json'
        test[4] = json.dumps(test[4])
    r = getattr(requests, test[1])(host + test[2],
                                   headers=test[3],
                                   data=test[4])

    if 'Content-Type' in r.headers and r.headers[
            'Content-Type'] == 'application/json':
        body = r.json()
    else:
        body = r.text

    if r.history and r.history[0]:
        # This will be the case if there's a redirect
        code = r.history[0].status_code
    else:
        code = r.status_code

    output = {'code': code, 'headers': r.headers, 'body': body}

    if (code != test[5]):
        print(output)
        raise Exception('A test failed!')

    if len(test) == 7:
        test[6](state, output)

    print('Done  #' + str(counter) + ': ' + test[0] + ' - ' +
          str(r.status_code) + ' (' + str(timems() - start) + 'ms)')

    return output
Ejemplo n.º 5
0
def var_homogeneity(x1, x2, alpha=0.1, verbose=1):
    x1 = utils.type_check(x1)
    x2 = utils.type_check(x2)
    _F, _p = base.var_homo_test(x1, x2)

    if verbose == 1:
        print("使用F-test检验方差齐性:")
        print("p = {0}, alpha = {1}".format(_p, alpha))
        if _p < alpha:
            print("p < alpha, 差异有统计学意义,两组总体方差不等")
        else:
            print("p >= alpha, 差异无统计学意义,尚不能认定两组总体方差不等")
    return _F, _p
Ejemplo n.º 6
0
def retrieveProgramsAfter (state, response, username):
    if not type_check (response ['body'], 'dict'):
        raise Exception ('Invalid response body')
    if not 'programs' in response ['body'] or not type_check (response ['body'] ['programs'], 'list'):
        raise Exception ('Invalid programs list')
    if len (response ['body'] ['programs']) != 1:
        raise Exception ('Programs list should contain one program')
    program = response ['body'] ['programs'] [0]
    state ['program'] = program
    if not type_check (program, 'dict'):
        raise Exception ('Invalid program type')
    if not 'code' in program or program ['code'] != 'print Hello world':
        raise Exception ('Invalid program.code')
    if not 'level' in program or program ['level'] != 1:
        raise Exception ('Invalid program.level')
Ejemplo n.º 7
0
    def recover():
        body = request.json
        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'body.username must be a string', 400

        # If username has an @-sign, then it's an email
        if re.match('@', body['username']):
            username = r.hget('emails', body['username'])
            if not username:
                return 'invalid username/password', 403
        else:
            username = body['username']

        username = username.strip().lower()

        user = r.hgetall('user:'******'invalid username', 403

        token = make_salt()
        hashed = hash(token, make_salt())

        r.setex('token:' + hashed, session_length, body['username'])
        # TODO: when in non-local environment, email the token instead of returning it
        return token
Ejemplo n.º 8
0
    def update_profile(user):

        body = request.json
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if 'email' in body:
            if not object_check(body, 'email', 'str'):
                return 'body.email must be a string', 400
            if not re.match(
                    '^(([a-zA-Z0-9_\.\-]+)@([\da-zA-Z\.\-]+)\.([a-zA-Z\.]{2,6})\s*)$',
                    body['email']):
                return 'body.email must be a valid email', 400
        if 'country' in body:
            if not body['country'] in countries:
                return 'body.country must be a valid country', 400
        if 'age' in body:
            if not object_check(body, 'age', 'int') or body['age'] <= 0:
                return 'body.age must be an integer larger than 0', 400
        if 'gender' in body:
            if body['gender'] != 'm' and body['gender'] != 'f':
                return 'body.gender must be m/f', 400

        if 'email' in body:
            r.hdel('emails', user['email'])
            r.hset('emails', body['email'], user['username'])
            r.hset('user:'******'username'], 'email', body['email'])

        if 'country' in body:
            r.hset('user:'******'username'], 'country', body['country'])
        if 'age' in body:
            r.hset('user:'******'username'], 'age', body['age'])
        if 'gender' in body:
            r.hset('user:'******'username'], 'gender', body['gender'])
        return '', 200
Ejemplo n.º 9
0
Archivo: auth.py Proyecto: tech189/hedy
    def recover ():
        body = request.json
        # Validations
        if not type_check (body, 'dict'):
            return 'body must be an object', 400
        if not object_check (body, 'username', 'str'):
            return 'body.username must be a string', 400

        # If username has an @-sign, then it's an email
        if '@' in body ['username']:
            user = db_get ('users', {'email': body ['username'].strip ().lower ()}, True)
        else:
            user = db_get ('users', {'username': body ['username'].strip ().lower ()})

        if not user:
            return 'invalid username', 403

        token = make_salt ()
        hashed = hash (token, make_salt ())

        db_set ('tokens', {'id': user ['username'], 'token': hashed, 'ttl': times () + session_length})

        if not env:
            # If on local environment, we return email verification token directly instead of emailing it, for test purposes.
            return jsonify ({'username': user ['username'], 'token': token}), 200
        else:
            send_email_template ('recover_password', user ['email'], requested_lang (), os.getenv ('BASE_URL') + '/reset?username='******'username']) + '&token=' + urllib.parse.quote_plus (token))
            return '', 200
Ejemplo n.º 10
0
    def login():
        body = request.json
        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'username must be a string', 400
        if not object_check(body, 'password', 'str'):
            return 'password must be a string', 400

        # If username has an @-sign, then it's an email
        if re.match('@', body['username']):
            username = r.hget('emails', body['username'])
            if not username:
                return 'invalid username/password', 403
        else:
            username = body['username']

        username = username.strip().lower()

        user = r.hgetall('user:'******'invalid username/password', 403
        if not check_password(body['password'], user['password']):
            return 'invalid username/password', 403

        cookie = make_salt()
        r.setex('sess:' + cookie, session_length, body['username'])
        r.hset('user:'******'username'], 'lastAccess', timems())
        resp = make_response({})
        resp.set_cookie(cookie_name, value=cookie, httponly=True, path='/')
        return resp
Ejemplo n.º 11
0
def index(level, step):
    session_id()  # Run this for the side effect of generating a session ID
    g.level = level = int(level)
    g.lang = requested_lang()
    g.prefix = '/hedy'

    # If step is a string that has more than two characters, it must be an id of a program
    if step and type_check(step, 'str') and len(step) > 2:
        result = db_get('programs', {'id': step})
        if not result:
            return 'No such program', 404
        # Allow only the owner of the program, the admin user and the teacher users to access the program
        user = current_user(request)
        if user['username'] != result['username'] and not is_admin(
                request) and not is_teacher(request):
            return 'No such program!', 404
        loaded_program = result['code']
        # We default to step 1 to provide a meaningful default assignment
        step = 1
    else:
        loaded_program = None

    return hedyweb.render_assignment_editor(request=request,
                                            course=HEDY_COURSE[g.lang],
                                            level_number=level,
                                            assignment_number=step,
                                            menu=render_main_menu('hedy'),
                                            translations=TRANSLATIONS,
                                            version=version(),
                                            loaded_program=loaded_program)
Ejemplo n.º 12
0
Archivo: auth.py Proyecto: balath/hedy
    def reset():
        body = request.json
        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'body.username must be a string', 400
        if not object_check(body, 'token', 'str'):
            return 'body.token must be a string', 400
        if not object_check(body, 'password', 'str'):
            return 'body.password be a string', 400

        if len(body['password']) < 6:
            return 'password must be at least six characters long', 400

        # There's no need to trim or lowercase username, because it should come within a link prepared by the app itself and not inputted manually by the user.
        token = db_get('tokens', {'id': body['username']})
        if not token:
            return 'invalid username/token', 403
        if not check_password(body['token'], token['token']):
            return 'invalid username/token', 403

        hashed = hash(body['password'], make_salt())
        token = db_del('tokens', {'id': body['username']})
        db_set('users', {'username': body['username'], 'password': hashed})
        user = db_get('users', {'username': body['username']})

        if env:
            send_email_template('reset_password', user['email'],
                                requested_lang(), None)

        return '', 200
Ejemplo n.º 13
0
Archivo: auth.py Proyecto: tech189/hedy
    def login ():
        body = request.json
        # Validations
        if not type_check (body, 'dict'):
            return 'body must be an object', 400
        if not object_check (body, 'username', 'str'):
            return 'username must be a string', 400
        if not object_check (body, 'password', 'str'):
            return 'password must be a string', 400

        # If username has an @-sign, then it's an email
        if '@' in body ['username']:
            user = db_get ('users', {'email': body ['username'].strip ().lower ()}, True)
        else:
            user = db_get ('users', {'username': body ['username'].strip ().lower ()})

        if not user:
            return 'invalid username/password', 403
        if not check_password (body ['password'], user ['password']):
            return 'invalid username/password', 403

        cookie = make_salt ()
        db_set ('tokens', {'id': cookie, 'username': user ['username'], 'ttl': times () + session_length})
        db_set ('users', {'username': user ['username'], 'last_login': timems ()})
        resp = make_response ({})
        resp.set_cookie (cookie_name, value=cookie, httponly=True, path='/')
        return resp
Ejemplo n.º 14
0
Archivo: auth.py Proyecto: balath/hedy
    def mark_as_teacher():
        if not is_admin(request):
            return 'unauthorized', 403

        body = request.json

        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'body.username must be a string', 400
        if not object_check(body, 'is_teacher', 'bool'):
            return 'body.is_teacher must be boolean', 400

        user = db_get('users', {'username': body['username'].strip().lower()})

        if not user:
            return 'invalid username', 400

        db_set(
            'users', {
                'username': user['username'],
                'is_teacher': 1 if body['is_teacher'] else 0
            })

        return '', 200
Ejemplo n.º 15
0
    def signup():
        body = request.json
        # Validations, mandatory fields
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'username must be a string', 400
        if re.match('@', body['username']):
            return 'username cannot contain an @-sign', 400
        if re.match(':', body['username']):
            return 'username cannot contain a colon', 400
        if not object_check(body, 'password', 'str'):
            return 'password must be a string', 400
        if len(body['password']) < 6:
            return 'password must be at least six characters long', 400
        if not object_check(body, 'email', 'str'):
            return 'email must be a string', 400
        if not re.match(
                '^(([a-zA-Z0-9_\.\-]+)@([\da-zA-Z\.\-]+)\.([a-zA-Z\.]{2,6})\s*)$',
                body['email']):
            return 'email must be a valid email', 400
        # Validations, optional fields
        if 'country' in body:
            if not body['country'] in countries:
                return 'country must be a valid country', 400
        if 'age' in body:
            if not object_check(body, 'age', 'int') or body['age'] <= 0:
                return 'age must be an integer larger than 0', 400
        if 'gender' in body:
            if body['gender'] != 'm' and body['gender'] != 'f':
                return 'gender must be m/f', 400

        user = r.hgetall('user:'******'username'])
        if user:
            return 'username exists', 403
        email = r.hget('emails', body['email'])
        if email:
            return 'email exists', 403

        hashed = hash(body['password'], make_salt())

        user = {
            'username': body['username'].strip().lower(),
            'password': hashed,
            'email': body['email'].strip().lower(),
            'created': timems()
        }

        if 'country' in body:
            user['country'] = body['country']
        if 'age' in body:
            user['age'] = body['age']
        if 'gender' in body:
            user['gender'] = body['gender']

        r.hmset('user:'******'username'], user)
        r.hset('emails', body['email'], body['username'])

        return '', 200
Ejemplo n.º 16
0
def save_program(user):

    body = request.json
    if not type_check(body, 'dict'):
        return 'body must be an object', 400
    if not object_check(body, 'code', 'str'):
        return 'code must be a string', 400
    if not object_check(body, 'name', 'str'):
        return 'name must be a string', 400
    if not object_check(body, 'level', 'int'):
        return 'level must be an integer', 400

    # We execute the saved program to see if it would generate an error or not
    error = None
    try:
        hedy_errors = TRANSLATIONS.get_translations(requested_lang(),
                                                    'HedyErrorMessages')
        result = hedy.transpile(body['code'], body['level'])
    except hedy.HedyException as E:
        error_template = hedy_errors[E.error_code]
        error = error_template.format(**E.arguments)
    except Exception as E:
        error = str(E)

    name = body['name']

    # We check if a program with a name `xyz` exists in the database for the username. If it does, we exist whether `xyz (1)` exists, until we find a program `xyz (NN)` that doesn't exist yet.
    # It'd be ideal to search by username & program name, but since DynamoDB doesn't allow searching for two indexes at the same time, this would require to create a special index to that effect, which is cumbersome.
    # For now, we bring all existing programs for the user and then search within them for repeated names.
    existing = db_get_many('programs', {'username': user['username']}, True)
    name_counter = 0
    for program in existing:
        if re.match('^' + re.escape(name) + '( \(\d+\))*', program['name']):
            name_counter = name_counter + 1
    if name_counter:
        name = name + ' (' + str(name_counter) + ')'

    db_set(
        'programs', {
            'id': uuid.uuid4().hex,
            'session': session_id(),
            'date': timems(),
            'lang': requested_lang(),
            'version': version(),
            'level': body['level'],
            'code': body['code'],
            'name': name,
            'server_error': error,
            'username': user['username']
        })
    program_count = 0
    if 'program_count' in user:
        program_count = user['program_count']
    db_set('users', {
        'username': user['username'],
        'program_count': program_count + 1
    })

    return jsonify({})
Ejemplo n.º 17
0
def chi2_test(xtab, alpha=0.05, verbose=1):
    xtab = utils.type_check(xtab)
    _chi2, _df, _p = base.chi2_rxc(xtab)

    if verbose == 1:
        utils.compare1(_p, alpha)

    return _chi2, _df, _p
Ejemplo n.º 18
0
Archivo: auth.py Proyecto: balath/hedy
    def login():
        body = request.json
        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'username', 'str'):
            return 'username must be a string', 400
        if not object_check(body, 'password', 'str'):
            return 'password must be a string', 400

        # If username has an @-sign, then it's an email
        if '@' in body['username']:
            user = db_get('users', {'email': body['username'].strip().lower()},
                          True)
        else:
            user = db_get('users',
                          {'username': body['username'].strip().lower()})

        if not user:
            return 'invalid username/password', 403
        if not check_password(body['password'], user['password']):
            return 'invalid username/password', 403

        # If the number of bcrypt rounds has changed, create a new hash.
        new_hash = None
        if config['bcrypt_rounds'] != extract_bcrypt_rounds(user['password']):
            new_hash = hash(body['password'], make_salt())

        cookie = make_salt()
        db_set(
            'tokens', {
                'id': cookie,
                'username': user['username'],
                'ttl': times() + session_length
            })
        if new_hash:
            db_set(
                'users', {
                    'username': user['username'],
                    'password': new_hash,
                    'last_login': timems()
                })
        else:
            db_set('users', {
                'username': user['username'],
                'last_login': timems()
            })
        resp = make_response({})
        # We set the cookie to expire in a year, just so that the browser won't invalidate it if the same cookie gets renewed by constant use.
        # The server will decide whether the cookie expires.
        resp.set_cookie(cookie_name,
                        value=cookie,
                        httponly=True,
                        secure=True,
                        samesite='Lax',
                        path='/',
                        max_age=365 * 24 * 60 * 60)
        return resp
Ejemplo n.º 19
0
def render_assignment_editor(request, course, level_number, assignment_number,
                             menu, translations, version, loaded_program,
                             loaded_program_name, adventure_assignments,
                             adventure_name):

    sublevel = None
    if type_check(level_number, 'str') and re.match('\d+-\d+', level_number):
        sublevel = int(level_number[level_number.index('-') + 1])
        level_number = int(level_number[0:level_number.index('-')])

    assignment = course.get_assignment(level_number, assignment_number,
                                       sublevel)

    if not assignment:
        abort(404)

    arguments_dict = {}

    # Meta stuff
    arguments_dict['course'] = course
    arguments_dict['level_nr'] = str(level_number)
    arguments_dict['sublevel'] = str(sublevel) if (sublevel) else None
    arguments_dict[
        'assignment_nr'] = assignment.step  # Give this a chance to be 'None'
    arguments_dict['lang'] = course.language
    arguments_dict['level'] = assignment.level
    arguments_dict['prev_level'] = int(level_number) - 1 if int(
        level_number) > 1 else None
    arguments_dict['next_level'] = int(level_number) + 1 if int(
        level_number) < course.max_level() else None
    arguments_dict['next_assignment'] = int(assignment_number) + 1 if int(
        assignment_number) < course.max_step(level_number) else None
    arguments_dict['menu'] = menu
    arguments_dict['latest'] = version
    arguments_dict['selected_page'] = 'code'
    arguments_dict['page_title'] = f'Level {level_number} – Hedy'
    arguments_dict['docs'] = [attr.asdict(d) for d in assignment.docs]
    arguments_dict['auth'] = translations.data[course.language]['Auth']
    arguments_dict['username'] = current_user(request)['username']
    arguments_dict['loaded_program'] = loaded_program
    arguments_dict['loaded_program_name'] = loaded_program_name
    arguments_dict['adventure_assignments'] = adventure_assignments
    arguments_dict['adventure_name'] = adventure_name

    # Translations
    arguments_dict.update(
        **translations.get_translations(course.language, 'ui'))

    # Actual assignment
    arguments_dict.update(**attr.asdict(assignment))

    # Add markdowns to docs
    for doc in arguments_dict['docs']:
        doc['markdown'] = (course.docs.get(int(level_number), doc['slug']) or {
            'markdown': ''
        }).markdown

    return render_template("code-page.html", **arguments_dict)
Ejemplo n.º 20
0
Archivo: app.py Proyecto: Tazaria/hedy
def save_program(user):

    body = request.json
    if not type_check(body, 'dict'):
        return 'body must be an object', 400
    if not object_check(body, 'code', 'str'):
        return 'code must be a string', 400
    if not object_check(body, 'name', 'str'):
        return 'name must be a string', 400
    if not object_check(body, 'level', 'int'):
        return 'level must be an integer', 400
    if 'adventure_name' in body:
        if not object_check(body, 'adventure_name', 'str'):
            return 'if present, adventure_name must be a string', 400

    name = body['name']

    # We check if a program with a name `xyz` exists in the database for the username.
    # It'd be ideal to search by username & program name, but since DynamoDB doesn't allow searching for two indexes at the same time, this would require to create a special index to that effect, which is cumbersome.
    # For now, we bring all existing programs for the user and then search within them for repeated names.
    programs = db_get_many('programs', {'username': user['username']}, True)
    program = {}
    overwrite = False
    for program in programs:
        if program['name'] == name:
            overwrite = True
            break

    stored_program = {
        'id': program.get('id') if overwrite else uuid.uuid4().hex,
        'session': session_id(),
        'date': timems(),
        'lang': requested_lang(),
        'version': version(),
        'level': body['level'],
        'code': body['code'],
        'name': name,
        'username': user['username']
    }

    if 'adventure_name' in body:
        stored_program['adventure_name'] = body['adventure_name']

    if overwrite:
        db_update('programs', stored_program)
    else:
        db_create('programs', stored_program)

    program_count = 0
    if 'program_count' in user:
        program_count = user['program_count']
    db_update('users', {
        'username': user['username'],
        'program_count': program_count + 1
    })

    return jsonify({'name': name})
Ejemplo n.º 21
0
def run_suite(tests):
    if not type_check(tests, 'list'):
        return print('Invalid test suite, must be a list.')
    counter = 1

    def run_test(test, counter):
        result = request(test, counter)

    for test in tests:
        # If test is nested, run a nested loop
        if not (type_check(test[0], 'str')):
            for subtest in test:
                run_test(subtest, counter)
                counter += 1
        else:
            run_test(test, counter)
            counter += 1

    print('Test suite successful! (' + str(timems() - t0) + 'ms)')
Ejemplo n.º 22
0
Archivo: app.py Proyecto: TiBiBa/hedy
def index(level, step):


    # Sublevel requested
    if re.match ('\d+-\d+', level):
        pass
        # If level has a dash, we keep it as a string
    # Normal level requested
    elif re.match ('\d', level):
        try:
            g.level = level = int(level)
        except:
            return 'No such Hedy level!', 404
    else:
        return 'No such Hedy level!', 404

    g.lang = requested_lang()
    g.prefix = '/hedy'

    initialize_gfi_session(g.lang)

    loaded_program = ''
    loaded_program_name = ''
    adventure_name = ''

    # If step is a string that has more than two characters, it must be an id of a program
    if step and type_check (step, 'str') and len (step) > 2:
        result = db_get ('programs', {'id': step})
        if not result:
            return 'No such program', 404
        # If the program is not public, allow only the owner of the program, the admin user and the teacher users to access the program
        user = current_user (request)
        public_program = 'public' in result and result ['public']
        if not public_program and user ['username'] != result ['username'] and not is_admin (request) and not is_teacher (request):
            return 'No such program!', 404
        loaded_program = result ['code']
        loaded_program_name = result ['name']
        if 'adventure_name' in result:
            adventure_name = result ['adventure_name']
        # We default to step 1 to provide a meaningful default assignment
        step = 1

    adventure_assignments = load_adventure_assignments_per_level(g.lang, level)
    return hedyweb.render_assignment_editor(
        request=request,
        course=HEDY_COURSE[g.lang],
        level_number=level,
        assignment_number=step,
        menu=render_main_menu('hedy'),
        translations=TRANSLATIONS,
        version=version(),
        adventure_assignments=adventure_assignments,
        loaded_program=loaded_program,
        loaded_program_name=loaded_program_name,
        adventure_name=adventure_name)
Ejemplo n.º 23
0
Archivo: app.py Proyecto: TiBiBa/hedy
def adventure_page(adventure_name, level):

    user = current_user (request)
    level = int (level)
    adventures = load_adventure_for_language (requested_lang ())

    # If requested adventure does not exist, return 404
    if not adventure_name in adventures ['adventures']:
        return 'No such Hedy adventure!', 404

    adventure = adventures ['adventures'] [adventure_name]

    # If no level is specified (this will happen if the last element of the path (minus the query parameter) is the same as the adventure_name)
    if re.sub (r'\?.+', '', request.url.split ('/') [len (request.url.split ('/')) - 1]) == adventure_name:
        # If user is logged in, check if they have a program for this adventure
        # If there are many, note the highest level for which there is a saved program
        desired_level = 0
        if user ['username']:
            existing_programs = db_get_many ('programs', {'username': user ['username']}, True)
            for program in existing_programs:
                if 'adventure_name' in program and program ['adventure_name'] == adventure_name and program ['level'] > desired_level:
                    desired_level = program ['level']
            # If the user has a saved program for this adventure, redirect them to the level with the highest adventure
            if desired_level != 0:
                return redirect(request.url.replace ('/' + adventure_name, '/' + adventure_name + '/' + str (desired_level)), code=302)
        # If user is not logged in, or has no saved programs for this adventure, default to the lowest level available for the adventure
        if desired_level == 0:
            for key in adventure ['levels'].keys ():
                if type_check (key, 'int') and (desired_level == 0 or desired_level > key):
                    desired_level = key
        level = desired_level

    # If requested level is not in adventure, return 404
    if not level in adventure ['levels']:
        abort(404)

    initialize_gfi_session(requested_lang())

    adventure_assignments = load_adventure_assignments_per_level(requested_lang(), level)
    g.prefix = '/hedy'
    return hedyweb.render_assignment_editor(
        request=request,
        course=HEDY_COURSE[requested_lang()],
        level_number=level,
        assignment_number=1,
        menu=render_main_menu('hedy'),
        translations=TRANSLATIONS,
        version=version(),
        adventure_assignments=adventure_assignments,
        # The relevant loaded program will be available to client-side js and it will be loaded by js.
        loaded_program='',
        loaded_program_name='',
        adventure_name=adventure_name)
Ejemplo n.º 24
0
def normality_test(x, alpha=0.1, verbose=1):
    x = utils.type_check(x)
    p_skew, p_kurtosis = base.norm_moment(x)

    if verbose == 1:
        print("使用矩法(动差法)检验正态性:")
        print("p_skew = {0}, p_kurtosis = {1}, alpha = {2}".format(
            p_skew, p_kurtosis, alpha))
        if p_skew < alpha and p_kurtosis < alpha:
            print("p_skew < alpha, p_kurtosis < alpha, 这些样本不服从正态分布")
        else:
            print("尚不能内定这些样本不服从正态分布")
    return p_skew, p_kurtosis
Ejemplo n.º 25
0
Archivo: app.py Proyecto: TiBiBa/hedy
def share_unshare_program(user):
    body = request.json
    if not type_check (body, 'dict'):
        return 'body must be an object', 400
    if not object_check (body, 'id', 'str'):
        return 'id must be a string', 400
    if not object_check (body, 'public', 'bool'):
        return 'public must be a string', 400

    result = db_get ('programs', {'id': body ['id']})
    if not result or result ['username'] != user ['username']:
        return 'No such program!', 404

    db_update ('programs', {'id': body ['id'], 'public': 1 if body ['public'] else None})
    return jsonify({})
Ejemplo n.º 26
0
def chi2_paired(xtab, alpha=0.05, verbose=1):
    xtab = utils.type_check(xtab)
    if xtab.shape != (2, 2):
        raise IOError("配对卡方检验仅支持四格表资料!!!")

    b, c = xtab[0, 1], xtab[1, 0]
    b_c = b + c
    if b_c >= 40:
        _chi2 = (b - c)**2 / b_c
    else:
        _chi2 = (np.abs(b - c) - 1)**2 / b_c
    _p = stats.chi2.sf(_chi2, 1)

    if verbose == 1:
        utils.compare0(_p, alpha)
    return _chi2, 1, _p
Ejemplo n.º 27
0
    def change_password(user):

        body = request.json
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'oldPassword', 'str'):
            return 'body.oldPassword must be a string', 400
        if not object_check(body, 'newPassword', 'str'):
            return 'body.newPassword must be a string', 400

        if not check_password(body['oldPassword'], user['password']):
            return 'invalid username/password', 403

        hashed = hash(body['newPassword'], make_salt())

        r.hset('user:'******'username'], 'password', hashed)
        return '', 200
Ejemplo n.º 28
0
def qqplot(x):
    x = utils.type_check(x)
    sigma = utils.sample_std(x)
    x.sort()
    qi = (x - x.mean()) / sigma

    i = np.arange(x.size) + 1
    ti = (i - 0.5) / x.size
    pi = -norm.isf(ti)

    line = [-4, 4]
    plt.figure()
    plt.scatter(pi, qi, s=25, marker='o')
    plt.plot(line, line, lw=0.5, c='black')
    plt.xlabel("t Quantiles")
    plt.ylabel("Studentized Residuals")
    plt.title("Q-Q Plot")
    plt.show()
Ejemplo n.º 29
0
    def reset():
        body = request.json
        # Validations
        if not type_check(body, 'dict'):
            return 'body must be an object', 400
        if not object_check(body, 'token', 'str'):
            return 'body.token must be a string', 400
        if not object_check(body, 'password', 'str'):
            return 'body.password be a string', 400

        username = r.get('token:' + body['token'])
        if not username:
            return 'invalid token', 403

        hashed = hash(body['password'], make_salt())
        r.delete('token:' + body['token'])
        r['hset']('user:'******'password', hashed)
        return {}, 200
Ejemplo n.º 30
0
Archivo: auth.py Proyecto: tech189/hedy
    def update_profile (user):

        body = request.json
        if not type_check (body, 'dict'):
            return 'body must be an object', 400
        if 'email' in body:
            if not object_check (body, 'email', 'str'):
                return 'body.email must be a string', 400
            if not re.match ('^(([a-zA-Z0-9_\.\-]+)@([\da-zA-Z\.\-]+)\.([a-zA-Z\.]{2,6})\s*)$', body ['email']):
                return 'body.email must be a valid email', 400
        if 'country' in body:
            if not body ['country'] in countries:
                return 'body.country must be a valid country', 400
        if 'birth_year' in body:
            if not object_check (body, 'birth_year', 'int') or body ['birth_year'] <= 1900 or body ['birth_year'] > datetime.datetime.now ().year:
                return 'birth_year must be a year between 1900 and ' + str (datetime.datetime.now ().year), 400
        if 'gender' in body:
            if body ['gender'] != 'm' and body ['gender'] != 'f' and body ['gender'] != 'o':
                return 'body.gender must be m/f/o', 400

        resp = {}
        if 'email' in body:
            email = body ['email'].strip ().lower ()
            if email != user ['email']:
                exists = db_get ('users', {'email': email}, True)
                if exists:
                    return 'email exists', 403
                token = make_salt ()
                hashed_token = hash (token, make_salt ())
                db_set ('users', {'username': user ['username'], 'email': email, 'verification_pending': hashed_token})
                if not env:
                   # If on local environment, we return email verification token directly instead of emailing it, for test purposes.
                   resp = {'username': user ['username'], 'token': hashed_token}
                else:
                    send_email_template ('welcome_verify', email, requested_lang (), os.getenv ('BASE_URL') + '/auth/verify?username='******'&token=' + urllib.parse.quote_plus (hashed_token))

        if 'country' in body:
            db_set ('users', {'username': user ['username'], 'country': body ['country']})
        if 'birth_year' in body:
            db_set ('users', {'username': user ['username'], 'birth_year': body ['birth_year']})
        if 'gender' in body:
            db_set ('users', {'username': user ['username'], 'gender': body ['gender']})

        return jsonify (resp)