import requests
import aiohttp
import asyncio

from bs4 import BeautifulSoup

import pandas as pd

import re
import time

ROOT = "https://www.coursera.org/"

async def async_get_course(session, url_course):
    async with session.get(url_course) as res:
        response = await res.content.read()
        return response

async def async_get_course_infos(courses):

  # Use this line to control number of courses to fetch during debugging and development
  #courses = courses[:3]

  actions = []
  urls = []
  course_infos = []
  async with aiohttp.ClientSession() as session:
      for course in courses:
          url_course = f"{ROOT}{course['course_link']}"
          urls.append(url_course)
          actions.append(asyncio.ensure_future(async_get_course(session, url_course)))
      results = await asyncio.gather(*actions)

      for idx, res in enumerate(results):
          course_infos.append(get_info_from_course((courses[idx], urls[idx], res)))

  return course_infos

def get_summary_page(category):

    course_html_containers = []
    url_browse = f"{ROOT}browse/{category}"
    request_counter = 0

    # Try requesting up to 30 times, otherwise be a respectful scraper and give up
    while not course_html_containers and request_counter < 31:
      request_browse = requests.get(url_browse)
      browse_soup = BeautifulSoup(request_browse.content, 'lxml', from_encoding='utf-8')
      course_html_containers = browse_soup.find_all('div', {'class': 'rc-ProductCard'})
      time.sleep(0.5)
      print("Coursera is not responding. I will try " + str(30 - request_counter) + " more times.")
      request_counter += 1

    browse_soup = BeautifulSoup(request_browse.content, 'lxml', from_encoding='utf-8')

    # Scraping 'Course Name' and 'Course Link' for each course found in Coursera's summary page
    courses = []
    for i, j in enumerate(course_html_containers):
        course_type = j.find('label', {'class': 'rc-CardText css-1feobmm'}).get_text()
        if course_type == 'Course':
            course_features = dict(course_name='', course_link='')
            course_features['course_name'] = j.find('a', {'class': 'CardText-link'}).get_text()
            course_features['course_link'] = j.find('a', {'class': 'CardText-link'})['href']
            courses.append(course_features)

    return courses

def get_info_from_course(response):
  # Scraping course page for each course. Updating 'Course Description', 'Enrollments' and 'Ratings'
  #for course in courses[:3]:

  course, _, course_response = response

  course_soup = BeautifulSoup(course_response, 'lxml', from_encoding='utf-8')
  course['instructor'] = get_course_instructor(course_soup)
  try:
    course['description'] = get_course_description(course_soup)
    course['students_enrolled'] = get_enrollments(course_soup)
    course['ratings'] = get_ratings(course_soup)
  except:
    course['description'] = "The course hasn't started yet."
    course['students_enrolled'] = "0"
    course['ratings'] = "0"

  return course

def get_course_instructor(soup):
    """
    Gets full description (all paragraphs) for a single course.
    """
    try:
      instructor = soup.find('div', {'class': 'rc-BannerInstructorInfo'}).find('span').get_text()
      instructor = re.sub(r'\s\+\d+\s[\w\s]+', '', instructor)
      if instructor[-1] == ' ':
          instructor = instructor[:-1]
    except:
      instructor = "NA"

    return instructor

def get_course_description(soup):
    """
    Gets full description (all paragraphs) for a single course.
    """
    descriptions_html_block = soup.find_all('div', {'class': 'content-inner'})
    html_paragraphs = descriptions_html_block[0].find_all('p')

    string_paragraphs = []
    for i in html_paragraphs:
        string_paragraphs.append(i.get_text())

    course_description = ''.join(string_paragraphs)

    return course_description

def get_enrollments(soup):
    """
    Gets number of enrolled students in a single course.
    """
    enrollments_as_str = soup.find('div', {'class': 'rc-ProductMetrics'}).find('strong').find('span').get_text()
    enrollments = int(enrollments_as_str.replace(',', ''))
    return enrollments

def get_ratings(soup):
    """
    Gets ratings of a single course.
    """
    ratings_as_str = soup.find('span', {'data-test': 'ratings-count-without-asterisks'}).find('span').get_text()
    ratings = int(ratings_as_str.strip(' ratings').replace(',', ''))
    return ratings

def scrape(category):
    """
    Gets a single course category and saves all courses from this category as .xslx file. Returns a list of courses
    with features.

    Excel file contains following categories: Course Name, Course Category, Instructor, Description, # of Students
    Enrolled, # of Ratings.

    In case, the course hasn't started yet (therefore has no ratings and no students enrolled), this information
    is shown in the .xlsx file in the following way: "Description": "The course hasn't started yet", "# of Students
    Enrolled": 0, "# of Ratings": 0

    DISCLAIMER: This function is designed to work with the server back end. In order to run it locally, pass the
    category argument in the following format: scrape('data-science'). You can choose from the following categories:
    ['data-science', 'business', 'personal-development', 'language-learning', 'math-and-logic', 'physical-science-and-engineering]
    """

    courses = get_summary_page(category)

    courses_final = asyncio.run(async_get_course_infos(courses))

    # Converting a list of courses into pandas DataFrame; Cleaning data structure, formatting column headers
    df = pd.DataFrame(courses_final)

    df['Category Name'] = category
    #df.drop('course_link', axis=1, inplace=True)
    df.rename(columns={'course_name': 'Course Name', 'instructor': 'First Instructor Name',
                       'description': 'Course Description',
                       'students_enrolled': '# of Students Enrolled', 'ratings': '# of Ratings'}, inplace=True)
    df = df.loc[:, ['Category Name', 'Course Name', 'First Instructor Name', 'Course Description',
                    '# of Students Enrolled', '# of Ratings']]
    df = df.drop_duplicates()

    # Printing summary information
    print(f'DONE! There are {len(courses_final)} courses in the category {category}.')
    print(df)

    return df

def get_dropdown_choices():
    """
    Gets each course category available in Coursera and returns a list which can be used as a dropdown list on the
    front end.
    DISCLAIMER: 'data-science' as a single value is hardcoded in the 'categories' value, as this element wasn't
    possible to get without using Selenium.
    """
    url_browse = "https://www.coursera.org/browse"
    request = requests.get(url_browse)
    soup = BeautifulSoup(request.content, 'lxml', from_encoding='utf-8')

    categories = soup.find_all('div', {'class': 'topic-column'})

    # data-science is hardcoded
    categories_list = ['data-science']
    for c in categories:
        categories_list.append(c.find('a')['to'][8:])

    categories_dict = {}
    for c in categories_list:
        categories_dict[c.replace('-', ' ').capitalize()] = c

    return categories_dict

#scrape_and_close = scrape('data-science')


#!/usr/bin/env python3

import torch
import torch.nn.functional as F
from regilib.core.invertible_modules.invertible_module import InvertibleModule

class SphericalStereographicProjection(InvertibleModule):
    def forward(self, ds, **kwargs):
        phi, Theta = ds['state'].T

        # unit-sphere -> polar
        r = torch.sin(phi) / (1 - torch.cos(phi))

        # polar -> xy
        ds['state'] = torch.stack([
            r*torch.cos(Theta), r*torch.sin(Theta)], -1)

        # deterministic pad: g: U → M ⊂ X
        ds['state'] = F.pad(ds['state'], (0, 1))
        return ds

    def inverse(self, ds, **kwargs):
        """ φ the zenith angle, 0 ≤ φ ≤ π, and θ the azimuth, -π ≤ θ ≤ π

        :param ds:
        :returns:

        """

        # deterministic project: g⁻¹: X -> U
        ds['state'] = ds['state'][:, :-1]

        # xy -> polar coordinates
        r = torch.norm(ds['state'], p=2, dim=1)
        Theta = torch.atan2(ds['state'][:, 1], ds['state'][:, 0])

        # polar -> unit-sphere
        phi = 2*torch.arctan(1/r)
        ds['state'] = torch.stack([phi, Theta], -1)

        return ds


import tensorflow as tf
import numpy as np
from scipy import ndimage

# zoom
@tf.function
def zoom(volume):
    """Zoom the volume by a few degrees"""

    volume_shape = volume.shape
    def augment_volume(volume):
        min_zoom = 0.8
        max_zoom = 1.2
        z = np.random.sample() *(max_zoom-min_zoom) + min_zoom
        zoom_matrix = np.array([[z, 0, 0, 0],
                                [0, z, 0, 0],
                                [0, 0, z, 0],
                                [0, 0, 0, 1]])
        return ndimage.affine_transform(volume, zoom_matrix, mode = "nearest", order = 1)

    augmented_volume = tf.py_function(augment_volume, [volume], tf.float32)
    augmented_volume.set_shape(volume_shape)
    return augmented_volume

@tf.function
def rotate(volume):
    """Rotate the volume by a few degrees"""

    volume_shape = volume.shape
    def augment_volume(volume):
        # define some rotation angles
        angles = [-20, -10, -5, 5, 10, 20]
        # pick angles at random
        angle = np.random.choice(angles)
        # rotate volume
        volume = ndimage.rotate(volume, angle, axes = (0,1), reshape = False, order = 3, mode = "nearest")
        #volume[volume < 0] = 0
        #volume[volume > 1] = 1
        return volume

    augmented_volume = tf.py_function(augment_volume, [volume], tf.float32)
    augmented_volume.set_shape(volume_shape)
    return augmented_volume

@tf.function
def shift(volume):
    """Shift the volume along the x and y axes"""

    volume_shape = volume.shape
    def augment_volume(volume):
        # define some shifts in the three different directions
        x_shift = np.random.uniform(-20, 20)
        y_shift = np.random.uniform(-20, 20)
        z_shift = np.random.uniform(0, 0)
        # shift volume
        volume = ndimage.shift(volume, [x_shift, y_shift, z_shift, 0], mode = "nearest", order = 0)
        return volume

    augmented_volume = tf.py_function(augment_volume, [volume], tf.float32)
    augmented_volume.set_shape(volume_shape)
    return augmented_volume

@tf.function
def flip(volume):
    """Randomly flip the volume"""
    volume_shape = volume.shape
    def augment_volume(volume):
        axis = np.random.choice([0,1])
        if(axis == 0): # vertical flip
            volume = volume[:,::-1,:,:]
        return volume

    augmented_volume = tf.py_function(augment_volume, [volume], tf.float32)
    augmented_volume.set_shape(volume_shape)
    return augmented_volume


from datetime import datetime as dt
from datetime import timedelta

ca_breaks = list()
sa_breaks = list()
all_break_dicts = list()
all_break_objs = list()

idCount = 0

class team_member:

    # No need to calculate all breaks at once just the next one for each person

    def __init__(self, name='', time_in='', time_out='', lanes=True, nb=None):
        self.generateID()
        self.name = name
        self.time_in = time_in
        self.time_out = time_out
        self.breaks_taken = 0
        self.lanes = lanes
        self.time_returned = time_in

        hrs = dt.strptime(time_out, "%I:%M %p") - dt.strptime(time_in, "%I:%M %p")
        self.hours = float(hrs.seconds/60/60)
        self.hours_left = self.hours

        if self.hours < 6:
            self.breaks_needed = 1
            self.need_lunch = False
        elif self.hours >= 6 and 6.5 >= self.hours:
            self.breaks_needed = 2
            self.need_lunch = True
        else:
            self.breaks_needed = 3
            self.need_lunch = True

        if nb is None:
            self.next_break()

        print(f'object created {self.__dict__} \n\n\n')

    def generateID(self):
        global idCount

        self.id = idCount

        idCount = idCount + 1

    def next_break(self):

        if self.breaks_taken == self.breaks_needed:

            print('max breaks reached')

            print(f'self {[self]}')
            print(f'Before removal: {all_break_objs}')
            if self in all_break_objs:
                all_break_objs.remove(self)
                print('removing')

            print(f'After removal {all_break_objs}')
            combine_n_sort()
            return

        tr = dt.strptime(self.time_returned, "%I:%M %p")

        till_nb = self.hours_left / \
            (self.breaks_needed - self.breaks_taken + 1)

        # check if its lunch or 15
        if self.breaks_taken == 1 and self.need_lunch:
            nb_start = tr + timedelta(hours=till_nb) - timedelta(minutes=15)
            nb_end = tr + timedelta(hours=till_nb) + timedelta(minutes=15)
            self.need_lunch = False
        else:
            nb_start = tr + timedelta(hours=till_nb) - timedelta(minutes=7.5)
            nb_end = tr + timedelta(hours=till_nb) + timedelta(minutes=7.5)

        nb_start = round(nb_start)
        nb_end = round(nb_end)

        break_tupp = (dt.strftime(nb_start, "%I:%M %p"),
                      dt.strftime(nb_end, "%I:%M %p"))

        self.nb = break_tupp

        if self.lanes:
            compare(self, ca_breaks)
        else:
            compare(self, sa_breaks)

        combine_n_sort()

    def take_break(self):

        print(f'inside taking break function for {self.name} ({[self]})')
        self.time_returned = self.nb[1]

        self.breaks_taken = self.breaks_taken + 1

        hrs = dt.strptime(self.time_out, "%I:%M %p") - \
            dt.strptime(self.time_returned, "%I:%M %p")
        self.hours_left = float(hrs.seconds/60/60)

        if self.lanes:
            bl = ca_breaks
        else:
            bl = sa_breaks

        for i in range(0, len(bl)):
            if self.id == bl[i-1].id:
                print(f'{[bl[i-1]]} should equal {[self]}')
                bl.pop(i-1)

    def __str__(self):
        return f"ID: {self.id}\nName: {self.name}\nTime In: {self.time_in}\nTime Out:{self.time_out}\nHours: {self.hours}\n\nBreaks Needed: {self.breaks_needed}\nBreaks Taken: {self.breaks_taken}\nhours left:{self.hours_left}\n\n\n"

def quick_sort(list_of_dicts):
    print('quick soarting')
    breaks = []
    length = len(list_of_dicts)
    if length <= 1:
        return (list_of_dicts)
    else:
        last_dict = list_of_dicts.pop()

        pivot = last_dict.nb[0]
        strp_pivot = dt.strptime(last_dict.nb[0], "%I:%M %p")

    items_greater = []
    items_lower = []

    for dict in list_of_dicts:
        if dt.strptime(dict.nb[0], "%I:%M %p") > strp_pivot:
            items_greater.append(dict)
        else:
            items_lower.append(dict)

        piv_list = []
        piv_list.append(last_dict)

    # print(f'Printing list of lastdict: {last_dict}')
    return quick_sort(items_lower) + piv_list + quick_sort(items_greater)

def round(t):
    # print('rounding')
    # print(t)
    t = t - timedelta(seconds=(t.second))
    # print(t)
    remainder = (t.minute) % 5
    difference = 5 - remainder
    #print(f'dif: {difference}')

    if difference >= 5:
        return (t)
    elif difference >= 2.5:
        return (t + timedelta(minutes=difference))
    else:
        return (t - timedelta(minutes=difference))

def compare(new_b, break_list):
    # Compare the values being added with the tupple in the correct dict.
    # if there is overlap, shift values around (5 min intervles right and left alternating)
    # if there is a shift we need to make sure it didnt mess with the other breaks
    # for loop nested within a while loop while shifted: for...
    # after this we need to merge and sort our lists

    # if the list doesnt have any break dicts in it: append
    # else compare the current break with all values in the list.
    # if overlap: call overlap function wich will return re arrange the list: then break out of the loop.
    print('Comparing and fixing')
    ol = False
    b_start = new_b.nb[0]
    b_end = new_b.nb[1]

    count = 0

    if len(break_list) > 0:
        for b in break_list:

            if b.nb[0] <= b_start and b_start < b.nb[1] or b.nb[0] < b_end and b_end <= b.nb[1]:
                print(
                    f"We have an overlap between {b.name}:{b.nb}  and {new_b.name}: {new_b.nb} ")
                ol = True
                print(f'popping {break_list.pop(count).name}')
                print(break_list)
                # break_list.pop(count)
                overlap(break_list, b, new_b, 0)
                break
            count = count + 1

        if not ol:
            print(f'no ol so appending {new_b.name}')
            break_list.append(new_b)

    else:
        print(f'appending first item {new_b.name}')
        break_list.append(new_b)

def overlap(bl, ol1, ol2, recur):

    global new_ol1_tupp, new_ol2_tupp
    print("in overlap function")
    print(ol1.nb)
    print(ol2.nb)

    ol1_start = dt.strptime(ol1.nb[0], "%I:%M %p")
    ol1_end = dt.strptime(ol1.nb[1], "%I:%M %p")

    ol2_start = dt.strptime(ol2.nb[0], "%I:%M %p")
    ol2_end = dt.strptime(ol2.nb[1], "%I:%M %p")

    while ol1_start <= ol2_start and ol2_start < ol1_end or ol1_start < ol2_end and ol2_end <= ol1_end:
        print('Fixing overlap')
        if ol1_start <= ol2_start:
            # ol1 moves <------ and
            # ol2 moves ---->
            if recur % 2 == 0:
                ol1_start = ol1_start - timedelta(minutes=5)
                ol1_end = ol1_end - timedelta(minutes=5)
            else:
                ol2_start = ol2_start + timedelta(minutes=5)
                ol2_end = ol2_end + timedelta(minutes=5)

        else:
            # can I pop the dict that im editiing or will i need to use an index for the second overlap
            if recur % 2 == 0:
                ol1_start = ol1_start + timedelta(minutes=5)
                ol1_end = ol1_end + timedelta(minutes=5)

            else:
                ol2_start = ol2_start - timedelta(minutes=5)
                ol2_end = ol2_end - timedelta(minutes=5)

        recur = recur + 1

        new_ol1_tupp = (dt.strftime(ol1_start, "%I:%M %p"),
                        dt.strftime(ol1_end, "%I:%M %p"))
        new_ol2_tupp = (dt.strftime(ol2_start, "%I:%M %p"),
                        dt.strftime(ol2_end, "%I:%M %p"))

        print(f'new tupp: {new_ol1_tupp}')
        print(f'new tupp: {new_ol2_tupp}')

    ol1.nb = new_ol1_tupp
    ol2.nb = new_ol2_tupp

    print(ol1.nb)
    print(ol2.nb)
    compare(ol1, bl)
    compare(ol2, bl)

    print()
    print(f"new list{bl}")

def print_list(b):
    # os.system('clear')
    for p in b:
        print(f'Name:{p.name}\tNext Break{p.nb}')

def combine_n_sort():
    global all_break_objs
    global all_break_dicts

    all_break_objs = sa_breaks + ca_breaks

    if len(all_break_dicts) > 0:
        all_break_dicts.clear()

    all_break_objs = quick_sort(all_break_objs)
    for obj in all_break_objs:
        all_break_dicts.append(obj.__dict__)

# ------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------

def loadDefaults():
    all_break_dicts.clear()
    all_break_objs.clear()
    ca_breaks.clear()
    sa_breaks.clear()

    jake = team_member('Jake', '10:00 AM', '8:00 PM', False)
    kyle = team_member('Kyle', '10:00 AM', '8:00 PM', False)
    marco = team_member('Marco', '10:00 AM', '8:00 PM', False)
    kaya = team_member('Kaya', '9:00 AM', '4:00 PM', True)
    loucks = team_member('Loucks', '10:00 AM', '3:00 PM', False)

def addTM(name, timeIn, timeOut, lanes):
    tempTM = team_member(name, timeIn, timeOut, lanes)


import os
import tensorflow as tf
import numpy as np
import cv2
from glob import glob
from tqdm import tqdm

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

if __name__ == "__main__":
    test_images = glob("segmentation_full_body_tik_tok_2615_img/images/*")
    model = tf.keras.models.load_model("weights/best.h5", compile=False)

    for path in tqdm(test_images, total=len(test_images)):
        x = cv2.imread(path, cv2.IMREAD_COLOR)
        original_image = x
        h, w, _ = x.shape

        x = cv2.resize(x, (256, 256))
        x = x / 255.0
        x = x.astype(np.float32)

        x = np.expand_dims(x, axis=0)
        pred_mask = model.predict(x)[0]

        pred_mask = np.concatenate(
            [
                pred_mask,
                pred_mask,
                pred_mask
            ], axis=2)
        pred_mask = (pred_mask > 0.5) * 255
        pred_mask = pred_mask.astype(np.float32)
        pred_mask = cv2.resize(pred_mask, (w, h))

        original_image = original_image.astype(np.float32)

        alpha = 0.6
        cv2.addWeighted(pred_mask, alpha, original_image, 1 - alpha, 0, original_image)

        name = path.split("/")[-1]

        cv2.imwrite(f"save_images/{name}", original_image)


import http
from flask_restx import Namespace,Resource,fields
from flask_jwt_extended import jwt_required,get_jwt_identity
from ..models.orders import Order
from ..models.users import User
from http import HTTPStatus
from ..utils.db import db

order_namespace=Namespace('orders',description="Namespace for orders")

order_model=order_namespace.model(
    'Order',{
        'id':fields.Integer(description="An ID"),
        'size':fields.String(description="Size of order",required=True,
            enum=['SMALL','MEDIUM','LARGE','EXTRA_LARGE']
        ),
        'order_status':fields.String(description="The status of the Order",
            required=True, enum=['PENDING','IN_TRANSIT','DELIVERED']
        )
    }
)

order_status_model=order_namespace.model(
    'OrderStatus',{
        'order_status':fields.String(description="Order status",
        enums=['PENDING','IN_TRANSIT','DELIVERED'])
    }
)

@order_namespace.route('/orders/')
class OrderGetCreate(Resource):

    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Retrieve all orders"
    )
    @jwt_required()
    def get(self):
        """
            Get all orders
        """
        orders=Order.query.all()

        return orders ,HTTPStatus.OK

    @order_namespace.expect(order_model)
    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Place an order"
    )
    @jwt_required()
    def post(self):
        """
            place a new order
        """

        username=get_jwt_identity()

        current_user=User.query.filter_by(username=username).first()

        data=order_namespace.payload

        new_order=Order(
            size=data['size'],
            quantity=data['quantity'],
            flavour=data['flavour']
        )

        new_order.user=current_user

        new_order.save()

        return new_order , HTTPStatus.CREATED

@order_namespace.route('/order/<int:order_id>')
class GetUpdateDelete(Resource):

    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Retrieve an order by ID",
        params={
            "order_id":"An ID for a given order"
        }
    )
    @jwt_required()
    def get(self,order_id):
        """
            Retrieve an order by its id
        """
        order=Order.get_by_id(order_id)

        return order ,HTTPStatus.OK

    @order_namespace.expect(order_model)
    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Update an order given an order ID",
        params={
            "order_id":"An ID for a given order"
        }
    )
    @jwt_required()
    def put(self,order_id):

        """
            Update an order with id
        """

        order_to_update=Order.get_by_id(order_id)

        data=order_namespace.payload

        order_to_update.quantity=data['quantity']
        order_to_update.size=data['size']
        order_to_update.flavour=data['flavour']

        db.session.commit()

        return order_to_update, HTTPStatus.OK

    @jwt_required()
    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Delete an order given an order ID",
        params={
            "order_id":"An ID for a given order"
        }
    )
    def delete(self,order_id):

        """
            Delete an order with id
        """
        order_to_delete=Order.get_by_id(order_id)

        order_to_delete.delete()

        return order_to_delete ,HTTPStatus.NO_CONTENT

@order_namespace.route('/user/<int:user_id>/order/<int:order_id>/')
class GetSpecificOrderByUser(Resource):

    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Get a user's specific order",
        params={
            "order_id":"An ID for a given order",
            "user_id":"A user's ID"
        }
    )
    @jwt_required()
    def get(self,order_id,user_id):

        """
            Get a user's specific order
        """

        user=User.get_by_id(user_id)

        order=Order.query.filter_by(id=order_id).filter_by(user=user).first()

        return  order ,HTTPStatus.OK

@order_namespace.route('/user/<int:user_id>/orders')
class UserOrders(Resource):

    @order_namespace.marshal_list_with(order_model)
    @order_namespace.doc(
        description="Get orders of a user given the user ID",
        params={
            "user_id":"An ID for a given user"
        }
    )
    @jwt_required()
    def get(self,user_id):
        """
            Get all orders by a specific user
        """

        user=User.get_by_id(user_id)

        orders=user.orders

        return orders, HTTPStatus.OK

@order_namespace.route('/order/status/<int:order_id>')
class UpdateOrderStatus(Resource):

    @order_namespace.expect(order_status_model)
    @order_namespace.marshal_with(order_model)
    @order_namespace.doc(
        description="Update an order status given the order  ID",
        params={
            "order_id":"An ID for a given order"
        }
    )
    @jwt_required()
    def patch(self,order_id):
        """
            Update an order's status
        """

        data=order_namespace.payload

        order_to_update=Order.get_by_id(order_id)

        order_to_update.order_status=data['order_status']

        db.session.commit()

        return order_to_update ,HTTPStatus.OK


#!/usr/bin/env python
#
# implements Python DBAPI 2.0
# see PEP 249 (http://www.python.org/dev/peps/pep-0249/)
import re
import base64
import decimal

from SPARQLWrapper.Wrapper import SELECT, INSERT, DELETE, MODIFY
# CONSTRUCT
# ASK
# DESCRIBE

class Error(Exception):
    pass

class SparqlSyntaxError(Exception):
    def __init__(self, message, line=None):
        self.message = message
        self.line = line

class DatabaseError(Error):
    pass

class ProgrammingError(DatabaseError):
    def __init__(self, msg, **kwargs):
        DatabaseError.__init__(self, msg)

class Cursor(object):
    def __init__(self, connection, prefixes=''):
        self.arraysize = 100
        self.connection = connection
        self.sparql = None
        self.results = None
        self.pointer = 0
        self.prefixes = prefixes
        self.rowcount = -1

    def __iter__(self):
        result = self.pointer and self.results[self.pointer:] or self.results
        return iter(result)

    def _desc(self):
        #(name, type_code, display_size, internal_size, precision, scale, null_ok)
        #first two are required, supply None for optional values
        if not self.results:
            return None

        if len(self.results) == 0:
            return None

        desc = []
        cols = [self.results.get_binding_name(i) for i in range(self.results.get_bindings_count())]
        for col in cols:
            desc_col = (col, literal_datatype(self.results.get_binding_value_by_name(col)), None, None, None, None, None)
            desc.append(desc_col)
        return desc

        #if no return values, or nothing executed
        return None
    description = property(_desc)

    def close(self):
        pass

    def _escape_param(self, param):
        # if type(param) in typeToSchema:
        #     return '%s^^%s' % (param, typeToSchema[type(param)])
        if isinstance(param, (str, unicode)):
            return '%s' % param
        return unicode(param)

    def escape_params(self, parameters):
        #for dict, return dict
        if isinstance(parameters, dict):
            params = {}
            for k, v in parameters.iteritems():
                params[k] = self._escape_param(v)
            return params
        #for sequence, return tuple
        params = []
        for p in parameters:
            params.append(self._escape_param(p))
        return tuple(params)

    def execute(self, sparql, params=[]):
        params = self.escape_params(params)
        sparql = '%s %s' % (' '.join(self.prefixes), sparql)
        self.sparql = sparql % params
        self.connection.setQuery(self.sparql)
        self.results = self.connection.query().convert()["results"]["bindings"]
        self.update_rowcount()

    def update_rowcount(self):
        if self.connection.queryType == SELECT:
            self.rowcount = len(self.results)
        elif self.connection.queryType == INSERT \
        or self.connection.queryType == DELETE:
            message = self.results[0]['callret-0']['value']
            finder = re.search('(?P<number>\d).*triples', message).groupdict()
            self.rowcount = int(finder['number'])
        elif self.connection.queryType == MODIFY:
            message = self.results[0]['callret-0']['value']
            finder = re.search('delete (?P<deleted>\d).*insert (?P<inserted>\d)', message).groupdict()
            deleted = int(finder['deleted'])
            inserted = int(finder['inserted'])
            self.rowcount = deleted or inserted
        else:
            raise NotImplementedError("Type %s cannot get a rowcount" % self.connection.queryType)

    def executemany(self, operation, seq_of_parameters):
        raise NotImplementedError('executemany need to implemented')

    # def next(self):
    #     row = self.fetchone()
    #     if row is None:
    #         raise StopIteration
    #     return row

    def fetchone(self):
        if self.pointer >= len(self.results):
            return None
        result = self.results[self.pointer]
        self.pointer += 1
        return _rowfactory(result)

    def fetchmany(self, size=None):
        end = self.pointer + (size or self.arraysize)
        results = self.results[self.pointer:end]
        self.pointer = min(end, len(self.results))
        return tuple([
            _rowfactory(r) for r in results
        ])

    def fetchall(self):
        if self.pointer:
            results = self.results[self.pointer:]
        else:
            results = self.results
        self.pointer = len(self.results)
        return tuple([
            _rowfactory(r) for r in results
        ])

    def dictfetchone(self):
        if not self.results:
            return None
        return self.results[0]

    def nextset(self):
        return None

    def setinputsizes(self):
        pass

    def setoutputsize(self, size, column=None):
        pass

def _rowfactory(row):
    return tuple([(key, value['value']) for key, value in row.items()])

def literal_datatype(node):
    if not node.is_literal():
        return None
    dt = node.literal_value['datatype']
    if dt:
        return unicode(dt)
    return u'http://www.w3.org/2001/XMLSchema#string'

typeToSchema = {
    unicode: '<http://www.w3.org/2001/XMLSchema#string>',
    bool: '<http://www.w3.org/2001/XMLSchema#boolean>',
    decimal: '<http://www.w3.org/2001/XMLSchema#decimal>',
    int: '<http://www.w3.org/2001/XMLSchema#integer>',
    long: '<http://www.w3.org/2001/XMLSchema#long>',
    float: '<http://www.w3.org/2001/XMLSchema#float>',
    base64: '<http://www.w3.org/2001/XMLSchema#base64Binary>',
}

SchemaToPython = {  # (schema->python, python->schema)  Does not validate.
    'http://www.w3.org/2001/XMLSchema#string': (unicode, unicode),
    'http://www.w3.org/2001/XMLSchema#normalizedString': (unicode, unicode),
    'http://www.w3.org/2001/XMLSchema#token': (unicode, unicode),
    'http://www.w3.org/2001/XMLSchema#language': (unicode, unicode),
    'http://www.w3.org/2001/XMLSchema#boolean': (bool, lambda i: unicode(i).lower()),
    'http://www.w3.org/2001/XMLSchema#decimal': (decimal.Decimal, unicode),
    'http://www.w3.org/2001/XMLSchema#integer': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#nonPositiveInteger': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#long': (long, unicode),
    'http://www.w3.org/2001/XMLSchema#nonNegativeInteger': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#negativeInteger': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#int': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#unsignedLong': (long, unicode),
    'http://www.w3.org/2001/XMLSchema#positiveInteger': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#short': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#unsignedInt': (long, unicode),
    'http://www.w3.org/2001/XMLSchema#byte': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#unsignedShort': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#unsignedByte': (int, unicode),
    'http://www.w3.org/2001/XMLSchema#float': (float, unicode),
    'http://www.w3.org/2001/XMLSchema#double': (float, unicode),  # doesn't do the whole range
#    duration
#    dateTime
#    time
#    date
#    gYearMonth
#    gYear
#    gMonthDay
#    gDay
#    gMonth
#    hexBinary
    'http://www.w3.org/2001/XMLSchema#base64Binary': (base64.decodestring, lambda i: base64.encodestring(i)[:-1]),
    'http://www.w3.org/2001/XMLSchema#anyURI': (str, str),
}


# This script computes the mutual information (MI) from the covariance between atomic displacements

import numpy as np
import time
from numpy import linalg as LA
import csv
import exclusion as ex
import MDAnalysis as mda
import MDAnalysis.analysis.encore.covariance as covar
import MDAnalysis.analysis.pca as pca
import covariance as covar

#_______________________________________
# INPUTS
structure_file = '/gpfs/scratch60/fas/batista/pd455/omcs_structure/2chains/fully_ox/CNA/matrix_calculation/extract_protein/myprot_reference_ox.psf'
dcd_trajectory = '/gpfs/scratch60/fas/batista/pd455/omcs_structure/2chains/fully_ox/CNA/matrix_calculation/extract_protein/trunc_prot_only_traj_ox.dcd'
#______________________________________

def MI(covar_matrix,natoms):
	# This function computes the linear mutual information matrix
	print('computing linear mutual information matrix\n')
	twobodycorr = np.zeros([natoms,natoms])
	for i in range(0,natoms):
		temp = mat_det(covar_matrix,i,i,3)
		for j in range(0,i):
			temp1 = mat_det(covar_matrix,j,j,3)
			temp2 = mat_det(covar_matrix,i,j,6)
			temp3 = temp*temp1/temp2
			temp3 = np.log(temp3)
			twobodycorr[i,j]=temp3
			twobodycorr[j,i] = twobodycorr[i,j]
	twobodycorr = 0.5 * twobodycorr

	return twobodycorr

def gen_corr(LMI_matrix,natoms,cen=None):
	# This function converts the linear mutual information into the generalized
	# correlation coefficient
	print('computing general correlation matrix\n')
	fileOUT = open('g_corr_list.txt','w')
	matOUT = open('g_corr_mat.txt','w')

	for j in range(0,natoms):
		for i in range(0,j):
			LMI_matrix[i,j] = 1.0 - np.exp((-2.0/3.0) * LMI_matrix[i,j])
			LMI_matrix[i,j] = np.sqrt(LMI_matrix[i,j])
			LMI_matrix[j,i] = LMI_matrix[i,j]
			print('%s	%s	%.3f' % (i,j,LMI_matrix[i,j]),file=fileOUT)
		LMI_matrix[j,j] = 1.0

	# Write general correlation matrix
	print("%s\n" % natoms,file=matOUT)
	with matOUT as f:
		csv_writer = csv.writer(f,delimiter = ' ')
		csv_writer.writerows(LMI_matrix)

	matOUT.close()

	if cen:
		centrality(LMI_matrix,natoms)

def mat_det(covar_matrix,ii,jj,n):
	matrix = np.zeros([n,n])
	l = 1
	if n == 6:
		for i in range(0,3):
			for j in range(0,3):
				matrix[i,j]=covar_matrix[ii*3+i,ii*3+j]
				matrix[i,j+3]=covar_matrix[ii*3+i,jj*3+j]
				matrix[i+3,j]=covar_matrix[jj*3+i,ii*3+j]
				matrix[i+3,j+3]=covar_matrix[jj*3+i,jj*3+j]
	elif n == 3:
		for i in range(0,3):
			for j in range(0,3):
				matrix[i,j]=covar_matrix[ii*3+i,jj*3+j]

	determinant = LA.det(matrix)
	return determinant

def centrality(g_corr_mat,natoms):
	cenOUT = open('eigvec_centrality.txt','w')

	[evalues,evectors] = LA.eig(g_corr_mat)
	idx = evalues.argsort()[::-1]
	evalues = evalues[idx]
	print(evalues[0])
	evectors = abs(evectors[:,idx])
	print(evectors[0:10,0])

	for i in range(natoms):
		sum_array = 0
		for j in range(natoms):
			sum_array += g_corr_mat[i,j]*evectors[j,0]
		cen_value = (1.0/evalues[0]) * sum_array
		print("%s       %s" % (i,cen_value), file=cenOUT)

start = time.time()

## Use MDAnalysis to compute the covariance matrix from your trajectory
u = mda.Universe(structure_file,dcd_trajectory)
nframes = len(u.trajectory)

# compute the covariance matrix
print('computing covariance matrix\n')
selection = 'all'
natoms = len(u.select_atoms(selection))
#print(natoms)
covar_matrix = covar.covariance(u,structure_file,selection)

# compute the mutual information matrix from the covariance matrix
LMI = MI(covar_matrix,natoms)

# compute and output the general correlation matrix
gen_corr(LMI,natoms,cen=True)

# compute the exclusion list
ex.exclusion(u,nframes,selection=selection)

end = time.time()
print('Done')
print('WallClock: %.6f' % (end-start))


import logging

from cubicweb_francearchives.dataimport import es_bulk_index

from cubicweb_elasticsearch.es import get_connection

def get_es_connection(cnx, index_name, log):
    es = get_connection(
        {
            "elasticsearch-locations": cnx.vreg.config["elasticsearch-locations"],
            "index-name": index_name,
            "elasticsearch-verify-certs": cnx.vreg.config["elasticsearch-verify-certs"],
            "elasticsearch-ssl-show-warn": cnx.vreg.config["elasticsearch-ssl-show-warn"],
        }
    )
    if es:
        return es
    if log:
        log.error("-> no es connection.abort")
    else:
        print("-> no es connection.abort")

def delete_autority_from_es(cnx, eids, log=None):
    """Delete authorities from all es indexes"""

    def docs_to_delete(es, eids, index_name):
        if log:
            log.info("es [%s]: deleting %s", index_name, eids)
        else:
            print(f"es [{index_name}]: deleting {eids}")
        for eid in eids:
            yield {
                "_op_type": "delete",
                "_index": index_name,
                "_type": "_doc",
                "_id": eid,
            }

    config = cnx.vreg.config
    indexes = [f"{config['index-name']}_suggest"]
    if config.get("published-index-name"):  # only in cms
        indexes.append(f"{config['published-index-name']}_suggest")
    if config["enable-kibana-indexes"]:
        indexes.append(config["kibana-authorities-index-name"])
    for index_name in indexes:
        es = get_es_connection(cnx, index_name, log)
        if not es:
            return
        es_docs = docs_to_delete(es, eids, index_name)
        es_bulk_index(es, es_docs, raise_on_error=False)

def update_index_mapping(cnx, index_name, mapping, log=None):
    if not log:
        log = logging.getLogger("update_index_mapping")
    es = get_es_connection(cnx, index_name, log)
    es.indices.put_mapping(index=index_name, body=mapping, doc_type="_doc", include_type_name=True)


import json
import sys
from argparse import ArgumentParser

import jsonschema

from pyrandall import commander
from pyrandall.hookspecs import get_plugin_manager
from pyrandall.spec import SpecBuilder
from pyrandall.types import Flags

FLAGS_MAP = {
    "simulate": Flags.SIMULATE,
    "validate": Flags.VALIDATE,
    "sanitytest": Flags.VALIDATE,  # legacy command
}

def run_command(config):
    specfile = config.pop("specfile")
    config["default_request_url"] = config["requests"].pop("url")

    # register plugins and call their initialize
    plugin_manager = get_plugin_manager()
    plugin_manager.hook.pyrandall_initialize(config=config)

    spec = SpecBuilder(specfile, hook=plugin_manager.hook, **config).feature()
    flags = FLAGS_MAP[config["command"]]
    # commander handles execution flow with specified data and config
    commander.Commander(spec, flags).invoke()

def add_common_args(parser):
    parser.add_argument("specfile", type=str, help="name of yaml file in scenario/")

def setup_args():
    parser = ArgumentParser(
        description="pyrandall a test framework oriented around data validation instead of code"
    )
    parser.add_argument(
        "--config",
        type=str,
        default="pyrandall_config.json",
        dest="config_path",
        help="path to json file for pyrandall config.",
    )
    parser.add_argument(
        "--dataflow",
        type=str,
        required=True,
        dest="dataflow_path",
        help="path to dataflow root directory",
    )

    subparsers = parser.add_subparsers(dest="command")
    # add simulate subcommand
    sim_parser = subparsers.add_parser("simulate", help="run Simulator for specfile")
    add_common_args(sim_parser)
    # add sanitycheck (legacy name)
    san_parser = subparsers.add_parser(
        "sanitytest", help="run Validate for specfile (Use validate command)"
    )
    add_common_args(san_parser)
    # add validate subcommand
    val_parser = subparsers.add_parser("validate", help="run Validate for specfile")
    add_common_args(val_parser)

    return parser

def argparse_error(args_data):
    msg = """
#######
Exit code was 2! Its assumed mocked arguments are wrong, see argparse usage below:

\t%s

actual arguments passed to mock:
\t%s

######
""" % (
        setup_args().format_help().replace("\n", "\n\t"),
        args_data,
    )
    return msg

def load_config(fpath):
    with open(fpath, "r") as f:
        return json.load(f)

def start(argv, config=None):
    parser = setup_args()
    args_config = parser.parse_args(argv)

    # TODO: add logging options
    # with open("logging.yaml") as log_conf_file:
    #     log_conf = yaml.safe_load(log_conf_file)
    #     dictConfig(log_conf)

    if args_config.command is None:
        parser.error("not a valid pyrandall command")
        exit(1)

    if config is None:
        config = load_config(args_config.config_path)

    # overwrite with cli options
    config.update(args_config.__dict__)

    try:
        run_command(config)
    except jsonschema.exceptions.ValidationError:
        print("Failed validating input yaml")
        exit(4)
    exit(0)

def main():
    start(sys.argv[1:])

if __name__ == "__main__":
    main()


from django.urls import include, path

from .views import ModelViewSet

model_list = ModelViewSet.as_view(
    {
        "get": "list",
        "post": "create",
        "delete": "destroy_list",
        "put": "update_list",
    }
)
model_details = ModelViewSet.as_view(
    {"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}
)

urlpatterns = [
    path("<str:model>/", model_list, name="model_api_model_list"),
    path("<str:model>/<str:id>", model_details, name="model_api_model_details"),
]


from urllib.error import URLError

import pandas as pd
import requests
import snowflake.connector
import streamlit

def requests_fruityvice(fruit: str):
    URL: str = "https://fruityvice.com/api/fruit/"
    try:
        response: requests.Response = requests.get(f"{URL}{fruit}")
        return pd.json_normalize(response.json())
    except Exception as e:
        return {"error": e}

def get_fruit_load():
    with my_cnx.cursor() as my_cur:
        my_cur.execute("SELECT * FROM FRUIT_LOAD_LIST")
        return my_cur.fetchall()

def insert_row_snoflake(new_fruit) -> str:
    with my_cnx.cursor() as my_cur:
        my_cur.execute(
            f"insert into PC_RIVERY_DB.PUBLIC.FRUIT_LOAD_LIST values ('{new_fruit}')")
        return f"Thanks for adding {new_fruit}"

streamlit.title("My parents new healthy diner")

streamlit.header("Breakfest menu")
streamlit.text("🥣 Omega 3 and Blueberry Oatmeal")
streamlit.text("🥗 Kale, Spinach and Rocket smoothie")
streamlit.text("🐔 Hard-Boiled Free-Range Egg")
streamlit.text("🥑🍞 Avocado toast")

streamlit.header('🍌🥭 Build Your Own Fruit Smoothie 🥝🍇')

# creating dataframe and putting on the app
my_fruit_list: pd.DataFrame = pd.read_csv(
    "https://uni-lab-files.s3.us-west-2.amazonaws.com/dabw/fruit_macros.txt")
my_fruit_list = my_fruit_list.set_index('Fruit')

# Let's put a pick list here so they can pick the fruit they want to include
fruits_selected = streamlit.multiselect("Pick some fruits:", list(
    my_fruit_list.index), ["Avocado", "Strawberries"])

# Filtered df to show
df_to_show = my_fruit_list.loc[fruits_selected]

# Display df
streamlit.dataframe(df_to_show)

# New header
streamlit.header("Fruityvice Fruit Advice!")

# User input
try:
    fruit_choice = streamlit.text_input(
        'What fruit would you like information about?')
    if not fruit_choice:
        streamlit.error("Please select a fruit to get information.")
    else:
        fruityvice_normalized = requests_fruityvice(fruit=fruit_choice)
        streamlit.dataframe(fruityvice_normalized)

except URLError as e:
    streamlit.error(e)

streamlit.header("The fruit load list contains:")
if streamlit.button("Get Fruit Load List"):
    my_cnx = snowflake.connector.connect(**streamlit.secrets["snowflake"])
    my_data_rows = get_fruit_load()
    my_cnx.close()
    streamlit.dataframe(my_data_rows)

second_fruit_choice = streamlit.text_input('What fruit do you  like to add?')
if streamlit.button("Add a Fruit to the List"):
    if second_fruit_choice:
        with snowflake.connector.connect(**streamlit.secrets["snowflake"]) as my_cnx:
            back_insert = insert_row_snoflake(new_fruit=second_fruit_choice)
            streamlit.text(back_insert)
    else:
        streamlit.error("Please to input a valid name")


import torch
from packaging import version
import numpy as np
import os
import torch.distributed as dist

if version.Version(torch.__version__) >= version.Version('1.0.0'):
  from torch import _softmax_backward_data as _softmax_backward_data
else:
  from torch import softmax_backward_data as _softmax_backward_data

class XSoftmax(torch.autograd.Function):
  """ Masked Softmax which is optimized for saving memory
  Args:

    input (:obj:`torch.tensor`): The input tensor that will apply softmax.
    mask (:obj:`torch.IntTensor`): The mask matrix where 0 indicate that element will be ignored in the softmax caculation.
    dim (int): The dimenssion that will apply softmax.

  Example::
    import torch
    from DeBERTa.deberta import XSoftmax
    # Make a tensor
    x = torch.randn([4,20,100])
    # Create a mask
    mask = (x>0).int()
    y = XSoftmax.apply(x, mask, dim=-1)

  """

  @staticmethod
  def forward(self, input, mask, dim):
    """
    """

    self.dim = dim
    if version.Version(torch.__version__) >= version.Version('1.2.0a'):
      rmask = ~(mask.bool())
    else:
      rmask = (1-mask).byte() # This line is not supported by Onnx tracing.

    output = input.masked_fill(rmask, float('-inf'))
    output = torch.softmax(output, self.dim)
    output.masked_fill_(rmask, 0)
    self.save_for_backward(output)
    return output

  @staticmethod
  def backward(self, grad_output):
    """
    """

    output, = self.saved_tensors
    inputGrad = _softmax_backward_data(grad_output, output, self.dim, output)
    return inputGrad, None, None

def build_relative_position(query_size, key_size, bucket_size=-1, max_position=-1):
  q_ids = np.arange(0, query_size)
  k_ids = np.arange(0, key_size)
  rel_pos_ids = q_ids[:, None] - np.tile(k_ids, (q_ids.shape[0],1))
  if bucket_size>0 and max_position > 0:
    rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position)
  rel_pos_ids = torch.tensor(rel_pos_ids, dtype=torch.long)
  rel_pos_ids = rel_pos_ids[:query_size, :]
  rel_pos_ids = rel_pos_ids.unsqueeze(0)
  return rel_pos_ids

def make_log_bucket_position(relative_pos, bucket_size, max_position):
  sign = np.sign(relative_pos)
  mid = bucket_size//2
  abs_pos = np.where((relative_pos<mid) & (relative_pos > -mid), mid-1, np.abs(relative_pos))
  log_pos = np.ceil(np.log(abs_pos/mid)/np.log((max_position-1)/mid) * (mid-1)) + mid
  bucket_pos = np.where(abs_pos<=mid, relative_pos, log_pos*sign).astype(np.int)
  return bucket_pos

class AverageMeter(object):
    """Computes and stores the average and current value"""
    def __init__(self, name, fmt=':f'):
        self.name = name
        self.fmt = fmt
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count

    def __str__(self):
        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'
        return fmtstr.format(**self.__dict__)

def accuracy(output, target, topk=(1,)):
    """Computes the accuracy over the k top predictions for the specified values of k"""
    with torch.no_grad():
        maxk = max(topk)
        batch_size = target.size(0)

        _, pred = output.topk(maxk, 1, True, True)
        pred = pred.t()
        correct = pred.eq(target.view(1, -1).expand_as(pred))

        res = []
        for k in topk:
            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)
            res.append(correct_k.mul_(100.0 / batch_size))
        return res

def init_distributed_mode(args):

    print('Setting up distributed mode...')
    args.num_gpu = 1
    args.device = 'cuda:%d' % args.local_rank
    torch.cuda.set_device(args.local_rank)
    torch.distributed.init_process_group(backend='nccl', init_method='env://')
    args.world_size = torch.distributed.get_world_size()
    args.rank = torch.distributed.get_rank()
    print('Distributed mode set...')

def setup_for_distributed(is_master):
    """
    This function disables printing when not in master process
    """
    import builtins as __builtin__
    builtin_print = __builtin__.print

    def print(*args, **kwargs):
        force = kwargs.pop('force', False)
        if is_master or force:
            builtin_print(*args, **kwargs)

    __builtin__.print = print

def is_dist_avail_and_initialized():
    if not dist.is_available():
        return False
    if not dist.is_initialized():
        return False
    return True

def get_world_size():
    if not is_dist_avail_and_initialized():
        return 1
    return dist.get_world_size()

def get_rank():
    if not is_dist_avail_and_initialized():
        return 0
    return dist.get_rank()


"""empty message

Revision ID: 1f119f1ea852
Revises: ef4f5d0dce05
Create Date: 2022-10-19 09:00:38.826310

"""
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from alembic import op

# revision identifiers, used by Alembic.
revision = "1f119f1ea852"
down_revision = "ef4f5d0dce05"
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "race",
        sa.Column("competition_id", postgresql.UUID(as_uuid=True), nullable=True),
    )
    op.drop_constraint("race_competion_id_fkey", "race", type_="foreignkey")
    op.create_foreign_key(None, "race", "competition", ["competition_id"], ["id"])
    op.drop_column("race", "competion_id")
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "race",
        sa.Column(
            "competion_id", postgresql.UUID(), autoincrement=False, nullable=True
        ),
    )
    op.drop_constraint(None, "race", type_="foreignkey")
    op.create_foreign_key(
        "race_competion_id_fkey", "race", "competition", ["competion_id"], ["id"]
    )
    op.drop_column("race", "competition_id")
    # ### end Alembic commands ###